comparison src/c/driver.c @ 854:158d980889ac

Further refactoring of request.c to work with CGI
author Adam Chlipala <adamc@hcoop.net>
date Tue, 23 Jun 2009 15:40:35 -0400
parents 19fdeef40ada
children
comparison
equal deleted inserted replaced
853:19fdeef40ada 854:158d980889ac
52 } 52 }
53 53
54 static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; 54 static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
55 static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; 55 static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER;
56 56
57 static char *get_header(void *data, const char *h) {
58 char *s = data;
59 int len = strlen(h);
60 char *p;
61
62 while (p = strchr(s, ':')) {
63 if (p - s == len && !strncasecmp(s, h, len)) {
64 return p + 2;
65 } else {
66 if ((s = strchr(p, 0)) && s[1] != 0)
67 s += 2;
68 else
69 return NULL;
70 }
71 }
72
73 return NULL;
74 }
75
57 static void *worker(void *data) { 76 static void *worker(void *data) {
58 int me = *(int *)data; 77 int me = *(int *)data;
59 uw_context ctx = uw_request_new_context(); 78 uw_context ctx = uw_request_new_context();
60 size_t buf_size = 2; 79 size_t buf_size = 2;
61 char *buf = malloc(buf_size); 80 char *buf = malloc(buf_size);
73 92
74 printf("Handling connection with thread #%d.\n", me); 93 printf("Handling connection with thread #%d.\n", me);
75 94
76 while (1) { 95 while (1) {
77 int r; 96 int r;
78 char *s1, *s2; 97 char *method, *path, *query_string, *headers, *body, *s, *s2;
79 98
80 if (back - buf == buf_size - 1) { 99 if (back - buf == buf_size - 1) {
81 char *new_buf; 100 char *new_buf;
82 buf_size *= 2; 101 buf_size *= 2;
83 new_buf = realloc(buf, buf_size); 102 new_buf = realloc(buf, buf_size);
98 } 117 }
99 118
100 back += r; 119 back += r;
101 *back = 0; 120 *back = 0;
102 121
103 if ((s1 = strstr(buf, "\r\n\r\n"))) { 122 if ((body = strstr(buf, "\r\n\r\n"))) {
104 request_result rr; 123 request_result rr;
105 124
106 if ((s2 = strcasestr(buf, "\r\nContent-Length: ")) && s2 < s1) { 125 body[0] = body[1] = 0;
126 body += 4;
127
128 if ((s = strcasestr(buf, "\r\nContent-Length: ")) && s < body) {
107 int clen; 129 int clen;
108 130
109 if (sscanf(s2 + 18, "%d\r\n", &clen) != 1) { 131 if (sscanf(s + 18, "%d\r\n", &clen) != 1) {
110 fprintf(stderr, "Malformed Content-Length header\n"); 132 fprintf(stderr, "Malformed Content-Length header\n");
111 break; 133 break;
112 } 134 }
113 135
114 if (s1 + 4 + clen > back) 136 while (back - body < clen) {
115 continue; 137 if (back - buf == buf_size - 1) {
116 } 138 char *new_buf;
117 139 buf_size *= 2;
118 rr = uw_request(rc, ctx, buf, back - buf, sock); 140 new_buf = realloc(buf, buf_size);
141
142 back = new_buf + (back - buf);
143 body = new_buf + (body - buf);
144 s = new_buf + (s - buf);
145
146 buf = new_buf;
147 }
148
149 r = recv(sock, back, buf_size - 1 - (back - buf), 0);
150
151 if (r < 0) {
152 fprintf(stderr, "Recv failed\n");
153 close(sock);
154 goto done;
155 }
156
157 if (r == 0) {
158 fprintf(stderr, "Connection closed.\n");
159 close(sock);
160 goto done;
161 }
162
163 back += r;
164 *back = 0;
165 }
166 }
167
168 if (!(s = strstr(buf, "\r\n"))) {
169 fprintf(stderr, "No newline in request\n");
170 close(sock);
171 goto done;
172 }
173
174 *s = 0;
175 headers = s + 2;
176 method = s = buf;
177
178 if (!strsep(&s, " ")) {
179 fprintf(stderr, "No first space in HTTP command\n");
180 close(sock);
181 goto done;
182 }
183 path = s;
184
185 if (s = strchr(path, ' '))
186 *s = 0;
187
188 if (s = strchr(path, '?')) {
189 *s = 0;
190 query_string = s+1;
191 }
192 else
193 query_string = NULL;
194
195 s = headers;
196 while (s2 = strchr(s, '\r')) {
197 s = s2;
198
199 if (s[1] == 0)
200 break;
201
202 *s = 0;
203 s += 2;
204 }
205
206 uw_set_headers(ctx, get_header, headers);
207
208 rr = uw_request(rc, ctx, method, path, query_string, body, back - body, sock);
119 uw_send(ctx, sock); 209 uw_send(ctx, sock);
120 210
121 if (rr == SERVED || rr == FAILED) 211 if (rr == SERVED || rr == FAILED)
122 close(sock); 212 close(sock);
123 else if (rr != KEEP_OPEN) 213 else if (rr != KEEP_OPEN)
125 215
126 break; 216 break;
127 } 217 }
128 } 218 }
129 219
220 done:
130 uw_reset(ctx); 221 uw_reset(ctx);
131 } 222 }
132 } 223 }
133 224
134 static void help(char *cmd) { 225 static void help(char *cmd) {