Advertisement
Guest User

cs50 server.c request()

a guest
Feb 9th, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.17 KB | None | 0 0
  1. /**
  2.  * Reads (without blocking) an HTTP request's headers into memory dynamically allocated on heap.
  3.  * Stores address thereof in *message and length thereof in *length.
  4.  */
  5. bool request(char** message, size_t* length)
  6. {
  7.     // ensure socket is open
  8.     if (cfd == -1)
  9.     {
  10.         return false;
  11.     }
  12.  
  13.     // initialize message and its length
  14.     *message = NULL;
  15.     *length = 0;
  16.  
  17.     // read message
  18.     while (*length < LimitRequestLine + LimitRequestFields * LimitRequestFieldSize + 4)
  19.     {
  20.         // read from socket
  21.         BYTE buffer[BYTES];
  22.         ssize_t bytes = read(cfd, buffer, BYTES);
  23.         if (bytes < 0)
  24.         {
  25.             if (*message != NULL)
  26.             {
  27.                 free(*message);
  28.                 *message = NULL;
  29.             }
  30.             *length = 0;
  31.             break;
  32.         }
  33.  
  34.         // append bytes to message
  35.         *message = realloc(*message, *length + bytes + 1);
  36.         if (*message == NULL)
  37.         {
  38.             *length = 0;
  39.             break;
  40.         }
  41.         memcpy(*message + *length, buffer, bytes);
  42.         *length += bytes;
  43.  
  44.         // null-terminate message thus far
  45.         *(*message + *length) = '\0';
  46.  
  47.         // search for CRLF CRLF
  48.         int offset = (*length - bytes < 3) ? *length - bytes : 3;
  49.         char* haystack = *message + *length - bytes - offset;
  50.         char* needle = strstr(haystack, "\r\n\r\n");
  51.         if (needle != NULL)
  52.         {
  53.             // trim to one CRLF and null-terminate
  54.             *length = needle - *message + 2;
  55.             *message = realloc(*message, *length + 1);
  56.             if (*message == NULL)
  57.             {
  58.                 break;
  59.             }
  60.             *(*message + *length) = '\0';
  61.  
  62.             // ensure request-line is no longer than LimitRequestLine
  63.             haystack = *message;
  64.             needle = strstr(haystack, "\r\n");
  65.             if (needle == NULL || (needle - haystack + 2) > LimitRequestLine)
  66.             {
  67.                 break;
  68.             }
  69.  
  70.             // count fields in message
  71.             int fields = 0;
  72.             haystack = needle + 2;
  73.             while (*haystack != '\0')
  74.             {
  75.                 // look for CRLF
  76.                 needle = strstr(haystack, "\r\n");
  77.                 if (needle == NULL)
  78.                 {
  79.                     break;
  80.                 }
  81.  
  82.                 // ensure field is no longer than LimitRequestFieldSize
  83.                 if (needle - haystack + 2 > LimitRequestFieldSize)
  84.                 {
  85.                     break;
  86.                 }
  87.  
  88.                 // look beyond CRLF
  89.                 haystack = needle + 2;
  90.             }
  91.  
  92.             // if we didn't get to end of message, we must have erred
  93.             if (*haystack != '\0')
  94.             {
  95.                 break;
  96.             }
  97.  
  98.             // ensure message has no more than LimitRequestFields
  99.             if (fields > LimitRequestFields)
  100.             {
  101.                 break;
  102.             }
  103.  
  104.             // valid
  105.             return true;
  106.         }
  107.     }
  108.  
  109.     // invalid
  110.     if (*message != NULL)
  111.     {
  112.         free(*message);
  113.     }
  114.     *message = NULL;
  115.     *length = 0;
  116.     return false;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement