text: /*
   * Copyright (C) Chenyang Li
   * Copyright (C) Vino
   */
  #ifndef VINO_VN_REQUEST_H
  #define VINO_VN_REQUEST_H
  
  #include <stdio.h>
  #include "vn_priority_queue.h"
  #include "vn_linked_list.h"
  #include "vn_palloc.h"
  #include "util.h"
  
  #define VN_BUFSIZE                8192
  #define VN_MAX_HTTP_HEADERS       20
  #define VN_MAX_HTTP_HEADER_NAME   50
  #define VN_MAX_HTTP_HEADER_VALUE  200
  
  /* HTTP request message */
  typedef struct vn_http_request_s {
  
      /* HTTP parser state */
      unsigned int    state;
      const char     *pos;
      const char     *last;
  
      /* HTTP request line */
      vn_str_t method;  /* "GET" */
      vn_str_t uri;     /* "/index.html" */
      vn_str_t proto;   /* "HTTP/1.1" */
   
      /*
       * Query string(part of URI), for example:
       *     GET /vino/index.html?param1=value1&param2=value2
       *         |      uri      |       query-string       |
       */
      vn_str_t          query_string;
  
      /* HTTP request headers */
      unsigned short    header_cnt;
      const char       *header_name_start, *header_value_start;
      int               header_name_len, header_value_len;
      vn_linked_list_t  header_name_list;
      vn_linked_list_t  header_value_list;
  
      /* HTTP body */
      vn_str_t       body;
      size_t         body_len;     /* HTTP body length (is exists) */
  } vn_http_request_t;
  
  typedef void (*timeout_handler_t)(void *);
  
  /* HTTP request connection */
  typedef struct vn_http_connection_s {
      int                        fd;
      int                        epfd;
      vn_pool_t                 *pool;
  
      /* HTTP request buffer */
      char                       req_buf[VN_BUFSIZE];
      char                      *req_buf_ptr;
      size_t                     remain_size;
  
      /* HTTP response buffer */
      char                      *resp_headers;            /* HTTP response headers (include response line) buffer (heap memory) */
      char                      *resp_headers_ptr;        /* Point to the next byte to be sent */
      size_t                     resp_headers_left;       /* Number of bytes left to be sent */
      char                      *resp_body;               /* HTTP response body buffer (mmap memory) */
      char                      *resp_body_ptr;           /* Point to the next byte to be sent */     
      size_t                     resp_body_left;          /* Number of bytes left to be sent */ 
      size_t                     resp_file_size;          /* The size of the mapped file */  
      int                        resp_mem_type;           /* The type of memory allocation, malloc or mmap */
  
      int                        keep_alive;
  
      vn_http_request_t          request;
      timeout_handler_t            handler;
      vn_priority_queue_node_t  *pq_node;
  } vn_http_connection_t;
  
  /*
   * Initialize HTTP request message.
   */
  void vn_init_http_request(vn_http_request_t *req);       
  
  /*
   * Initialize HTTP request connection.
   */ 
  void vn_init_http_connection(vn_http_connection_t *conn, int fd, int epfd);
  
  /*
   * Reset HTTP request connectin. 
   */ 
  void vn_reset_http_connection(vn_http_connection_t *conn);
  
  /*
   * Search and return the header `name` in parsed HTTP request
   * message `req`.
   * 
   * If header `name` is not found, NULL is returned.
   */
  vn_str_t *vn_get_http_header(vn_http_request_t *req, const char *name);
  
  /*
   * Close the connection, don't forget to cast the
   * type of `connection` to (vn_http_connection *).
   */
  void vn_close_http_connection(void *connection);
  
  #endif /* VINO_VN_REQUEST_H */