diff options
| -rw-r--r-- | main.c | 79 |
1 files changed, 54 insertions, 25 deletions
| @@ -64,50 +64,80 @@ void * next_customer(void * new_socket) { | |||
| 64 | char boundary[64] = {0}; | 64 | char boundary[64] = {0}; |
| 65 | int boundary_size = 0; | 65 | int boundary_size = 0; |
| 66 | 66 | ||
| 67 | char current_name[64] = {0}; | ||
| 68 | |||
| 67 | usleep(100); // wait to avoid poll, epoll or evil select | 69 | usleep(100); // wait to avoid poll, epoll or evil select |
| 68 | 70 | ||
| 71 | char * output_buffer = NULL; | ||
| 72 | size_t output_buffer_length = 0; | ||
| 73 | FILE * output = open_memstream(&output_buffer, &output_buffer_length); | ||
| 74 | |||
| 69 | FILE * f = fdopen((size_t) new_socket, "r"); | 75 | FILE * f = fdopen((size_t) new_socket, "r"); |
| 70 | char buffer[MAX_HEADER_LINE_LENGTH]; | 76 | char buffer[MAX_HEADER_LINE_LENGTH]; |
| 71 | while(fgets(buffer, MAX_HEADER_LINE_LENGTH, f)) { | 77 | char * s = NULL; |
| 72 | printf("%s [%d]", buffer, errno); | 78 | while(1) { |
| 79 | // printf("[errno: %d] %s", errno, buffer); | ||
| 80 | s = fgets(buffer, MAX_HEADER_LINE_LENGTH, f); | ||
| 81 | |||
| 82 | if(boundary[0] != '\0' && buffer[0] == '-') { // first char minus. could be a new chunk of post data | ||
| 83 | int i = 0; | ||
| 84 | for(i = 1; i < MAX_HEADER_LINE_LENGTH; i++) { | ||
| 85 | if(buffer[i] != '-') { // skip all minus | ||
| 86 | if(0 == strncmp(&buffer[i], boundary, boundary_size)) { | ||
| 87 | fflush(output); | ||
| 88 | printf("> name='%s' value='%*s'\n", current_name, (int) output_buffer_length, output_buffer); | ||
| 89 | setenv(current_name, output_buffer, 0); | ||
| 90 | current_name[0] = '\0'; | ||
| 91 | rewind(output); | ||
| 92 | i = 0; | ||
| 93 | |||
| 94 | puts("================================================================================"); | ||
| 95 | } | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | if (i == 0) continue; | ||
| 100 | } | ||
| 101 | |||
| 73 | 102 | ||
| 74 | if(buffer[0] == '\n' || (buffer[0] == '\r' && buffer[1] == '\n')) { // either LF or CR/LF (windows) | 103 | if(!s || strspn(buffer, "\n\r") > 0) { // either LF or CR/LF (windows) |
| 75 | puts("END HEADER\n"); | 104 | puts("END HEADER\n"); |
| 76 | if (!boundary[0]) break; | 105 | // s != NULL ? break : continue; |
| 77 | continue; | 106 | if(!s) break; else continue; // either eof or only end of (chunk-)header |
| 78 | } | 107 | } |
| 79 | 108 | ||
| 80 | const char header_multipart[] = "Content-Type: multipart/form-data; boundary="; | 109 | const char header_multipart[] = "Content-Type: multipart/form-data; boundary="; |
| 81 | if (!boundary[0] && 0 == strncasecmp(buffer, header_multipart, sizeof(header_multipart) - 1)) { | 110 | if (!boundary[0] && 0 == strncasecmp(buffer, header_multipart, sizeof(header_multipart) - 1)) { |
| 111 | // we could potentially optimize this part with strspn and moving the buffer point, why not? | ||
| 82 | for(int i=sizeof(header_multipart); i<MAX_HEADER_LINE_LENGTH; i++) | 112 | for(int i=sizeof(header_multipart); i<MAX_HEADER_LINE_LENGTH; i++) |
| 83 | if(buffer[i] != '-') { | 113 | if(buffer[i] != '-') { |
| 84 | strncpy(boundary, &buffer[i], 64); | 114 | strncpy(boundary, &buffer[i], 64); |
| 85 | boundary_size = strnlen(boundary, 64); | 115 | boundary_size = strnlen(boundary, 64); |
| 86 | boundary[boundary_size] = '\0'; | 116 | boundary[boundary_size] = '\0'; |
| 87 | printf("BOUNDARY[%d]: %s\n", boundary_size, boundary); | 117 | printf("> [%s] %s\n", header_multipart, boundary); |
| 88 | break; | 118 | break; |
| 89 | } | 119 | } |
| 120 | continue; | ||
| 90 | } | 121 | } |
| 91 | 122 | ||
| 92 | const char header_disposition[] = "Content-Disposition: form-data; "; | 123 | const char header_disposition[] = "Content-Disposition: form-data; "; |
| 93 | if (boundary[0] && 0 == strncasecmp(header_disposition, buffer, sizeof(header_disposition) - 1)) { | 124 | if (boundary[0] && 0 == strncasecmp(header_disposition, buffer, sizeof(header_disposition) - 1)) { |
| 94 | printf("FFFFFFFFFFFFFFFFFFFFFFF %s\n", buffer); | 125 | printf("> %s :: %s\n", header_disposition, buffer); |
| 126 | const char header_disposition_name[] = "name=\""; | ||
| 127 | s = strstr(&buffer[sizeof(header_disposition) - 1], header_disposition_name); | ||
| 128 | if(s) { | ||
| 129 | s += sizeof(header_disposition_name) - 1; | ||
| 130 | s[strcspn(s, "\"")] = '\0'; | ||
| 131 | strncpy(current_name, s, 64); | ||
| 132 | printf("> /%s.*%s/ :: \"%s\"\n", header_disposition, header_disposition_name, s); | ||
| 133 | } else { | ||
| 134 | warnx("string not found in \"%s\".", &buffer[sizeof(header_disposition)]); | ||
| 135 | } | ||
| 95 | continue; | 136 | continue; |
| 96 | }// else { printf("FUCK: %*s [%d/%ld]\n", (int) sizeof(header_disposition), buffer, strncasecmp(header_disposition, buffer, sizeof(header_disposition)), sizeof(header_disposition)); } | 137 | }// else { printf("FUCK: %*s [%d/%ld]\n", (int) sizeof(header_disposition), buffer, strncasecmp(header_disposition, buffer, sizeof(header_disposition)), sizeof(header_disposition)); } |
| 97 | 138 | ||
| 98 | if(buffer[0] == '-') { // first char minus. could be a new chunk of post data | 139 | printf("> [unknown] %s", buffer); |
| 99 | for(int i=1; i<MAX_HEADER_LINE_LENGTH; i++) { | 140 | fputs(buffer, output); |
| 100 | if(buffer[i] != '-') { // skip all minus | ||
| 101 | if(0 == strncmp(&buffer[i], boundary, boundary_size)) { | ||
| 102 | printf("\n\n> NEXT CHUNK: %s\n", buffer); | ||
| 103 | i = 0; | ||
| 104 | } | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } else { | ||
| 109 | printf("%s", buffer); | ||
| 110 | } | ||
| 111 | 141 | ||
| 112 | 142 | ||
| 113 | // I think another if could now search for "Content-Disposition: form-data; " and store the remaining fields | 143 | // I think another if could now search for "Content-Disposition: form-data; " and store the remaining fields |
| @@ -161,16 +191,15 @@ int main(int argc, char const *argv[]) | |||
| 161 | address.sin_port = htons(PORT); | 191 | address.sin_port = htons(PORT); |
| 162 | 192 | ||
| 163 | 0 == (server_fd = socket(AF_INET, SOCK_STREAM, 0)) | 193 | 0 == (server_fd = socket(AF_INET, SOCK_STREAM, 0)) |
| 164 | ? err(EXIT_FAILURE, NULL) | 194 | ? err(errno, NULL) |
| 165 | : setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) | 195 | : setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) |
| 166 | ? err(EXIT_FAILURE, "setsockopt failed on socket with fileno %d", server_fd) | 196 | ? err(errno, "setsockopt failed on socket with fileno %d", server_fd) |
| 167 | : bind(server_fd, (struct sockaddr*) &address, sizeof(address)) | 197 | : bind(server_fd, (struct sockaddr*) &address, sizeof(address)) |
| 168 | ? err(EXIT_FAILURE, NULL) | 198 | ? err(errno, NULL) |
| 169 | : listen(server_fd, SOMAXCONN) | 199 | : listen(server_fd, SOMAXCONN) |
| 170 | ? err(EXIT_FAILURE, NULL) | 200 | ? err(errno, NULL) |
| 171 | : serve(server_fd); | 201 | : serve(server_fd); |
| 172 | 202 | ||
| 173 | |||
| 174 | return 0; | 203 | return 0; |
| 175 | } | 204 | } |
| 176 | 205 | ||
