HTTP request and response can contain what's called a (body).
We already know that the HTTP request itself consists of headers and an optional request body. There are certain rules for separating headers from the body. Let's look at an example of how to work with body and how to send data other than headers. Make an HTTP request to the host hexlet.io:
telnet hexlet.io 80
GET / HTTP/1.1
Host: hexlet.io
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: https://34.102.241.4/
Content-Length: 218
Date: Tue, 07 Jul 2020 03:50:16 GMT
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://34.102.241.4/">here</A>.
</BODY></HTML>
The response is some headers, and after that it's the body we're concerned about. In this case, this isn't a page on our site, just a page that the server gives. It's related to redirection.
If everything is clear with the headers, they're separated from each other by a line break, and we add another line, which just looks like an empty string, to send it. Then what about the request body? It can contain anything inside. We can't encode a line break as a special character. After all, those same two line breaks might be inside the request body. But there are other reasons why the text protocol simply can't determine when the body ends. If we accepted the response in the absence of any special mechanisms, then after the server sent the first two line breaks, we would immediately see the response and everything that was sent after wouldn't be considered part of the HTTP response at all. To solve this problem, another, more universal mechanism was invented. It is based on passing a special header.
While sending the response, the server generates a special header called Content-Length. This is the key to working with body. Before sending the response body, its length is calculated, and the number of bytes is recorded.
# number — the number of bytes
Content-Length: 218
After the header is passed, the other side will expect exactly as many bytes as are specified in it. As we remember, it works exactly the same for response and request After the last character has been passed, the connection is closed. It's worth clarifying that it's the HTTP session that is being closed. The server may be kept active by keep-alive, but the key point is that the request is considered completed and displayed.
Giving the body size is necessary not only for sending a response, but also for requests when, for example, form data is sent to a server.
Practice shows that not all servers work correctly with only the Content-Length. header. They're missing one. The type of request or response content that contains the body, must be identified somehow. By default, the standard says that the server itself can try to determine the content of the content based on various methods. For example, if we make an image.png in query string.
POST /image.png HTTP/1.1
It's not necessarily required, but the server can understand that this is a png image and make use of it somehow. In all other cases, when the server can't determine the content type, it must use the Content-Type: application/octet-stream. This means that only a stream of bytes is passed in the request body. Although servers should work this way, it's often all done differently. If only Content-Length, is specified, the server will refuse to accept any data. It just closes the connection after two line breaks, and the body doesn't even get a look in. This nuance was discovered by experimenting.
One more remark about the body. From the perspective of the HTTP standard, the body can be present in any request and has nothing to do with the verb. You can send a body in HEAD, POST, PUT and other requests. This isn't described in the standard, but if we send a body with GET, the server won't react to it in any way, and nor should it, since from a practical standpoint, it doesn't make sense. There are also types of requests that you can't send a body with ever. For example, the response to HEAD, when we're only requesting headers, since that's the kind of semantics this verb has. The body is also not sent when we receive statuses like “204 — no content” as a response, and others.
The Hexlet support team or other students will answer you.
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.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
From a novice to a developer. Get a job or your money back!
Sign up or sign in
Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.