Entendendo um pouco mais sobre o protocolo HTTP


Leia em 4 minutos

Uma coisa que percebi é que nem todo mundo que trabalha com desenvolvimento web sabe como funciona o protocolo HTTP. Eu não sou nenhum expert no assunto, mas dei uma lida na especificação há uns 4 anos atrás.

Agora, com toda esta história de REST, não tem como escapar. Se você não souber o mínimo sobre o protocolo, vai trabalhar no escuro, sem saber ao certo o que está fazendo. Aqui, você verá um resumo da especificação. Divirta-se!

Sobre o HTTP

Hypertext Transfer Protocol (HTTP) é o método utilizado para enviar e receber informações na web. A versão mais utilizada atualmente é a 1.1, definida pela especificação RFC 2616. Embora esta especificação devesse ser leitura obrigatória para todo desenvolvedor web, muitos nem sabem como ela se parece. Tal desconhecimento ficou bastante claro quando, na época do lançamento do Google Web Accelerator (GWA), muitas informações começaram a ser excluídas. O GWA tem um princípio muito simples: ele acessa cada um dos links de uma determinado endereço sem se preocupar — e como iria saber? — com as consequências de tal acesso para fazer cache das informações e, então, exibí-las de um arquivo local quando forem solicitadas. Perda de informações como esta poderia ter sido evitada se a especificação HTTP fosse seguida da maneira como foi originalmente projetada.

O protocolo HTTP é baseado em requisições e respostas entre clientes e servidores. O cliente — navegador ou dispositivo que fará a requisição; também é conhecido como user agent — solicita um determinado recurso (resource), enviando um pacote de informações contendo alguns cabeçalhos (headers) a um URI ou, mais especificamente, URL. O servidor recebe estas informações e envia uma resposta, que pode ser um recurso ou um simplesmente um outro cabeçalho.

Se você utilizar um programa para visualizar os cabeçalhos de uma requisição — conhecidos como sniffers — na URL http://spesa.com.br, poderá ver algo semelhante a isto.

GET / HTTP/1.1
Host: spesa.com.br
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) Gecko/20061201 Firefox/2.0.0.3 (Ubuntu-feisty)
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Segundo este cabeçalho, estamos enviando algumas informações que identificam nosso cliente no caminho (path) / e, o mais importante, qual o método da requisição. O servidor, por sua vez, identifica os cabeçalhos que lhe são convenientes e envia uma resposta. Neste exemplo, recebemos os cabeçalhos de resposta, além de todo o conteúdo HTML da página inicial do Spesa.

HTTP/1.x 200 OK
Date: Fri, 04 May 2007 16:05:43 GMT
Server: Apache/2.0.59 (Unix) mod_ssl/2.0.59 OpenSSL/0.9.7a DAV/2 PHP/4.4.4 mod_bwlimited/1.4
Cache-Control: no-cache
Keep-Alive: timeout=3, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

Nos cabeçalhos de resposta, você pode obter algumas informações muito importantes, dentre elas o código de resposta (Status). Este código identifica se uma requisição foi concluída com sucesso (200) ou se ela não existe (404), por exemplo, mas existem muitos outros.

O protocolo HTTP é stateless, ou seja, ele não é capaz por si só de reter informações entre requisições diferentes. Para persistir informações você precisa utilizar cookies, sessões, campos de formulário ou variáveis na própria URL.

Métodos HTTP

Quando você vai fazer uma requisição, é preciso que você especifique qual o método será utilizado. Os métodos HTTP, também conhecidos como verbos, identificam qual a ação que deve ser executada em um determinado recurso. Existem 8 métodos HTTP, mas apenas 5 são mais utilizados.

GET
Solicita a representação de um determinado recurso. É definido como um método seguro e não deve ser usado para disparar uma ação (remover um usuário, por exemplo).
POST
As informações enviadas no corpo (body) da requisição são utilizadas para criar um novo recurso. Também é responsável por fazer processamentos que não são diretamente relacionados a um recurso.
DELETE
Remove um recurso. Deve retornar o status 204 caso não exista nenhum recurso para a URI especificada.
PUT
Atualiza um recurso na URI especificada. Caso o recurso não exista, ele pode criar um. A principal diferenteça entre POST e PUT é que o primeiro pode lidar não somente com recursos, mas pode fazer processamento de informações, por exemplo.
HEAD
Retorna informações sobre um recurso. Na prática, funciona semelhante ao método GET, mas sem retornar o recurso no corpo da requisição. Também é considerado um método seguro.

Os outros métodos disponíveis são OPTIONS, TRACE e CONNECT. Em teoria, os servidores devem implementar os métodos GET e HEAD e, sempre que possível, o método OPTIONS.

Status

Toda requisição recebe um código de resposta conhecido como status. Com o status é possível saber se uma operação foi realizada com sucesso (200), se ele foi movida e agora existe em outro lugar (301) ou se não existe mais (404).

Existem muitos status divididos em diversas categorias. Na especificação você pode ver cada um deles com uma descrição bastante detalhada. Abaixo, mostro alguns códigos que são mais frequentes.

200 OK
A requisição foi bem sucedida.
301 Moved Permanently
O recurso foi movido permanentemente para outra URI.
302 Found
O recurso foi movido temporariamente para outra URI.
304 Not Modified
O recurso não foi alterado.
401 Unauthorized
A URI especificada exige autenticação do cliente. O cliente pode tentar fazer novas requisições.
403 Forbidden
O servidor entende a requisição, mas se recusa em atendê-la. O cliente não deve tentar fazer uma nova requisição.
404 Not Found
O servidor não encontrou nenhuma URI correspondente.
405 Method Not Allowed
O método especificado na requisição não é válido na URI. A resposta deve incluir um cabeçalho Allow com uma lista dos métodos aceitos.
410 Gone
O recurso solicitado está indisponível mas seu endereço atual não é conhecido.
500 Internal Server Error
O servidor não foi capaz de concluir a requisição devido a um erro inesperado.
502 Bad Gateway
O servidor, enquanto agindo como proxy ou gateway, recebeu uma resposta inválida do servidor upstream a que fez uma requisição.
503 Service Unavailable
O servidor não é capaz de processar a requisição pois está temporariamente indisponível.

E para finalizar...

Dê uma lida na especificação HTTP. Existem muitas informações que não foram colocadas aqui, mas que são importantes. Só assim você será capaz de entender melhor alguns problemas relacionados ao seu trabalho.