networking · intermediate · ~20 min

Parse a Cookie header into name/value pairs

Strict header-parsing pattern with name validation.

Challenge

An HTTP Cookie header is one line of semicolon-separated pairs: name1=value1; name2=value2; name3=value3. Look up one cookie by name and copy out its value.

Task

Implement int find_cookie(const char *header, const char *name, char *out_value, int cap) that finds the cookie named name in header and copies its value into out_value.

Behaviour:

  • Skip leading whitespace after each ;.
  • Match name exactly (case-sensitive, whole name only — not as a substring).
  • Copy the value into out_value, NUL-terminated.
  • If the same name appears more than once, use the first occurrence.

Input

  • header: the Cookie header line.
  • name: the cookie name to look up.
  • out_value, cap: destination buffer and its capacity.

Output

Returns 1 if the cookie was found (with its value written to out_value), or 0 if not found or on a rejected input.

Example

find_cookie("session=abc123; theme=dark", "session", out, cap)   ->   1, out="abc123"
find_cookie("session=abc123; theme=dark", "lang",    out, cap)   ->   0
find_cookie("subsession=x", "session", out, cap)                 ->   0   (no substring match)

Edge cases

  • Empty value (session=) returns 1 with out_value empty.
  • A name found only as a substring of another cookie name must not match.

Rules

  • Reject (return 0) if name itself contains any of: =, ;, \r, \n, or space.

Why this matters

Every web server, every WAF, every analytics tag needs to read Cookie headers. Doing it strictly catches malformed cookies that smuggle attacks.

Input format

The Cookie header line (header), the cookie name to find (name), and an output buffer (out_value) with capacity (cap).

Output format

Returns 1 if found (value written to out_value), or 0 if absent or on rejected input.

Constraints

Match the whole name only (no substring match). Reject a name containing '=', ';', CR, LF, or space.

Starter code

int find_cookie(const char *header, const char *name, char *out_value, int cap) { /* TODO */ (void)header; (void)name; (void)out_value; (void)cap; return 0; }

Common mistakes

Using strstr — matches bar=x inside foobar=x. Use word-boundary matching.

Edge cases to handle

Empty header. Cookie with empty value (name=;). Multiple instances (use first).

Complexity

O(strlen).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.