diff --git a/src/posts/2024/03/http2-and-http3-explained.md b/src/posts/2024/03/http2-and-http3-explained.md
index 17a75f9..5ef7381 100644
--- a/src/posts/2024/03/http2-and-http3-explained.md
+++ b/src/posts/2024/03/http2-and-http3-explained.md
@@ -123,14 +123,19 @@ sequenceDiagram
With HTTP/2, this problem is solved with *streams*, each stream corresponds to a message. Many streams can be interleaved in a single TCP packet. If a stream can't emit its data for some reason, other streams can take its place in the TCP packet.
-HTTP/2 streams are composed by *frames*, each one containing: the frame type, the stream that it belongs to, and the length in bytes. In the diagram below, one ✉ is a HTTP/2 frame and each line is one TCP packet. The third TCP packet carries frames of two different streams.
+HTTP/2 streams are composed by *frames*, each one containing: the frame type, the stream that it belongs to, and the length in bytes. In the diagram below, a coloured rectangle is a TCP packet and a ✉ is a HTTP/2 frame inside it. The first and third TCP packets carry frames of different streams.
```mermaid
sequenceDiagram
- Client->>+Server: req1: #9993;1/1
- Client->>+Server: req2: #9993;1/1
- Server-->>-Client: res1: #9993;1/2 + res2: #9993;1/1
- Server-->>-Client: res1: #9993;2/2
+ rect rgb(239,190,125)
+ Client->>+Server: req1: #9993;1/1
+
req2: #9993;1/1
+ end
+ rect rgb(197, 234, 189)
+ Server-->>Client: res1: #9993;1/2
+ end
+ rect rgb(197, 234, 189)
+ Server-->>-Client: res1: #9993;2/2
+
res2: #9993;1/1
+ end
```
The image below shows how frames go inside a TCP packet. Stream 1 carries a HTTP response for a JavaScript file and stream 2 carries a HTTP response for a CSS file.
@@ -147,16 +152,23 @@ HTTP/3 was born from a new transport protocol, QUIC, created by Google in 2012.
HTTP/2 solves the HTTP head-of-line blocking, but, this problem also happens with TCP and TLS. TCP understands that the data it needs to send is a contiguous sequence of packets, and if any packet is lost, it must be resent, in order to preserve information integrity. *With TCP, subsequent packets cannot be sent until the lost packet is successfully resent to the destination.*
-The diagram below explains visually how this happens in HTTP/2, with each line corresponding to a TCP packet. The third packet had frames of both response 1 and response 2 and its loss delays both responses - that means that in this case, there is no parallelism.
+The diagram below explains visually how this happens in HTTP/2. The third packet only had frames of response 1, but its loss delays both of responses - that means that in this case, there is no parallelism.
```mermaid
sequenceDiagram
- Client->>+Server: req1: #9993;1/1
- Client->>+Server: req2: #9993;1/1
- Server--xClient: res1: #9993;1/2 + res2: #9993;1/1
- Note over Client,Server: lost TCP packet delays res1 and res2
- Server-->>-Client: res1: #9993;1/2 + res2: #9993;1/1
- Server-->>-Client: res1: #9993;2/2
+ rect rgb(239,190,125)
+ Client->>+Server: req1: #9993;1/1
+
req2: #9993;1/1
+ end
+ rect rgb(197, 234, 189)
+ Server--xClient: res1: #9993;1/2
+ end
+ Note over Client,Server: lost TCP packet
must be resent.
delays res1 and res2
+ rect rgb(197, 234, 189)
+ Server-->>Client: res1: #9993;1/2
+ end
+ rect rgb(197, 234, 189)
+ Server-->>-Client: res1: #9993;2/2
+
res2: #9993;1/1
+ end
```
To solve TCP's head-of-line blocking, QUIC decided to use UDP for its transport protocol, because UDP does not care for guarantees of arrival. The data integrity responsibility, that in TCP is part of the transport layer, is moved in QUIC to the application layer, and the frames of a message can arrive out of order, without blocking unrelated streams.
@@ -165,15 +177,20 @@ To solve TCP's head-of-line blocking, QUIC decided to use UDP for its transport
```mermaid
sequenceDiagram
- Client->>+Server: req1: #9993;1/1
- Client->>+Server: req2: #9993;1/1
- Client->>+Server: req3: #9993;1/1
- Server--xClient: res1: #9993;1/1 + res2: #9993;1/2
- Note over Client,Server: res2: #9993;2/2 can be sent even
without res2: #9993;1/2 arriving
- Server-->>Client: res2: #9993;2/2 + res3: #9993;1/2
- Server-->>-Client: res3: #9993;2/2
- Note over Client,Server: resent of the lost packet.
res3 was unharmed
- Server-->>-Client: res1: #9993;1/1 + res2: #9993;1/2
+ rect rgb(253, 213, 224)
+ Client->>Server: req1: #9993;1/1
+
req2: #9993;1/1
+
req3: #9993;1/1
+ end
+ rect rgb(179, 205, 230)
+ Server--xClient: res1: #9993;1/2
+
res2: #9993;1/2
+ end
+ Note over Client,Server: lost QUIC packet
doesn't block sending
other packets
+ rect rgb(179, 205, 230)
+ Server-->>Client: res1: #9993;2/2
+
res2: #9993;2/2
+
res3: #9993;1/1
+ end
+ Note over Client,Server: resending lost packet.
res3 wasn't delayed
+ rect rgb(179, 205, 230)
+ Server-->>Client: res1: #9993;1/2
+
res2: #9993;1/2
+ end
```
The head-of-line blocking related to TLS (SSL) happens on TCP because the cryptography is usually applied over the entire message content, meaning that all data (all packets) needs to be received for the decryption to happen. With QUIC, the cryptography is individual for each QUIC packet, that is decrypted on arrival, without having to receive all packets beforehand.
diff --git a/src/posts/2024/03/http2-e-http3-explicados.md b/src/posts/2024/03/http2-e-http3-explicados.md
index 7398cef..4d8622e 100644
--- a/src/posts/2024/03/http2-e-http3-explicados.md
+++ b/src/posts/2024/03/http2-e-http3-explicados.md
@@ -123,14 +123,19 @@ sequenceDiagram
Com o HTTP/2, esse problema é resolvido através de *streams*: cada *stream* corresponde a uma mensagem. Vários *streams* podem estar entremeados dentro de um mesmo pacote TCP. Se um *stream* não puder emitir dados por algum motivo, outros podem aproveitar e entrar em seu lugar no pacote TCP.
-Os *streams* são divididos em *frames*, cada um contendo: o tipo do *frame*, o *stream* ao qual pertence, e o comprimento em bytes. No diagrama abaixo, um ✉ é um *frame* HTTP/2 e cada linha é um pacote TCP. O terceiro pacote TCP carrega *frames* de dois *streams* diferentes.
+Os *streams* são divididos em *frames*, cada um contendo: o tipo do *frame*, o *stream* ao qual pertence, e o comprimento em bytes. No diagrama abaixo, um retângulo colorido é um pacote TCP e um ✉ é um *frame* HTTP/2. O primeiro e o terceiro pacotes TCP carregam *frames* de *streams* diferentes.
```mermaid
sequenceDiagram
- Cliente->>+Servidor: req1: #9993;1/1
- Cliente->>+Servidor: req2: #9993;1/1
- Servidor-->>-Cliente: res1: #9993;1/2 + res2: #9993;1/1
- Servidor-->>-Cliente: res1: #9993;2/2
+ rect rgb(239,190,125)
+ Cliente->>+Servidor: req1: #9993;1/1
+
req2: #9993;1/1
+ end
+ rect rgb(197, 234, 189)
+ Servidor-->>Cliente: res1: #9993;1/2
+ end
+ rect rgb(197, 234, 189)
+ Servidor-->>-Cliente: res1: #9993;2/2
+
res2: #9993;1/1
+ end
```
A imagem abaixo mostra como os *frames* entram em pacotes TCP. O *stream* 1 representa uma resposta HTTP de um arquivo JavaScript e o *stream* 2 representa uma resposta HTTP de um arquivo CSS, transmitidos via HTTP/2.
@@ -147,16 +152,23 @@ O HTTP/3 surgiu diante de um novo protocolo de transporte proposto pelo Google,
O HTTP/2 consegue resolver o bloqueio de cabeça de fila relacionado ao HTTP, porém, esse tipo de bloqueio também existe no protocolo TCP e no TLS. O TCP entende que os dados que deve enviar fazem parte de uma seqüência de pacotes contígüos, e se um desses pacotes for perdido, ele deve ser reenviado para o destinatário, a fim de que se preserve a integridade da informação. *No TCP, pacotes subseqüentes não podem ser enviados enquanto o pacote perdido não chegar com sucesso no destino.*
-O diagrama abaixo explica visualmente como isso ocorre no HTTP/2, com cada linha correspondendo a um pacote TCP enviado. O terceiro pacote tinha *frames* tanto da resposta 1 como resposta 2 e a perda desse pacote atrasa ambas - ou seja, não há paralelismo nesse caso.
+O diagrama abaixo explica visualmente como isso ocorre no HTTP/2. O terceiro pacote tinha *frames* apenas da resposta 1, porém a perda dele atrasa ambas as respostas - ou seja, não há paralelismo nesse caso.
```mermaid
sequenceDiagram
- Cliente->>+Servidor: req1: #9993;1/1
- Cliente->>+Servidor: req2: #9993;1/1
- Servidor--xCliente: res1: #9993;1/2 + res2: #9993;1/1
- Note over Cliente,Servidor: pacote TCP perdido atrasa res1 e res2
- Servidor-->>-Cliente: res1: #9993;1/2 + res2: #9993;1/1
- Servidor-->>-Cliente: res1: #9993;2/2
+ rect rgb(239,190,125)
+ Cliente->>+Servidor: req1: #9993;1/1
+
req2: #9993;1/1
+ end
+ rect rgb(197, 234, 189)
+ Servidor--xCliente: res1: #9993;1/2
+ end
+ Note over Cliente,Servidor: pacote TCP perdido
precisa ser reenviado.
atrasa res1 e res2
+ rect rgb(197, 234, 189)
+ Servidor-->>Cliente: res1: #9993;1/2
+ end
+ rect rgb(197, 234, 189)
+ Servidor-->>-Cliente: res1: #9993;2/2
+
res2: #9993;1/1
+ end
```
Para resolver o bloqueio de cabeça de fila do TCP, o QUIC opta por utilizar o UDP como protocolo de transporte, pois este é um protocolo sem garantias de recebimento. A responsabilidade de garantia de integridade, que no TCP fica na camada de transporte, passa no QUIC para a camada de aplicação, de modo que os *frames* de uma mensagem podem chegar fora de ordem, sem bloquear *streams* não-relacionados.
@@ -165,15 +177,20 @@ Para resolver o bloqueio de cabeça de fila do TCP, o QUIC opta por utilizar o U
```mermaid
sequenceDiagram
- Cliente->>+Servidor: req1: #9993;1/1
- Cliente->>+Servidor: req2: #9993;1/1
- Cliente->>+Servidor: req3: #9993;1/1
- Servidor--xCliente: res1: #9993;1/1 + res2: #9993;1/2
- Note over Cliente,Servidor: res2: #9993;2/2 pode ser enviado mesmo
sem res2: #9993;1/2 ter chegado
- Servidor-->>Cliente: res2: #9993;2/2 + res3: #9993;1/2
- Servidor-->>-Cliente: res3: #9993;2/2
- Note over Cliente,Servidor: reenvio do pacote perdido.
res3 não foi afetado
- Servidor-->>-Cliente: res1: #9993;1/1 + res2: #9993;1/2
+ rect rgb(253, 213, 224)
+ Client->>Server: req1: #9993;1/1
+
req2: #9993;1/1
+
req3: #9993;1/1
+ end
+ rect rgb(179, 205, 230)
+ Server--xClient: res1: #9993;1/2
+
res2: #9993;1/2
+ end
+ Note over Client,Server: lost QUIC packet
doesn't block other packets
+ rect rgb(179, 205, 230)
+ Server-->>Client: res1: #9993;2/2
+
res2: #9993;2/2
+
res3: #9993;1/1
+ end
+ Note over Client,Server: resending lost packet.
res3 unaffected
+ rect rgb(179, 205, 230)
+ Server-->>Client: res1: #9993;1/2
+
res2: #9993;1/2
+ end
```
O bloqueio de cabeça de fila relacionado ao TLS (criptografia SSL) ocorre no TCP porque a criptografia é geralmente aplicada sobre a mensagem inteira, de modo que todos os seus pacotes precisam chegar ao destino para então ocorrer a decriptação. No caso do QUIC, a criptografia é individual para cada pacote QUIC, que é decriptado na chegada, sem haver a necessidade de receber todos os pacotes primeiro.