Mercurial > urweb
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) { |