summaryrefslogtreecommitdiff
path: root/http_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'http_parser.c')
-rw-r--r--http_parser.c109
1 files changed, 55 insertions, 54 deletions
diff --git a/http_parser.c b/http_parser.c
index 30e74c8..03d8d91 100644
--- a/http_parser.c
+++ b/http_parser.c
@@ -54,7 +54,7 @@ static inline char * handle_colon(char ** start, char ** end, char ** search) {
54 return *start; // remember, where name starts, will be important in the newline case 54 return *start; // remember, where name starts, will be important in the newline case
55} 55}
56 56
57static inline void handle_semicolon(char ** start, char ** end, char ** search) { 57static inline char * handle_semicolon(char ** start, char ** end, char ** search) {
58 // find the form-data boundary in the main header 58 // find the form-data boundary in the main header
59 *start += strspn(*start, "; "); // remove spaces and semicolons (boundary check implicit; also stops at '\0') 59 *start += strspn(*start, "; "); // remove spaces and semicolons (boundary check implicit; also stops at '\0')
60 60
@@ -63,10 +63,15 @@ static inline void handle_semicolon(char ** start, char ** end, char ** search)
63 { 63 {
64 *end = *end + sizeof(s_multipart_form_data) + 1; 64 *end = *end + sizeof(s_multipart_form_data) + 1;
65 *end += strspn(*end, "-"); 65 *end += strspn(*end, "-");
66 *start = *end;
66 DEBUG("> Boundary found, now looking where it ends...\n"); 67 DEBUG("> Boundary found, now looking where it ends...\n");
68
69 *end += strcspn(*end, "\r\n ");
70 *end[0] = '\0';
67 } 71 }
68 72
69 *search = "\r\n"; // do not search further semicolons 73 *search = "\r\n"; // do not search further semicolons
74 return *start;
70} 75}
71 76
72void parse_http(size_t new_socket, char * request, size_t request_length) { 77void parse_http(size_t new_socket, char * request, size_t request_length) {
@@ -90,12 +95,11 @@ void parse_http(size_t new_socket, char * request, size_t request_length) {
90 size_t matchlen = strspn(end, search); 95 size_t matchlen = strspn(end, search);
91 switch(end[0]) { 96 switch(end[0]) {
92 case ':': 97 case ':':
93 handle_colon(&start, &end, &search); 98 name = handle_colon(&start, &end, &search);
94 name = start;
95 break; 99 break;
96 case ';': 100 case ';':
97 handle_semicolon(&start, &end, &search); 101 http_header.boundary = handle_semicolon(&start, &end, &search);
98 http_header.boundary = end; 102 http_header.boundary_size = end - start;
99 break; 103 break;
100 case '\r': // fallthrough 104 case '\r': // fallthrough
101 case '\n': 105 case '\n':
@@ -123,62 +127,59 @@ void parse_http(size_t new_socket, char * request, size_t request_length) {
123 if (0 == strcasecmp("Content-Disposition", name)) 127 if (0 == strcasecmp("Content-Disposition", name))
124 { http_header.content_disposition = start; } 128 { http_header.content_disposition = start; }
125 } // }}} 129 } // }}}
126 DEBUG("\033[32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start);
127 // {{{ check if a http header ended (e.g. two newlines)
128 if(matchlen > http_header.newline_length) {
129 DEBUG("> END HEADERS, because there were %d newlines; boundary='%s'[%ld]\n", matchlen / http_header.newline_length, http_header.boundary, http_header.boundary_size);
130 end += matchlen;
131
132 // if it was the first header, we calculate the boundary size and expect more headers to come after a boundary
133 if(http_header.boundary && http_header.boundary_size == 0) {
134 DEBUG("================================================================================\n");
135 http_header.boundary_size = strlen(http_header.boundary);
136 // skip the first header and boundary...
137 start = end;
138 start += strspn(start, "-");
139 start += http_header.boundary_size;
140 start += http_header.newline_length;
141 continue;
142 } else {
143 char * content_start = end;
144 while(1)
145 {
146 size_t size_remaining = (size_t) request_length - (end - request) - 1;
147 DEBUG("%ld remaining.\n", size_remaining);
148
149 if(size_remaining <= 0) {
150 DEBUG("> not even the boundary would fit in that what is left.\n");
151 break;
152 }
153
154 if(NULL == (end = memchr((void*) end, '-', size_remaining))) {
155 DEBUG("no further '-' found\n");
156 break;
157 }
158
159 char * content_end = end - http_header.newline_length;
160
161 end += strspn(end, "-");
162 if(0 == strncmp(end, http_header.boundary, http_header.boundary_size)) {
163 size_t file_size = content_end - content_start;
164 DEBUG("> Content ends here, size of the last file is %ld\n", file_size);
165 130
166 content_start[file_size + 1] = '\0'; 131 // {{{ DEBUG
167 next_part(&http_header, content_start, file_size); 132 DEBUG("\033[32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start);
168 133 // }}}
169 end += http_header.boundary_size;
170 matchlen = strspn(end, "\r\n");
171 DEBUG("> end is at %p, matchlen is %ld\n", end, matchlen);
172 134
173 search = ":"; 135 // check if a http header ended (e.g. two newlines)
136 if(matchlen > http_header.newline_length) {
137 end += matchlen; // go behind the double line break...
138
139 //{{{ DEBUG
140 DEBUG("> END HEADERS, because there were %d newlines; boundary='%s'[%ld]\n",
141 matchlen / http_header.newline_length,
142 http_header.boundary,
143 http_header.boundary_size
144 ); // }}}
145
146 start = end;
147 for(; ; )
148 {
149 size_t size_remaining = (size_t) request_length - (end - request) - 1;
150
151 // {{{ DEBUG
152 DEBUG("%ld remaining.\n", size_remaining);
153 // }}}
154
155 matchlen = strspn(end, "-");
156 if(0 == strncmp(end + matchlen, http_header.boundary, http_header.boundary_size)) {
157 size_t file_size = end - http_header.newline_length - start;
158 DEBUG("> Content ends here, size of the last file is %ld\n", file_size);
159 start[file_size + 1] = '\0';
160
161 next_part(&http_header, start, file_size);
162
163 end += http_header.boundary_size + matchlen;
164 matchlen = http_header.newline_length;
165 DEBUG("> end is at %p, matchlen is %ld\n", end, matchlen);
166 search = ":";
167 break;
168 } else {
169
170 if(!http_header.boundary
171 || size_remaining <= 0
172 || NULL == (end = memchr((void*) end, '-', size_remaining))) {
173 // {{{ DEBUG
174 DEBUG("EOF reached or no further '-' found\n");
175 // }}}
174 break; 176 break;
175 } else {
176 end = end + 1;
177 } 177 }
178 // end++;
178 } 179 }
179 } 180 }
180 break; 181 break;
181 } // }}} if condition after a header 182 } // if condition after a header
182 } // switch 183 } // switch
183 184
184 if(NULL == end) 185 if(NULL == end)
..