# Protocolo HTTP

Vimos anteriormente como funciona a [comunicação TCP/IP](/comunicacao-tcp-ip.md) e como ela pode ser utilizada em uma arquitetura de rede cliente-servidor.&#x20;

![](/files/RPOOuLUfov6g7CnePxZJ)

O quê poderia acontecer caso a mensagem do cliente estivesse colocada de outra forma?

```
Client
-> QUERO fotos_da_festa.jpg
-> IWANT videos_de_domingo.mp4
-> PORFAVOR /hello

Server
-> if QUERO fotos_da_festa.jpg, then "Desculpa mas não tenho"
-> if IWANT videos_de_domingo.mp4, then "Aqui está!"
-> if PORFAVOR /hello, then "Hello client!"
```

Neste caso, diferentes clients poderiam enviar mensagens de diferentes formatos, cada qual com seu *próprio formato*, obrigado servers a saberem **interpretar** todos os formatos adequadamente.&#x20;

Como podemos então criar uma forma **padronizada** de mensagens, onde *clients e servers* pudessem todos utilizar o mesmo padrão? Quando queremos padronizar algo, geralmente criamos um **protocolo**.

Um protocolo é uma especificação bem definida e *documentada* de diretrizes e regras que, se seguidas, garantem que todas as partes possam estar uniformes. \
\
Para resolver o problema de padronizar mensagens na internet através de TCP/IP, foi criado um conjunto de especificações para envio com conteúdo que suportasse diferentes formatos (text, PDF, video etc), que se tornou o protocolo HyperText Transfer Protocol, ou [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol).

### O formato HTTP

Não esquecendo que a comunicação TCP/IP é baseada em client enviando um *request* e server enviando um *response*, logo o protocolo HTTP também está sujeito a tal característica.

#### Request

Um simples request com formato HTTP pode ser definido da seguinte forma:

```
GET /hello HTTP/2
```

Onde

* `GET` é o *verbo* da mensagem, neste caso remete semanticamente a "buscar algum recurso"
* `/hello` é o predicado da mensagem, remete a "caminho do recurso"
* `HTTP/2` é a versão do protocolo

#### Response

Já o response com formato HTTP pode ser algo do tipo:

```
HTTP/2 200

Hello
```

Onde

* `HTTP/2` representa a versão do protocolo
* `200` é o *código* status da resposta, que indica que o request foi recebido e interpretado com sucesso, retornando o que foi pedido
* `Hello` é o corpo da mensagem

### Informações adicionais no HTTP

E se quisermos enviar mais informações na mensagem HTTP, como por exemplo:

* o *tipo* de conteúdo que queremos enviar/receber
* quanto tempo o recurso deve "durar"
* o tamanho máximo permitido

...pra não mencionar diversas outras informações relevantes e que não são possíveis de enviar no **corpo** da mensagem? Para isto existem os HTTP headers. \
\
Portanto, podemos definir o template de uma mensagem HTTP como sendo da seguinte forma:

```
<request ou response>\r\n
Header1: valor1\r\n
Header2: valor2\r\n
\r\n
<corpo da mensagem>
```

O que são esses `\r\n` na mensagem? Este caracter é muito importante no protocolo HTTP, e pode ser explicado da seguinte forma:

* `\r` significa *carriage return*, move o cursor para o início da linha sem avançar para a próxima linha
* `\n` significa *line feed*, move o cursos para a próxima linha sem recuar para o início da linha
* `\r\n` é a combinação dos dois primeiros, ou seja, move o cursor para o início da próxima linha. É uma forma da mensagem ser consumida \*continuamente\* no socket TCP/IP até **não ter mais conteúdo no socket**.

### Um simples HTTP server em Ruby

Vamos então implementar uma simples comunicação HTTP **sem headers** em Ruby.

`client.rb`

```ruby
require 'socket'

server = TCPSocket.new('0.0.0.0', 3000)

request = %{
GET /hello HTTP/2\r\n
\r\n
\r\n
}

server.puts(request)

server.close
```

E vamos ao server:

`server.rb`

```ruby
require 'socket'

socket = TCPServer.new(3000)
puts 'Listening to the port 3000...'

loop do
  client = socket.accept

  request = client.gets
  puts "Request: #{request}"
  
  response = %{
HTTP/2 200\r\n
\r\n
\r\n
Hello
}
  client.puts(response)

  client.close
end

socket.close
```

Ao rodarmos `ruby server.rb` e `ruby client.rb`, conseguimos ver a mensagem "Hello" aparecendo no screen do client.&#x20;

Yay, nossa primeira implementação de HTTP em Ruby!&#x20;

[Mais detalhes no pull request](https://github.com/leandronsp/yatax/pull/2)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yatax.leandronsp.com/protocolo-http.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
