Advertisement
GodlyPacketz

http_processor.c

Aug 13th, 2022
992
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.25 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <arpa/inet.h>
  8. #include <unistd.h>
  9. #include <time.h>
  10.  
  11. #include "http_processor.h"
  12. #include "../util.h"
  13.  
  14.  
  15. static uint8_t parse_cookie(char **out, char *buffer, int buffer_len);
  16. static int parse_status(char *buffer, int buffer_len);
  17.  
  18. struct http_connection_t *http_proc_create_conn(char *host)
  19. {
  20.     struct http_connection_t *conn = malloc(sizeof(struct http_connection_t));
  21.     memset(conn, 0, sizeof(struct http_connection_t));
  22.     strcpy(conn->host, host);
  23.     conn->cookies = NULL;
  24.     conn->cookies_num = 0;
  25.     return conn;
  26. }
  27.  
  28. void http_proc_destroy_conn(struct http_connection_t *conn)
  29. {
  30.     if(conn != NULL)
  31.     {
  32.         int j;
  33.         for(j = 0; j < conn->cookies_num; j++)
  34.         {
  35.              free(conn->cookies[j]);
  36.         }
  37.         free(conn->cookies);
  38.         memset(conn, 0, sizeof(struct http_connection_t));
  39.         free(conn);
  40.     }
  41. }
  42.  
  43. struct http_request_t *http_proc_create_request(struct http_connection_t *conn, uint8_t method, int fd, char *path)
  44. {
  45.     struct http_request_t *req = malloc(sizeof(struct http_request_t));
  46.     memset(req, 0, sizeof(struct http_request_t));
  47.     req->conn = conn;
  48.     req->headers = malloc(1*sizeof(struct http_header_t *));
  49.     req->headers[0] = malloc(sizeof(struct http_header_t));
  50.     memset(req->headers[0], 0, sizeof(struct http_header_t));
  51.     strcpy(req->headers[0]->id, "Host");
  52.     strcpy(req->headers[0]->value, conn->host);
  53.     strcpy(req->path, path);
  54.     req->headers_num = 1;
  55.     req->method = method;
  56.     req->fd = fd;
  57. }
  58.  
  59. void http_proc_destroy_request(struct http_request_t *req)
  60. {
  61.     if(req != NULL)
  62.     {
  63.         int j;
  64.         for(j = 0; j < req->headers_num; j++)
  65.         {
  66.             free(req->headers[j]);
  67.         }
  68.         free(req->headers);
  69.         req->conn = NULL;
  70.         memset(req, 0, sizeof(struct http_request_t));
  71.         free(req);
  72.     }    
  73. }
  74.  
  75. void http_proc_req_addhdr(struct http_request_t *req, char *id, char *value)
  76. {
  77.     req->headers = realloc(req->headers, (req->headers_num+1)*sizeof(struct http_header_t *));
  78.     req->headers[req->headers_num] = malloc(sizeof(struct http_header_t));
  79.     memset(req->headers[req->headers_num], 0, sizeof(struct http_header_t));
  80.     strcpy(req->headers[req->headers_num]->id, id);
  81.     strcpy(req->headers[req->headers_num]->value, value);
  82.     req->headers_num += 1;
  83.     return;
  84. }
  85.  
  86. void http_proc_req_send(struct http_request_t *req, char *data)
  87. {
  88.     char sendbuffer[4096];
  89.     memset(sendbuffer, 0, 4096);
  90.    
  91.     switch(req->method)
  92.     {
  93.         case HTTP_METHOD_GET:
  94.             sprintf(sendbuffer, "GET %s HTTP/1.1\r\n", req->path);
  95.             break;
  96.         case HTTP_METHOD_POST:
  97.             sprintf(sendbuffer, "POST %s HTTP/1.1\r\n", req->path);
  98.             break;
  99.         case HTTP_METHOD_HEAD:
  100.             sprintf(sendbuffer, "HEAD %s HTTP/1.1\r\n", req->path);
  101.             break;
  102.     }
  103.    
  104.     int j;
  105.     for(j = 0; j < req->headers_num; j++)
  106.     {
  107.         int sendbuffer_len = strlen(sendbuffer);
  108.         strcpy(sendbuffer+sendbuffer_len, req->headers[j]->id);
  109.         sendbuffer_len = strlen(sendbuffer);
  110.         strcpy(sendbuffer+sendbuffer_len, ": ");
  111.         sendbuffer_len = strlen(sendbuffer);
  112.         strcpy(sendbuffer+sendbuffer_len, req->headers[j]->value);
  113.     }
  114.    
  115.     if(req->conn->cookies_num > 0)
  116.     {
  117.         char cookie_hdr[512];
  118.         int cookie_hdr_len = 0;
  119.         sprintf(cookie_hdr, "Cookie: ");
  120.         for(j = 0; j < req->conn->cookies_num; j++)
  121.         {
  122.             cookie_hdr_len = strlen(cookie_hdr);
  123.             if(j == req->conn->cookies_num-1)
  124.             {
  125.                 sprintf(cookie_hdr+cookie_hdr_len, "%s\r\n", req->conn->cookies[j]);
  126.                 break;
  127.             }
  128.             sprintf(cookie_hdr+cookie_hdr_len, "%s; ", req->conn->cookies[j]);
  129.         }
  130.         int sendbuffer_len = strlen(sendbuffer);
  131.         sprintf(sendbuffer+sendbuffer_len, "%s", cookie_hdr);
  132.     }
  133.     else
  134.     {   // some implementations of digest auth demand there be a cookie even though we werent given one ;)
  135.         int sendbuffer_len = strlen(sendbuffer);
  136.         sprintf(sendbuffer+sendbuffer_len, "Cookie: fake=fake_value\r\n");
  137.     }
  138.    
  139.     int sendbuffer_len = strlen(sendbuffer);
  140.     sprintf(sendbuffer+sendbuffer_len, "\r\n");
  141.     sendbuffer_len = strlen(sendbuffer);
  142.     if(data != NULL)
  143.     {
  144.         sprintf(sendbuffer+sendbuffer_len, "%s\r\n", data);
  145.     }
  146.    
  147.     #ifdef DEBUG_HTTP
  148.           printf("[http_processor] Sending the following request:\r\n");
  149.           printf("-----------------------------------------------------\r\n");
  150.           printf("%s\r\n", sendbuffer);
  151.           printf("-----------------------------------------------------\r\n");
  152.     #endif
  153.    
  154.     send(req->fd, sendbuffer, 4096, MSG_NOSIGNAL);
  155.    
  156.     return;
  157. }
  158.  
  159. struct http_request_resp_t *http_proc_req_parse(struct http_connection_t *conn, char *buffer, int buffer_len)
  160. {
  161.     struct http_request_resp_t *resp = malloc(sizeof(struct http_request_resp_t));
  162.     memset(resp, 0, sizeof(struct http_request_resp_t));
  163.     resp->status = parse_status(buffer, buffer_len);
  164.     resp->text_resp = buffer;
  165.     resp->text_resp_len = buffer_len;
  166.     conn->cookies_num = parse_cookie(conn->cookies, buffer, buffer_len);
  167.     return resp;
  168. }
  169.  
  170.  
  171.  
  172. static int parse_status(char *buffer, int buffer_len)
  173. {
  174.     int ret = -1;
  175.     int j = 0, line_len = 0;
  176.     char line[1024];
  177.     memset(line, 0, 1024);
  178.     for(j = 0; j < buffer_len; j++)
  179.     {
  180.         if(buffer[j] == '\r')
  181.         {
  182.             continue;
  183.         }
  184.         if(buffer[j] == '\n')
  185.         {
  186.             if(strstr(line, "HTTP") != NULL)
  187.             {
  188.                 ret = atoi(line+strlen("HTTP/1.1 "));
  189.             }
  190.             memset(line, 0, 512);
  191.             line_len = 0;
  192.             break;
  193.         }
  194.         line[line_len] = buffer[j];
  195.         line_len++;
  196.     }
  197.    
  198.     printf("Got resp code %d!\r\n", ret);
  199.     return ret;
  200. }
  201.  
  202. static uint8_t parse_cookie(char **out, char *buffer, int buffer_len)
  203. {
  204.     uint8_t ret = 0;
  205.     int j = 0, line_len = 0;
  206.     char line[1024];
  207.     char lastfour[4];
  208.     memset(lastfour, 0, 4);
  209.     memset(line, 0, 1024);
  210.     for(j = 0; j < buffer_len; j++)
  211.     {
  212.         lastfour[0] = lastfour[1];
  213.         lastfour[1] = lastfour[2];
  214.         lastfour[2] = lastfour[3];
  215.         lastfour[3] = buffer[j];
  216.         if(lastfour[0] == '\r' && lastfour[1] == '\n' && lastfour[2] == '\r' && lastfour[3] == '\n')
  217.         {
  218.                 break;
  219.         }
  220.         if(buffer[j] == '\r')
  221.         {
  222.                 continue;
  223.         }
  224.         if(buffer[j] == '\n')
  225.         {
  226.             if(strstr(line, "Set-Cookie: ") != NULL)
  227.             {
  228.                 char *cookies_ptr = line+strlen("Set-Cookie: ");
  229.                 // server wants us to save data in client session
  230.                 int cookies_count = 0;
  231.                 uint8_t **cookies = util_tokenize(cookies_ptr, line_len-strlen("Set-Cookie: "), &cookies_count, ',');
  232.                 int i;
  233.                 for(i = 0; i < cookies_count; i++)
  234.                 {
  235.                     if((cookies[i])[0] == ' ')
  236.                     {
  237.                         memcpy(cookies[i], (cookies[i])+1, strlen(cookies[i])-1);
  238.                         (cookies[i])[strlen(cookies[i])-1] = 0;
  239.                     }
  240.                     int cookie_attr_count = 0;
  241.                     uint8_t **cookie_attr = util_tokenize(cookies[i], util_len(cookies[i]), &cookie_attr_count, ';');
  242.                     if(cookie_attr_count > 0)
  243.                     {
  244.                         out = realloc(out, (ret+1)*sizeof(char *));
  245.                         out[ret] = malloc(strlen(cookie_attr[0]));
  246.                         util_cpy(out[ret], cookie_attr[0], strlen(cookie_attr[0]));
  247.                         ret++;
  248.                     }
  249.                 }
  250.             }
  251.             memset(line, 0, 512);
  252.             line_len = 0;
  253.             continue;
  254.         }
  255.         line[line_len] = buffer[j];
  256.         line_len++;
  257.     }
  258.    
  259.     printf("Got %d cookies!\r\n", ret);
  260.     for(j = 0; j < ret; j++)
  261.     {
  262.          printf("Cookie %d ~> \"%s\"\r\n", j, out[j]);
  263.     }
  264.     return ret;
  265. }
  266.  
  267.  
  268.  
  269.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement