Primeira versão do server

Uma vez que sabemos o formato da mensagem HTTP, podemos voltar à utilização do netcat, que foi muito útil para entendermos sobre Sockets, para darmos início ao web server.

Vamos então iniciar o server:

## Server
$ nc -lv 8080
Listening on 0.0.0.0 8080

Em seguida, em outra sessão, iniciamos o client:

## Client
$ nc -v localhost 8080
Connection to localhost (127.0.0.1) 3000 port [tcp/*] succeeded!

No lado client, digitamos o HTTP request. E do lado server, digitamos o HTTP response.

Yay! Nossa primeira mensagem HTTP através de TCP sockets!

Repare que o client escreve a mensagem a partir da interface interativa STDIN do client, pelo que também o server escreve a mensagem a partir da interface interativa STDIN do server.

É um pouco trabalhoso escrever a mensagem direto no STDIN, não? E se pudéssemos automatizar isto, fazendo com que a mensagem seja enviada com o comando echo por exemplo?

Redirecionando streams

Sim, redirecionamento de streams nos ajuda a resolver este problema. Assim, o output do comando echo passa a ser o input do comando netcat, assim nosso server pode ser iniciado da seguinte forma:

## Server
$ echo -e "HTTP/1.1 200\r\nContent-Type: application/text\r\n\r\n\PONG" | nc -lv 8080
Listening on 0.0.0.0 8080

Ou melhor, com quebra de linhas utilizando backslash \:

## Server
$ echo -e "HTTP/1.1 200\r\n\
Content-Type: application/text\r\n\
\r\n\
PONG" | nc -lv 8080

Listening on 0.0.0.0 8080

Okay, entendemos o formato da mensagem HTTP, mas o que é esse tal de \r\n?

Line feed

Quando qualquer mensagem é lida no socket, esta chega como uma string literal sem quebra de linhas por padrão. Se quisermos indicar que entre HTTP/1.1 200 e Content-Type: application/text haja uma quebra de linha como manda o protocolo, temos que indicar para o programa que lê do socket (neste caso o netcat) que é necessário quebrar a linha.

Por padrão, \n significa quebra de linha. Mas queremos que o programa leia a próxima linha a partir do primeiro caracter mais à esquerda, ou seja, do início. E por isto, é necessário prefixar o \r.

Portanto, \r\n significa alimentação de linha, ou line feed.

E como fica o request?

## Client
$ echo -e "GET / HTTP/1.1\r\n\
Content-Type: application/text\r\n\
\r\n\
PING" | nc -v localhost 8080

Nice!

Note que, após enviar a mensagem de volta, o server não encerrou a conexão, fazendo com que o client ficasse bloqueado. Para mitigar isto por agora, podemos utilizar a opção -N no comando, que indica ao server para terminar quando a mensagem chegar ao fim.

## Server
$ echo -e "HTTP/1.1 200\r\n\
Content-Type: application/text\r\n\
\r\n\
PONG" | nc -lvN 8080

Listening on 0.0.0.0 8080

Last updated