http-parser.c

Small C library to parse HTTP requests
Log | Files | Refs | README | LICENSE

README.md (9097B)


      1 # http-parser
      2 
      3 Small http message parsing library. Keep in mind that this library only handles
      4 parsing the http request into a method, headers and body.
      5 
      6 ## Dependencies
      7 
      8 This library makes use of [dep](https://github.com/finwo/dep) to manage it's
      9 dependencies and exports.
     10 
     11 - [finwo/asprintf][finwo/asprintf]
     12 - [finwo/mindex][finwo/mindex]
     13 - [finwo/str_extra][finwo/str_extra]
     14 - [tidwall/buf][tidwall/buf]
     15 
     16 ## API
     17 
     18 ### Structs
     19 
     20 <details>
     21   <summary>struct http_parser_event</summary>
     22 
     23   ```c
     24   struct http_parser_event {
     25     struct http_parser_message *request;
     26     struct http_parser_message *response;
     27     struct http_parser_pair *pair;
     28     struct buf *chunk;
     29     void *udata;
     30   };
     31   ```
     32 
     33   Represents an event triggered by the http-parser, like a request being
     34   detected and ready for processing by the user.
     35 
     36   The `request` of the event represents the http request that the event relates
     37   to. Same for the `response` on the event in relation to the response that is
     38   detected. The `pair` is simply a wrapper around these two entities.
     39 
     40   The `udata` is pulled directly from the pair.
     41 </details>
     42 
     43 <details>
     44   <summary>struct http_parser_message</summary>
     45 
     46   ```c
     47   struct http_parser_message {
     48     int ready;
     49     int status;
     50     char *statusMessage;
     51     char *method;
     52     char *path;
     53     char *query;
     54     char *version;
     55     struct mindex_t *meta;
     56     struct buf *body;
     57     struct buf *buf;
     58     int chunksize;
     59     int _state;
     60     void (*onChunk)(struct http_parser_event*);
     61     void *udata;
     62   };
     63   ```
     64 
     65   Represents an http message, can be either a request or a response and
     66   formatted as such.
     67 </details>
     68 
     69 <details>
     70   <summary>struct http_parser_pair</summary>
     71 
     72   ```c
     73   struct http_parser_pair {
     74     struct http_parser_message *request;
     75     struct http_parser_message *response;
     76     void *udata;
     77     void (*onRequest)(struct http_parser_event*);
     78     void (*onResponse)(struct http_parser_event*);
     79   };
     80   ```
     81 
     82   Simply a wrapper around 2 http_parser_message entities and container for the
     83   onRequest and onResponse callbacks
     84 </details>
     85 
     86 ### Methods
     87 
     88 <details>
     89   <summary>http_parser_pair_init(udata)</summary>
     90 
     91   ```c
     92   struct http_parser_pair    * http_parser_pair_init(void *udata);
     93   ```
     94 
     95   Initializes a pair of messages stored as request and response you can use to
     96   send data into that you want to parse and handle requests or responses on.
     97 </details>
     98 
     99 <details>
    100   <summary>http_parser_request_init()</summary>
    101 
    102   ```c
    103   struct http_parser_message * http_parser_request_init();
    104   ```
    105 
    106   Initializes an http_parser_message as a request to be used for parsing or
    107   rendering an http request.
    108 </details>
    109 
    110 <details>
    111   <summary>http_parser_response_init()</summary>
    112 
    113   ```c
    114   struct http_parser_message * http_parser_response_init();
    115   ```
    116 
    117   Initializes an http_parser_message as a response to be used for parsing or
    118   rendering an http response.
    119 </details>
    120 
    121 
    122 <details>
    123   <summary>http_parser_meta_get(subject,key)</summary>
    124 
    125   ```c
    126   const char * http_parser_meta_get(struct http_parser_message *subject, const char *key);
    127   ```
    128 
    129   Fetches a metadata value by the given key from the http_parser_message.
    130 
    131   **DO NOT** call `free()` on the returned `char*`, it's a pointer directly into
    132   the meta map.
    133 </details>
    134 
    135 <details>
    136   <summary>http_parser_meta_set(subject,key,value)</summary>
    137 
    138   ```c
    139   void http_parser_meta_set(struct http_parser_message *subject, const char *key, const char *value);
    140   ```
    141 
    142   Sets a metadata value on the given key on the subject. Makes a copy of both
    143   the key and the value, so it's still the user's responsibility to free these
    144   pointers if needed.
    145 </details>
    146 
    147 <details>
    148   <summary>http_parser_meta_del(subject,key)</summary>
    149 
    150   ```c
    151   void http_parser_meta_del(struct http_parser_message *subject, const char *key);
    152   ```
    153 
    154   Deletes a metadata value on the given key from the subject.
    155 </details>
    156 
    157 <details>
    158   <summary>http_parser_header_get(subject,key)</summary>
    159 
    160   ```c
    161   const char * http_parser_header_get(struct http_parser_message *subject, const char *key);
    162   ```
    163 
    164   Wrapper around `http_parser_meta_get`, prefixing the key with `header:`
    165 </details>
    166 
    167 <details>
    168   <summary>http_parser_header_set(subject,key,value)</summary>
    169 
    170   ```c
    171   void http_parser_header_set(struct http_parser_message *subject ,const char *key, const char *value);
    172   ```
    173 
    174   Wrapper around `http_parser_meta_set`, prefixing the key with `header:`
    175 </details>
    176 
    177 <details>
    178   <summary>http_parser_header_del(subject,key)</summary>
    179 
    180   ```c
    181   void http_parser_header_del(struct http_parser_message *subject, const char *key);
    182   ```
    183 
    184   Wrapper around `http_parser_meta_del`, prefixing the key with `header:`
    185 </details>
    186 
    187 <details>
    188   <summary>http_parser_request_data(request,data)</summary>
    189 
    190   ```c
    191   void http_parser_request_data(struct http_parser_message *request, const struct buf *data);
    192   ```
    193 
    194   Ingests data to parse as a request. Sets the `ready` field to 1 once a
    195   complete request has been detected and parsed.
    196 </details>
    197 
    198 <details>
    199   <summary>http_parser_response_data(response,data)</summary>
    200 
    201   ```c
    202   void http_parser_response_data(struct http_parser_message *response, const struct buf *data);
    203   ```
    204 
    205   Ingests data to parse as a response. Sets the `ready` field to 1 once a
    206   complete response has been detected and parsed.
    207 </details>
    208 
    209 <details>
    210   <summary>http_parser_pair_request_data(pair,data)</summary>
    211 
    212   ```c
    213   void http_parser_pair_request_data(struct http_parser_pair *pair, const struct buf *data);
    214   ```
    215 
    216   Ingests data to parse as a request on the pair's request using
    217   http_parser_request_data, and calls the onRequest callback once a complete
    218   request has been detected.
    219 </details>
    220 
    221 <details>
    222   <summary>http_parser_pair_response_data(pair,data)</summary>
    223 
    224   ```c
    225   void http_parser_pair_response_data(struct http_parser_pair *pair, const struct buf *data);
    226   ```
    227 
    228   Ingests data to parse as a response on the pair's response using
    229   http_parser_response_data, and calls the onResponse callback once a complete
    230   response has been detected.
    231 </details>
    232 
    233 <details>
    234   <summary>http_parser_message_free(subject)</summary>
    235 
    236   ```c
    237   void http_parser_message_free(struct http_parser_message *subject);
    238   ```
    239 
    240   Handles freeing of the allocated memory of a single http-parser message.
    241 </details>
    242 
    243 <details>
    244   <summary>http_parser_pair_free(pair)</summary>
    245 
    246   ```c
    247   void http_parser_pair_free(struct http_parser_pair *pair);
    248   ```
    249 
    250   Handles freeing of the allocated memory of a http-parser message pair,
    251   including it's request and response, excluding user-data.
    252 </details>
    253 
    254 <details>
    255   <summary>http_parser_status_message(status)</summary>
    256 
    257   ```c
    258   const char * http_parser_status_message(int status);
    259   ```
    260 
    261   Returns the default status message for a given status number.
    262 </details>
    263 
    264 <details>
    265   <summary>http_parser_sprintt_response(response)</summary>
    266 
    267   ```c
    268   struct buf * http_parser_sprint_response(struct http_parser_message *response);
    269   ```
    270 
    271   Returns a buffer representing the response as http response.
    272 </details>
    273 
    274 <details>
    275   <summary>http_parser_sprint_request(request)</summary>
    276 
    277   ```c
    278   struct buf * http_parser_sprint_request(struct http_parser_message *request);
    279   ```
    280 
    281   Returns a buffer representing the request as http request.
    282 </details>
    283 
    284 <details>
    285   <summary>http_parser_sprint_pair_response(pair)</summary>
    286 
    287   ```c
    288   struct buf * http_parser_sprint_pair_response(struct http_parser_pair *pair);
    289   ```
    290 
    291   Calls `http_parser_sprint_response` on the pair's response.
    292 </details>
    293 
    294 <details>
    295   <summary>http_parser_sprint_pair_request(pair)</summary>
    296 
    297   ```c
    298   struct buf * http_parser_sprint_pair_request(struct http_parser_pair *pair);
    299   ```
    300 
    301   Calls `http_parser_sprint_request` on the pair's request.
    302 </details>
    303 
    304 ## Basic usage
    305 
    306 ```c
    307 static void onRequest(struct http_parser_event *ev) {
    308   // The request has been received
    309   // Answer the request directly or pass it to a route handler of sorts
    310 
    311   // Fetching the request
    312   // Has been wrapped in http_parser_event to support more features in the future
    313   struct http_parser_message *request = ev->request;
    314 
    315   // Basic http request data
    316   printf("Method: %s\n", request->method);
    317 
    318   // Reading headers are case-insensitive due to non-compliant clients/servers
    319   printf("Host:   %s\n", http_parser_header_get(request, "host"));
    320 
    321   // Once you're done with the request, you'll have to free it yourself
    322   http_parser_message_free(request);
    323 
    324   // Or you can free the whole pair
    325   http_parser_pair_free(ev->pair);
    326 }
    327 
    328 // Initialize a request/response pair
    329 struct http_parser_pair *reqres = http_parser_pair_init();
    330 
    331 // Userdata to be included can be assigned
    332 reqres->udata = (void*)...;
    333 
    334 // Trigger function 'onRequest' when the request is ready
    335 reqres->onRequest = onRequest;
    336 
    337 // Stored http message
    338 char *message =
    339   "GET / HTTP/1.1\r\n"
    340   "Host: localhost\r\n"
    341   "\r\n"
    342 ;
    343 
    344 // Passing network data into it
    345 http_parser_pair_request_data(reqseq, message, strlen(message));
    346 ```
    347 
    348 [finwo/asprintf]: https://github.com/finwo/c-asprintf
    349 [finwo/mindex]: https://github.com/finwo/c-mindex
    350 [finwo/str_extra]: https://github.com/finwo/c-strextra
    351 [tidwall/buf]: https://github.com/tidwall/buf.c