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

Legend:
Removed from v.123  
changed lines
  Added in v.177

  ViewVC Help
Powered by ViewVC 1.1.24