HTTP requests and responses can contain a body.
We already know that the HTTP request consists of two components:
Let's explore certain rules explaining how to separate headers from the body. Here is an example showing how to work with the body and how to send data other than headers.
Now we will make an HTTP request to the host
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://18.104.22.168/ 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://22.214.171.124/">here</A>. </BODY></HTML>
Here we get a response with some headers and 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.
The situation with headers is clear, they are separated from each other by a line break, and to send it we add another line, which looks like an empty string.
But what about the request body? It can contain anything inside. We cannot 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 can't determine when the body ends.
Imagine we accepted the response in the absence of any special mechanisms. Then the server sent the first two line breaks. We immediately saw the response. Everything sent after that is not be considered part of the HTTP response at all.
There is a universal mechanism to solve this problem. It's based on passing a special header.
While sending the response, the server generates a special header called Content-Length. It is the key to working with the body. Before sending the response body, the server calculates its length and records the number of bytes:
# 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 the same for responses and requests. After the last character has been passed, the connection is closed. It's worth clarifying that we close the HTTP session.
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 for sending responses and 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. The problem is that the type of content that contains the body must be identified somehow.
By default, the standard says that the server can try to determine the content of the content based on various methods. For example, if we make an
image.png in a query string:
POST /image.png HTTP/1.1
Actually, the server can understand that this is a png image and use it somehow.
In all other cases, when the server can't determine the content type, it must use the
Content-Type: application/octet-stream. It indicates that a stream of bytes is passed in the request body.
Although servers should work this way, it is often all done differently. If only
Content-Length is specified, the server will refuse to accept any data. It 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. If we send a body with GET, the server won't react to it, and nor should it. From a practical standpoint, it doesn't make sense.
There are also types of requests that can't be sent with a body. For example, the response to HEAD works this way, when we're only requesting headers. The body also can't be 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:
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.