> For the complete documentation index, see [llms.txt](https://web101.leandronsp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://web101.leandronsp.com/construindo-um-simples-echo-web-server/primeira-versao-do-server.md).

# 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:

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

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

```bash
## 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.

<figure><img src="/files/4o0Fb08D2aKRdusLp0HJ" alt=""><figcaption></figcaption></figure>

Yay! *Nossa primeira mensagem HTTP* através de TCP sockets!&#x20;

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:

```bash
## 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 `\`:

```bash
## 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`.&#x20;

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

#### E como fica o request?

<pre class="language-bash"><code class="lang-bash"><strong>## Client
</strong><strong>$ echo -e "GET / HTTP/1.1\r\n\
</strong>Content-Type: application/text\r\n\
\r\n\
PING" | nc -v localhost 8080

</code></pre>

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.

```bash
## 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
```
