Skip to content

Parts of the HTTP header

Greg Bowler edited this page Apr 24, 2026 · 7 revisions

Every HTTP message starts with a line that tells us the broad meaning of the message, followed by zero or more header fields.

At a high level, it looks like this:

A B C
X: Y

The first line means different things depending on whether the message is a request or a response.

Request start line

For an HTTP request:

  • A is the request method, such as GET or POST
  • B is the request target, such as /index.html or /api/user?id=5
  • C is the protocol version, such as HTTP/1.1

Example:

GET /articles?page=2 HTTP/1.1
Host: example.com
Accept: text/html

Response start line

For an HTTP response:

  • A is the protocol version, such as HTTP/1.1
  • B is the numeric status code, such as 200 or 404
  • C is the reason phrase, such as OK or Not Found

Example:

HTTP/1.1 404 Not Found
Content-Type: text/plain
Content-Length: 9

Header fields

After the start line come the header fields.

  • X is the header name, such as Content-Type
  • Y is the header value, such as application/json

Each header field is one name/value pair:

Content-Type: application/json
Cache-Control: no-store

Some header values themselves contain multiple parts. For example:

Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

That is still one header field. The commas are part of the value syntax.

A practical mapping to this library

In phpgt/http:

  • the request start line becomes the request method, target URI, and protocol version on Request
  • the response start line becomes the status code and protocol version on Response
  • the header fields are stored in Headers, RequestHeaders, or ResponseHeaders

The GT\Http\Header\Parser class can parse a raw response-style header block into:

  • protocol version
  • status code
  • header key/value pairs

One important exception: Set-Cookie

Most repeated headers can be merged safely, but Set-Cookie should stay as separate lines.

This library preserves that distinction, which is why cookie headers are treated slightly differently from normal comma-combinable headers.

Why this matters

Understanding the shape of an HTTP message makes the rest of the library much easier to follow. Once you can recognise the start line, the header fields, and the body as separate concerns, the purpose of Request, Response, Headers, and Stream becomes much clearer.


Learn about FormData and URLSearchParams to work with body data more comfortably.

Clone this wiki locally