Mercurial > urweb
comparison src/c/urweb.c @ 856:86ec89baee01
cgi protocol
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 23 Jun 2009 17:59:23 -0400 |
parents | 158d980889ac |
children | a738002d5b4d |
comparison
equal
deleted
inserted
replaced
855:28e42b22424d | 856:86ec89baee01 |
---|---|
19 | 19 |
20 // Socket extras | 20 // Socket extras |
21 | 21 |
22 int uw_really_send(int sock, const void *buf, size_t len) { | 22 int uw_really_send(int sock, const void *buf, size_t len) { |
23 while (len > 0) { | 23 while (len > 0) { |
24 size_t n = send(sock, buf, len, 0); | 24 ssize_t n = send(sock, buf, len, 0); |
25 | |
26 if (n < 0) | |
27 return n; | |
28 | |
29 buf += n; | |
30 len -= n; | |
31 } | |
32 | |
33 return 0; | |
34 } | |
35 | |
36 int uw_really_write(int fd, const void *buf, size_t len) { | |
37 while (len > 0) { | |
38 ssize_t n = write(fd, buf, len); | |
25 | 39 |
26 if (n < 0) | 40 if (n < 0) |
27 return n; | 41 return n; |
28 | 42 |
29 buf += n; | 43 buf += n; |
162 --c->refcount; | 176 --c->refcount; |
163 pthread_mutex_unlock(&c->lock); | 177 pthread_mutex_unlock(&c->lock); |
164 | 178 |
165 } | 179 } |
166 | 180 |
167 static const char begin_msgs[] = "HTTP/1.1 200 OK\r\nContent-type: text/plain\r\n\r\n"; | 181 static const char begin_msgs[] = "Content-type: text/plain\r\n\r\n"; |
168 | 182 |
169 static client *find_client(unsigned id) { | 183 static client *find_client(unsigned id) { |
170 client *c; | 184 client *c; |
171 | 185 |
172 pthread_mutex_lock(&clients_mutex); | 186 pthread_mutex_lock(&clients_mutex); |
178 | 192 |
179 c = clients[id]; | 193 c = clients[id]; |
180 | 194 |
181 pthread_mutex_unlock(&clients_mutex); | 195 pthread_mutex_unlock(&clients_mutex); |
182 return c; | 196 return c; |
197 } | |
198 | |
199 static char *on_success = "HTTP/1.1 200 OK\r\n"; | |
200 | |
201 void uw_set_on_success(char *s) { | |
202 on_success = s; | |
183 } | 203 } |
184 | 204 |
185 void uw_client_connect(unsigned id, int pass, int sock) { | 205 void uw_client_connect(unsigned id, int pass, int sock) { |
186 client *c = find_client(id); | 206 client *c = find_client(id); |
187 | 207 |
213 } | 233 } |
214 | 234 |
215 c->last_contact = time(NULL); | 235 c->last_contact = time(NULL); |
216 | 236 |
217 if (buf_used(&c->msgs) > 0) { | 237 if (buf_used(&c->msgs) > 0) { |
238 uw_really_send(sock, on_success, strlen(on_success)); | |
218 uw_really_send(sock, begin_msgs, sizeof(begin_msgs) - 1); | 239 uw_really_send(sock, begin_msgs, sizeof(begin_msgs) - 1); |
219 uw_really_send(sock, c->msgs.start, buf_used(&c->msgs)); | 240 uw_really_send(sock, c->msgs.start, buf_used(&c->msgs)); |
220 buf_reset(&c->msgs); | 241 buf_reset(&c->msgs); |
221 close(sock); | 242 close(sock); |
222 } | 243 } |
225 | 246 |
226 pthread_mutex_unlock(&c->lock); | 247 pthread_mutex_unlock(&c->lock); |
227 } | 248 } |
228 | 249 |
229 static void free_client(client *c) { | 250 static void free_client(client *c) { |
230 printf("Freeing client %u\n", c->id); | |
231 | |
232 c->mode = UNUSED; | 251 c->mode = UNUSED; |
233 c->pass = -1; | 252 c->pass = -1; |
234 | 253 |
235 c->next = clients_free; | 254 c->next = clients_free; |
236 clients_free = c; | 255 clients_free = c; |
243 | 262 |
244 static void client_send(client *c, buf *msg) { | 263 static void client_send(client *c, buf *msg) { |
245 pthread_mutex_lock(&c->lock); | 264 pthread_mutex_lock(&c->lock); |
246 | 265 |
247 if (c->sock != -1) { | 266 if (c->sock != -1) { |
267 uw_really_send(c->sock, on_success, strlen(on_success)); | |
248 uw_really_send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); | 268 uw_really_send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); |
249 uw_really_send(c->sock, msg->start, buf_used(msg)); | 269 uw_really_send(c->sock, msg->start, buf_used(msg)); |
250 close(c->sock); | 270 close(c->sock); |
251 c->sock = -1; | 271 c->sock = -1; |
252 } else | 272 } else |
1066 return n; | 1086 return n; |
1067 | 1087 |
1068 return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start); | 1088 return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start); |
1069 } | 1089 } |
1070 | 1090 |
1091 int uw_print(uw_context ctx, int fd) { | |
1092 int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); | |
1093 | |
1094 if (n < 0) | |
1095 return n; | |
1096 | |
1097 n = uw_really_write(fd, "\r\n", 2); | |
1098 | |
1099 if (n < 0) | |
1100 return n; | |
1101 | |
1102 return uw_really_write(fd, ctx->page.start, ctx->page.front - ctx->page.start); | |
1103 } | |
1104 | |
1071 static void uw_check_headers(uw_context ctx, size_t extra) { | 1105 static void uw_check_headers(uw_context ctx, size_t extra) { |
1072 buf_check(&ctx->outHeaders, extra); | 1106 buf_check(&ctx->outHeaders, extra); |
1073 } | 1107 } |
1074 | 1108 |
1075 void uw_write_header(uw_context ctx, uw_Basis_string s) { | 1109 void uw_write_header(uw_context ctx, uw_Basis_string s) { |
2547 } | 2581 } |
2548 if (fk == SUCCESS) | 2582 if (fk == SUCCESS) |
2549 free_client(c); | 2583 free_client(c); |
2550 else { | 2584 else { |
2551 uw_db_rollback(ctx); | 2585 uw_db_rollback(ctx); |
2552 printf("Expunge blocked by error: %s\n", uw_error_message(ctx)); | 2586 fprintf(stderr, "Expunge blocked by error: %s\n", uw_error_message(ctx)); |
2553 } | 2587 } |
2554 } | 2588 } |
2555 else | 2589 else |
2556 prev = c; | 2590 prev = c; |
2557 pthread_mutex_unlock(&c->lock); | 2591 pthread_mutex_unlock(&c->lock); |
2662 int len; | 2696 int len; |
2663 | 2697 |
2664 buf_reset(&ctx->outHeaders); | 2698 buf_reset(&ctx->outHeaders); |
2665 buf_reset(&ctx->page); | 2699 buf_reset(&ctx->page); |
2666 | 2700 |
2667 uw_write_header(ctx, "HTTP/1.1 200 OK\r\nContent-Type: "); | 2701 uw_write_header(ctx, on_success); |
2702 uw_write_header(ctx, "Content-Type: "); | |
2668 uw_write_header(ctx, mimeType); | 2703 uw_write_header(ctx, mimeType); |
2669 uw_write_header(ctx, "\r\nContent-Length: "); | 2704 uw_write_header(ctx, "\r\nContent-Length: "); |
2670 buf_check(&ctx->outHeaders, INTS_MAX); | 2705 buf_check(&ctx->outHeaders, INTS_MAX); |
2671 sprintf(ctx->outHeaders.front, "%d%n", b.size, &len); | 2706 sprintf(ctx->outHeaders.front, "%d%n", b.size, &len); |
2672 ctx->outHeaders.front += len; | 2707 ctx->outHeaders.front += len; |