1// httpserver.h has been automatically generated from httpserver.m4 and the
   2// source files under /src
   3#ifndef HTTPSERVER_H
   4#define HTTPSERVER_H
   5#line 1 "api.h"
   6#ifndef HS_API_H
   7#define HS_API_H
   8/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   9 * @file api.h
  10 *
  11 * MIT License
  12 *
  13 * Copyright (c) 2019 Jeremy Williams
  14 *
  15 * Permission is hereby granted, free of charge, to any person obtaining a copy
  16 * of this software and associated documentation files (the "Software"), to deal
  17 * in the Software without restriction, including without limitation the rights
  18 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19 * copies of the Software, and to permit persons to whom the Software is
  20 * furnished to do so, subject to the following conditions:
  21 *
  22 * The above copyright notice and this permission notice shall be included in
  23 * all copies or substantial portions of the Software.
  24 *
  25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  31 * SOFTWARE.
  32 *
  33 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  34 *
  35 * httpserver.h (0.9.0)
  36 *
  37 * Description:
  38 *
  39 *   A single header C library for building non-blocking event driven HTTP
  40 *   servers
  41 *
  42 * Usage:
  43 *
  44 *   Do this:
  45 *      #define HTTPSERVER_IMPL
  46 *   before you include this file in *one* C or C++ file to create the
  47 *   implementation.
  48 *
  49 *   // i.e. it should look like this:
  50 *   #include ...
  51 *   #include ...
  52 *   #include ...
  53 *   #define HTTPSERVER_IMPL
  54 *   #include "httpserver.h"
  55 *
  56 *   There are some #defines that can be configured. This must be done in the
  57 *   same file that you define HTTPSERVER_IMPL These defines have default values
  58 *   and will need to be #undef'd and redefined to configure them.
  59 *
  60 *     HTTP_REQUEST_BUF_SIZE - default 1024 - The initial size in bytes of the
  61 *       read buffer for the request. This buffer grows automatically if it's
  62 *       capacity is reached but it certain environments it may be optimal to
  63 *       change this value.
  64 *
  65 *     HTTP_RESPONSE_BUF_SIZE - default 1024 - Same as above except for the
  66 *       response buffer.
  67 *
  68 *     HTTP_REQUEST_TIMEOUT - default 20 - The amount of seconds the request
  69 * will wait for activity on the socket before closing. This only applies mid
  70 *       request. For the amount of time to hold onto keep-alive connections see
  71 *       below.
  72 *
  73 *     HTTP_KEEP_ALIVE_TIMEOUT - default 120 - The amount of seconds to keep a
  74 *       connection alive a keep-alive request has completed.
  75 *
  76 *     HTTP_MAX_TOTAL_EST_MEM_USAGE - default 4294967296 (4GB) - This is the
  77 *       amount of read/write buffer space that is allowed to be allocated
  78 * across all requests before new requests will get 503 responses.
  79 *
  80 *     HTTP_MAX_TOKEN_LENGTH - default 8192 (8KB) - This is the max size of any
  81 *       non body http tokens. i.e: header names, header values, url length,
  82 * etc.
  83 *
  84 *     HTTP_MAX_REQUEST_BUF_SIZE - default 8388608 (8MB) - This is the maximum
  85 *       amount of bytes that the request buffer will grow to. If the body of
  86 * the request + headers cannot fit in this size the request body will be
  87 *       streamed in.
  88 *
  89 *   For more details see the documentation of the interface and the example
  90 *   below.
  91 *
  92 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  93
  94#ifdef __cplusplus
  95extern "C" {
  96#endif
  97
  98// String type used to read the request details. The char pointer is NOT null
  99// terminated.
 100struct http_string_s;
 101
 102struct http_server_s;
 103struct http_request_s;
 104struct http_response_s;
 105
 106/**
 107 * Get the event loop descriptor that the server is running on.
 108 *
 109 * This will be an epoll fd when running on Linux or a kqueue on BSD. This can
 110 * be used to listen for activity on sockets, etc. The only caveat is that the
 111 * user data must be set to a struct where the first member is the function
 112 * pointer to a callback that will handle the event. i.e:
 113 *
 114 * For kevent:
 115 *
 116 *   struct foo {
 117 *     void (*handler)(struct kevent*);
 118 *     ...
 119 *   }
 120 *
 121 *   // Set ev.udata to a foo pointer when registering the event.
 122 *
 123 * For epoll:
 124 *
 125 *   struct foo {
 126 *     void (*handler)(struct epoll_event*);
 127 *     ...
 128 *   }
 129 *
 130 *   // Set ev.data.ptr to a foo pointer when registering the event.
 131 *
 132 * @param server The server.
 133 *
 134 * @return The descriptor of the event loop.
 135 */
 136int http_server_loop(struct http_server_s *server);
 137
 138/**
 139 * Allocates and initializes the http server.
 140 *
 141 * @param port The port to listen on.
 142 * @param handler The callback that will fire to handle requests.
 143 *
 144 * @return Pointer to the allocated server.
 145 */
 146struct http_server_s *
 147http_server_init(int port, void (*handler)(struct http_request_s *));
 148
 149/**
 150 * Listens on the server socket and starts an event loop.
 151 *
 152 * During normal operation this function will not return.
 153 *
 154 * @param server The server.
 155 * @param ipaddr The ip to bind to if NULL binds to all interfaces.
 156 *
 157 * @return Error code if the server fails.
 158 */
 159int http_server_listen_addr(struct http_server_s *server, const char *ipaddr);
 160
 161/**
 162 * See http_server_listen_addr
 163 */
 164int http_server_listen(struct http_server_s *server);
 165
 166/**
 167 * Poll the server socket on specific interface.
 168 *
 169 * Use this listen call in place of the one above when you want to integrate
 170 * an http server into an existing application that has a loop already and you
 171 * want to use the polling functionality instead. This works well for
 172 * applications like games that have a constant update loop.
 173 *
 174 * @param server The server.
 175 * @param ipaddr The ip to bind to if NULL bind to all.
 176 *
 177 * @return Error code if the poll fails.
 178 */
 179int http_server_listen_addr_poll(struct http_server_s *server,
 180                                 const char *ipaddr);
 181
 182/**
 183 * Poll the server socket on all interfaces. See http_server_listen_addr_poll
 184 *
 185 * @param server The server.
 186 *
 187 * @return Error code if the poll fails.
 188 */
 189int http_server_listen_poll(struct http_server_s *server);
 190/**
 191 * Poll of the request sockets.
 192 *
 193 * Call this function in your update loop. It will trigger the request handler
 194 * once if there is a request ready. It should be called in a loop until it
 195 * returns 0.
 196 *
 197 * @param server The server.
 198 *
 199 * @return Returns 1 if a request was handled and 0 if no requests were handled.
 200 */
 201int http_server_poll(struct http_server_s *server);
 202
 203/**
 204 * Check if a request flag is set.
 205 *
 206 * The flags that can be queried are listed below:
 207 *
 208 * HTTP_FLG_STREAMED
 209 *
 210 *   This flag will be set when the request body is chunked or the body is too
 211 *   large to fit in memory are once. This means that the
 212 *   http_request_read_chunk function must be used to read the body piece by
 213 *   piece.
 214 *
 215 * @param request The request.
 216 * @param flag One of the flags listed above.
 217 *
 218 * @return 1 or 0 if the flag is set or not respectively.
 219 */
 220int http_request_has_flag(struct http_request_s *request, int flag);
 221
 222/**
 223 * Returns the request method as it was read from the HTTP request line.
 224 *
 225 * @param request The request.
 226 *
 227 * @return The HTTP method.
 228 */
 229struct http_string_s http_request_method(struct http_request_s *request);
 230
 231/**
 232 * Returns the full request target (url) from the HTTP request line.
 233 *
 234 * @param request The request.
 235 *
 236 * @return The target.
 237 */
 238struct http_string_s http_request_target(struct http_request_s *request);
 239
 240/**
 241 * Retrieves the request body.
 242 *
 243 * @param request The request.
 244 *
 245 * @return The request body. If no request body was sent buf and len of the
 246 *   string will be set to 0.
 247 */
 248struct http_string_s http_request_body(struct http_request_s *request);
 249
 250/**
 251 * Returns the request header value for the given header key.
 252 *
 253 * @param request The request.
 254 * @param key The case insensitive header key to search for.
 255 *
 256 * @return The value for the header matching the key. Will be length 0 if not
 257 *   found.
 258 */
 259struct http_string_s http_request_header(struct http_request_s *request,
 260                                         char const *key);
 261
 262/**
 263 * Iterate over the request headers.
 264 *
 265 * Each call will set key and val to the key and value of the next header.
 266 *
 267 * @param request The request.
 268 * @param[out] key The key of the header.
 269 * @param[out] value The key of the header.
 270 * @param[inout] iter Should be initialized to 0 before calling. Pass back in
 271 *   with each consecutive call.
 272 *
 273 * @return 0 when there are no more headers.
 274 */
 275int http_request_iterate_headers(struct http_request_s *request,
 276                                 struct http_string_s *key,
 277                                 struct http_string_s *val, int *iter);
 278
 279/**
 280 * Stores an arbitrary userdata pointer for this request.
 281 *
 282 * This is not used by the library in any way and is strictly for you, the
 283 * application programmer to make use of.
 284 *
 285 * @param request The request.
 286 * @param data Opaque pointer to user data.
 287 */
 288void http_request_set_userdata(struct http_request_s *request, void *data);
 289
 290/**
 291 * Retrieve the opaque data pointer that was set with http_request_set_userdata.
 292 *
 293 * @param request The request.
 294 */
 295void *http_request_userdata(struct http_request_s *request);
 296
 297/**
 298 * Stores a server wide opaque pointer for future retrieval.
 299 *
 300 * This is not used by the library in any way and is strictly for you, the
 301 * application programmer to make use of.
 302 *
 303 * @param server The server.
 304 * @param data Opaque data pointer.
 305 */
 306void http_server_set_userdata(struct http_server_s *server, void *data);
 307
 308/**
 309 * Retrieve the server wide userdata pointer.
 310 *
 311 * @param request The request.
 312 */
 313void *http_request_server_userdata(struct http_request_s *request);
 314
 315/**
 316 * Sets how the request will handle it's connection
 317 *
 318 * By default the server will inspect the Connection header and the HTTP
 319 * version to determine whether the connection should be kept alive or not.
 320 * Use this function to override that behaviour to force the connection to
 321 * keep-alive or close by passing in the HTTP_KEEP_ALIVE or HTTP_CLOSE
 322 * directives respectively. This may provide a minor performance improvement
 323 * in cases where you control client and server and want to always close or
 324 * keep the connection alive.
 325 *
 326 * @param request The request.
 327 * @param directive One of HTTP_KEEP_ALIVE or HTTP_CLOSE
 328 */
 329void http_request_connection(struct http_request_s *request, int directive);
 330
 331/**
 332 * Frees the buffer of a request.
 333 *
 334 * When reading in the HTTP request the server allocates a buffer to store
 335 * the request details such as the headers, method, body, etc. By default this
 336 * memory will be freed when http_respond is called. This function lets you
 337 * free that memory before the http_respond call. This can be useful if you
 338 * have requests that take a long time to complete and you don't require the
 339 * request data. Accessing any http_string_s's will be invalid after this call.
 340 *
 341 * @param request The request to free the buffer of.
 342 */
 343void http_request_free_buffer(struct http_request_s *request);
 344
 345/**
 346 * Allocates an http response.
 347 *
 348 * This memory will be freed when http_respond is called.
 349 *
 350 * @return Allocated response.
 351 */
 352struct http_response_s *http_response_init();
 353
 354/**
 355 * Set the response status.
 356 *
 357 * Accepts values between 100 and 599 inclusive. Any other value will map to
 358 * 500.
 359 *
 360 * @param response The response struct to set status on.
 361 * @param status The HTTP status code.
 362 */
 363void http_response_status(struct http_response_s *response, int status);
 364
 365/**
 366 * Sets an HTTP response header.
 367 *
 368 * @param response The response struct to set the header on.
 369 * @param key The null-terminated key of the header eg: Content-Type
 370 * @param value The null-terminated value of the header eg: application/json
 371 */
 372void http_response_header(struct http_response_s *response, char const *key,
 373                          char const *value);
 374
 375/**
 376 * Set the response body.
 377 *
 378 * The caller is responsible for freeing any memory that
 379 * may have been allocated for the body. It is safe to free this memory AFTER
 380 * http_respond has been called. If responding with chunked transfer encoding
 381 * this will become a single chunk. This procedure can be used again to set
 382 * subsequent chunks.
 383 *
 384 * @param response The response struct to set the body for.
 385 * @param body The body of the response.
 386 * @param length The length of the body
 387 */
 388void http_response_body(struct http_response_s *response, char const *body,
 389                        int length);
 390
 391/**
 392 * Starts writing the response to the client.
 393 *
 394 * Any memory allocated for the response body or response headers is safe to
 395 * free after this call. Adds the default HTTP response headers, Date and
 396 * Connection.
 397 *
 398 * @param request The request to respond to.
 399 * @param response The response to respond with.
 400 */
 401void http_respond(struct http_request_s *request,
 402                  struct http_response_s *response);
 403
 404/**
 405 * Writes a chunk to the client.
 406 *
 407 * The notify_done callback will be called when the write is complete. This call
 408 * consumes the response so a new response will need to be initialized for each
 409 * chunk. The response status of the request will be the response status that is
 410 * set when http_respond_chunk is called the first time. Any headers set for the
 411 * first call will be sent as the response headers. Transfer-Encoding header
 412 * will automatically be set to chunked. Headers set for subsequent calls will
 413 * be ignored.
 414 *
 415 * @param request The request to respond to.
 416 * @param response The response to respond with.
 417 * @param notify_done The callback that's used to signal user code that another
 418 *   chunk is ready to be written out.
 419 */
 420void http_respond_chunk(struct http_request_s *request,
 421                        struct http_response_s *response,
 422                        void (*notify_done)(struct http_request_s *));
 423
 424/**
 425 * Ends the chunked response.
 426 *
 427 * Used to signal end of transmission on chunked requests. Any headers set
 428 * before this call will be included as what the HTTP spec refers to as
 429 * 'trailers' which are essentially more response headers.
 430 *
 431 * @param request The request to respond to.
 432 * @param response  The response to respond with.
 433 */
 434void http_respond_chunk_end(struct http_request_s *request,
 435                            struct http_response_s *response);
 436
 437/**
 438 * Read a chunk of the request body.
 439 *
 440 * If a request has Transfer-Encoding: chunked or the body is too big to fit in
 441 * memory all at once you cannot read the body in the typical way. Instead you
 442 * need to call this function to read one chunk at a time. To check if the
 443 * request requires this type of reading you can call the http_request_has_flag
 444 * function to check if the HTTP_FLG_STREAMED flag is set. To read a streamed
 445 * body you pass a callback that will be called when the chunk is ready. When
 446 * the callback is called you can use 'http_request_chunk' to get the current
 447 * chunk. When done with that chunk call this function again to request the
 448 * next chunk. If the chunk has size 0 then the request body has been completely
 449 * read and you can now respond.
 450 *
 451 * @param request The request.
 452 * @param chunk_cb Callback for when the chunk is ready.
 453 */
 454void http_request_read_chunk(struct http_request_s *request,
 455                             void (*chunk_cb)(struct http_request_s *));
 456
 457/**
 458 * Returns the current chunk of the request body.
 459 *
 460 * This chunk is only valid until the next call to 'http_request_read_chunk'.
 461 *
 462 * @param request The request.
 463 *
 464 * @return The chunk data.
 465 */
 466struct http_string_s http_request_chunk(struct http_request_s *request);
 467
 468#define http_request_read_body http_request_read_chunk
 469
 470#ifdef __cplusplus
 471}
 472#endif
 473
 474// Minimal example usage.
 475#ifdef HTTPSERVER_EXAMPLE
 476
 477#define RESPONSE "Hello, World!"
 478
 479void handle_request(struct http_request_s *request) {
 480  struct http_response_s *response = http_response_init();
 481  http_response_status(response, 200);
 482  http_response_header(response, "Content-Type", "text/plain");
 483  http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
 484  http_respond(request, response);
 485}
 486
 487int main() {
 488  struct http_server_s *server = http_server_init(8080, handle_request);
 489  http_server_listen(server);
 490}
 491
 492#endif
 493
 494#endif
 495
 496#line 1 "common.h"
 497#ifndef HS_COMMON_H
 498#define HS_COMMON_H
 499
 500// http session states
 501#define HTTP_SESSION_INIT 0
 502#define HTTP_SESSION_READ 1
 503#define HTTP_SESSION_WRITE 2
 504#define HTTP_SESSION_NOP 3
 505
 506#define HTTP_REQUEST_TIMEOUT 20
 507
 508#define HTTP_FLAG_SET(var, flag) var |= flag
 509#define HTTP_FLAG_CLEAR(var, flag) var &= ~flag
 510#define HTTP_FLAG_CHECK(var, flag) (var & flag)
 511
 512#define HTTP_AUTOMATIC 0x8
 513#define HTTP_CHUNKED_RESPONSE 0x20
 514
 515#define HTTP_KEEP_ALIVE 1
 516#define HTTP_CLOSE 0
 517
 518#include <arpa/inet.h>
 519#include <sys/socket.h>
 520#ifdef KQUEUE
 521#include <sys/event.h>
 522#else
 523#include <sys/epoll.h>
 524#endif
 525
 526#ifdef EPOLL
 527typedef void (*epoll_cb_t)(struct epoll_event *);
 528#endif
 529
 530typedef struct http_ev_cb_s {
 531#ifdef KQUEUE
 532  void (*handler)(struct kevent *ev);
 533#else
 534  epoll_cb_t handler;
 535#endif
 536} ev_cb_t;
 537
 538struct hsh_buffer_s {
 539  char *buf;
 540  int32_t capacity;
 541  int32_t length;
 542  int32_t index;
 543  int32_t after_headers_index;
 544  int8_t sequence_id;
 545};
 546
 547enum hsh_token_e {
 548  HSH_TOK_METHOD,
 549  HSH_TOK_TARGET,
 550  HSH_TOK_VERSION,
 551  HSH_TOK_HEADER_KEY,
 552  HSH_TOK_HEADER_VALUE,
 553  HSH_TOK_HEADERS_DONE,
 554  HSH_TOK_BODY,
 555  HSH_TOK_NONE,
 556  HSH_TOK_ERR
 557};
 558
 559struct hsh_token_s {
 560  enum hsh_token_e type;
 561  uint8_t flags;
 562  int len;
 563  int index;
 564};
 565
 566struct hsh_parser_s {
 567  int64_t content_length;
 568  int64_t content_remaining;
 569  struct hsh_token_s token;
 570  int16_t limit_count;
 571  int16_t limit_max;
 572  int8_t state;
 573  int8_t flags;
 574  int8_t sequence_id;
 575};
 576
 577struct hs_token_array_s {
 578  struct hsh_token_s *buf;
 579  int capacity;
 580  int size;
 581};
 582
 583typedef struct http_request_s {
 584#ifdef KQUEUE
 585  void (*handler)(struct kevent *ev);
 586#else
 587  epoll_cb_t handler;
 588  epoll_cb_t timer_handler;
 589  int timerfd;
 590#endif
 591  void (*chunk_cb)(struct http_request_s *);
 592  void *data;
 593  struct hsh_buffer_s buffer;
 594  struct hsh_parser_s parser;
 595  struct hs_token_array_s tokens;
 596  int state;
 597  int socket;
 598  int timeout;
 599  int64_t bytes_written;
 600  struct http_server_s *server;
 601  char flags;
 602} http_request_t;
 603
 604typedef struct http_server_s {
 605#ifdef KQUEUE
 606  void (*handler)(struct kevent *ev);
 607#else
 608  epoll_cb_t handler;
 609  epoll_cb_t timer_handler;
 610#endif
 611  int64_t memused;
 612  int socket;
 613  int port;
 614  int loop;
 615  int timerfd;
 616  socklen_t len;
 617  void (*request_handler)(http_request_t *);
 618  struct sockaddr_in addr;
 619  void *data;
 620  char date[32];
 621} http_server_t;
 622
 623#endif
 624
 625#line 1 "buffer_util.h"
 626#ifndef HS_BUFFER_UTIL_H
 627#define HS_BUFFER_UTIL_H
 628
 629#include <stdlib.h>
 630
 631#ifndef HTTPSERVER_IMPL
 632// #include "common.h"
 633#endif
 634
 635static inline void _hs_buffer_free(struct hsh_buffer_s *buffer,
 636                                   int64_t *memused) {
 637  if (buffer->buf) {
 638    free(buffer->buf);
 639    *memused -= buffer->capacity;
 640    buffer->buf = NULL;
 641  }
 642}
 643
 644#endif
 645
 646#line 1 "request_util.h"
 647#ifndef HS_REQUEST_UTIL_H
 648#define HS_REQUEST_UTIL_H
 649
 650// #include "common.h"
 651
 652// http version indicators
 653#define HTTP_1_0 0
 654#define HTTP_1_1 1
 655
 656struct http_string_s {
 657  char const *buf;
 658  int len;
 659};
 660
 661typedef struct http_string_s http_string_t;
 662
 663http_string_t hs_get_token_string(http_request_t *request,
 664                                  enum hsh_token_e token_type);
 665http_string_t hs_request_header(http_request_t *request, char const *key);
 666void hs_request_detect_keep_alive_flag(http_request_t *request);
 667int hs_request_iterate_headers(http_request_t *request, http_string_t *key,
 668                               http_string_t *val, int *iter);
 669void hs_request_set_keep_alive_flag(http_request_t *request, int directive);
 670http_string_t hs_request_chunk(struct http_request_s *request);
 671
 672#endif
 673
 674#line 1 "parser.h"
 675#ifndef HTTP_PARSER_H
 676#define HTTP_PARSER_H
 677
 678// HSH_TOK_HEADERS_DONE flags
 679#define HSH_TOK_FLAG_NO_BODY 0x1
 680#define HSH_TOK_FLAG_STREAMED_BODY 0x2
 681
 682// HSH_TOK_BODY flags
 683#define HSH_TOK_FLAG_BODY_FINAL 0x1
 684#define HSH_TOK_FLAG_SMALL_BODY 0x2
 685
 686struct hsh_token_s hsh_parser_exec(struct hsh_parser_s *parser,
 687                                   struct hsh_buffer_s *buffer,
 688                                   int max_buf_capacity);
 689void hsh_parser_init(struct hsh_parser_s *parser);
 690
 691#endif
 692
 693#line 1 "read_socket.h"
 694#ifndef HS_READ_SOCKET_H
 695#define HS_READ_SOCKET_H
 696
 697#define HTTP_FLG_STREAMED 0x1
 698
 699#include <stdint.h>
 700
 701struct http_request_s;
 702
 703// Response code for hs_read_socket
 704enum hs_read_rc_e {
 705  // Execution was successful
 706  HS_READ_RC_SUCCESS,
 707  // There was an error parsing the HTTP request
 708  HS_READ_RC_PARSE_ERR,
 709  // There was an error reading the socket
 710  HS_READ_RC_SOCKET_ERR
 711};
 712
 713// Holds configuration options for the hs_read_socket procedure.
 714struct hs_read_opts_s {
 715  // Restricts the request buffer from ever growing larger than this size
 716  int64_t max_request_buf_capacity;
 717  // The value to be compared to the return of the read call to determine if
 718  // the connection has been closed. Should generally be 0 in normal operation
 719  // using sockets but can be useful to change if you want to use files instead
 720  // of sockets for testing.
 721  int eof_rc;
 722  // The initial capacity that is allocated for the request buffer
 723  int initial_request_buf_capacity;
 724};
 725
 726enum hs_read_rc_e
 727hs_read_request_and_exec_user_cb(struct http_request_s *request,
 728                                 struct hs_read_opts_s opts);
 729
 730#endif
 731
 732#line 1 "respond.h"
 733#ifndef HS_RESPOND_H
 734#define HS_RESPOND_H
 735
 736#define HTTP_RESPONSE_BUF_SIZE 1024
 737
 738struct http_request_s;
 739
 740typedef void (*hs_req_fn_t)(struct http_request_s *);
 741
 742// Represents a single header of an HTTP response.
 743typedef struct http_header_s {
 744  // The key of the header eg: Content-Type
 745  char const *key;
 746  // The value of the header eg: application/json
 747  char const *value;
 748  // Pointer to the next header in the linked list.
 749  struct http_header_s *next;
 750} http_header_t;
 751
 752// Represents the response of an HTTP request before it is serialized on the
 753// wire.
 754typedef struct http_response_s {
 755  // Head of the linked list of response headers
 756  http_header_t *headers;
 757  // The complete body of the response or the chunk if generating a chunked
 758  // response.
 759  char const *body;
 760  // The length of the body or chunk.
 761  int content_length;
 762  // The HTTP status code for the response.
 763  int status;
 764} http_response_t;
 765
 766http_response_t *hs_response_init();
 767void hs_response_set_header(http_response_t *response, char const *key,
 768                            char const *value);
 769void hs_response_set_status(http_response_t *response, int status);
 770void hs_response_set_body(http_response_t *response, char const *body,
 771                          int length);
 772void hs_request_respond(struct http_request_s *request,
 773                        http_response_t *response, hs_req_fn_t http_write);
 774void hs_request_respond_chunk(struct http_request_s *request,
 775                              http_response_t *response, hs_req_fn_t cb,
 776                              hs_req_fn_t http_write);
 777void hs_request_respond_chunk_end(struct http_request_s *request,
 778                                  http_response_t *response,
 779                                  hs_req_fn_t http_write);
 780void hs_request_respond_error(struct http_request_s *request, int code,
 781                              char const *message, hs_req_fn_t http_write);
 782
 783#endif
 784
 785#line 1 "server.h"
 786#ifndef HS_SERVER_H
 787#define HS_SERVER_H
 788
 789#ifdef KQUEUE
 790
 791struct kevent;
 792
 793typedef void (*hs_evt_cb_t)(struct kevent *ev);
 794
 795#else
 796
 797struct epoll_event;
 798
 799typedef void (*hs_evt_cb_t)(struct epoll_event *ev);
 800
 801#endif
 802
 803struct http_request_s;
 804struct http_server_s;
 805
 806void hs_server_listen_on_addr(struct http_server_s *serv, const char *ipaddr);
 807int hs_server_run_event_loop(struct http_server_s *serv, const char *ipaddr);
 808void hs_generate_date_time(char *datetime);
 809struct http_server_s *hs_server_init(int port,
 810                                     void (*handler)(struct http_request_s *),
 811                                     hs_evt_cb_t accept_cb,
 812                                     hs_evt_cb_t timer_cb);
 813int hs_server_poll_events(struct http_server_s *serv);
 814
 815#endif
 816
 817#line 1 "write_socket.h"
 818#ifndef HS_WRITE_SOCKET_H
 819#define HS_WRITE_SOCKET_H
 820
 821#define HTTP_KEEP_ALIVE_TIMEOUT 120
 822
 823struct http_request_s;
 824
 825// Response code for hs_write_socket
 826enum hs_write_rc_e {
 827  // Successful and has written the full response
 828  HS_WRITE_RC_SUCCESS,
 829  // Successful and has written the full chunk
 830  HS_WRITE_RC_SUCCESS_CHUNK,
 831  // Successful, has written the full response and the socket should be closed
 832  HS_WRITE_RC_SUCCESS_CLOSE,
 833  // Successful but has not written the full response, wait for write ready
 834  HS_WRITE_RC_CONTINUE,
 835  // Error writing to the socket
 836  HS_WRITE_RC_SOCKET_ERR
 837};
 838
 839enum hs_write_rc_e hs_write_socket(struct http_request_s *request);
 840
 841#endif
 842
 843#line 1 "connection.h"
 844#ifndef HS_CONNECTION_H
 845#define HS_CONNECTION_H
 846
 847// Forward declarations
 848struct http_request_s;
 849struct http_server_s;
 850
 851#ifdef KQUEUE
 852struct kevent;
 853typedef void (*hs_io_cb_t)(struct kevent *ev);
 854#else
 855struct epoll_event;
 856typedef void (*hs_io_cb_t)(struct epoll_event *ev);
 857#endif
 858
 859/* Closes the requests socket and frees its resources.
 860 *
 861 * Removes all event watchers from the request socket and frees any allocated
 862 * buffers associated with the request struct.
 863 *
 864 * @param request The request to close
 865 */
 866void hs_request_terminate_connection(struct http_request_s *request);
 867
 868/* Accepts connections on the server socket in a loop until it would block.
 869 *
 870 * When a connection is accepted a request struct is allocated and initialized
 871 * and the request socket is set to non-blocking mode. Event watchers are set
 872 * on the socket to call io_cb with a read/write ready event occurs. If the
 873 * server has reached max_mem_usage the err_responder function is called to
 874 * handle the issue.
 875 *
 876 * @param server The http server struct.
 877 * @param io_cb The callback function to respond to events on the request socket
 878 * @param epoll_timer_cb The callback function to respond to timer events for
 879 *   epoll. Can be NULL if not using epoll.
 880 * @param err_responder The procedure to call when memory usage has reached the
 881 *   given limit. Typically this could respond with a 503 error and close the
 882 *   connection.
 883 * @param max_mem_usage The limit at which err_responder should be called
 884 *   instead of regular operation.
 885 */
 886struct http_request_s *hs_server_accept_connection(struct http_server_s *server,
 887                                                   hs_io_cb_t io_cb,
 888                                                   hs_io_cb_t epoll_timer_cb);
 889
 890#endif
 891
 892#line 1 "io_events.h"
 893#ifndef HS_IO_EVENTS_H
 894#define HS_IO_EVENTS_H
 895
 896#define HTTP_REQUEST_BUF_SIZE 1024
 897#define HTTP_MAX_REQUEST_BUF_SIZE 8388608       // 8mb
 898#define HTTP_MAX_TOTAL_EST_MEM_USAGE 4294967296 // 4gb
 899
 900struct http_request_s;
 901
 902void hs_request_begin_write(struct http_request_s *request);
 903void hs_request_begin_read(struct http_request_s *request);
 904
 905#ifdef KQUEUE
 906
 907struct kevent;
 908
 909void hs_on_kqueue_server_event(struct kevent *ev);
 910
 911#else
 912
 913struct epoll_event;
 914
 915void hs_on_epoll_server_connection_event(struct epoll_event *ev);
 916void hs_on_epoll_server_timer_event(struct epoll_event *ev);
 917
 918#endif
 919
 920#endif
 921
 922#ifdef HTTPSERVER_IMPL
 923#ifndef HTTPSERVER_IMPL_ONCE
 924#define HTTPSERVER_IMPL_ONCE
 925#line 1 "api.c"
 926#include <stdlib.h>
 927
 928#ifndef HTTPSERVER_IMPL
 929#include "api.h"
 930#include "buffer_util.h"
 931#include "common.h"
 932#include "io_events.h"
 933#include "request_util.h"
 934#include "respond.h"
 935#include "server.h"
 936#endif
 937
 938int http_request_has_flag(http_request_t *request, int flag) {
 939  return HTTP_FLAG_CHECK(request->flags, flag);
 940}
 941
 942int http_server_loop(http_server_t *server) { return server->loop; }
 943
 944http_server_t *http_server_init(int port, void (*handler)(http_request_t *)) {
 945#ifdef KQUEUE
 946  return hs_server_init(port, handler, hs_on_kqueue_server_event, NULL);
 947#else
 948  return hs_server_init(port, handler, hs_on_epoll_server_connection_event,
 949                        hs_on_epoll_server_timer_event);
 950#endif
 951}
 952
 953void http_request_free_buffer(http_request_t *request) {
 954  _hs_buffer_free(&request->buffer, &request->server->memused);
 955}
 956
 957void *http_request_userdata(http_request_t *request) { return request->data; }
 958
 959void http_request_set_userdata(http_request_t *request, void *data) {
 960  request->data = data;
 961}
 962
 963void http_server_set_userdata(struct http_server_s *serv, void *data) {
 964  serv->data = data;
 965}
 966
 967void *http_request_server_userdata(struct http_request_s *request) {
 968  return request->server->data;
 969}
 970
 971int http_request_iterate_headers(http_request_t *request, http_string_t *key,
 972                                 http_string_t *val, int *iter) {
 973  return hs_request_iterate_headers(request, key, val, iter);
 974}
 975
 976http_string_t http_request_header(http_request_t *request, char const *key) {
 977  return hs_request_header(request, key);
 978}
 979
 980void http_request_connection(http_request_t *request, int directive) {
 981  hs_request_set_keep_alive_flag(request, directive);
 982}
 983
 984http_string_t http_request_chunk(struct http_request_s *request) {
 985  return hs_request_chunk(request);
 986}
 987
 988http_response_t *http_response_init() { return hs_response_init(); }
 989
 990void http_response_header(http_response_t *response, char const *key,
 991                          char const *value) {
 992  return hs_response_set_header(response, key, value);
 993}
 994
 995void http_response_status(http_response_t *response, int status) {
 996  hs_response_set_status(response, status);
 997}
 998
 999void http_response_body(http_response_t *response, char const *body,
1000                        int length) {
1001  hs_response_set_body(response, body, length);
1002}
1003
1004void http_respond(http_request_t *request, http_response_t *response) {
1005  hs_request_respond(request, response, hs_request_begin_write);
1006}
1007
1008void http_respond_chunk(http_request_t *request, http_response_t *response,
1009                        void (*cb)(http_request_t *)) {
1010  hs_request_respond_chunk(request, response, cb, hs_request_begin_write);
1011}
1012
1013void http_respond_chunk_end(http_request_t *request,
1014                            http_response_t *response) {
1015  hs_request_respond_chunk_end(request, response, hs_request_begin_write);
1016}
1017
1018http_string_t http_request_method(http_request_t *request) {
1019  return hs_get_token_string(request, HSH_TOK_METHOD);
1020}
1021
1022http_string_t http_request_target(http_request_t *request) {
1023  return hs_get_token_string(request, HSH_TOK_TARGET);
1024}
1025
1026http_string_t http_request_body(http_request_t *request) {
1027  return hs_get_token_string(request, HSH_TOK_BODY);
1028}
1029
1030int http_server_listen(http_server_t *serv) {
1031  return hs_server_run_event_loop(serv, NULL);
1032}
1033
1034int http_server_listen_addr(http_server_t *serv, const char *ipaddr) {
1035  return hs_server_run_event_loop(serv, ipaddr);
1036}
1037
1038int http_server_poll(http_server_t *serv) {
1039  return hs_server_poll_events(serv);
1040}
1041
1042int http_server_listen_poll(http_server_t *serv) {
1043  hs_server_listen_on_addr(serv, NULL);
1044  return 0;
1045}
1046
1047int http_server_listen_addr_poll(http_server_t *serv, const char *ipaddr) {
1048  hs_server_listen_on_addr(serv, ipaddr);
1049  return 0;
1050}
1051
1052void http_request_read_chunk(struct http_request_s *request,
1053                             void (*chunk_cb)(struct http_request_s *)) {
1054  request->state = HTTP_SESSION_READ;
1055  request->chunk_cb = chunk_cb;
1056  hs_request_begin_read(request);
1057}
1058
1059#line 1 "request_util.c"
1060#include <stdlib.h>
1061#include <string.h>
1062
1063#ifndef HTTPSERVER_IMPL
1064#include "common.h"
1065#include "request_util.h"
1066#endif
1067
1068int _hs_case_insensitive_cmp(char const *a, char const *b, int len) {
1069  for (int i = 0; i < len; i++) {
1070    char c1 = a[i] >= 'A' && a[i] <= 'Z' ? a[i] + 32 : a[i];
1071    char c2 = b[i] >= 'A' && b[i] <= 'Z' ? b[i] + 32 : b[i];
1072    if (c1 != c2)
1073      return 0;
1074  }
1075  return 1;
1076}
1077
1078http_string_t hs_get_token_string(http_request_t *request,
1079                                  enum hsh_token_e token_type) {
1080  http_string_t str = {0, 0};
1081  if (request->tokens.buf == NULL)
1082    return str;
1083  for (int i = 0; i < request->tokens.size; i++) {
1084    struct hsh_token_s token = request->tokens.buf[i];
1085    if (token.type == token_type) {
1086      str.buf = &request->buffer.buf[token.index];
1087      str.len = token.len;
1088      return str;
1089    }
1090  }
1091  return str;
1092}
1093
1094http_string_t hs_request_header(http_request_t *request, char const *key) {
1095  int len = strlen(key);
1096  for (int i = 0; i < request->tokens.size; i++) {
1097    struct hsh_token_s token = request->tokens.buf[i];
1098    if (token.type == HSH_TOK_HEADER_KEY && token.len == len) {
1099      if (_hs_case_insensitive_cmp(&request->buffer.buf[token.index], key,
1100                                   len)) {
1101        token = request->tokens.buf[i + 1];
1102        return (http_string_t){.buf = &request->buffer.buf[token.index],
1103                               .len = token.len};
1104      }
1105    }
1106  }
1107  return (http_string_t){};
1108}
1109
1110void hs_request_detect_keep_alive_flag(http_request_t *request) {
1111  http_string_t str = hs_get_token_string(request, HSH_TOK_VERSION);
1112  if (str.buf == NULL)
1113    return;
1114  int version = str.buf[str.len - 1] == '1';
1115  str = hs_request_header(request, "Connection");
1116  if ((str.len == 5 && _hs_case_insensitive_cmp(str.buf, "close", 5)) ||
1117      (str.len == 0 && version == HTTP_1_0)) {
1118    HTTP_FLAG_CLEAR(request->flags, HTTP_KEEP_ALIVE);
1119  } else {
1120    HTTP_FLAG_SET(request->flags, HTTP_KEEP_ALIVE);
1121  }
1122}
1123
1124int _hs_get_header_key_val(http_request_t *request, http_string_t *key,
1125                           http_string_t *val, int iter) {
1126  struct hsh_token_s token = request->tokens.buf[iter];
1127  if (request->tokens.buf[iter].type == HSH_TOK_HEADERS_DONE)
1128    return 0;
1129  *key = (http_string_t){.buf = &request->buffer.buf[token.index],
1130                         .len = token.len};
1131  token = request->tokens.buf[iter + 1];
1132  *val = (http_string_t){.buf = &request->buffer.buf[token.index],
1133                         .len = token.len};
1134  return 1;
1135}
1136
1137int hs_request_iterate_headers(http_request_t *request, http_string_t *key,
1138                               http_string_t *val, int *iter) {
1139  if (*iter == 0) {
1140    for (; *iter < request->tokens.size; (*iter)++) {
1141      struct hsh_token_s token = request->tokens.buf[*iter];
1142      if (token.type == HSH_TOK_HEADER_KEY) {
1143        int more = _hs_get_header_key_val(request, key, val, *iter);
1144        (*iter)++;
1145        return more;
1146      }
1147    }
1148    return 0;
1149  } else {
1150    (*iter)++;
1151    int more = _hs_get_header_key_val(request, key, val, *iter);
1152    (*iter)++;
1153    return more;
1154  }
1155}
1156
1157void hs_request_set_keep_alive_flag(http_request_t *request, int directive) {
1158  if (directive == HTTP_KEEP_ALIVE) {
1159    HTTP_FLAG_CLEAR(request->flags, HTTP_AUTOMATIC);
1160    HTTP_FLAG_SET(request->flags, HTTP_KEEP_ALIVE);
1161  } else if (directive == HTTP_CLOSE) {
1162    HTTP_FLAG_CLEAR(request->flags, HTTP_AUTOMATIC);
1163    HTTP_FLAG_CLEAR(request->flags, HTTP_KEEP_ALIVE);
1164  }
1165}
1166
1167http_string_t hs_request_chunk(struct http_request_s *request) {
1168  struct hsh_token_s token = request->tokens.buf[request->tokens.size - 1];
1169  return (http_string_t){.buf = &request->buffer.buf[token.index],
1170                         .len = token.len};
1171}
1172
1173#line 1 "parser.c"
1174
1175#line 1 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1176#include <string.h>
1177#include <stdlib.h>
1178
1179#ifndef HTTPSERVER_IMPL
1180#include "common.h"
1181#include "parser.h"
1182#endif
1183
1184#define HSH_P_FLAG_CHUNKED 0x1
1185#define HSH_P_FLAG_TOKEN_READY 0x2
1186#define HSH_P_FLAG_DONE 0x4
1187
1188#define HSH_ENTER_TOKEN(tok_type, max_len) \
1189  parser->token.type = tok_type; \
1190  parser->token.index = p - buffer->buf; \
1191  parser->token.flags = 0; \
1192  parser->limit_count = 0; \
1193  parser->limit_max = max_len;
1194
1195
1196#line 232 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1197
1198
1199
1200#line 28 "/Users/jeremywilliams/code/httpserver.h/build/src/parser.c"
1201static const char _hsh_http_actions[] = {
1202	0, 1, 2, 1, 6, 1, 10, 1, 
1203	13, 1, 14, 1, 15, 1, 16, 1, 
1204	17, 1, 18, 2, 0, 10, 2, 1, 
1205	10, 2, 4, 10, 2, 5, 14, 2, 
1206	5, 16, 2, 5, 17, 2, 7, 10, 
1207	2, 8, 10, 2, 10, 11, 2, 12, 
1208	13, 2, 13, 14, 3, 3, 9, 10, 
1209	3, 4, 10, 6, 3, 7, 4, 10, 
1210	3, 9, 3, 10, 3, 13, 5, 14, 
1211	3, 13, 14, 12, 3, 14, 12, 13, 
1212	4, 5, 14, 12, 13, 4, 13, 5, 
1213	14, 12, 4, 14, 12, 13, 15
1214};
1215
1216static const short _hsh_http_key_offsets[] = {
1217	0, 0, 4, 9, 10, 11, 12, 13, 
1218	14, 15, 16, 17, 18, 20, 21, 22, 
1219	39, 53, 55, 58, 60, 61, 79, 94, 
1220	110, 126, 142, 158, 174, 190, 205, 221, 
1221	237, 253, 269, 285, 301, 315, 317, 322, 
1222	324, 328, 344, 360, 376, 392, 408, 424, 
1223	440, 455, 471, 487, 503, 519, 535, 551, 
1224	567, 583, 597, 599, 603, 606, 609, 612, 
1225	615, 618, 621, 622, 623, 624, 631, 632, 
1226	632, 633, 634, 635, 642, 643, 643, 644, 
1227	652, 661, 669, 677, 686, 688, 697, 698, 
1228	699, 699, 699, 713, 713, 713, 721, 729, 
1229	729, 729
1230};
1231
1232static const char _hsh_http_trans_keys[] = {
1233	65, 90, 97, 122, 32, 65, 90, 97, 
1234	122, 32, 32, 72, 84, 84, 80, 47, 
1235	49, 46, 48, 49, 13, 10, 9, 32, 
1236	34, 44, 47, 67, 84, 99, 116, 123, 
1237	125, 40, 41, 58, 64, 91, 93, 9, 
1238	32, 34, 44, 47, 58, 123, 125, 40, 
1239	41, 59, 64, 91, 93, 9, 32, 9, 
1240	13, 32, 10, 13, 10, 9, 13, 32, 
1241	34, 44, 47, 67, 84, 99, 116, 123, 
1242	125, 40, 41, 58, 64, 91, 93, 9, 
1243	10, 32, 34, 44, 47, 58, 123, 125, 
1244	40, 41, 59, 64, 91, 93, 9, 32, 
1245	34, 44, 47, 58, 79, 111, 123, 125, 
1246	40, 41, 59, 64, 91, 93, 9, 32, 
1247	34, 44, 47, 58, 78, 110, 123, 125, 
1248	40, 41, 59, 64, 91, 93, 9, 32, 
1249	34, 44, 47, 58, 84, 116, 123, 125, 
1250	40, 41, 59, 64, 91, 93, 9, 32, 
1251	34, 44, 47, 58, 69, 101, 123, 125, 
1252	40, 41, 59, 64, 91, 93, 9, 32, 
1253	34, 44, 47, 58, 78, 110, 123, 125, 
1254	40, 41, 59, 64, 91, 93, 9, 32, 
1255	34, 44, 47, 58, 84, 116, 123, 125, 
1256	40, 41, 59, 64, 91, 93, 9, 32, 
1257	34, 44, 45, 47, 58, 123, 125, 40, 
1258	41, 59, 64, 91, 93, 9, 32, 34, 
1259	44, 47, 58, 76, 108, 123, 125, 40, 
1260	41, 59, 64, 91, 93, 9, 32, 34, 
1261	44, 47, 58, 69, 101, 123, 125, 40, 
1262	41, 59, 64, 91, 93, 9, 32, 34, 
1263	44, 47, 58, 78, 110, 123, 125, 40, 
1264	41, 59, 64, 91, 93, 9, 32, 34, 
1265	44, 47, 58, 71, 103, 123, 125, 40, 
1266	41, 59, 64, 91, 93, 9, 32, 34, 
1267	44, 47, 58, 84, 116, 123, 125, 40, 
1268	41, 59, 64, 91, 93, 9, 32, 34, 
1269	44, 47, 58, 72, 104, 123, 125, 40, 
1270	41, 59, 64, 91, 93, 9, 32, 34, 
1271	44, 47, 58, 123, 125, 40, 41, 59, 
1272	64, 91, 93, 9, 32, 9, 13, 32, 
1273	48, 57, 10, 13, 10, 13, 48, 57, 
1274	9, 32, 34, 44, 47, 58, 82, 114, 
1275	123, 125, 40, 41, 59, 64, 91, 93, 
1276	9, 32, 34, 44, 47, 58, 65, 97, 
1277	123, 125, 40, 41, 59, 64, 91, 93, 
1278	9, 32, 34, 44, 47, 58, 78, 110, 
1279	123, 125, 40, 41, 59, 64, 91, 93, 
1280	9, 32, 34, 44, 47, 58, 83, 115, 
1281	123, 125, 40, 41, 59, 64, 91, 93, 
1282	9, 32, 34, 44, 47, 58, 70, 102, 
1283	123, 125, 40, 41, 59, 64, 91, 93, 
1284	9, 32, 34, 44, 47, 58, 69, 101, 
1285	123, 125, 40, 41, 59, 64, 91, 93, 
1286	9, 32, 34, 44, 47, 58, 82, 114, 
1287	123, 125, 40, 41, 59, 64, 91, 93, 
1288	9, 32, 34, 44, 45, 47, 58, 123, 
1289	125, 40, 41, 59, 64, 91, 93, 9, 
1290	32, 34, 44, 47, 58, 69, 101, 123, 
1291	125, 40, 41, 59, 64, 91, 93, 9, 
1292	32, 34, 44, 47, 58, 78, 110, 123, 
1293	125, 40, 41, 59, 64, 91, 93, 9, 
1294	32, 34, 44, 47, 58, 67, 99, 123, 
1295	125, 40, 41, 59, 64, 91, 93, 9, 
1296	32, 34, 44, 47, 58, 79, 111, 123, 
1297	125, 40, 41, 59, 64, 91, 93, 9, 
1298	32, 34, 44, 47, 58, 68, 100, 123, 
1299	125, 40, 41, 59, 64, 91, 93, 9, 
1300	32, 34, 44, 47, 58, 73, 105, 123, 
1301	125, 40, 41, 59, 64, 91, 93, 9, 
1302	32, 34, 44, 47, 58, 78, 110, 123, 
1303	125, 40, 41, 59, 64, 91, 93, 9, 
1304	32, 34, 44, 47, 58, 71, 103, 123, 
1305	125, 40, 41, 59, 64, 91, 93, 9, 
1306	32, 34, 44, 47, 58, 123, 125, 40, 
1307	41, 59, 64, 91, 93, 9, 32, 9, 
1308	13, 32, 99, 10, 13, 104, 10, 13, 
1309	117, 10, 13, 110, 10, 13, 107, 10, 
1310	13, 101, 10, 13, 100, 13, 10, 48, 
1311	13, 48, 57, 65, 70, 97, 102, 10, 
1312	13, 10, 48, 13, 48, 57, 65, 70, 
1313	97, 102, 10, 48, 13, 48, 49, 57, 
1314	65, 70, 97, 102, 10, 13, 48, 49, 
1315	57, 65, 70, 97, 102, 13, 48, 49, 
1316	57, 65, 70, 97, 102, 13, 48, 49, 
1317	57, 65, 70, 97, 102, 10, 13, 48, 
1318	49, 57, 65, 70, 97, 102, 13, 48, 
1319	10, 13, 48, 49, 57, 65, 70, 97, 
1320	102, 13, 10, 9, 32, 34, 44, 47, 
1321	58, 123, 125, 40, 41, 59, 64, 91, 
1322	93, 13, 48, 49, 57, 65, 70, 97, 
1323	102, 13, 48, 49, 57, 65, 70, 97, 
1324	102, 0
1325};
1326
1327static const char _hsh_http_single_lengths[] = {
1328	0, 0, 1, 1, 1, 1, 1, 1, 
1329	1, 1, 1, 1, 0, 1, 1, 11, 
1330	8, 2, 3, 2, 1, 12, 9, 10, 
1331	10, 10, 10, 10, 10, 9, 10, 10, 
1332	10, 10, 10, 10, 8, 2, 3, 2, 
1333	2, 10, 10, 10, 10, 10, 10, 10, 
1334	9, 10, 10, 10, 10, 10, 10, 10, 
1335	10, 8, 2, 4, 3, 3, 3, 3, 
1336	3, 3, 1, 1, 1, 1, 1, 0, 
1337	1, 1, 1, 1, 1, 0, 1, 2, 
1338	3, 2, 2, 3, 2, 3, 1, 1, 
1339	0, 0, 8, 0, 0, 2, 2, 0, 
1340	0, 0
1341};
1342
1343static const char _hsh_http_range_lengths[] = {
1344	0, 2, 2, 0, 0, 0, 0, 0, 
1345	0, 0, 0, 0, 1, 0, 0, 3, 
1346	3, 0, 0, 0, 0, 3, 3, 3, 
1347	3, 3, 3, 3, 3, 3, 3, 3, 
1348	3, 3, 3, 3, 3, 0, 1, 0, 
1349	1, 3, 3, 3, 3, 3, 3, 3, 
1350	3, 3, 3, 3, 3, 3, 3, 3, 
1351	3, 3, 0, 0, 0, 0, 0, 0, 
1352	0, 0, 0, 0, 0, 3, 0, 0, 
1353	0, 0, 0, 3, 0, 0, 0, 3, 
1354	3, 3, 3, 3, 0, 3, 0, 0, 
1355	0, 0, 3, 0, 0, 3, 3, 0, 
1356	0, 0
1357};
1358
1359static const short _hsh_http_index_offsets[] = {
1360	0, 0, 3, 7, 9, 11, 13, 15, 
1361	17, 19, 21, 23, 25, 27, 29, 31, 
1362	46, 58, 61, 65, 68, 70, 86, 99, 
1363	113, 127, 141, 155, 169, 183, 196, 210, 
1364	224, 238, 252, 266, 280, 292, 295, 300, 
1365	303, 307, 321, 335, 349, 363, 377, 391, 
1366	405, 418, 432, 446, 460, 474, 488, 502, 
1367	516, 530, 542, 545, 550, 554, 558, 562, 
1368	566, 570, 574, 576, 578, 580, 585, 587, 
1369	588, 590, 592, 594, 599, 601, 602, 604, 
1370	610, 617, 623, 629, 636, 639, 646, 648, 
1371	650, 651, 652, 664, 665, 666, 672, 678, 
1372	679, 680
1373};
1374
1375static const char _hsh_http_indicies[] = {
1376	1, 1, 0, 2, 3, 3, 0, 0, 
1377	4, 6, 5, 7, 0, 8, 0, 9, 
1378	0, 10, 0, 11, 0, 12, 0, 13, 
1379	0, 14, 0, 15, 0, 16, 0, 0, 
1380	0, 0, 0, 0, 18, 19, 18, 19, 
1381	0, 0, 0, 0, 0, 17, 0, 0, 
1382	0, 0, 0, 21, 0, 0, 0, 0, 
1383	0, 20, 22, 22, 0, 24, 25, 24, 
1384	23, 0, 27, 26, 28, 0, 0, 30, 
1385	0, 0, 0, 0, 31, 32, 31, 32, 
1386	0, 0, 0, 0, 0, 29, 0, 33, 
1387	0, 0, 0, 0, 21, 0, 0, 0, 
1388	0, 0, 20, 0, 0, 0, 0, 0, 
1389	21, 34, 34, 0, 0, 0, 0, 0, 
1390	20, 0, 0, 0, 0, 0, 21, 35, 
1391	35, 0, 0, 0, 0, 0, 20, 0, 
1392	0, 0, 0, 0, 21, 36, 36, 0, 
1393	0, 0, 0, 0, 20, 0, 0, 0, 
1394	0, 0, 21, 37, 37, 0, 0, 0, 
1395	0, 0, 20, 0, 0, 0, 0, 0, 
1396	21, 38, 38, 0, 0, 0, 0, 0, 
1397	20, 0, 0, 0, 0, 0, 21, 39, 
1398	39, 0, 0, 0, 0, 0, 20, 0, 
1399	0, 0, 0, 40, 0, 21, 0, 0, 
1400	0, 0, 0, 20, 0, 0, 0, 0, 
1401	0, 21, 41, 41, 0, 0, 0, 0, 
1402	0, 20, 0, 0, 0, 0, 0, 21, 
1403	42, 42, 0, 0, 0, 0, 0, 20, 
1404	0, 0, 0, 0, 0, 21, 43, 43, 
1405	0, 0, 0, 0, 0, 20, 0, 0, 
1406	0, 0, 0, 21, 44, 44, 0, 0, 
1407	0, 0, 0, 20, 0, 0, 0, 0, 
1408	0, 21, 45, 45, 0, 0, 0, 0, 
1409	0, 20, 0, 0, 0, 0, 0, 21, 
1410	46, 46, 0, 0, 0, 0, 0, 20, 
1411	0, 0, 0, 0, 0, 47, 0, 0, 
1412	0, 0, 0, 20, 48, 48, 0, 49, 
1413	25, 49, 50, 23, 28, 27, 26, 0, 
1414	27, 51, 26, 0, 0, 0, 0, 0, 
1415	21, 52, 52, 0, 0, 0, 0, 0, 
1416	20, 0, 0, 0, 0, 0, 21, 53, 
1417	53, 0, 0, 0, 0, 0, 20, 0, 
1418	0, 0, 0, 0, 21, 54, 54, 0, 
1419	0, 0, 0, 0, 20, 0, 0, 0, 
1420	0, 0, 21, 55, 55, 0, 0, 0, 
1421	0, 0, 20, 0, 0, 0, 0, 0, 
1422	21, 56, 56, 0, 0, 0, 0, 0, 
1423	20, 0, 0, 0, 0, 0, 21, 57, 
1424	57, 0, 0, 0, 0, 0, 20, 0, 
1425	0, 0, 0, 0, 21, 58, 58, 0, 
1426	0, 0, 0, 0, 20, 0, 0, 0, 
1427	0, 59, 0, 21, 0, 0, 0, 0, 
1428	0, 20, 0, 0, 0, 0, 0, 21, 
1429	60, 60, 0, 0, 0, 0, 0, 20, 
1430	0, 0, 0, 0, 0, 21, 61, 61, 
1431	0, 0, 0, 0, 0, 20, 0, 0, 
1432	0, 0, 0, 21, 62, 62, 0, 0, 
1433	0, 0, 0, 20, 0, 0, 0, 0, 
1434	0, 21, 63, 63, 0, 0, 0, 0, 
1435	0, 20, 0, 0, 0, 0, 0, 21, 
1436	64, 64, 0, 0, 0, 0, 0, 20, 
1437	0, 0, 0, 0, 0, 21, 65, 65, 
1438	0, 0, 0, 0, 0, 20, 0, 0, 
1439	0, 0, 0, 21, 66, 66, 0, 0, 
1440	0, 0, 0, 20, 0, 0, 0, 0, 
1441	0, 21, 67, 67, 0, 0, 0, 0, 
1442	0, 20, 0, 0, 0, 0, 0, 68, 
1443	0, 0, 0, 0, 0, 20, 69, 69, 
1444	0, 70, 25, 70, 71, 23, 0, 27, 
1445	72, 26, 0, 27, 73, 26, 0, 27, 
1446	74, 26, 0, 27, 75, 26, 0, 27, 
1447	76, 26, 0, 27, 77, 26, 78, 0, 
1448	79, 0, 81, 80, 82, 83, 83, 83, 
1449	0, 84, 0, 85, 86, 0, 87, 0, 
1450	89, 88, 90, 91, 91, 91, 0, 92, 
1451	0, 93, 95, 94, 96, 97, 98, 98, 
1452	98, 94, 99, 96, 97, 98, 98, 98, 
1453	94, 101, 102, 103, 103, 103, 100, 104, 
1454	97, 98, 98, 98, 94, 105, 96, 97, 
1455	98, 98, 98, 94, 106, 95, 94, 107, 
1456	96, 97, 98, 98, 98, 94, 108, 0, 
1457	109, 0, 110, 111, 0, 0, 0, 0, 
1458	0, 21, 0, 0, 0, 0, 0, 20, 
1459	112, 0, 101, 102, 103, 103, 103, 100, 
1460	96, 97, 98, 98, 98, 94, 0, 113, 
1461	114, 0
1462};
1463
1464static const char _hsh_http_trans_targs[] = {
1465	0, 2, 3, 2, 4, 4, 5, 6, 
1466	7, 8, 9, 10, 11, 12, 13, 14, 
1467	15, 16, 23, 41, 16, 17, 18, 19, 
1468	18, 39, 19, 20, 21, 16, 22, 23, 
1469	41, 90, 24, 25, 26, 27, 28, 29, 
1470	30, 31, 32, 33, 34, 35, 36, 37, 
1471	38, 38, 40, 40, 42, 43, 44, 45, 
1472	46, 47, 48, 49, 50, 51, 52, 53, 
1473	54, 55, 56, 57, 58, 59, 59, 60, 
1474	61, 62, 63, 64, 65, 19, 67, 68, 
1475	69, 72, 70, 69, 71, 91, 73, 92, 
1476	75, 86, 76, 75, 77, 78, 79, 84, 
1477	80, 82, 79, 81, 79, 80, 82, 79, 
1478	83, 93, 85, 94, 87, 95, 96, 97, 
1479	91, 96, 97
1480};
1481
1482static const char _hsh_http_trans_actions[] = {
1483	17, 19, 3, 5, 22, 5, 3, 1, 
1484	0, 0, 0, 0, 0, 0, 0, 3, 
1485	0, 64, 64, 64, 5, 3, 0, 25, 
1486	25, 56, 5, 3, 5, 52, 52, 52, 
1487	52, 43, 5, 5, 5, 5, 5, 5, 
1488	5, 5, 5, 5, 5, 5, 5, 3, 
1489	0, 25, 60, 37, 5, 5, 5, 5, 
1490	5, 5, 5, 5, 5, 5, 5, 5, 
1491	5, 5, 5, 5, 3, 0, 25, 25, 
1492	5, 5, 5, 5, 5, 40, 0, 0, 
1493	46, 0, 0, 7, 0, 28, 0, 11, 
1494	46, 0, 0, 7, 0, 28, 76, 9, 
1495	76, 49, 72, 76, 80, 80, 68, 85, 
1496	76, 90, 76, 90, 0, 11, 31, 34, 
1497	9, 13, 15
1498};
1499
1500static const char _hsh_http_eof_actions[] = {
1501	0, 17, 17, 17, 17, 17, 17, 17, 
1502	17, 17, 17, 17, 17, 17, 17, 17, 
1503	17, 17, 17, 17, 17, 17, 17, 17, 
1504	17, 17, 17, 17, 17, 17, 17, 17, 
1505	17, 17, 17, 17, 17, 17, 17, 17, 
1506	17, 17, 17, 17, 17, 17, 17, 17, 
1507	17, 17, 17, 17, 17, 17, 17, 17, 
1508	17, 17, 17, 17, 17, 17, 17, 17, 
1509	17, 17, 17, 17, 17, 17, 17, 17, 
1510	17, 17, 17, 17, 17, 17, 17, 17, 
1511	17, 17, 17, 17, 17, 17, 17, 17, 
1512	0, 0, 0, 0, 0, 0, 0, 0, 
1513	0, 0
1514};
1515
1516static const int hsh_http_start = 1;
1517static const int hsh_http_first_final = 90;
1518static const int hsh_http_error = 0;
1519
1520static const int hsh_http_en_chunk_end = 66;
1521static const int hsh_http_en_chunked_body = 74;
1522static const int hsh_http_en_small_body = 88;
1523static const int hsh_http_en_large_body = 89;
1524static const int hsh_http_en_main = 1;
1525
1526
1527#line 235 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1528
1529void hsh_parser_init(struct hsh_parser_s* parser) {
1530  memset(parser, 0, sizeof(struct hsh_parser_s));
1531  parser->state = hsh_http_start;
1532}
1533
1534struct hsh_token_s hsh_parser_exec(struct hsh_parser_s* parser, struct hsh_buffer_s* buffer, int max_buf_capacity) {
1535  struct hsh_token_s none = {};
1536  none.type = HSH_TOK_NONE;
1537  if (HTTP_FLAG_CHECK(parser->flags, HSH_P_FLAG_DONE) || parser->sequence_id == buffer->sequence_id) {
1538    return none;
1539  }
1540  int cs = parser->state;
1541  char* eof = NULL;
1542  char *p = buffer->buf + buffer->index;
1543  char *pe = buffer->buf + buffer->length;
1544  
1545#line 373 "/Users/jeremywilliams/code/httpserver.h/build/src/parser.c"
1546	{
1547	int _klen;
1548	unsigned int _trans;
1549	const char *_acts;
1550	unsigned int _nacts;
1551	const char *_keys;
1552
1553	if ( p == pe )
1554		goto _test_eof;
1555	if ( cs == 0 )
1556		goto _out;
1557_resume:
1558	_keys = _hsh_http_trans_keys + _hsh_http_key_offsets[cs];
1559	_trans = _hsh_http_index_offsets[cs];
1560
1561	_klen = _hsh_http_single_lengths[cs];
1562	if ( _klen > 0 ) {
1563		const char *_lower = _keys;
1564		const char *_mid;
1565		const char *_upper = _keys + _klen - 1;
1566		while (1) {
1567			if ( _upper < _lower )
1568				break;
1569
1570			_mid = _lower + ((_upper-_lower) >> 1);
1571			if ( (*p) < *_mid )
1572				_upper = _mid - 1;
1573			else if ( (*p) > *_mid )
1574				_lower = _mid + 1;
1575			else {
1576				_trans += (unsigned int)(_mid - _keys);
1577				goto _match;
1578			}
1579		}
1580		_keys += _klen;
1581		_trans += _klen;
1582	}
1583
1584	_klen = _hsh_http_range_lengths[cs];
1585	if ( _klen > 0 ) {
1586		const char *_lower = _keys;
1587		const char *_mid;
1588		const char *_upper = _keys + (_klen<<1) - 2;
1589		while (1) {
1590			if ( _upper < _lower )
1591				break;
1592
1593			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
1594			if ( (*p) < _mid[0] )
1595				_upper = _mid - 2;
1596			else if ( (*p) > _mid[1] )
1597				_lower = _mid + 2;
1598			else {
1599				_trans += (unsigned int)((_mid - _keys)>>1);
1600				goto _match;
1601			}
1602		}
1603		_trans += _klen;
1604	}
1605
1606_match:
1607	_trans = _hsh_http_indicies[_trans];
1608	cs = _hsh_http_trans_targs[_trans];
1609
1610	if ( _hsh_http_trans_actions[_trans] == 0 )
1611		goto _again;
1612
1613	_acts = _hsh_http_actions + _hsh_http_trans_actions[_trans];
1614	_nacts = (unsigned int) *_acts++;
1615	while ( _nacts-- > 0 )
1616	{
1617		switch ( *_acts++ )
1618		{
1619	case 0:
1620#line 23 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1621	{ HSH_ENTER_TOKEN(HSH_TOK_METHOD, 32) }
1622	break;
1623	case 1:
1624#line 24 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1625	{ HSH_ENTER_TOKEN(HSH_TOK_TARGET, 1024) }
1626	break;
1627	case 2:
1628#line 25 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1629	{ HSH_ENTER_TOKEN(HSH_TOK_VERSION, 16) }
1630	break;
1631	case 3:
1632#line 26 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1633	{ HSH_ENTER_TOKEN(HSH_TOK_HEADER_KEY, 256) }
1634	break;
1635	case 4:
1636#line 27 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1637	{ HSH_ENTER_TOKEN(HSH_TOK_HEADER_VALUE, 4096) }
1638	break;
1639	case 5:
1640#line 28 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1641	{
1642    parser->token.type = HSH_TOK_BODY;
1643    parser->token.flags = 0;
1644    parser->token.index = p - buffer->buf;
1645  }
1646	break;
1647	case 6:
1648#line 33 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1649	{
1650    parser->token.len = p - (buffer->buf + parser->token.index);
1651    // hsh_token_array_push(&parser->tokens, parser->token);
1652    HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1653    {p++; goto _out; }
1654  }
1655	break;
1656	case 7:
1657#line 40 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1658	{
1659    parser->content_length *= 10;
1660    parser->content_length += (*p) - '0';
1661  }
1662	break;
1663	case 8:
1664#line 45 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1665	{
1666    HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_CHUNKED);
1667  }
1668	break;
1669	case 9:
1670#line 49 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1671	{
1672    parser->limit_count = 0;
1673    parser->limit_max = 256;
1674  }
1675	break;
1676	case 10:
1677#line 54 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1678	{
1679    parser->limit_count++;
1680    if (parser->limit_count > parser->limit_max) {
1681      // parser->rc = (int8_t)HSH_PARSER_ERR;
1682      {p++; goto _out; }
1683    }
1684  }
1685	break;
1686	case 11:
1687#line 62 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1688	{
1689    buffer->after_headers_index = p - buffer->buf + 1;
1690    parser->content_remaining = parser->content_length;
1691    parser->token = (struct hsh_token_s){ };
1692    parser->token.type = HSH_TOK_HEADERS_DONE;
1693    HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1694    if (HTTP_FLAG_CHECK(parser->flags, HSH_P_FLAG_CHUNKED)) {
1695      HTTP_FLAG_SET(parser->token.flags, HSH_TOK_FLAG_STREAMED_BODY);
1696      cs = 74;
1697      {p++; goto _out; }
1698    } else if (parser->content_length == 0) {
1699      HTTP_FLAG_SET(parser->token.flags, HSH_TOK_FLAG_NO_BODY);
1700      {p++; goto _out; }
1701    // The body won't fit into the buffer at maximum capacity.
1702    } else if (parser->content_length > max_buf_capacity - buffer->after_headers_index) {
1703      HTTP_FLAG_SET(parser->token.flags, HSH_TOK_FLAG_STREAMED_BODY);
1704      cs = 89;
1705      {p++; goto _out; }
1706    } else {
1707      // Resize the buffer to hold the full body
1708      if (parser->content_length + buffer->after_headers_index > buffer->capacity) {
1709        buffer->buf = (char*)realloc(buffer->buf, parser->content_length + buffer->after_headers_index);
1710        buffer->capacity = parser->content_length + buffer->after_headers_index;
1711      }
1712      cs = 88;
1713      {p++; goto _out; }
1714    }
1715  }
1716	break;
1717	case 12:
1718#line 91 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1719	{
1720    parser->content_length = 0;
1721  }
1722	break;
1723	case 13:
1724#line 95 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1725	{
1726    if ((*p) >= 'A' && (*p) <= 'F') {
1727      parser->content_length *= 0x10;
1728      parser->content_length += (*p) - 55;
1729    } else if ((*p) >= 'a' && (*p) <= 'f') {
1730      parser->content_length *= 0x10;
1731      parser->content_length += (*p) - 87;
1732    } else if ((*p) >= '0' && (*p) <= '9') {
1733      parser->content_length *= 0x10;
1734      parser->content_length += (*p) - '0';
1735    }
1736  }
1737	break;
1738	case 14:
1739#line 108 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1740	{
1741    char* last_body_byte = buffer->buf + parser->token.index + parser->content_length - 1;
1742    if (pe >= last_body_byte) {
1743      p = last_body_byte;
1744      parser->token.len = parser->content_length;
1745      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1746      cs = 66;
1747      {p++; goto _out; }
1748    // The current chunk is at the end of the buffer and the buffer cannot be expanded.
1749    // Move the remaining contents of the buffer to just after the headers to free up
1750    // capacity in the buffer.
1751    } else if (p - buffer->buf + parser->content_length > max_buf_capacity) {
1752      memcpy(buffer->buf + buffer->after_headers_index, p, pe - p);
1753      buffer->length = buffer->after_headers_index + pe - p;
1754      p = buffer->buf + buffer->after_headers_index;
1755      parser->token.index = buffer->after_headers_index;
1756      parser->sequence_id = buffer->sequence_id;
1757      p--;
1758      {p++; goto _out; }
1759    }
1760  }
1761	break;
1762	case 15:
1763#line 130 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1764	{
1765    // write 0 byte body to tokens
1766    parser->token.type = HSH_TOK_BODY;
1767    parser->token.index = 0;
1768    parser->token.len = 0;
1769    parser->token.flags = HSH_TOK_FLAG_BODY_FINAL;
1770    HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1771    HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_DONE);
1772    {p++; goto _out; }
1773  }
1774	break;
1775	case 16:
1776#line 141 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1777	{
1778    parser->token.index = buffer->after_headers_index;
1779    parser->token.len = parser->content_length;
1780    HTTP_FLAG_SET(parser->token.flags, HSH_TOK_FLAG_SMALL_BODY);
1781    char* last_body_byte = buffer->buf + parser->token.index + parser->content_length - 1;
1782    if (pe >= last_body_byte) {
1783      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1784      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_DONE);
1785    }
1786    p = pe;
1787    p--;
1788    {p++; goto _out; }
1789  }
1790	break;
1791	case 17:
1792#line 155 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1793	{
1794    parser->token.index = buffer->after_headers_index;
1795    char* last_body_byte = buffer->buf + buffer->after_headers_index + parser->content_remaining - 1;
1796    if (pe >= last_body_byte) {
1797      parser->token.flags = HSH_TOK_FLAG_BODY_FINAL;
1798      parser->token.len = parser->content_remaining;
1799      parser->content_remaining = 0;
1800      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1801      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_DONE);
1802    } else {
1803      parser->token.len = pe - p;
1804      parser->content_remaining -= parser->token.len;
1805      HTTP_FLAG_SET(parser->flags, HSH_P_FLAG_TOKEN_READY);
1806      p = buffer->buf + buffer->after_headers_index;
1807      buffer->length = buffer->after_headers_index;
1808      parser->sequence_id = buffer->sequence_id;
1809    }
1810    p--;
1811    {p++; goto _out; }
1812  }
1813	break;
1814	case 18:
1815#line 176 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1816	{
1817    // parser->rc = (int8_t)HSH_PARSER_ERR;
1818    {p++; goto _out; }
1819  }
1820	break;
1821#line 649 "/Users/jeremywilliams/code/httpserver.h/build/src/parser.c"
1822		}
1823	}
1824
1825_again:
1826	if ( cs == 0 )
1827		goto _out;
1828	if ( ++p != pe )
1829		goto _resume;
1830	_test_eof: {}
1831	if ( p == eof )
1832	{
1833	const char *__acts = _hsh_http_actions + _hsh_http_eof_actions[cs];
1834	unsigned int __nacts = (unsigned int) *__acts++;
1835	while ( __nacts-- > 0 ) {
1836		switch ( *__acts++ ) {
1837	case 18:
1838#line 176 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1839	{
1840    // parser->rc = (int8_t)HSH_PARSER_ERR;
1841    {p++; goto _out; }
1842  }
1843	break;
1844#line 672 "/Users/jeremywilliams/code/httpserver.h/build/src/parser.c"
1845		}
1846	}
1847	}
1848
1849	_out: {}
1850	}
1851
1852#line 252 "/Users/jeremywilliams/code/httpserver.h/src/parser.rl"
1853  parser->state = cs;
1854  buffer->index = p - buffer->buf;
1855  if (HTTP_FLAG_CHECK(parser->flags, HSH_P_FLAG_TOKEN_READY)) {
1856    HTTP_FLAG_CLEAR(parser->flags, HSH_P_FLAG_TOKEN_READY);
1857    return parser->token;
1858  } else {
1859    parser->sequence_id = buffer->sequence_id;
1860    return none;
1861  }
1862}
1863
1864#line 1 "read_socket.c"
1865#include <assert.h>
1866#include <stdlib.h>
1867#include <string.h>
1868#include <unistd.h>
1869
1870#ifndef HTTPSERVER_IMPL
1871#include "common.h"
1872#include "parser.h"
1873#include "read_socket.h"
1874#endif
1875
1876void _hs_token_array_push(struct hs_token_array_s *array,
1877                          struct hsh_token_s a) {
1878  if (array->size == array->capacity) {
1879    array->capacity *= 2;
1880    array->buf = (struct hsh_token_s *)realloc(
1881        array->buf, array->capacity * sizeof(struct hsh_token_s));
1882    assert(array->buf != NULL);
1883  }
1884  array->buf[array->size] = a;
1885  array->size++;
1886}
1887
1888void _hs_buffer_init(struct hsh_buffer_s *buffer, int initial_capacity,
1889                     int64_t *memused) {
1890  *buffer = (struct hsh_buffer_s){0};
1891  buffer->buf = (char *)calloc(1, initial_capacity);
1892  *memused += initial_capacity;
1893  assert(buffer->buf != NULL);
1894  buffer->capacity = initial_capacity;
1895}
1896
1897int _hs_read_into_buffer(struct hsh_buffer_s *buffer, int request_socket,
1898                         int64_t *server_memused,
1899                         int64_t max_request_buf_capacity) {
1900  int bytes;
1901  do {
1902    bytes = read(request_socket, buffer->buf + buffer->length,
1903                 buffer->capacity - buffer->length);
1904    if (bytes > 0)
1905      buffer->length += bytes;
1906
1907    if (buffer->length == buffer->capacity &&
1908        buffer->capacity != max_request_buf_capacity) {
1909      *server_memused -= buffer->capacity;
1910      buffer->capacity *= 2;
1911      if (buffer->capacity > max_request_buf_capacity) {
1912        buffer->capacity = max_request_buf_capacity;
1913      }
1914      *server_memused += buffer->capacity;
1915      buffer->buf = (char *)realloc(buffer->buf, buffer->capacity);
1916      assert(buffer->buf != NULL);
1917    }
1918  } while (bytes > 0 && buffer->capacity < max_request_buf_capacity);
1919
1920  buffer->sequence_id++;
1921
1922  return bytes;
1923}
1924
1925int _hs_buffer_requires_read(struct hsh_buffer_s *buffer) {
1926  return buffer->index >= buffer->length;
1927}
1928
1929void _hs_exec_callback(http_request_t *request,
1930                       void (*cb)(struct http_request_s *)) {
1931  request->state = HTTP_SESSION_NOP;
1932  cb(request);
1933}
1934
1935enum hs_read_rc_e
1936_hs_parse_buffer_and_exec_user_cb(http_request_t *request,
1937                                  int max_request_buf_capacity) {
1938  enum hs_read_rc_e rc = HS_READ_RC_SUCCESS;
1939
1940  do {
1941    struct hsh_token_s token = hsh_parser_exec(
1942        &request->parser, &request->buffer, max_request_buf_capacity);
1943
1944    switch (token.type) {
1945    case HSH_TOK_HEADERS_DONE:
1946      _hs_token_array_push(&request->tokens, token);
1947      if (HTTP_FLAG_CHECK(token.flags, HSH_TOK_FLAG_STREAMED_BODY) ||
1948          HTTP_FLAG_CHECK(token.flags, HSH_TOK_FLAG_NO_BODY)) {
1949        HTTP_FLAG_SET(request->flags, HTTP_FLG_STREAMED);
1950        _hs_exec_callback(request, request->server->request_handler);
1951        return rc;
1952      }
1953      break;
1954    case HSH_TOK_BODY:
1955      _hs_token_array_push(&request->tokens, token);
1956      if (HTTP_FLAG_CHECK(token.flags, HSH_TOK_FLAG_SMALL_BODY)) {
1957        _hs_exec_callback(request, request->server->request_handler);
1958      } else {
1959        if (HTTP_FLAG_CHECK(token.flags, HSH_TOK_FLAG_BODY_FINAL) &&
1960            token.len > 0) {
1961          _hs_exec_callback(request, request->chunk_cb);
1962
1963          // A zero length body is used to indicate to the user code that the
1964          // body has finished streaming. This is natural when dealing with
1965          // chunked request bodies but requires us to inject a zero length
1966          // body for non-chunked requests.
1967          struct hsh_token_s token = {};
1968          memset(&token, 0, sizeof(struct hsh_token_s));
1969          token.type = HSH_TOK_BODY;
1970          _hs_token_array_push(&request->tokens, token);
1971          _hs_exec_callback(request, request->chunk_cb);
1972        } else {
1973          _hs_exec_callback(request, request->chunk_cb);
1974        }
1975      }
1976      return rc;
1977    case HSH_TOK_ERR:
1978      return HS_READ_RC_PARSE_ERR;
1979    case HSH_TOK_NONE:
1980      return rc;
1981    default:
1982      _hs_token_array_push(&request->tokens, token);
1983      break;
1984    }
1985  } while (1);
1986}
1987
1988// Reads the request socket if required and parses HTTP in a non-blocking
1989// manner.
1990//
1991// It should be called when a new connection is established and when a read
1992// ready event occurs for the request socket. It parses the HTTP request and
1993// fills the tokens array of the request struct. It will also invoke the
1994// request_hander callback and the chunk_cb callback in the appropriate
1995// scenarios.
1996enum hs_read_rc_e hs_read_request_and_exec_user_cb(http_request_t *request,
1997                                                   struct hs_read_opts_s opts) {
1998  request->state = HTTP_SESSION_READ;
1999  request->timeout = HTTP_REQUEST_TIMEOUT;
2000
2001  if (request->buffer.buf == NULL) {
2002    _hs_buffer_init(&request->buffer, opts.initial_request_buf_capacity,
2003                    &request->server->memused);
2004    hsh_parser_init(&request->parser);
2005  }
2006
2007  if (_hs_buffer_requires_read(&request->buffer)) {
2008    int bytes = _hs_read_into_buffer(&request->buffer, request->socket,
2009                                     &request->server->memused,
2010                                     opts.max_request_buf_capacity);
2011
2012    if (bytes == opts.eof_rc) {
2013      return HS_READ_RC_SOCKET_ERR;
2014    }
2015  }
2016
2017  return _hs_parse_buffer_and_exec_user_cb(request,
2018                                           opts.max_request_buf_capacity);
2019}
2020
2021#line 1 "respond.c"
2022#include <assert.h>
2023#include <stdarg.h>
2024#include <stdint.h>
2025#include <stdio.h>
2026#include <stdlib.h>
2027#include <string.h>
2028
2029#ifndef HTTPSERVER_IMPL
2030#include "buffer_util.h"
2031#include "common.h"
2032#include "request_util.h"
2033#include "respond.h"
2034#endif
2035
2036char const *hs_status_text[] = {
2037    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2038    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2039    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2040    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2041    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2042    "", "", "", "", "",
2043
2044    // 100s
2045    "Continue", "Switching Protocols", "", "", "", "", "", "", "", "", "", "",
2046    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2047    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2048    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2049    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2050    "", "", "", "", "", "", "", "", "", "", "", "",
2051
2052    // 200s
2053    "OK", "Created", "Accepted", "Non-Authoritative Information", "No Content",
2054    "Reset Content", "Partial Content", "", "", "",
2055
2056    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2057    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2058    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2059    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2060    "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2061
2062    // 300s
2063    "Multiple Choices", "Moved Permanently", "Found", "See Other",
2064    "Not Modified", "Use Proxy", "", "Temporary Redirect", "", "",
2065
2066    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2067    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2068    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2069    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2070    "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2071
2072    // 400s
2073    "Bad Request", "Unauthorized", "Payment Required", "Forbidden", "Not Found",
2074    "Method Not Allowed", "Not Acceptable", "Proxy Authentication Required",
2075    "Request Timeout", "Conflict",
2076
2077    "Gone", "Length Required", "", "Payload Too Large", "", "", "", "", "", "",
2078
2079    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2080    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2081    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2082    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2083    "", "", "", "",
2084
2085    // 500s
2086    "Internal Server Error", "Not Implemented", "Bad Gateway",
2087    "Service Unavailable", "Gateway Timeout", "", "", "", "", "",
2088
2089    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2090    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2091    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2092    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
2093    "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
2094typedef struct {
2095  char *buf;
2096  int capacity;
2097  int size;
2098  int64_t *memused;
2099} grwprintf_t;
2100
2101void _grwprintf_init(grwprintf_t *ctx, int capacity, int64_t *memused) {
2102  ctx->memused = memused;
2103  ctx->size = 0;
2104  ctx->buf = (char *)malloc(capacity);
2105  *ctx->memused += capacity;
2106  assert(ctx->buf != NULL);
2107  ctx->capacity = capacity;
2108}
2109
2110void _grwmemcpy(grwprintf_t *ctx, char const *src, int size) {
2111  if (ctx->size + size > ctx->capacity) {
2112    *ctx->memused -= ctx->capacity;
2113    ctx->capacity = ctx->size + size;
2114    *ctx->memused += ctx->capacity;
2115    ctx->buf = (char *)realloc(ctx->buf, ctx->capacity);
2116    assert(ctx->buf != NULL);
2117  }
2118  memcpy(ctx->buf + ctx->size, src, size);
2119  ctx->size += size;
2120}
2121
2122void _grwprintf(grwprintf_t *ctx, char const *fmt, ...) {
2123  va_list args;
2124  va_start(args, fmt);
2125
2126  int bytes =
2127      vsnprintf(ctx->buf + ctx->size, ctx->capacity - ctx->size, fmt, args);
2128  if (bytes + ctx->size > ctx->capacity) {
2129    *ctx->memused -= ctx->capacity;
2130    while (bytes + ctx->size > ctx->capacity)
2131      ctx->capacity *= 2;
2132    *ctx->memused += ctx->capacity;
2133    ctx->buf = (char *)realloc(ctx->buf, ctx->capacity);
2134    assert(ctx->buf != NULL);
2135    bytes +=
2136        vsnprintf(ctx->buf + ctx->size, ctx->capacity - ctx->size, fmt, args);
2137  }
2138  ctx->size += bytes;
2139
2140  va_end(args);
2141}
2142
2143void _http_serialize_headers_list(http_response_t *response,
2144                                  grwprintf_t *printctx) {
2145  http_header_t *header = response->headers;
2146  while (header) {
2147    _grwprintf(printctx, "%s: %s\r\n", header->key, header->value);
2148    header = header->next;
2149  }
2150  _grwprintf(printctx, "\r\n");
2151}
2152
2153void _http_serialize_headers(http_request_t *request, http_response_t *response,
2154                             grwprintf_t *printctx) {
2155  if (HTTP_FLAG_CHECK(request->flags, HTTP_AUTOMATIC)) {
2156    hs_request_detect_keep_alive_flag(request);
2157  }
2158  if (HTTP_FLAG_CHECK(request->flags, HTTP_KEEP_ALIVE)) {
2159    hs_response_set_header(response, "Connection", "keep-alive");
2160  } else {
2161    hs_response_set_header(response, "Connection", "close");
2162  }
2163  _grwprintf(printctx, "HTTP/1.1 %d %s\r\nDate: %s\r\n", response->status,
2164             hs_status_text[response->status], request->server->date);
2165  if (!HTTP_FLAG_CHECK(request->flags, HTTP_CHUNKED_RESPONSE)) {
2166    _grwprintf(printctx, "Content-Length: %d\r\n", response->content_length);
2167  }
2168  _http_serialize_headers_list(response, printctx);
2169}
2170
2171void _http_perform_response(http_request_t *request, http_response_t *response,
2172                            grwprintf_t *printctx, hs_req_fn_t http_write) {
2173  http_header_t *header = response->headers;
2174  while (header) {
2175    http_header_t *tmp = header;
2176    header = tmp->next;
2177    free(tmp);
2178  }
2179  _hs_buffer_free(&request->buffer, &request->server->memused);
2180  free(response);
2181  request->buffer.buf = printctx->buf;
2182  request->buffer.length = printctx->size;
2183  request->buffer.capacity = printctx->capacity;
2184  request->bytes_written = 0;
2185  request->state = HTTP_SESSION_WRITE;
2186  http_write(request);
2187}
2188
2189// See api.h http_response_header
2190void hs_response_set_header(http_response_t *response, char const *key,
2191                            char const *value) {
2192  http_header_t *header = (http_header_t *)malloc(sizeof(http_header_t));
2193  assert(header != NULL);
2194  header->key = key;
2195  header->value = value;
2196  http_header_t *prev = response->headers;
2197  header->next = prev;
2198  response->headers = header;
2199}
2200
2201// Serializes the response into the request buffer and calls http_write.
2202// See api.h http_respond for more details
2203void hs_request_respond(http_request_t *request, http_response_t *response,
2204                        hs_req_fn_t http_write) {
2205  grwprintf_t printctx;
2206  _grwprintf_init(&printctx, HTTP_RESPONSE_BUF_SIZE, &request->server->memused);
2207  _http_serialize_headers(request, response, &printctx);
2208  if (response->body) {
2209    _grwmemcpy(&printctx, response->body, response->content_length);
2210  }
2211  _http_perform_response(request, response, &printctx, http_write);
2212}
2213
2214// Serializes a chunk into the request buffer and calls http_write.
2215// See api.h http_respond_chunk for more details.
2216void hs_request_respond_chunk(http_request_t *request,
2217                              http_response_t *response, hs_req_fn_t cb,
2218                              hs_req_fn_t http_write) {
2219  grwprintf_t printctx;
2220  _grwprintf_init(&printctx, HTTP_RESPONSE_BUF_SIZE, &request->server->memused);
2221  if (!HTTP_FLAG_CHECK(request->flags, HTTP_CHUNKED_RESPONSE)) {
2222    HTTP_FLAG_SET(request->flags, HTTP_CHUNKED_RESPONSE);
2223    hs_response_set_header(response, "Transfer-Encoding", "chunked");
2224    _http_serialize_headers(request, response, &printctx);
2225  }
2226  request->chunk_cb = cb;
2227  _grwprintf(&printctx, "%X\r\n", response->content_length);
2228  _grwmemcpy(&printctx, response->body, response->content_length);
2229  _grwprintf(&printctx, "\r\n");
2230  _http_perform_response(request, response, &printctx, http_write);
2231}
2232
2233// Serializes the zero sized final chunk into the request buffer and calls
2234// http_write. See api.h http_respond_chunk_end for more details.
2235void hs_request_respond_chunk_end(http_request_t *request,
2236                                  http_response_t *response,
2237                                  hs_req_fn_t http_write) {
2238  grwprintf_t printctx;
2239  _grwprintf_init(&printctx, HTTP_RESPONSE_BUF_SIZE, &request->server->memused);
2240  _grwprintf(&printctx, "0\r\n");
2241  _http_serialize_headers_list(response, &printctx);
2242  _grwprintf(&printctx, "\r\n");
2243  HTTP_FLAG_CLEAR(request->flags, HTTP_CHUNKED_RESPONSE);
2244  _http_perform_response(request, response, &printctx, http_write);
2245}
2246
2247// See api.h http_response_status
2248void hs_response_set_status(http_response_t *response, int status) {
2249  response->status = status > 599 || status < 100 ? 500 : status;
2250}
2251
2252// See api.h http_response_body
2253void hs_response_set_body(http_response_t *response, char const *body,
2254                          int length) {
2255  response->body = body;
2256  response->content_length = length;
2257}
2258
2259// See api.h http_response_init
2260http_response_t *hs_response_init() {
2261  http_response_t *response =
2262      (http_response_t *)calloc(1, sizeof(http_response_t));
2263  assert(response != NULL);
2264  response->status = 200;
2265  return response;
2266}
2267
2268// Simple less flexible interface for responses, used for errors.
2269void hs_request_respond_error(http_request_t *request, int code,
2270                              char const *message, hs_req_fn_t http_write) {
2271  struct http_response_s *response = hs_response_init();
2272  hs_response_set_status(response, code);
2273  hs_response_set_header(response, "Content-Type", "text/plain");
2274  hs_response_set_body(response, message, strlen(message));
2275  hs_request_respond(request, response, http_write);
2276  http_write(request);
2277}
2278
2279#line 1 "server.c"
2280#include <arpa/inet.h>
2281#include <assert.h>
2282#include <fcntl.h>
2283#include <netinet/in.h>
2284#include <signal.h>
2285#include <stdlib.h>
2286#include <sys/socket.h>
2287#include <time.h>
2288
2289#ifdef EPOLL
2290#include <sys/epoll.h>
2291#include <sys/timerfd.h>
2292#else
2293#include <sys/event.h>
2294#endif
2295
2296#ifndef HTTPSERVER_IMPL
2297#include "common.h"
2298#include "server.h"
2299#endif
2300
2301void _hs_bind_localhost(int s, struct sockaddr_in *addr, const char *ipaddr,
2302                        int port) {
2303  addr->sin_family = AF_INET;
2304  if (ipaddr == NULL) {
2305    addr->sin_addr.s_addr = INADDR_ANY;
2306  } else {
2307    addr->sin_addr.s_addr = inet_addr(ipaddr);
2308  }
2309  addr->sin_port = htons(port);
2310  int rc = bind(s, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
2311  if (rc < 0) {
2312    exit(1);
2313  }
2314}
2315
2316#ifdef KQUEUE
2317
2318void _hs_add_server_sock_events(http_server_t *serv) {
2319  struct kevent ev_set;
2320  EV_SET(&ev_set, serv->socket, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, serv);
2321  kevent(serv->loop, &ev_set, 1, NULL, 0, NULL);
2322}
2323
2324void _hs_server_init_events(http_server_t *serv, hs_evt_cb_t unused) {
2325  (void)unused;
2326
2327  serv->loop = kqueue();
2328  struct kevent ev_set;
2329  EV_SET(&ev_set, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_SECONDS, 1, serv);
2330  kevent(serv->loop, &ev_set, 1, NULL, 0, NULL);
2331}
2332
2333int hs_server_run_event_loop(http_server_t *serv, const char *ipaddr) {
2334  hs_server_listen_on_addr(serv, ipaddr);
2335
2336  struct kevent ev_list[1];
2337
2338  while (1) {
2339    int nev = kevent(serv->loop, NULL, 0, ev_list, 1, NULL);
2340    for (int i = 0; i < nev; i++) {
2341      ev_cb_t *ev_cb = (ev_cb_t *)ev_list[i].udata;
2342      ev_cb->handler(&ev_list[i]);
2343    }
2344  }
2345  return 0;
2346}
2347
2348int hs_server_poll_events(http_server_t *serv) {
2349  struct kevent ev;
2350  struct timespec ts = {0, 0};
2351  int nev = kevent(serv->loop, NULL, 0, &ev, 1, &ts);
2352  if (nev <= 0)
2353    return nev;
2354  ev_cb_t *ev_cb = (ev_cb_t *)ev.udata;
2355  ev_cb->handler(&ev);
2356  return nev;
2357}
2358
2359#else
2360
2361void _hs_server_init_events(http_server_t *serv, hs_evt_cb_t timer_cb) {
2362  serv->loop = epoll_create1(0);
2363  serv->timer_handler = timer_cb;
2364
2365  int tfd = timerfd_create(CLOCK_MONOTONIC, 0);
2366  struct itimerspec ts = {};
2367  ts.it_value.tv_sec = 1;
2368  ts.it_interval.tv_sec = 1;
2369  timerfd_settime(tfd, 0, &ts, NULL);
2370
2371  struct epoll_event ev;
2372  ev.events = EPOLLIN | EPOLLET;
2373  ev.data.ptr = &serv->timer_handler;
2374  epoll_ctl(serv->loop, EPOLL_CTL_ADD, tfd, &ev);
2375  serv->timerfd = tfd;
2376}
2377
2378void _hs_add_server_sock_events(http_server_t *serv) {
2379  struct epoll_event ev;
2380  ev.events = EPOLLIN | EPOLLET;
2381  ev.data.ptr = serv;
2382  epoll_ctl(serv->loop, EPOLL_CTL_ADD, serv->socket, &ev);
2383}
2384
2385int hs_server_run_event_loop(http_server_t *serv, const char *ipaddr) {
2386  hs_server_listen_on_addr(serv, ipaddr);
2387  struct epoll_event ev_list[1];
2388  while (1) {
2389    int nev = epoll_wait(serv->loop, ev_list, 1, -1);
2390    for (int i = 0; i < nev; i++) {
2391      ev_cb_t *ev_cb = (ev_cb_t *)ev_list[i].data.ptr;
2392      ev_cb->handler(&ev_list[i]);
2393    }
2394  }
2395  return 0;
2396}
2397
2398int hs_server_poll_events(http_server_t *serv) {
2399  struct epoll_event ev;
2400  int nev = epoll_wait(serv->loop, &ev, 1, 0);
2401  if (nev <= 0)
2402    return nev;
2403  ev_cb_t *ev_cb = (ev_cb_t *)ev.data.ptr;
2404  ev_cb->handler(&ev);
2405  return nev;
2406}
2407
2408#endif
2409
2410void hs_server_listen_on_addr(http_server_t *serv, const char *ipaddr) {
2411  // Ignore SIGPIPE. We handle these errors at the call site.
2412  signal(SIGPIPE, SIG_IGN);
2413  serv->socket = socket(AF_INET, SOCK_STREAM, 0);
2414  int flag = 1;
2415  setsockopt(serv->socket, SOL_SOCKET, SO_REUSEPORT, &flag, sizeof(flag));
2416  _hs_bind_localhost(serv->socket, &serv->addr, ipaddr, serv->port);
2417  serv->len = sizeof(serv->addr);
2418  int flags = fcntl(serv->socket, F_GETFL, 0);
2419  fcntl(serv->socket, F_SETFL, flags | O_NONBLOCK);
2420  listen(serv->socket, 128);
2421  _hs_add_server_sock_events(serv);
2422}
2423
2424void hs_generate_date_time(char *datetime) {
2425  time_t rawtime;
2426  struct tm *timeinfo;
2427  time(&rawtime);
2428  timeinfo = gmtime(&rawtime);
2429  strftime(datetime, 32, "%a, %d %b %Y %T GMT", timeinfo);
2430}
2431
2432http_server_t *hs_server_init(int port, void (*handler)(http_request_t *),
2433                              hs_evt_cb_t accept_cb,
2434                              hs_evt_cb_t epoll_timer_cb) {
2435  http_server_t *serv = (http_server_t *)malloc(sizeof(http_server_t));
2436  assert(serv != NULL);
2437  serv->port = port;
2438  serv->memused = 0;
2439  serv->handler = accept_cb;
2440  _hs_server_init_events(serv, epoll_timer_cb);
2441  hs_generate_date_time(serv->date);
2442  serv->request_handler = handler;
2443  return serv;
2444}
2445
2446#line 1 "write_socket.c"
2447#include <errno.h>
2448#include <unistd.h>
2449
2450#ifndef HTTPSERVER_IMPL
2451#include "common.h"
2452#include "write_socket.h"
2453#endif
2454
2455#ifdef DEBUG
2456#define write hs_test_write
2457ssize_t hs_test_write(int fd, char const *data, size_t size);
2458#endif
2459
2460// Writes response bytes from the buffer out to the socket.
2461//
2462// Runs when we get a socket ready to write event or when initiating an HTTP
2463// response and writing to the socket for the first time. If the response is
2464// chunked the chunk_cb callback will be invoked signalling to the user code
2465// that another chunk is ready to be written.
2466enum hs_write_rc_e hs_write_socket(http_request_t *request) {
2467  int bytes =
2468      write(request->socket, request->buffer.buf + request->bytes_written,
2469            request->buffer.length - request->bytes_written);
2470  if (bytes > 0)
2471    request->bytes_written += bytes;
2472
2473  enum hs_write_rc_e rc = HS_WRITE_RC_SUCCESS;
2474
2475  if (errno == EPIPE) {
2476    rc = HS_WRITE_RC_SOCKET_ERR;
2477  } else {
2478    if (request->bytes_written != request->buffer.length) {
2479      // All bytes of the body were not written and we need to wait until the
2480      // socket is writable again to complete the write
2481      rc = HS_WRITE_RC_CONTINUE;
2482    } else if (HTTP_FLAG_CHECK(request->flags, HTTP_CHUNKED_RESPONSE)) {
2483      // All bytes of the chunk were written and we need to get the next chunk
2484      // from the application.
2485      rc = HS_WRITE_RC_SUCCESS_CHUNK;
2486    } else {
2487      if (HTTP_FLAG_CHECK(request->flags, HTTP_KEEP_ALIVE)) {
2488        rc = HS_WRITE_RC_SUCCESS;
2489      } else {
2490        rc = HS_WRITE_RC_SUCCESS_CLOSE;
2491      }
2492    }
2493  }
2494
2495  return rc;
2496}
2497
2498#line 1 "connection.c"
2499#include <assert.h>
2500#include <fcntl.h>
2501#include <stdlib.h>
2502#include <sys/socket.h>
2503#include <unistd.h>
2504
2505#ifdef KQUEUE
2506#include <sys/event.h>
2507#else
2508#include <sys/epoll.h>
2509#include <sys/timerfd.h>
2510#include <time.h>
2511#endif
2512
2513#ifndef HTTPSERVER_IMPL
2514#include "buffer_util.h"
2515#include "common.h"
2516#include "connection.h"
2517#endif
2518
2519#ifdef KQUEUE
2520
2521void _hs_delete_events(http_request_t *request) {
2522  struct kevent ev_set;
2523  EV_SET(&ev_set, request->socket, EVFILT_TIMER, EV_DELETE, 0, 0, request);
2524  kevent(request->server->loop, &ev_set, 1, NULL, 0, NULL);
2525}
2526
2527void _hs_add_timer_event(http_request_t *request, hs_io_cb_t unused) {
2528  (void)unused;
2529
2530  struct kevent ev_set;
2531  EV_SET(&ev_set, request->socket, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 1000,
2532         request);
2533  kevent(request->server->loop, &ev_set, 1, NULL, 0, NULL);
2534}
2535
2536#else
2537
2538void _hs_delete_events(http_request_t *request) {
2539  epoll_ctl(request->server->loop, EPOLL_CTL_DEL, request->socket, NULL);
2540  epoll_ctl(request->server->loop, EPOLL_CTL_DEL, request->timerfd, NULL);
2541  close(request->timerfd);
2542}
2543
2544void _hs_add_timer_event(http_request_t *request, hs_io_cb_t timer_cb) {
2545  request->timer_handler = timer_cb;
2546
2547  // Watch for read events
2548  struct epoll_event ev;
2549  ev.events = EPOLLIN | EPOLLET;
2550  ev.data.ptr = request;
2551  epoll_ctl(request->server->loop, EPOLL_CTL_ADD, request->socket, &ev);
2552
2553  // Add timer to timeout requests.
2554  int tfd = timerfd_create(CLOCK_MONOTONIC, 0);
2555  struct itimerspec ts = {};
2556  ts.it_value.tv_sec = 1;
2557  ts.it_interval.tv_sec = 1;
2558  timerfd_settime(tfd, 0, &ts, NULL);
2559
2560  ev.events = EPOLLIN | EPOLLET;
2561  ev.data.ptr = &request->timer_handler;
2562  epoll_ctl(request->server->loop, EPOLL_CTL_ADD, tfd, &ev);
2563  request->timerfd = tfd;
2564}
2565
2566#endif
2567
2568void hs_request_terminate_connection(http_request_t *request) {
2569  _hs_delete_events(request);
2570  close(request->socket);
2571  _hs_buffer_free(&request->buffer, &request->server->memused);
2572  free(request->tokens.buf);
2573  request->tokens.buf = NULL;
2574  free(request);
2575}
2576
2577void _hs_token_array_init(struct hs_token_array_s *array, int capacity) {
2578  array->buf =
2579      (struct hsh_token_s *)malloc(sizeof(struct hsh_token_s) * capacity);
2580  assert(array->buf != NULL);
2581  array->size = 0;
2582  array->capacity = capacity;
2583}
2584
2585http_request_t *_hs_request_init(int sock, http_server_t *server,
2586                                 hs_io_cb_t io_cb) {
2587  http_request_t *request = (http_request_t *)calloc(1, sizeof(http_request_t));
2588  assert(request != NULL);
2589  request->socket = sock;
2590  request->server = server;
2591  request->handler = io_cb;
2592  request->timeout = HTTP_REQUEST_TIMEOUT;
2593  request->flags = HTTP_AUTOMATIC;
2594  request->parser = (struct hsh_parser_s){};
2595  request->buffer = (struct hsh_buffer_s){};
2596  request->tokens.buf = NULL;
2597  _hs_token_array_init(&request->tokens, 32);
2598  return request;
2599}
2600
2601http_request_t *hs_server_accept_connection(http_server_t *server,
2602                                            hs_io_cb_t io_cb,
2603                                            hs_io_cb_t epoll_timer_cb) {
2604  http_request_t *request = NULL;
2605  int sock = 0;
2606
2607  sock = accept(server->socket, (struct sockaddr *)&server->addr, &server->len);
2608
2609  if (sock > 0) {
2610    int flags = fcntl(sock, F_GETFL, 0);
2611    fcntl(sock, F_SETFL, flags | O_NONBLOCK);
2612
2613    request = _hs_request_init(sock, server, io_cb);
2614    _hs_add_timer_event(request, epoll_timer_cb);
2615  }
2616  return request;
2617}
2618
2619#line 1 "io_events.c"
2620#include <stdlib.h>
2621
2622#ifdef KQUEUE
2623#include <sys/event.h>
2624#else
2625#include <stdint.h>
2626#include <sys/epoll.h>
2627#include <unistd.h>
2628#endif
2629
2630#ifndef HTTPSERVER_IMPL
2631#include "buffer_util.h"
2632#include "common.h"
2633#include "connection.h"
2634#include "io_events.h"
2635#include "read_socket.h"
2636#include "respond.h"
2637#include "server.h"
2638#include "write_socket.h"
2639#endif
2640
2641void _hs_read_socket_and_handle_return_code(http_request_t *request) {
2642  struct hs_read_opts_s opts;
2643  opts.initial_request_buf_capacity = HTTP_REQUEST_BUF_SIZE;
2644  opts.max_request_buf_capacity = HTTP_MAX_REQUEST_BUF_SIZE;
2645  opts.eof_rc = 0;
2646
2647  enum hs_read_rc_e rc = hs_read_request_and_exec_user_cb(request, opts);
2648  switch (rc) {
2649  case HS_READ_RC_PARSE_ERR:
2650    hs_request_respond_error(request, 400, "Bad Request",
2651                             hs_request_begin_write);
2652    break;
2653  case HS_READ_RC_SOCKET_ERR:
2654    hs_request_terminate_connection(request);
2655    break;
2656  case HS_READ_RC_SUCCESS:
2657    break;
2658  }
2659}
2660
2661void hs_request_begin_read(http_request_t *request);
2662
2663void _hs_write_socket_and_handle_return_code(http_request_t *request) {
2664  enum hs_write_rc_e rc = hs_write_socket(request);
2665
2666  request->timeout = rc == HS_WRITE_RC_SUCCESS ? HTTP_KEEP_ALIVE_TIMEOUT
2667                                               : HTTP_REQUEST_TIMEOUT;
2668
2669  if (rc != HS_WRITE_RC_CONTINUE)
2670    _hs_buffer_free(&request->buffer, &request->server->memused);
2671
2672  switch (rc) {
2673  case HS_WRITE_RC_SUCCESS_CLOSE:
2674  case HS_WRITE_RC_SOCKET_ERR:
2675    // Error or response complete, connection: close
2676    hs_request_terminate_connection(request);
2677    break;
2678  case HS_WRITE_RC_SUCCESS:
2679    // Response complete, keep-alive connection
2680    hs_request_begin_read(request);
2681    break;
2682  case HS_WRITE_RC_SUCCESS_CHUNK:
2683    // Finished writing chunk, request next
2684    request->state = HTTP_SESSION_NOP;
2685    request->chunk_cb(request);
2686    break;
2687  case HS_WRITE_RC_CONTINUE:
2688    break;
2689  }
2690}
2691
2692void _hs_accept_and_begin_request_cycle(http_server_t *server,
2693                                        hs_io_cb_t on_client_connection_cb,
2694                                        hs_io_cb_t on_timer_event_cb) {
2695  http_request_t *request = NULL;
2696  while ((request = hs_server_accept_connection(server, on_client_connection_cb,
2697                                                on_timer_event_cb))) {
2698    if (server->memused > HTTP_MAX_TOTAL_EST_MEM_USAGE) {
2699      hs_request_respond_error(request, 503, "Service Unavailable",
2700                               hs_request_begin_write);
2701    } else {
2702      hs_request_begin_read(request);
2703    }
2704  }
2705}
2706
2707#ifdef KQUEUE
2708
2709void _hs_on_kqueue_client_connection_event(struct kevent *ev) {
2710  http_request_t *request = (http_request_t *)ev->udata;
2711  if (ev->filter == EVFILT_TIMER) {
2712    request->timeout -= 1;
2713    if (request->timeout == 0)
2714      hs_request_terminate_connection(request);
2715  } else {
2716    if (request->state == HTTP_SESSION_READ) {
2717      _hs_read_socket_and_handle_return_code(request);
2718    } else if (request->state == HTTP_SESSION_WRITE) {
2719      _hs_write_socket_and_handle_return_code(request);
2720    }
2721  }
2722}
2723
2724void hs_on_kqueue_server_event(struct kevent *ev) {
2725  http_server_t *server = (http_server_t *)ev->udata;
2726  if (ev->filter == EVFILT_TIMER) {
2727    hs_generate_date_time(server->date);
2728  } else {
2729    _hs_accept_and_begin_request_cycle(
2730        server, _hs_on_kqueue_client_connection_event, NULL);
2731  }
2732}
2733
2734#else
2735
2736void _hs_on_epoll_client_connection_event(struct epoll_event *ev) {
2737  http_request_t *request = (http_request_t *)ev->data.ptr;
2738  if (request->state == HTTP_SESSION_READ) {
2739    _hs_read_socket_and_handle_return_code(request);
2740  } else if (request->state == HTTP_SESSION_WRITE) {
2741    _hs_write_socket_and_handle_return_code(request);
2742  }
2743}
2744
2745void _hs_on_epoll_request_timer_event(struct epoll_event *ev) {
2746  http_request_t *request =
2747      (http_request_t *)((char *)ev->data.ptr - sizeof(epoll_cb_t));
2748  uint64_t res;
2749  int bytes = read(request->timerfd, &res, sizeof(res));
2750  (void)bytes; // suppress warning
2751  request->timeout -= 1;
2752  if (request->timeout == 0)
2753    hs_request_terminate_connection(request);
2754}
2755
2756void hs_on_epoll_server_connection_event(struct epoll_event *ev) {
2757  _hs_accept_and_begin_request_cycle((http_server_t *)ev->data.ptr,
2758                                     _hs_on_epoll_client_connection_event,
2759                                     _hs_on_epoll_request_timer_event);
2760}
2761
2762void hs_on_epoll_server_timer_event(struct epoll_event *ev) {
2763  http_server_t *server =
2764      (http_server_t *)((char *)ev->data.ptr - sizeof(epoll_cb_t));
2765  uint64_t res;
2766  int bytes = read(server->timerfd, &res, sizeof(res));
2767  (void)bytes; // suppress warning
2768  hs_generate_date_time(server->date);
2769}
2770
2771#endif
2772
2773void _hs_add_write_event(http_request_t *request) {
2774#ifdef KQUEUE
2775  struct kevent ev_set[2];
2776  EV_SET(&ev_set[0], request->socket, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0,
2777         request);
2778  EV_SET(&ev_set[1], request->socket, EVFILT_READ, EV_DISABLE, 0, 0, request);
2779  kevent(request->server->loop, ev_set, 2, NULL, 0, NULL);
2780#else
2781  struct epoll_event ev;
2782  ev.events = EPOLLOUT | EPOLLET;
2783  ev.data.ptr = request;
2784  epoll_ctl(request->server->loop, EPOLL_CTL_MOD, request->socket, &ev);
2785#endif
2786}
2787
2788void hs_request_begin_write(http_request_t *request) {
2789  request->state = HTTP_SESSION_WRITE;
2790  _hs_add_write_event(request);
2791  _hs_write_socket_and_handle_return_code(request);
2792}
2793
2794void _hs_add_read_event(http_request_t *request) {
2795#ifdef KQUEUE
2796  // No action needed for kqueue since it's read event stays active. Should
2797  // it be disabled during write?
2798  struct kevent ev_set;
2799  EV_SET(&ev_set, request->socket, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0,
2800         request);
2801  kevent(request->server->loop, &ev_set, 1, NULL, 0, NULL);
2802#else
2803  struct epoll_event ev;
2804  ev.events = EPOLLIN | EPOLLET;
2805  ev.data.ptr = request;
2806  epoll_ctl(request->server->loop, EPOLL_CTL_MOD, request->socket, &ev);
2807#endif
2808}
2809
2810void hs_request_begin_read(http_request_t *request) {
2811  request->state = HTTP_SESSION_READ;
2812  _hs_add_read_event(request);
2813  _hs_read_socket_and_handle_return_code(request);
2814}
2815
2816#endif
2817#endif
2818#endif