What comes back
The server answers with the same text format, just a different first line:
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1256 <html> ...the page itself... </html>
- Status line:
VERSION CODE REASON. The status code200is the machine-readable result, andOKis the human-readable label. - Headers, again
Name: value.Content-Typesays what the body is, because the client handles each format differently.text/htmlis a web page to render,image/pngis picture bytes to display, andapplication/jsonis JSON, short for JavaScript Object Notation, a plain-text format for structured data that looks like{"user": "ada"}and is the standard language of APIs. Lesson 4-4 covers it properly.Content-Lengthsays how many bytes the body is, so the client knows when it has everything. - Blank line, then the body: the actual page, data, or image bytes.
Everything your browser shows you arrived as the body of some response. The headers are invisible to users but they are the first thing an engineer reads when debugging, because they tell you what the server thinks it sent.
Reading the status line
A response is stored in a variable, and the script pulls out its code, which is the first thing every HTTP client library does.
response="HTTP/1.1 404 Not Found Content-Type: text/html Content-Length: 1207 <html>...page not found...</html>" status_line=$(echo "$response" | head -n 1) code=$(echo "$status_line" | cut -d' ' -f2) echo "status line: $status_line" echo "code: $code"
Output
status line: HTTP/1.1 404 Not Found code: 404
head -n 1 takes the first line, and cut -d' ' -f2 takes the second space-separated field, which is the code.
Notice that a 404 still has a body, and Content-Length: 1207 says it is a substantial one. An error response is a normal response with an unhappy code, usually carrying a human-readable page explaining the problem.
That is a distinction worth keeping straight while debugging. A 404 means the exchange worked perfectly and the answer was "no such thing", which is very different from a connection that never completed.
Extracting code and headers together
Three values out of one stored response: the status code, the Content-Type, and the Content-Length.
response='HTTP/1.1 200 OK Content-Type: application/json Content-Length: 27 {"user":"ada","plan":"pro"}' code=$(echo "$response" | head -n 1 | cut -d' ' -f2) ctype=$(echo "$response" | grep '^Content-Type:' | cut -d' ' -f2) clen=$(echo "$response" | grep '^Content-Length:' | cut -d' ' -f2) echo "code: $code" echo "type: $ctype" echo "length: $clen"
Output
code: 200 type: application/json length: 27
Reading the pipelines
- The code is field 2 of line 1, so
head -n 1narrows to the line andcut -d' ' -f2picks the field. - For each header,
grepmatches its name with a leading^so the pattern only matches at the start of a line, thencuttakes field 2. The anchor matters, sinceContent-Typealso appears as a substring in other contexts. - Each pipeline is wrapped in
$( ... )to store its output in a variable rather than print it. - Counting the body confirms the header:
{"user":"ada","plan":"pro"}is exactly 27 characters, which is how the client knows it has read everything and can stop.
What Content-Type: application/json tells a client
It says the body should be parsed as JSON data, not displayed as a web page.
Content-Type describes the body's format so the client knows what to do with it. It renders text/html as a page, parses application/json as data, and displays image/png as a picture.
The header is a claim rather than a guarantee. A server can label JSON as text/plain by mistake, and the client will then hand you a string where you expected an object, which is a common cause of a confusing parse error.
APIs almost always speak application/json, which you will drive with curl in unit 5.