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;