/[jscoverage]/trunk/http-message.c
ViewVC logotype

Diff of /trunk/http-message.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 116 by siliconforks, Sat May 31 21:42:36 2008 UTC revision 303 by siliconforks, Mon Oct 13 05:27:41 2008 UTC
# Line 22  Line 22 
22  #include "http-server.h"  #include "http-server.h"
23    
24  #include <assert.h>  #include <assert.h>
 #include <errno.h>  
25  #include <string.h>  #include <string.h>
26    
 #include <sys/socket.h>  
   
27  #include "stream.h"  #include "stream.h"
28  #include "util.h"  #include "util.h"
29    
# Line 52  Line 49 
49    bool is_started;    bool is_started;
50  };  };
51    
52    static bool is_lws(uint8_t c) {
53      return c == '\r' || c == '\n' || c == ' ' || c == '\t';
54    }
55    
56    static bool is_separator(uint8_t c) {
57      /* RFC 2616 2.2 */
58      return strchr("()<>@,;:\\\"/[]?={} \t", c) != NULL;
59    }
60    
61    static bool is_token_char(uint8_t c) {
62      /* RFC 2616 2.2 */
63      return 32 <= c && c <= 126 && ! is_separator(c);
64    }
65    
66    static bool is_text(uint8_t c) {
67      return ! (c <= 31 || c == 127);
68    }
69    
70    static void skip_lws(const uint8_t ** p) {
71      while (**p != '\0' && is_lws(**p)) {
72        (*p)++;
73      }
74    }
75    
76    static uint8_t * parse_token(const uint8_t ** p) {
77      const uint8_t * start = *p;
78      while (**p != '\0' && is_token_char(**p)) {
79        (*p)++;
80      }
81    
82      if (*p == start) {
83        return NULL;
84      }
85    
86      return (uint8_t *) xstrndup((char *) start, *p - start);
87    }
88    
89    static uint8_t * parse_quoted_string(const uint8_t ** p) {
90      const uint8_t * start = *p;
91    
92      if (**p != '"') {
93        return NULL;
94      }
95      (*p)++;
96    
97      while (**p != '\0' && **p != '"') {
98        if (**p == '\\') {
99          (*p)++;
100          if (**p < 1 || **p > 127) {
101            return NULL;
102          }
103          (*p)++;
104        }
105        else if (is_text(**p)) {
106          (*p)++;
107        }
108        else {
109          return NULL;
110        }
111      }
112    
113      if (**p != '"') {
114        return NULL;
115      }
116      (*p)++;
117    
118      return (uint8_t *) xstrndup((char *) start, *p - start);
119    }
120    
121  HTTPMessage * HTTPMessage_new(HTTPConnection * connection) {  HTTPMessage * HTTPMessage_new(HTTPConnection * connection) {
122    HTTPMessage * message = xmalloc(sizeof(HTTPMessage));    HTTPMessage * message = xmalloc(sizeof(HTTPMessage));
123    message->start_line = NULL;    message->start_line = NULL;
# Line 127  Line 193 
193    HTTPMessage_add_header(message, name, value);    HTTPMessage_add_header(message, name, value);
194  }  }
195    
196    char * HTTPMessage_get_charset(const HTTPMessage * message) {
197      const char * content_type = HTTPMessage_find_header(message, HTTP_CONTENT_TYPE);
198      if (content_type == NULL) {
199        return NULL;
200      }
201    
202      const uint8_t * p = (const uint8_t *) content_type;
203    
204      /* e.g., text/html */
205      uint8_t * token;
206      skip_lws(&p);
207      if (! is_token_char(*p)) {
208        return NULL;
209      }
210      token = parse_token(&p);
211      free(token);
212      skip_lws(&p);
213      if (*p != '/') {
214        return NULL;
215      }
216      p++;
217      skip_lws(&p);
218      if (! is_token_char(*p)) {
219        return NULL;
220      }
221      token = parse_token(&p);
222      free(token);
223    
224      skip_lws(&p);
225    
226      while (*p != '\0') {
227        bool is_charset = false;
228        if (*p != ';') {
229          return NULL;
230        }
231        p++;
232    
233        skip_lws(&p);
234    
235        if (! is_token_char(*p)) {
236          return NULL;
237        }
238        uint8_t * attribute = parse_token(&p);
239        if (strcasecmp((char *) attribute, "charset") == 0) {
240          is_charset = true;
241        }
242        free(attribute);
243        skip_lws(&p);
244        if (*p != '=') {
245          return NULL;
246        }
247        p++;
248    
249        skip_lws(&p);
250    
251        if (*p == '"') {
252          uint8_t * value = parse_quoted_string(&p);
253          if (value == NULL) {
254            return NULL;
255          }
256          if (is_charset) {
257            return (char *) value;
258          }
259          free(value);
260        }
261        else if (is_token_char(*p)) {
262          uint8_t * value = parse_token(&p);
263          if (is_charset) {
264            return (char *) value;
265          }
266          free(value);
267        }
268        else {
269          return NULL;
270        }
271    
272        skip_lws(&p);
273      }
274    
275      return NULL;
276    }
277    
278  void HTTPMessage_set_content_length(HTTPMessage * message, size_t value) {  void HTTPMessage_set_content_length(HTTPMessage * message, size_t value) {
279    char * s;    char * s;
280    xasprintf(&s, "%u", value);    xasprintf(&s, "%u", value);
# Line 207  Line 355 
355    return 0;    return 0;
356  }  }
357    
 static bool is_lws(uint8_t c) {  
   return c == '\r' || c == '\n' || c == ' ' || c == '\t';  
 }  
   
 static bool is_separator(uint8_t c) {  
   /* RFC 2616 2.2 */  
   return strchr("()<>@,;:\\\"/[]?={} \t", c) != NULL;  
 }  
   
 static bool is_token_char(uint8_t c) {  
   /* RFC 2616 2.2 */  
   return 32 <= c && c <= 126 && ! is_separator(c);  
 }  
   
 static bool is_text(uint8_t c) {  
   return ! (c <= 31 || c == 127);  
 }  
   
 static void skip_lws(const uint8_t ** p) {  
   while (**p != '\0' && is_lws(**p)) {  
     (*p)++;  
   }  
 }  
   
 static uint8_t * parse_token(const uint8_t ** p) {  
   const uint8_t * start = *p;  
   while (**p != '\0' && is_token_char(**p)) {  
     (*p)++;  
   }  
   
   if (*p == start) {  
     return NULL;  
   }  
   
   return (uint8_t *) xstrndup((char *) start, *p - start);  
 }  
   
 static uint8_t * parse_quoted_string(const uint8_t ** p) {  
   const uint8_t * start = *p;  
   
   if (**p != '"') {  
     return NULL;  
   }  
   (*p)++;  
   
   while (**p != '\0' && **p != '"') {  
     if (**p == '\\') {  
       (*p)++;  
       if (**p < 1 || **p > 127) {  
         return NULL;  
       }  
       (*p)++;  
     }  
     else if (is_text(**p)) {  
       (*p)++;  
     }  
     else {  
       return NULL;  
     }  
   }  
   
   if (**p != '"') {  
     return NULL;  
   }  
   (*p)++;  
   
   return (uint8_t *) xstrndup((char *) start, *p - start);  
 }  
   
358  static bool stream_contains_nul(const Stream * stream) {  static bool stream_contains_nul(const Stream * stream) {
359    for (size_t i = 0; i < stream->length; i++) {    for (size_t i = 0; i < stream->length; i++) {
360      if (stream->data[i] == '\0') {      if (stream->data[i] == '\0') {

Legend:
Removed from v.116  
changed lines
  Added in v.303

  ViewVC Help
Powered by ViewVC 1.1.24