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?

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.

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:

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

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

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.

Yay, nossa primeira implementação de HTTP em Ruby!

Mais detalhes no pull request

Last updated