Skip to content

Latest commit

 

History

History
262 lines (172 loc) · 12.1 KB

ch05.0-http-deep-dive.md

File metadata and controls

262 lines (172 loc) · 12.1 KB

Read Prev

Mergulho Profundo no HTTP

Esse capítulo fornece uma visão geral de como a web funciona hoje, discutindo conceitos importantes que são fundamentais para entender o resto do livro. Apesar de alguns leitores poderem ter familiaridade com o material, esse capítulo fornece uma oportunidade valiosa de revisitar o básico.

Todos os navegadores, servidores e outras tecnologias relacionadas à web falam entre si através do HTTP, ou Hypertext Transfer Protocol. O HTTP é a linguagem em comum utilizada hoje na internet.

O conteúdo da web é armazenado nos servidores que se comunicam usando o protocolo HTTP, normalmente chamados de servidores HTTP. Eles guardam os dados da Internet e os fornecem quando solicitados por clientes HTTP.

Clientes pedem pelos dados enviando requisições HTTP aos servidores. Então os servidores respondem com os dados em respostas HTTP.

A mensagem que foi enviada pelo seu navegador é chamada de Requisição ou Requisição HTTP. A mensagem recebida pelo seu navegador, que foi enviada por um servidor, é chamada de Resposta HTTP ou apenas de Resposta. Juntas, a resposta e a requisição, são chamadas de Mensagem HTTP.

Alerta: Não visite a URL mencionada acima.

Um Pequeno Servidor Web

Antes de introduzir mais componentes do HTTP, vamos construir um servidor HTTP básico usando Node.js.

Crie um novo projeto, coloque o nome que você quiser. Dentro do diretório, crie um novo arquivo index.js

// file: index.js

// Importa o módulo 'node:http' e o atribui à constante 'http'.
const http = require("node:http");

// Define uma função chamada 'handle_request' que recebe dois parâmetros: 'request' and 'response'.
function handle_request(request, response) {
    // Envia a string "Hello world" como conteúdo da resposta.
    // Não faz nada com a requisição, por agora.
    response.end("Hello world");
}

// Cria um servidor HTTP usando o método 'createServer' do módulo 'http'.
// Passa a função 'handle_request' como o callback para lidar com solicitações recebidas.
const server = http.createServer(handle_request);

// Inicia o servidor para escutar requisições recebidas na porta 3000 e no host 'localhost'
server.listen(3000, "localhost");

// De maneira alternativa, você pode usar o endereço IP '127.0.0.1' ao invés de 'localhost'
server.listen(3000, "127.0.0.1");

Vamos passar pelo código acima em mais detalhes:

const http = require("node:http");

Essa linha traz o módulo http do Node.js, que fornece funcionalidades básicas para criar servidores HTTP.

function handle_request(request, response) {
    response.end("Hello world");
}

Essa função possui dois parâmetros de entrada: request (é a mensagem que vem da internet) e response (mensagem que enviamos de volta ao usuário). Estamos simplesmente enviando de volta um "Hello world" de resposta.

const server = http.createServer(handle_request);

Estamos criando um servidor HTTP usando o método createServer do módulo http. A função handle_request é atribuída como a função callback que será chamada quando o servidor receber uma requisição.

Então, sempre que houver uma nova requisição HTTP, nossa função handle_request será invocada e dois argumentos, request e response, serão fornecidos.

server.listen(3000, "localhost");

Essa linha do código inicia o servidor e o deixa disponível em http://localhost:3000.

server.listen(3000, "127.0.0.1");

Você também pode usar o endereço IP '127.0.0.1' ao invés de 'localhost' para atingir o mesmo resultado.

Ambos, localhost e 127.0.0.1, fazem referência ao endereço loopback, o que significa que o servidor só será acessível da mesma máquina que está sendo executado. Isso é geralmente usado por desenvolvedores para fins de teste e debugging.

Na verdade, é uma boa prática desenvolver e testar aplicações localmente antes de realizar o deploy para um ambiente de produção, já que isso permite o debugging e correção de maneira mais fácil para qualquer problema que possa aparecer.

Iniciando Nosso Servidor Web

Para iniciar o servidor web, precisamos simplesmente executar o arquivo index.js. Vamos tentar executá-lo:

$ node index

# no response, is there something wrong?

Você deve ter notado que o programa não fechou como ele costumáva fazer anteriormente, quando rodávamos nossa biblioteca de logging ou em exemplos de códigos anteriores. Esse comportamento pode ser um pouco surpreendente, mas é esperado devido à natureza do funcionamento dos servidores HTTP.

Quando executamos um servidor HTTP usando http.createServer(), o servidor é feito para escutar por requisições recebidas de maneira indefinida. Ele não termina assim que o script termina a execução, diferente de alguns outros scripts que podem executar uma única tarefa e então encerrar.

Isso porque o propósito de um servidor HTTP é escutar continuamente por requisições recebidas e respondê-las em tempo real. Se o servidor fechasse imediatamente, ele não seria capaz de completar seu propósito de servir conteúdo aos clientes.

Testando Nosso Servidor Web

Para ver se o nosso servidor web está funcionando como esperado, e para ver a resposta "Hello world", precisamos primeiro fazer uma requisição. Há algumas maneiras de fazer uma requisição. Vamos pegar o caminho fácil.

Vá ao navegador de sua escolha, e visite a URL http://localhost:3000 ou http://127.0.0.1 ou localhost:3000 ou 127.0.0.1:3000.

Sim, parece funcionar corretamente. Vamos fazer uma requisição para o nosso servidor de uma maneira diferente, para ver todas as partes necessárias que compõem uma requisição HTTP.

