summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Christian Pohle2021-11-14 15:23:27 +0100
committerMax Christian Pohle2021-11-14 15:23:27 +0100
commit89944e70b8e100e39ef65190ad1816dafde326eb (patch)
tree7712082026a7e323c30faeabacb112af8069370c
parent8f0f398fc49cd5d0ed5d97099bd6547ea52ce44b (diff)
downloadohmycgi-89944e70b8e100e39ef65190ad1816dafde326eb.tar.bz2
ohmycgi-89944e70b8e100e39ef65190ad1816dafde326eb.zip
Now that I can parse individual fields I see potential optimizations.
Well-- If I had read the entire input stream into the buffer, I would afterwards be able to change the buffer in memory and append \0 in places, where a name/value pair exists and that would every second pair a name and avoid many unnecessary memcpy.
-rw-r--r--main.c79
1 files changed, 54 insertions, 25 deletions
diff --git a/main.c b/main.c
index 9c1d177..6613df0 100644
--- a/main.c
+++ b/main.c
@@ -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
..