/[osn-commons]/trunk/freehttpd/request.c
ViewVC logotype

Diff of /trunk/freehttpd/request.c

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

revision 44 by rakinar2, Sat Aug 10 18:33:37 2024 UTC revision 45 by rakinar2, Sun Aug 11 17:35:46 2024 UTC
# Line 4  Line 4 
4  #include <stdio.h>  #include <stdio.h>
5  #include <stdlib.h>  #include <stdlib.h>
6  #include <string.h>  #include <string.h>
7    #include <sys/socket.h>
8  #include <unistd.h>  #include <unistd.h>
9    
10  freehttpd_request_t *  freehttpd_request_t *
# Line 38  freehttpd_request_init (const char *meth Line 39  freehttpd_request_init (const char *meth
39  }  }
40    
41  freehttpd_header_t *  freehttpd_header_t *
42  freehttpd_header_init (const char *name, const char *value)  freehttpd_header_init (const char *name, const char *value, size_t name_length,
43                           size_t value_length)
44  {  {
45      freehttpd_header_t *header = calloc (1, sizeof (freehttpd_header_t));      freehttpd_header_t *header = calloc (1, sizeof (freehttpd_header_t));
46    
# Line 46  freehttpd_header_init (const char *name, Line 48  freehttpd_header_init (const char *name,
48          return NULL;          return NULL;
49    
50      if (name != NULL)      if (name != NULL)
51          header->name = strdup (name);          {
52                header->name = strdup (name);
53                header->name_length
54                    = name_length == 0 ? strlen (name) : name_length;
55            }
56    
57      if (value != NULL)      if (value != NULL)
58          header->value = strdup (value);          {
59                header->value = strdup (value);
60                header->value_length
61                    = value_length == 0 ? strlen (value) : value_length;
62            }
63    
64      return header;      return header;
65  }  }
# Line 82  freehttpd_request_free (freehttpd_reques Line 92  freehttpd_request_free (freehttpd_reques
92          free (request->uri);          free (request->uri);
93    
94      if (request->version != NULL)      if (request->version != NULL)
95          free (request->version);          free (request->version - 5);
96    
97        if (request->path != NULL)
98            free (request->path);
99    
100        if (request->query != NULL)
101            free (request->query);
102    
103      if (request->headers != NULL)      if (request->headers != NULL)
104          {          {
# Line 98  freehttpd_request_free (freehttpd_reques Line 114  freehttpd_request_free (freehttpd_reques
114      free (request);      free (request);
115  }  }
116    
117    static char *
118    urldecode (const char *input, size_t *len)
119    {
120        char *output = calloc (strlen (input) + 1, 1);
121    
122        if (output == NULL)
123            return NULL;
124    
125        size_t i = 0, j = 0;
126    
127        for (; input[i] != 0; i++, j++)
128            {
129                if (input[i] == '%')
130                    {
131                        if (input[i + 1] == 0 || input[i + 2] == 0)
132                            {
133                                free (output);
134                                return NULL;
135                            }
136    
137                        char c1 = tolower (input[i + 1]);
138                        char c2 = tolower (input[i + 2]);
139                        int c1n = isdigit (c1) ? c1 - '0' : c1 - 'a' + 10;
140                        int c2n = isdigit (c2) ? c2 - '0' : c2 - 'a' + 10;
141                        int code = c1n * 16 + c2n;
142                        output[j] = (char) code;
143                        i += 2;
144                    }
145                else
146                    output[j] = input[i];
147            }
148    
149        output[j] = 0;
150    
151        printf ("output: %s\n", output);
152    
153        if (len != NULL)
154            *len = j;
155    
156        return output;
157    }
158    
159  const char *const SUPPORTED_METHODS[]  const char *const SUPPORTED_METHODS[]
160      = { "GET",     "POST",  "PUT",     "DELETE", "HEAD",      = { "GET",     "POST",  "PUT",     "DELETE", "HEAD",
161          "OPTIONS", "TRACE", "CONNECT", NULL };          "OPTIONS", "TRACE", "CONNECT", NULL };
# Line 126  freehttpd_request_parse (freehttpd_t *fr Line 184  freehttpd_request_parse (freehttpd_t *fr
184              char c;              char c;
185              size_t j = 0;              size_t j = 0;
186    
187              while (read (sockfd, &c, 1) == 1)              /* TODO: instead of always calling read with size 1, we could
188                   optimize this by reading more bytes at once and then parsing
189                   the buffer. */
190                while (recv (sockfd, &c, 1, 0) == 1)
191                  {                  {
192                      if (isspace (c))                      if (isspace (c))
193                          break;                          break;
# Line 172  freehttpd_request_parse (freehttpd_t *fr Line 233  freehttpd_request_parse (freehttpd_t *fr
233              return NULL;              return NULL;
234          }          }
235    
236        if (memcmp (request->version, "HTTP/", 5) != 0)
237            {
238                freehttpd_request_free (request);
239                *error = E_MALFORMED_REQUEST;
240                return NULL;
241            }
242    
243        request->version += 5;
244        request->version_length -= 5;
245    
246        char *path = strchr (request->uri, '?');
247    
248        if (path != NULL)
249            {
250                path = strndup (request->uri, path - request->uri);
251                request->query = strdup (path + 1);
252                request->query_length
253                    = request->uri_length - request->path_length - 1;
254            }
255        else
256            path = strdup (request->uri);
257    
258        request->path = urldecode (path, &request->path_length);
259        free (path);
260      *error = E_OK;      *error = E_OK;
261      return request;      return request;
262  }  }

Legend:
Removed from v.44  
changed lines
  Added in v.45

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26