Estágio 01 · 01-03
LockedToda aplicação web roda sobre uma pilha de protocolos que vai desde sinais elétricos (camada física) até JSON sobre HTTPS (camada de aplicação). Não entender o que está embaixo do fetch() significa não saber:
Exemplos onde desconhecimento custa caro:
Cache-Control: no-cache achando que desabilita cache. Não desabilita, só força revalidação. Pra desabilitar é no-store. Pequeno detalhe que custou caro.Este módulo te dá o modelo mental completo da pilha de rede, desde o pacote IP até o cookie HTTP.
O OSI é um modelo de referência de 7 camadas, didático mas pouco aderente à prática. O TCP/IP (4-5 camadas) é o que internet realmente usa.
| OSI | TCP/IP | Exemplo |
|---|---|---|
| 7. Application | Application | HTTP, gRPC, DNS, SMTP |
| 6. Presentation | (parte de Application) | TLS, JSON, gzip |
| 5. Session | (parte de Application) | Sessions, cookies |
| 4. Transport | Transport | TCP, UDP, QUIC |
| 3. Network | Internet | IP, ICMP |
| 2. Data Link | Link | Ethernet, Wi-Fi |
| 1. Physical | Link | Cabo, ondas |
Cada camada encapsula a anterior: pacote IP carrega segmento TCP, que carrega request HTTP. Cada camada adiciona seu cabeçalho.
[Ethernet header | [IP header | [TCP header | [HTTP request]]]]
IP é roteamento. Cada interface de rede tem um endereço IP (IPv4 32-bit, IPv6 128-bit). Pacote IP tem destino → roteadores encaminham.
IPv4 (192.168.1.10): 4 octetos, ~4 bilhões de endereços. Esgotado, usamos NAT.
IPv6 (2001:0db8::1): 8 grupos de 4 hex, virtualmente infinitos endereços. Adoção crescente mas ainda parcial.
IP é stateless e sem garantia. Pacotes podem:
MTU (Maximum Transmission Unit): tipicamente 1500 bytes em Ethernet. Pacotes maiores são fragmentados.
Subnets e roteamento: mascará 192.168.1.0/24 define rede. Router compara IP destino com tabela de rotas e encaminha. Internet é uma teia de roteadores BGP.
NAT (Network Address Translation): seu roteador doméstico tem 1 IP público; máquinas internas têm IPs privados (192.168.x.x, 10.x.x.x). NAT mapeia conexões saintes pra portas. Por isso você não pode receber conexão de fora sem port forwarding.
ICMP: protocolo de controle. ping usa ICMP echo request/reply. traceroute usa TTL incrementado.
TCP é a camada que dá garantias em cima do IP não-confiável:
TCP three-way handshake:
Cliente Servidor
│ │
│──── SYN (seq=x) ──────────►│
│ │
│◄── SYN-ACK (seq=y, ack=x+1)│
│ │
│──── ACK (ack=y+1) ────────►│
│ │
│◄════════ data ════════════►│
Custo: 1 RTT (round-trip time) antes de enviar dado. Se RTT é 50ms, 50ms de overhead. Por isso reuso de conexão (HTTP keepalive) importa muito.
TCP four-way close:
Cliente Servidor
│──── FIN ──────────────────►│
│◄─── ACK ───────────────────│
│◄─── FIN ───────────────────│
│──── ACK ──────────────────►│
Existe estado TIME_WAIT (~2 minutos) onde a conexão fica "fantasma" pra evitar pacotes atrasados confundirem nova conexão. Servidores que abrem muitas conexões saintes podem esgotar portas locais por TIME_WAIT.
Slow start e congestion control: TCP começa enviando pouco e dobra (exponencialmente) até ver perda; então reduz e cresce linearmente. Conexões novas são lentas no início. Conexões longas estabilizam em alta vazão.
Nagle's algorithm: agrupa pequenas escritas em um segmento maior. Útil pra throughput, ruim pra latência. Pode ser desabilitado com TCP_NODELAY (Node: socket.setNoDelay(true)).
UDP é IP + portas + checksum. Sem garantias. Sem ordem. Sem retransmissão. Sem controle de fluxo.
Por que existe:
QUIC (sobre UDP, usado em HTTP/3) implementa as garantias do TCP em user space, mais flexível e com features novas (0-RTT, conexão persistente em mudança de IP).
DNS resolve nomes (example.com) em IPs.
Hierárquico:
a.root-servers.net ... m.).com, .org, .br)Tipos de record:
A, IPv4AAAA, IPv6CNAME, alias pra outro nomeMX, mail serverTXT, texto livre (SPF, DMARC, verificações)NS, name server autoritativoSOA, start of authorityCache e TTL: cada resposta tem TTL. Resolvers e clientes cacheiam até expirar. Por isso mudanças de DNS demoram a propagar.
Custo de DNS: lookup pode levar 10-100ms na primeira vez. Browsers cacheiam. Aplicações podem cachear via lib (Node: dns.setServers, ou pacote cacheable-lookup).
DNS over HTTPS (DoH) / DNS over TLS (DoT): DNS criptografado.
HTTP/1.1 (1997, RFC 9112):
Connection: keep-alive) reusa conexão TCP.HTTP/2 (2015, RFC 9113):
HTTP/3 (2022, RFC 9114):
QUIC (RFC 9000, 9001, 9002) é o substrato de HTTP/3 mas tem importância autônoma. Em 2026 já é majoritário em CDN traffic (Cloudflare, Akamai, Fastly reportam 30-50% das requests). Vale entender pra design de protocolos novos.
Por que UDP em vez de TCP:
Connection vs streams:
0-RTT na prática:
Connection migration:
Trade-offs reais:
Quando você toca QUIC:
quiche da Cloudflare em Rust, msquic da Microsoft, lsquic da LiteSpeed).curl --http3, libs HTTP em todas as linguagens majoritárias têm clients h3.Métodos HTTP:
GET (idempotente, sem body, com query string)POST (criação, com body, não idempotente)PUT (substituição completa, idempotente)PATCH (modificação parcial, geralmente não idempotente, mas depende)DELETE (idempotente)HEAD, OPTIONS (metadados, CORS preflight)Status codes (categorias):
1xx, Informational (raro)2xx, Success (200 OK, 201 Created, 204 No Content)3xx, Redirect (301, 302, 304 Not Modified)4xx, Client error (400, 401, 403, 404, 409, 429)5xx, Server error (500, 502, 503, 504)TLS adiciona confidencialidade, integridade e autenticação sobre TCP. HTTPS = HTTP sobre TLS.
TLS 1.3 handshake (simplificado):
Cliente Servidor
│── ClientHello (suites, key share) ───►│
│ │
│◄─ ServerHello + cert + key share ─────│
│ (+ Finished, encrypted) │
│ │
│── Finished (encrypted) ──────────────►│
│ │
│◄═══════ Application Data ════════════►│
1 RTT pra estabelecer (vs 2 RTT em TLS 1.2). 0-RTT em sessões repetidas (resumption).
Componentes:
Validação de certificado:
Erros comuns: SELF_SIGNED_CERT_IN_CHAIN em dev, CERT_HAS_EXPIRED, hostname mismatch.
mTLS (mutual TLS): cliente também apresenta certificado. Usado em service mesh (Istio), zero-trust networking.
Caching (RFC 9111):
Cache-Control: max-age=3600, cache por 1hCache-Control: no-cache, usa cache mas valida primeiro com servidor (ETag/Last-Modified)Cache-Control: no-store, não cacheia (use pra dados sensíveis)Cache-Control: private, só cliente cacheia, não proxies/CDNETag: "abc123", fingerprint de conteúdo. Cliente envia If-None-Match em revalidação; servidor responde 304 Not Modified se igual.Cookies:
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Lax; Max-Age=3600HttpOnly: JS não acessa (defesa contra XSS roubar token).Secure: só envia em HTTPS.SameSite=Strict|Lax|None: defesa contra CSRF.Domain, Path: escopo do cookie.CORS, Cross-Origin Resource Sharing:
Access-Control-Allow-Origin: https://my.com, Allow-Methods, Allow-Headers, Allow-Credentials.* com credentials: 'include' (não funciona, Origin tem que ser explícito).import net from 'node:net';
// Servidor TCP simples
const server = net.createServer((socket) => {
socket.setNoDelay(true); // desabilita Nagle
socket.on('data', (buf) => socket.write(`echo: ${buf}`));
socket.on('end', () => console.log('client disconnected'));
});
server.listen(3000); // syscalls: socket, bind, listen
Internamente: socket() → FD; bind() → associa FD a porta; listen() → kernel aceita conexões; accept() → nova conexão é novo FD; cada data é read(fd, buf); write é syscall.
Quando o cliente conecta, o kernel notifica via epoll. libuv leva isso pra event loop. Sua callback é chamada em JS.
Pra passar o Portão Conceitual, sem consultar:
Access-Control-Allow-Origin: * falha (e por quê).Cache-Control: no-cache vs no-store.SameSite=Lax vs Strict em termos de proteção CSRF.Connection: keep-alive é prejudicial (ex: load balancer com conexões longas presas).EAGAIN aparece em sockets não-bloqueantes e como tratar.Implementar um proxy HTTP/1.1 reverso em Node, do zero (sem http).
Você vai construir um servidor TCP que:
Content-Length e Transfer-Encoding: chunked.BACKEND=http://localhost:8080).Connection: keep-alive).node:net, node:url, node:crypto (e tipagem TypeScript).node:http, node:fetch, libs como http-proxy, axios, etc.node -e 'require("http").createServer((req,res)=>res.end("hi")).listen(8080)' em background.wrk -t4 -c100 -d10s http://localhost:3000/ mantendo correção (todas as responses corretas, sem corrupção).data event traz tudo).READING_REQUEST_LINE → READING_HEADERS → READING_BODY → ...).100 Continue.epoll é o que sustenta servidores high-concurrency. Acceptar conexão é syscall.net e http são thin wrappers em libuv + parsing TS.Content-Type: text/event-stream.curl -v: ver request/response HTTP completo.tcpdump, wireshark: capturar pacotes raw.mtr: ping + traceroute em tempo real.dig, nslookup: queries DNS.openssl s_client -connect host:443: inspecionar TLS handshake.mitmproxy: proxy MITM pra debug HTTP/HTTPS.wrk, k6, vegeta: load testing.lib/http.c, lib/conncache.c.Encerramento: após 01-03 você consegue ler logs HTTP, debug de DNS, configuração de TLS, sem chutar. CORS deixa de ser misterioso. Latência vira algo que você pode raciocinar (RTT, slow start, handshake) e medir.
Destrava
01-03 é prereq dos seguintes módulos: