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."); |
