diff options
author | Max Christian Pohle | 2021-11-18 01:23:05 +0100 |
---|---|---|
committer | Max Christian Pohle | 2021-11-18 01:23:05 +0100 |
commit | e6f9bc88a029bff63df9b029d986d5961a3ce021 (patch) | |
tree | 6553df6f131cfa883ae2b32c93ef3e899b37d576 | |
parent | 316d434ea8c0e7de1359dd04644cdc9dc955c839 (diff) | |
download | ohmycgi-e6f9bc88a029bff63df9b029d986d5961a3ce021.tar.bz2 ohmycgi-e6f9bc88a029bff63df9b029d986d5961a3ce021.zip |
Looking for a good way to parse binary data
-rw-r--r-- | main.c | 61 |
1 files changed, 47 insertions, 14 deletions
@@ -91,13 +91,13 @@ typedef struct { | |||
91 | int newline_length; // lenght of one newline in bytes (\n has 1, CR/LF has 2) | 91 | int newline_length; // lenght of one newline in bytes (\n has 1, CR/LF has 2) |
92 | char * method; | 92 | char * method; |
93 | char * boundary; | 93 | char * boundary; |
94 | size_t boundary_size; | ||
94 | char * content_type; | 95 | char * content_type; |
95 | char * content_disposition; | 96 | char * content_disposition; |
96 | } Http_Header; | 97 | } Http_Header; |
97 | 98 | ||
98 | void * next_customer(size_t new_socket) { | 99 | void * next_customer(size_t new_socket) { |
99 | FILE * f_r = fdopen((size_t) new_socket, "r"); | 100 | FILE * f_r = fdopen((size_t) new_socket, "rw"); |
100 | FILE * f_w = fdopen((size_t) new_socket, "w"); | ||
101 | 101 | ||
102 | char * output_buffer = NULL; | 102 | char * output_buffer = NULL; |
103 | size_t output_buffer_length = 0; | 103 | size_t output_buffer_length = 0; |
@@ -105,9 +105,9 @@ void * next_customer(size_t new_socket) { | |||
105 | 105 | ||
106 | verbose("\n\n########################################## Content Reader [%d]\n", f_r); | 106 | verbose("\n\n########################################## Content Reader [%d]\n", f_r); |
107 | read_everything(f_r, output); | 107 | read_everything(f_r, output); |
108 | shutdown(new_socket, SHUT_RD); // shutdown the reading half of the connection | ||
108 | verbose("\n\n########################################## Content Parser\n"); | 109 | verbose("\n\n########################################## Content Parser\n"); |
109 | 110 | ||
110 | |||
111 | // token parser... | 111 | // token parser... |
112 | char * key = output_buffer; | 112 | char * key = output_buffer; |
113 | 113 | ||
@@ -116,10 +116,11 @@ void * next_customer(size_t new_socket) { | |||
116 | char * content_end = NULL; | 116 | char * content_end = NULL; |
117 | 117 | ||
118 | char * start = output_buffer; | 118 | char * start = output_buffer; |
119 | char * end; | 119 | char * end = NULL; |
120 | char * search = "\r\n"; | 120 | char * search = "\r\n"; |
121 | 121 | ||
122 | Http_Header http_header; | 122 | Http_Header http_header; |
123 | http_header.boundary_size = 0; | ||
123 | http_header.newline_length = 1; | 124 | http_header.newline_length = 1; |
124 | http_header.method = NULL; | 125 | http_header.method = NULL; |
125 | http_header.boundary = NULL; | 126 | http_header.boundary = NULL; |
@@ -127,7 +128,9 @@ void * next_customer(size_t new_socket) { | |||
127 | http_header.content_type = NULL; | 128 | http_header.content_type = NULL; |
128 | 129 | ||
129 | char * name = NULL; | 130 | char * name = NULL; |
131 | // while(NULL != (end = strpbrk(start, search))) { | ||
130 | while(NULL != (end = strpbrk(start, search))) { | 132 | while(NULL != (end = strpbrk(start, search))) { |
133 | // verbose("\033[31m[%ld|%ld|%ld]\033[0m\n", start - output_buffer, end - start, end - output_buffer); | ||
131 | 134 | ||
132 | size_t matchlen = strspn(end, search); | 135 | size_t matchlen = strspn(end, search); |
133 | switch(end[0]) { | 136 | switch(end[0]) { |
@@ -152,7 +155,7 @@ void * next_customer(size_t new_socket) { | |||
152 | { | 155 | { |
153 | http_header.boundary = end + sizeof(s_multipart_form_data) + 1; | 156 | http_header.boundary = end + sizeof(s_multipart_form_data) + 1; |
154 | http_header.boundary += strspn(http_header.boundary, "-"); | 157 | http_header.boundary += strspn(http_header.boundary, "-"); |
155 | // verbose("GESCHAFFT %s QQQQ %s\n", http_header.boundary, end); | 158 | // verbose("GESCHAFFT %s [%ld] QQQQ %s\n", http_header.boundary, http_header.boundary_size, end); |
156 | search = "\r\n"; | 159 | search = "\r\n"; |
157 | continue; | 160 | continue; |
158 | } | 161 | } |
@@ -163,6 +166,9 @@ void * next_customer(size_t new_socket) { | |||
163 | end[0] = '\0'; | 166 | end[0] = '\0'; |
164 | search = ":"; // we will continue to search for headers | 167 | search = ":"; // we will continue to search for headers |
165 | 168 | ||
169 | if(http_header.boundary && http_header.boundary_size == 0) { | ||
170 | http_header.boundary_size = strlen(http_header.boundary); | ||
171 | } | ||
166 | 172 | ||
167 | if(NULL == name) { | 173 | if(NULL == name) { |
168 | if(NULL == http_header.method) { | 174 | if(NULL == http_header.method) { |
@@ -178,11 +184,10 @@ void * next_customer(size_t new_socket) { | |||
178 | { http_header.content_disposition = start; } | 184 | { http_header.content_disposition = start; } |
179 | } | 185 | } |
180 | 186 | ||
181 | verbose("\033[0;32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start); | 187 | verbose("\033[32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start); |
182 | 188 | ||
183 | if(matchlen > http_header.newline_length) { | 189 | if(matchlen > http_header.newline_length) { |
184 | verbose("END HEADERS, boundary='%s'\n", http_header.boundary); | 190 | verbose("END HEADERS, boundary='%s'[%ld]\n", http_header.boundary, http_header.boundary_size); |
185 | // start = strstr(end, http_header.boundary); | ||
186 | search = "-"; | 191 | search = "-"; |
187 | } | 192 | } |
188 | break; | 193 | break; |
@@ -192,11 +197,11 @@ void * next_customer(size_t new_socket) { | |||
192 | content_start += strspn(content_start, "-"); | 197 | content_start += strspn(content_start, "-"); |
193 | // verbose("CONTENT: %s\n", content_start); | 198 | // verbose("CONTENT: %s\n", content_start); |
194 | if(0 <= strcmp(content_start, http_header.boundary)) { | 199 | if(0 <= strcmp(content_start, http_header.boundary)) { |
195 | verbose("MATCH\n"); | 200 | verbose("MATCH for %s // %s\n", http_header.content_type, http_header.content_disposition); |
201 | |||
196 | search = "\r\n"; | 202 | search = "\r\n"; |
197 | start = content_start + strlen(http_header.boundary); | 203 | matchlen = http_header.boundary_size; |
198 | name = NULL; | 204 | name = NULL; |
199 | continue; | ||
200 | } else { | 205 | } else { |
201 | verbose("NO MATCH\n"); | 206 | verbose("NO MATCH\n"); |
202 | } | 207 | } |
@@ -206,15 +211,43 @@ void * next_customer(size_t new_socket) { | |||
206 | 211 | ||
207 | start = end + matchlen; | 212 | start = end + matchlen; |
208 | } | 213 | } |
214 | printf("last known position: %p / %p with %s\n", start, end, search); | ||
215 | |||
216 | |||
217 | char * p; | ||
218 | if(NULL != (p = strstr(start, http_header.boundary))) { | ||
219 | puts("OKAY?"); | ||
220 | } | ||
221 | |||
222 | p = start; | ||
223 | while(1) { | ||
224 | size_t size_remaining = (size_t) output_buffer_length - (p - output_buffer) - 1; | ||
225 | printf("%ld remaining.\n", size_remaining); fflush(stdout); | ||
226 | if(size_remaining <= 0) | ||
227 | break; | ||
228 | |||
229 | p = (char *) memchr( | ||
230 | (void *) p, '-', size_remaining); | ||
231 | |||
232 | p += strspn(p, "-"); | ||
233 | |||
234 | if(0 >= strcmp(p, http_header.boundary)) { | ||
235 | verbose("content ends here"); | ||
236 | break; | ||
237 | } else { | ||
238 | printf("[%ld] kack: %c\n", size_remaining, p[0]); fflush(stdout); | ||
239 | p = p + 1; | ||
240 | } | ||
241 | } | ||
242 | start = p; | ||
243 | // exit(0); | ||
209 | 244 | ||
210 | if(http_header.boundary) | 245 | if(http_header.boundary) |
211 | verbose("http-boundary: %s", http_header.boundary); | 246 | verbose("http-boundary: %s", http_header.boundary); |
212 | 247 | ||
213 | 248 | ||
214 | verbose("> sending answer..."); | 249 | verbose("> sending answer..."); |
215 | send_answer(f_w); | 250 | send_answer(f_r); |
216 | |||
217 | fclose(f_w); | ||
218 | fclose(f_r); | 251 | fclose(f_r); |
219 | 252 | ||
220 | verbose("> answer sent."); | 253 | verbose("> answer sent."); |