The text below is selected, press Ctrl+C to copy to your clipboard. (⌘+C on Mac) No line numbers will be copied.
Guest
Proxy-parseh
By Guest on 5th October 2022 10:04:40 PM | Syntax: TEXT | Views: 1



New paste | Download | Show/Hide line no. | Copy text to clipboard
  1. /*
  2.  * proxy_parse.h -- a HTTP Request Parsing Library.
  3.  *
  4.  * Written by: Matvey Arye
  5.  * For: COS 518
  6.  *
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #include <errno.h>
  14.  
  15. #include <ctype.h>
  16.  
  17. #ifndef PROXY_PARSE
  18. #define PROXY_PARSE
  19.  
  20. #define DEBUG 0
  21.  
  22. /*
  23.    ParsedRequest objects are created from parsing a buffer containing a HTTP
  24.    request. The request buffer consists of a request line followed by a number
  25.    of headers. Request line fields such as method, protocol etc. are stored
  26.    explicitly. Headers such as 'Content-Length' and their values are maintained
  27.    in a linked list. Each node in this list is a ParsedHeader and contains a
  28.    key-value pair.
  29.  
  30.    The buf and buflen fields are used internally to maintain the parsed request
  31.    line.
  32.  */
  33. struct ParsedRequest {
  34.      char *method;
  35.      char *protocol;
  36.      char *host;
  37.      char *port;
  38.      char *path;
  39.      char *version;
  40.      char *buf;
  41.      size_t buflen;
  42.      struct ParsedHeader *headers;
  43.      size_t headersused;
  44.      size_t headerslen;
  45. };
  46.  
  47. /*
  48.    ParsedHeader: any header after the request line is a key-value pair with the
  49.    format "key:value\r\n" and is maintained in the ParsedHeader linked list
  50.    within ParsedRequest
  51. */
  52. struct ParsedHeader {
  53.      char * key;
  54.      size_t keylen;
  55.      char * value;
  56.      size_t valuelen;
  57. };
  58.  
  59.  
  60. /* Create an empty parsing object to be used exactly once for parsing a single
  61.  * request buffer */
  62. struct ParsedRequest* ParsedRequest_create();
  63.  
  64. /* Parse the request buffer in buf given that buf is of length buflen */
  65. int ParsedRequest_parse(struct ParsedRequest * parse, const char *buf,
  66.                         int buflen);
  67.  
  68. /* Destroy the parsing object. */
  69. void ParsedRequest_destroy(struct ParsedRequest *pr);
  70.  
  71. /*
  72.    Retrieve the entire buffer from a parsed request object. buf must be an
  73.    allocated buffer of size buflen, with enough space to write the request
  74.    line, headers and the trailing \r\n. buf will not be NUL terminated by
  75.    unparse().
  76.  */
  77. int ParsedRequest_unparse(struct ParsedRequest *pr, char *buf,
  78.                           size_t buflen);
  79.  
  80. /*
  81.    Retrieve the entire buffer with the exception of request line from a parsed
  82.    request object. buf must be an allocated buffer of size buflen, with enough
  83.    space to write the headers and the trailing \r\n. buf will not be NUL
  84.    terminated by unparse(). If there are no headers, the trailing \r\n is
  85.    unparsed.
  86.  */
  87. int ParsedRequest_unparse_headers(struct ParsedRequest *pr, char *buf,
  88.                                   size_t buflen);
  89.  
  90. /* Total length including request line, headers and the trailing \r\n*/
  91. size_t ParsedRequest_totalLen(struct ParsedRequest *pr);
  92.  
  93. /* Length including headers, if any, and the trailing \r\n but excluding the
  94.  * request line.
  95.  */
  96. size_t ParsedHeader_headersLen(struct ParsedRequest *pr);
  97.  
  98. /* Set, get, and remove null-terminated header keys and values */
  99. int ParsedHeader_set(struct ParsedRequest *pr, const char * key,
  100.                       const char * value);
  101. struct ParsedHeader* ParsedHeader_get(struct ParsedRequest *pr,
  102.                                       const char * key);
  103. int ParsedHeader_remove (struct ParsedRequest *pr, const char * key);
  104.  
  105. /* debug() prints out debugging info if DEBUG is set to 1 */
  106. void debug(const char * format, ...);
  107.  
  108. /* Example usage:
  109.  
  110.    const char *c =
  111.    "GET http://www.google.com:80/index.html/ HTTP/1.0\r\nContent-Length:"
  112.    " 80\r\nIf-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\r\n\r\n";
  113.    
  114.    int len = strlen(c);
  115.    //Create a ParsedRequest to use. This ParsedRequest
  116.    //is dynamically allocated.
  117.    ParsedRequest *req = ParsedRequest_create();
  118.    if (ParsedRequest_parse(req, c, len) < 0) {
  119.        printf("parse failed\n");
  120.        return -1;
  121.    }
  122.  
  123.    printf("Method:%s\n", req->method);
  124.    printf("Host:%s\n", req->host);
  125.  
  126.    // Turn ParsedRequest into a string.
  127.    // Friendly reminder: Be sure that you need to
  128.    // dynamically allocate string and if you
  129.    // do, remember to free it when you are done.
  130.    // (Dynamic allocation wasn't necessary here,
  131.    // but it was used as an example.)
  132.    int rlen = ParsedRequest_totalLen(req);
  133.    char *b = (char *)malloc(rlen+1);
  134.    if (ParsedRequest_unparse(req, b, rlen) < 0) {
  135.       printf("unparse failed\n");
  136.       return -1;
  137.    }
  138.    b[rlen]='\0';
  139.    // print out b for text request
  140.    free(b);
  141.  
  142.  
  143.    // Turn the headers from the request into a string.
  144.    rlen = ParsedHeader_headersLen(req);
  145.    char buf[rlen+1];
  146.    if (ParsedRequest_unparse_headers(req, buf, rlen) < 0) {
  147.       printf("unparse failed\n");
  148.       return -1;
  149.    }
  150.    buf[rlen] ='\0';
  151.    //print out buf for text headers only
  152.  
  153.    // Get a specific header (key) from the headers. A key is a header field
  154.    // such as "If-Modified-Since" which is followed by ":"
  155.    struct ParsedHeader *r = ParsedHeader_get(req, "If-Modified-Since");
  156.    printf("Modified value: %s\n", r->value);
  157.    
  158.    // Remove a specific header by name. In this case remove
  159.    // the "If-Modified-Since" header.
  160.    if (ParsedHeader_remove(req, "If-Modified-Since") < 0){
  161.       printf("remove header key not work\n");
  162.      return -1;
  163.    }
  164.  
  165.    // Set a specific header (key) to a value. In this case,
  166.    //we set the "Last-Modified" key to be set to have as
  167.    //value  a date in February 2014
  168.    
  169.     if (ParsedHeader_set(req, "Last-Modified", " Wed, 12 Feb 2014 12:43:31 GMT") < 0){
  170.      printf("set header key not work\n");
  171.      return -1;
  172.  
  173.     }
  174.  
  175.    // Check the modified Header key value pair
  176.     r = ParsedHeader_get(req, "Last-Modified");
  177.     printf("Last-Modified value: %s\n", r->value);
  178.  
  179.    // Call destroy on any ParsedRequests that you
  180.    // create once you are done using them. This will
  181.    // free memory dynamically allocated by the proxy_parse library.
  182.    ParsedRequest_destroy(req);
  183. */
  184.  
  185. #endif



  • Recent Pastes