summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Christian Pohle2021-11-29 16:14:37 +0100
committerMax Christian Pohle2021-11-29 16:14:37 +0100
commit512c406b4fb3bc4054073608707ae07f65a65890 (patch)
tree4352c5587cbc4fd185b2cfc76bb68df53bf43b89
parent7fd1bbc1abafee0f1db19118d127c5bd744f1b67 (diff)
downloadohmycgi-512c406b4fb3bc4054073608707ae07f65a65890.tar.bz2
ohmycgi-512c406b4fb3bc4054073608707ae07f65a65890.zip
still getting this code shorter
-rw-r--r--http_parser.c81
-rw-r--r--main.c2
-rw-r--r--main.h1
3 files changed, 43 insertions, 41 deletions
diff --git a/http_parser.c b/http_parser.c
index 03d8d91..fb891cc 100644
--- a/http_parser.c
+++ b/http_parser.c
@@ -36,6 +36,7 @@
36*/ 36*/
37 37
38#include "main.h" 38#include "main.h"
39#include <string.h>
39 40
40static inline char * handle_colon(char ** start, char ** end, char ** search) { 41static inline char * handle_colon(char ** start, char ** end, char ** search) {
41 // HTTP headers and content are separated by an empty line (which is two 42 // HTTP headers and content are separated by an empty line (which is two
@@ -64,10 +65,11 @@ static inline char * handle_semicolon(char ** start, char ** end, char ** searc
64 *end = *end + sizeof(s_multipart_form_data) + 1; 65 *end = *end + sizeof(s_multipart_form_data) + 1;
65 *end += strspn(*end, "-"); 66 *end += strspn(*end, "-");
66 *start = *end; 67 *start = *end;
67 DEBUG("> Boundary found, now looking where it ends...\n");
68 68
69 *end += strcspn(*end, "\r\n "); 69 *end += strcspn(*end, "\r\n ");
70 *end[0] = '\0'; 70 *end[0] = '\0';
71
72 DEBUG("> Boundary found: %s\n", *start);
71 } 73 }
72 74
73 *search = "\r\n"; // do not search further semicolons 75 *search = "\r\n"; // do not search further semicolons
@@ -84,11 +86,30 @@ void parse_http(size_t new_socket, char * request, size_t request_length) {
84 // generic and only requires content length bounary checks. 86 // generic and only requires content length bounary checks.
85 87
86 char * start = request; 88 char * start = request;
87 char * end = NULL; 89 char * end = "\0";
88 char * search = "\r\n"; 90 char * search = "\r\n";
89 91
90 Http_Header http_header = {0}; 92 Http_Header http_header = {0};
91 93
94 request[request_length] = '\0';
95
96 // {{{ Parse the request line (e.g. "POST / HTTP/1.1")
97 http_header.method = start;
98 start += strcspn(start, " ");
99 start[0] = '\0';
100 http_header.url = ++start;
101 start += strcspn(start, " ");
102 start[0] = '\0';
103 http_header.protocol = ++start;
104 start += strcspn(start, "\r\n");
105 http_header.newline_length = strspn(start, "\r\n");
106 start[0] = '\0';
107 start += http_header.newline_length;
108
109 DEBUG("%% Request line: method='%s' url='%s' protocol='%s' newline_length=%ld\n",
110 http_header.method, http_header.url, http_header.protocol, http_header.newline_length);
111 // }}}
112
92 char * name = NULL; 113 char * name = NULL;
93 while(NULL != (end = strpbrk(start, search))) { // TODO: try harder to break things (are SEGFAULTs possible?) 114 while(NULL != (end = strpbrk(start, search))) { // TODO: try harder to break things (are SEGFAULTs possible?)
94 115
@@ -96,61 +117,39 @@ void parse_http(size_t new_socket, char * request, size_t request_length) {
96 switch(end[0]) { 117 switch(end[0]) {
97 case ':': 118 case ':':
98 name = handle_colon(&start, &end, &search); 119 name = handle_colon(&start, &end, &search);
99 break; 120 break;
100 case ';': 121 case ';':
101 http_header.boundary = handle_semicolon(&start, &end, &search); 122 http_header.boundary = handle_semicolon(&start, &end, &search);
102 http_header.boundary_size = end - start; 123 http_header.boundary_size = end - start;
103 break; 124 break;
104 case '\r': // fallthrough 125 case '\r': // fallthrough
105 case '\n': 126 case '\n':
106 // {{{ newlines are special: sometimes content parts follow and sometimes headers, guess what...
107 end[0] = '\0'; 127 end[0] = '\0';
108 search = ":"; // we will continue to search for headers 128 search = ":"; // we will continue to search for headers
109 if(NULL == name) { 129
110 if(NULL == http_header.method) { 130 // {{{ NAME AND VALUE OF A HEADER FIELD KNOWN
111 DEBUG("[%ld]> HTTP REQUEST LINE :: %s \n", matchlen, start); 131 if(NULL != name) {
112 end[0] = '\0'; 132 DEBUG("\033[32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start);
113 133
114 while(NULL != (start = memchr(start, ' ', end - start))) {
115 if(NULL == http_header.url)
116 http_header.url = ++start;
117 else
118 start[0] = '\0';
119 }
120 http_header.method = start;
121 http_header.newline_length = matchlen;
122 } else {
123 DEBUG("[...]\n"); // if we want to intentially skip something, we land here by setting name = NUL;
124 break;
125 }
126 } else { // we know that name is not NULL and can work with it
127 if (0 == strcasecmp("Content-Disposition", name)) 134 if (0 == strcasecmp("Content-Disposition", name))
128 { http_header.content_disposition = start; } 135 { http_header.content_disposition = start; }
129 } // }}} 136 } // }}}
130 137 // {{{ END OF A HTTP HEADER (two newlines)
131 // {{{ DEBUG
132 DEBUG("\033[32m[%ld]> '% 20s' = '%s'\033[0m\n", matchlen, name, start);
133 // }}}
134
135 // check if a http header ended (e.g. two newlines)
136 if(matchlen > http_header.newline_length) { 138 if(matchlen > http_header.newline_length) {
137 end += matchlen; // go behind the double line break... 139 end += matchlen; // go behind the double line break...
138 140
139 //{{{ DEBUG 141 DEBUG("%% END HEADERS, because there were %d newlines; boundary='%s'[%ld]\n",
140 DEBUG("> END HEADERS, because there were %d newlines; boundary='%s'[%ld]\n", 142 matchlen / http_header.newline_length,
141 matchlen / http_header.newline_length, 143 http_header.boundary,
142 http_header.boundary, 144 http_header.boundary_size
143 http_header.boundary_size 145 );
144 ); // }}}
145 146
146 start = end; 147 start = end;
147 for(; ; ) 148 for(; ; )
148 { 149 {
149 size_t size_remaining = (size_t) request_length - (end - request) - 1; 150 size_t size_remaining = (size_t) request_length - (end - request) - 1;
150 151
151 // {{{ DEBUG
152 DEBUG("%ld remaining.\n", size_remaining); 152 DEBUG("%ld remaining.\n", size_remaining);
153 // }}}
154 153
155 matchlen = strspn(end, "-"); 154 matchlen = strspn(end, "-");
156 if(0 == strncmp(end + matchlen, http_header.boundary, http_header.boundary_size)) { 155 if(0 == strncmp(end + matchlen, http_header.boundary, http_header.boundary_size)) {
@@ -170,16 +169,18 @@ void parse_http(size_t new_socket, char * request, size_t request_length) {
170 if(!http_header.boundary 169 if(!http_header.boundary
171 || size_remaining <= 0 170 || size_remaining <= 0
172 || NULL == (end = memchr((void*) end, '-', size_remaining))) { 171 || NULL == (end = memchr((void*) end, '-', size_remaining))) {
173 // {{{ DEBUG
174 DEBUG("EOF reached or no further '-' found\n"); 172 DEBUG("EOF reached or no further '-' found\n");
175 // }}}
176 break; 173 break;
177 } 174 }
178 // end++; 175 // end++;
179 } 176 }
180 } 177 }
181 break; 178 } // }}} if condition after a header
182 } // if condition after a header 179 break;
180
181 default:
182 DEBUG("Unknown char found: '%c'\n ", end[0]);
183 break;
183 } // switch 184 } // switch
184 185
185 if(NULL == end) 186 if(NULL == end)
diff --git a/main.c b/main.c
index 96cfa67..887680a 100644
--- a/main.c
+++ b/main.c
@@ -70,7 +70,7 @@ static void * answer_request(size_t new_socket) {
70 fflush(output); 70 fflush(output);
71 // shutdown(new_socket, SHUT_RD); // shutdown the reading half of the connection 71 // shutdown(new_socket, SHUT_RD); // shutdown the reading half of the connection
72 72
73 DEBUG("output buffer has a length of %ld bytes\n", output_buffer_length); 73 DEBUG("> Output buffer has a length of %ld bytes\n", output_buffer_length);
74 74
75 // TODO: make parsing function abstract (e.g. parse(...) function point with dlsym) 75 // TODO: make parsing function abstract (e.g. parse(...) function point with dlsym)
76 parse_http(new_socket, output_buffer, output_buffer_length); 76 parse_http(new_socket, output_buffer, output_buffer_length);
diff --git a/main.h b/main.h
index 826ef47..a9509f0 100644
--- a/main.h
+++ b/main.h
@@ -73,6 +73,7 @@ static inline int verbose(const char * format, ...) {
73typedef struct { 73typedef struct {
74 int newline_length; // lenght of one newline in bytes (\n has 1, CR/LF has 2) 74 int newline_length; // lenght of one newline in bytes (\n has 1, CR/LF has 2)
75 char * method; // GET/POST or something like that 75 char * method; // GET/POST or something like that
76 char * protocol; // mostly HTTP/1.0 or HTTP/1.1
76 char * url; // request URL (e.g. /index.html) 77 char * url; // request URL (e.g. /index.html)
77 char * boundary; // usually looks similar to ------1234 78 char * boundary; // usually looks similar to ------1234
78 size_t boundary_size; // size in bytes, calculated after first header complete; is an indicator for the first header 79 size_t boundary_size; // size in bytes, calculated after first header complete; is an indicator for the first header
..