Introduction
The operations engineer stared at the 60-second loading progress bar on the monitoring screen, frowning. A JS file of less than 400KB was stuck in the browser for a full 60 seconds. Network packet capture showed a peculiar TCP closing trilogy between the SSL gateway and the backend server, with everything pointing to that overlooked detail of the HTTP protocol—when the response lacks both the Content-Length header and Chunked encoding, the rules of communication in the digital world quietly change…

Protocol Dilemma: Rules for Determining Response Integrity
In the HTTP protocol, the method for determining response integrity varies depending on the content type.
Precise Measurement of Static Content (Content-Length)
For static resource types (such as CSS/JS), the size of the response message can be calculated in advance, and the complete response size can be communicated by including the Content-Length in the response header.
GET /static/main.css HTTP/1.1 200 OK Content-Length: 1024 # The complete body is 1024 bytes, and upon receiving 1024 bytes, it is clear that the response has been fully received.
Progress Reporting for Dynamic Content (Transfer-Encoding: chunked)
For dynamic resource types (such as real-time reports/streaming data), since the size of the response message cannot be calculated in advance, the Chunked encoding method can be used to signal that the response has been fully received when the last chunk is received.
GET /live-report Transfer-Encoding: chunked 1F4 // 500-byte data chunk C8 // 200-byte summary 0 // Last chunk = transmission ends, upon receiving the last chunk, it is clear that the response has been fully received.
Ultimate Signal of Traditional Dilemma (Connection Closure)
However, when the response contains neither the Content-Length header nor uses Chunked encoding, both mechanisms fail. How can we determine if the response has been fully received in this case?
HTTP/1.0 200 OK Content-Type: text/css ……
At this point, it is necessary to rely on the underlying TCP connection closure event as the end-of-response marker:

In this special scenario, the SSL gateway finds itself in a dilemma: it cannot actively close the connection (which may truncate the response), nor can it wait indefinitely, leading to three TCP closure scenarios.
Analysis of the Three Closure Scenarios
Scenario 1: Immediate Connection Closure

If the application strictly follows this paradigm and closes the TCP connection immediately after the response ends, the SSL gateway can complete the response forwarding in milliseconds. Unfortunately, in actual scenarios, while this situation is common, it is not 100% guaranteed.

Scenario 2: Passive Connection Closure within 60 Seconds

The SSL gateway has a 60-second receive timeout. If the browser does not wait for the response within 60 seconds, it actively closes the TCP connection with the SSL gateway, making it meaningless for the SSL gateway to continue waiting for the web application response. This is akin to a customer (the browser) ordering takeout and impatiently banging the table, while the merchant (the web application) is busy preparing the meal but does not inform the current progress. The delivery person (the SSL gateway) stands anxiously in front of the shop with the food box, and after 7 seconds of waiting, the customer (the browser) decisively cancels the order (sends FIN). Seeing the customer (the browser) cancel the order, the delivery person (the SSL gateway) helplessly informs the merchant (the web application): “Boss, stop cooking, the customer has canceled the order” (sends FIN to the merchant).

2024-05-14 14:29:11 [warn] 19839#0: *345 epoll_wait() reported that client prematurely closed connection, so upstream connection is closed too while reading upstream……
Scenario 3: Connection Closure Due to 60-Second Timeout

The SSL gateway’s receive timeout is configured for 60 seconds. If the web application does not inform the SSL gateway whether the response has been sent within 60 seconds, the timeout triggers the SSL gateway to actively close the connection with the web application.

2024-05-14 14:29:32 [error] 24132#0: *31 upstream timed out (110: Connection timed out) while reading upstream……
Fault Source: The Chain Reaction of Incomplete Responses
By comparing the three scenarios, the crux of the problem emerges:
- 1. Web service defect: The response returned neither set the Content-Length header nor used Chunked encoding.
- 2. Protocol specification constraints: According to HTTP protocol requirements, the receiver must wait for the connection closure event to confirm that the response has been fully received.
- 3. Timeout mechanism collision:
- • Browser connection timeout > 60 seconds
- • SSL gateway proxy_read_timeout = 60s
- • Backend TCP connection keeps alive > 60 seconds
These three parties collectively created this precise 60-second delay:
Web application -> SSL gateway 60-second timeout closes connection -> Browser takes 60 seconds to load less than 400KB of resources.
Postscript
The ruler of Content-Length and the measuring cup of Chunked encoding were originally lighthouses guiding the journey through the digital ocean. Even as the reality’s waves crash against their base, they still scatter the dawn’s faint light. When the sixty-second hourglass becomes the measure of fate: the server has clearly released the complete chapter, yet the proxy component remains anxiously waiting, causing the browser to crawl in the abyss of entropy—though the three parties may occasionally enter the chaotic star domain, they allow the boundaries of rules to bloom anew: each timeout alarm’s ringing is humanity’s exploration of the unknown abyss, even as the waves of entropy will ultimately lick the rocks, the footprints of the measurer have left immortal coordinates in the abyss.