cybersecurity · intermediate · ~15 min · safe pentest lab

Parse an HTTP request line into method/path/version

Bounded parsing of a text protocol with allow-list character validation.

Challenge

Your job

Implement:

typedef struct {
    char method[8];    /* e.g. "GET", "POST" */
    char path[256];
    char version[16];  /* e.g. "HTTP/1.1" */
} http_req_t;

int parse_request_line(const char *buf, http_req_t *out);

Return 0 on success, -1 on any failure.

Examples

  • "GET /index.html HTTP/1.1\r\n" → method=GET, path=/index.html, version=HTTP/1.1 → 0
  • "GET /<255 chars> HTTP/1.1\r\n" (path overflows) → -1
  • "GET /a\n" (no \r\n) → -1
  • "GET /a\0b HTTP/1.1\r\n" (embedded NUL, or any non-allowed byte) → -1

Rules

  • The line ends in \r\n. Reject if not.
  • Three space-separated tokens. Reject if more or fewer.
  • Each token must fit in its bounded field (method ≤ 7, path ≤ 255, version ≤ 15 bytes excluding NUL).
  • Path may contain A-Za-z0-9/?&=._- only.

Hints

  1. (concept) Walk the buffer with three pointer indices: start of method, of path, of version, of CRLF.
  2. (direction) Use strchr(buf, ' ') to find each separator; bail if any returns NULL or if the resulting length exceeds the field.
  3. (common bug) Forgetting that memcpy does not NUL-terminate. Always set out->method[len] = '\0' after the copy.

Why this matters

The request line is where every HTTP attack starts. A bounded, allow-list parser stops the easy ones at the door.

Input format

A NUL-terminated buffer containing the first line of an HTTP request.

Output format

0 on success, -1 on any malformed input. Output struct fields are written only on success.

Constraints

No strcpy without length. CRLF required. Allow-list characters only.

Starter code

#include <stddef.h>
typedef struct {
    char method[8];
    char path[256];
    char version[16];
} http_req_t;

int parse_request_line(const char *buf, http_req_t *out) {
    /* TODO */
    (void)buf; (void)out;
    return -1;
}

Common mistakes

Using sscanf without length specifiers. Forgetting NUL terminator. Allowing double-space (potential request smuggling vector).

Edge cases to handle

Method that's exactly 7 chars (fits, since NUL needs slot 8). Path with ? and &. Trailing space before CRLF.

Complexity

O(n) in the line length.

Background lessons

Up next

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