Protocolo HTTP
O que é HTTP, pra que serve e como funciona
Vimos anteriormente como funciona a comunicação TCP/IP e como ela pode ser utilizada em uma arquitetura de rede cliente-servidor.
O quê poderia acontecer caso a mensagem do cliente estivesse colocada de outra forma?
1
Client
2
-> QUERO fotos_da_festa.jpg
3
-> IWANT videos_de_domingo.mp4
4
-> PORFAVOR /hello
5
6
Server
7
-> if QUERO fotos_da_festa.jpg, then "Desculpa mas não tenho"
8
-> if IWANT videos_de_domingo.mp4, then "Aqui está!"
9
-> if PORFAVOR /hello, then "Hello client!"
Copied!
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.
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.

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:
1
GET /hello HTTP/2
Copied!
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:
1
HTTP/2 200
2
3
Hello
Copied!
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:
1
<request ou response>\r\n
2
Header1: valor1\r\n
3
Header2: valor2\r\n
4
\r\n
5
<corpo da mensagem>
Copied!
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
1
require 'socket'
2
3
server = TCPSocket.new('0.0.0.0', 3000)
4
5
request = %{
6
GET /hello HTTP/2\r\n
7
\r\n
8
\r\n
9
}
10
11
server.puts(request)
12
13
server.close
Copied!
E vamos ao server:
server.rb
1
require 'socket'
2
3
socket = TCPServer.new(3000)
4
puts 'Listening to the port 3000...'
5
6
loop do
7
client = socket.accept
8
9
request = client.gets
10
puts "Request: #{request}"
11
12
response = %{
13
HTTP/2 200\r\n
14
\r\n
15
\r\n
16
Hello
17
}
18
client.puts(response)
19
20
client.close
21
end
22
23
socket.close
Copied!
Ao rodarmos ruby server.rb e ruby client.rb, conseguimos ver a mensagem "Hello" aparecendo no screen do client.
Yay, nossa primeira implementação de HTTP em Ruby!