Testando com o cURL

Abra seu terminal e digite o seguinte comando cURL:

$ curl http://localhost:3000
Hello world%

Perfeito. cURL é um modo rápido e conveniente de testar endpoints HTTP. É fácil de usar e não necessita ter outros clientes HTTP em execução, ou da aba do seu chrome aberta.

Vamos modificar a requisição cURL:

$ curl http://localhost:3000 -v

Estamos especificando o argumento -v (ou --verbose) que exibe mais informações sobre o ciclo de vida da conexão HTTP. Essa é a saída que você obtém ao executar o comando acima:

$ curl http://localhost:3000 -v
*   Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.87.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 23 Aug 2023 13:13:32 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Content-Length: 11
<
* Connection #0 to host localhost left intact
Hello world%

Isso é bastante coisa pra digerir. Uma coisa a ser notada são os dois diferentes operadores utilizados - > e <. A flecha > indica que isso está sendo enviado como uma requisição pelo cliente. O cliente aqui se refere ao cURL no seu terminal. A flecha < indica que essas linhas foram recebidas como uma resposta do servidor.

Vamos dar uma olhada nisso linha por linha:

Trying 127.0.0.1:3000...

Essa linha está indicando que cURL está tentando estabilizar uma conexão com o endereço IP 127.0.0.1. Esse endereço IP também é conhecido como localhost e se refere ao computador local no qual você está trabalhando atualmente.

A conexão está sendo feita na porta número 3000, que é um número usado para identificar um processo específico no qual os dados são enviados ou recebidos. Vamos falar sobre PORTs (portas) no próximo capítulo.

Connected to localhost (127.0.0.1) port 3000 (#0)

Isso significa que a conexão ao endereço IP e porta especificados foram estabilizados com sucesso. Essa é uma boa notícia e significa que você pode prosseguir com sua tarefa sem mais demora.

O (#0) na mensagem se refere ao index (índice) da conexão. Isso é uma informação útil, especialmente se você está fazendo múltiplas conexões ao mesmo tempo. Ao monitorar o index da conexão, você consegue evitar qualquer confusão ou erro que possa aparecer ao misturar diferentes conexões.

> GET / HTTP/1.1

O cURL está enviando uma requisição HTTP ao servidor utilizando o método GET. A / depois do método indica que a requisição está sendo feita para o path raiz, ou o endpoint root (raiz) do servidor.

> Host: localhost:3000

Essa linha especifica que o comando cURL está definindo o cabeçalho Host na requisição, que diz ao servidor o nome do domínio e a porta da requisição.

> User-Agent: curl/7.87.0

Essa linha também faz parte dos cabeçalhos da requisição HTTP. Inclui o cabeçalho User-Agent, que identifica o cliente fazendo uma requisição. Neste caso, indica que a requisição está sendo feita utilizando curl versão 7.87.0.

> Accept: */*

Essa linha define o cabeçalho Accept, que diz ao servidor que tipos de conteúdo-resposta os clientes podem lidar. Nesse caso, indica que o cliente aceita qualquer tipo de conteúdo.

>

Essa linha indica o fim dos cabeçalhos de requisição HTTP. Uma linha vazia como essa separa os cabeçalhos do corpo da requisição, que não está presente nesse caso por ser uma requisição GET. Vamos falar sobre o POST e outros verbos/métodos http nos capítulos a seguir.

Mark bundle as not supporting multiuse

Essa é uma mensagem de log interna do curl e não tem um impacto direto na interpretação da requisição ou da resposta. Está relacionado a como o curl gerencia múltiplas conexões em uma sessão.

< HTTP/1.1 200 OK

Essa linha é parte da resposta HTTP. Indica que o servidor respondeu com um código de status HTTP 200 OK, o que significa que a requisição foi bem sucedida. De novo, vamos entender os códigos de status HTTP no próximo capítulo. Por agora, é o suficiente imaginar que qualquer código de status na forma 2xx, onde x é um número, significa que está tudo bem.

< Date: Wed, 23 Aug 2023 13:13:32 GMT

Essa linha faz parte dos cabeçalhos de resposta HTTP. Uma coisa importante a notar, esse é o cabeçalho definido pelo servidor e não pelo cliente. Inclui o cabeçalho Date, que indica a data e hora de quando a resposta foi gerada no servidor.

< Connection: keep-alive

Essa linha faz parte dos cabeçalhos de resposta e informa ao cliente que o servidor deseja manter uma conexão persistente, e reutilizar a conexão para requisições futuras em potencial. Isso ajuda com a performance.

< Keep-Alive: timeout=5

Essa linha, também pertencente aos cabeçalhos de resposta, especifica o tempo (5 segundos neste caso) que o servidor manterá a conexão ativa se nenhuma solicitação adicional for feita.

< Content-Length: 11

Essa linha indica o tamanho do conteúdo da resposta em bytes. Nesse caso, o corpo da resposta tem um comprimento de 11 bytes.

<

Essa linha marca o fim dos cabeçalhos de resposta e o início do corpo da resposta.

Connection #0 to host localhost left intact

Essa linha é uma mensagem de log do curl indicando que a conexão com o servidor está sendo deixada aberta (intact) e não foi fechada imediatamente depois de receber a resposta. Ela poderia ser potencialmente reutilizada para requisições subsequentes.

Hello world%

Esse é o corpo real da resposta retornada pelo servidor. Nesse caso, é uma simples string de texto dizendo "Hello world". O % não é nada para se preocupar. Indica que a resposta não termina com um caracter \n.

Agora que entendemos quais são os componentes básicos da requisição e da resposta, vamos entender esses componentes em mais detalhes, no próximo capítulo

Read Prev