Sometimes, users pass large amounts of data to the server. Moreover, we might not know their final size. For example, if you need to stream a video or download an archive.
To solve this problem, you can load the data completely into the server's RAM, calculate the Content-Length
and pass it. When the browser fully accepts the content, it'll display it straight away.
There is another solution. It allows us to reliably pass data when we don't know their final size. This link leads to an example of an image that is rendered gradually while data is transferred.
To do so, we use a technique for passing in small parts called chunks, and a special Transfer-Encoding
header with the value chunked
.
In a standard response, we get the whole body and then process it. We can't process it in parts because then we can't introduce unique rules inside the protocol. But when transmitting chunks, we can process the response until the body is fully received.
Let's make a request to the site httpwatch.com
:
telnet httpwatch.com 80
GET https://www.httpwatch.com/httpgallery/chunked/chunkedimage.aspx HTTP/1.1
Host: httpwatch.com
Connection: close
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Trailer: X-HttpWatch-Sample
# Instead of Content-Length here's the title Transfer-Encoding
Transfer-Encoding: chunked
Content-Type: image/jpeg; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Arr-Disable-Session-Affinity: True
Date: Fri, 10 Jul 2020 09:18:05 GMT
400 # chunk length
Some data from the first chunk
400
Data from the second chunk
400
etc
0 # the last chunk has a length of zero
Note that the headers are separated from the request body by a line break, as we usually do. At the beginning of each chunk, we see the chunk's size. After it we see the data, a line break at the end of the chunk, then we have the next chunk, and so on.
By doing this, you can pass as many chunks as you want. The only limit is a timeout of a server.
To finish the process, you need to pass the last chunk, which must be of zero length. Then, two line breaks follow, and the request is considered fully passed.
Message format
To separate records of block sizes from their contents, we use a CRLF separator:
- As a string:
\r\n
- As bytes in HEX format:
0x0D
,0x0A
The block length is the size of the block content. The CRLF separators are not considered.
It can be represented like this:
<block length in HEX><CRLF><block content><CRLF>
The last block is built in the same way, so it looks like this due to the lack of content: 0<CRLF><CRLF>
The standard also allows you to use only CR or only LF as a separator.
Recommended materials
- Link to the image transmitted using chunks (example from the video)
- Chunked transfer encoding / Wikipedia
- RFC2616 Hypertext Transfer Protocol
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.