An implementation for parsing an http request/response. Internally the parser does not allocate memory from the heap. The aim is for a simple function call requiring as little setup as possible.
The primary struct http_request_t has the following fields:
- http_method:
GET,HEAD,POST,PUT,PATCH,CONNECT,DELETE,TRACE,OPTIONS - path: the requested path i.e
/name-of/resource - http_version:
"1.1","1" - headers: An array of headers in key value pairings;
main.c can accept a file with an http header and will attempt the use the http_parser to parse the headers as a demonstration
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "http_parser.h"
void someFunction(void) {
char buf[BUFSIZ];
int socket_fd, bytes;
http_request_t req;
while ((bytes = read(socket_fd, buf, BUFSIZ)) > 0);
if (bytes == 0) {
// handle error
return;
}
httpParseRequest(buf, &req);
printf("%s %s HTTP/%s\n", req.http_method, req.path, req.http_version);
for (int i = 0; i < req.num_headers; ++i) {
printf("%s: %s\n", req.headers[i].key, req.headers[i].value);
}
}void httpParseRequest(char *request_raw, http_request_t *req);bufa character array used internallyreq_rawthe raw responsereqahttp_response_t, which on success will be populated explicity with the HTTP Version, http Method and the path.
A very simliar the request parser.
The primary struct http_response_t consists of the following fields:
http_version-"1","1.1","2"status_codechar * i.e"200","400".status_textchar * i.e "OK", "Bad Request"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "http_parser.h"
void someFunction(void) {
char buf[BUFSIZ];
int socket_fd, bytes;
http_response_t res;
while ((bytes = read(socket_fd, buf, BUFSIZ)) > 0);
if (bytes == 0) {
// handle error
return;
}
httpParseResponse(buf, &res);
printf("HTTP/%s %s %s\n", res.http_version, res.status_code, res.status_text);
for (int i = 0; i < res.num_headers; ++i) {
printf("%s: %s\n", res.headers[i].key, res.headers[i].value);
}
}void httpParseResponse(char *resonse_raw, http_response_t *res);req_rawthe raw responsereqahttp_response_t, which on success will be populated explicitly with the HTTP version, Status code and Status Text
As a convenience for getting a header, will return a pointer to a header or NULL.
headers_kv_t *httpFindHeader(headers_kv_t *headers, int num_headers, char *key);Utliity for getting the response body if there is one or NULL. The "body" is a header that has been added as a convenience for getting the response body. It is the last header and can be accessed in O(1).
char *httpGetResponseBody(http_response_t *res);