diff 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
line wrap: on
line diff
--- a/src/c/urweb.c	Tue Jun 23 15:56:04 2009 -0400
+++ b/src/c/urweb.c	Tue Jun 23 17:59:23 2009 -0400
@@ -21,7 +21,21 @@
 
 int uw_really_send(int sock, const void *buf, size_t len) {
   while (len > 0) {
-    size_t n = send(sock, buf, len, 0);
+    ssize_t n = send(sock, buf, len, 0);
+
+    if (n < 0)
+      return n;
+
+    buf += n;
+    len -= n;
+  }
+
+  return 0;
+}
+
+int uw_really_write(int fd, const void *buf, size_t len) {
+  while (len > 0) {
+    ssize_t n = write(fd, buf, len);
 
     if (n < 0)
       return n;
@@ -164,7 +178,7 @@
 
 }
 
-static const char begin_msgs[] = "HTTP/1.1 200 OK\r\nContent-type: text/plain\r\n\r\n";
+static const char begin_msgs[] = "Content-type: text/plain\r\n\r\n";
 
 static client *find_client(unsigned id) {
   client *c;
@@ -182,6 +196,12 @@
   return c;
 }
 
+static char *on_success = "HTTP/1.1 200 OK\r\n";
+
+void uw_set_on_success(char *s) {
+  on_success = s;
+}
+
 void uw_client_connect(unsigned id, int pass, int sock) {
   client *c = find_client(id);
 
@@ -215,6 +235,7 @@
   c->last_contact = time(NULL);
 
   if (buf_used(&c->msgs) > 0) {
+    uw_really_send(sock, on_success, strlen(on_success));
     uw_really_send(sock, begin_msgs, sizeof(begin_msgs) - 1);
     uw_really_send(sock, c->msgs.start, buf_used(&c->msgs));
     buf_reset(&c->msgs);
@@ -227,8 +248,6 @@
 }
 
 static void free_client(client *c) {
-  printf("Freeing client %u\n", c->id);
-
   c->mode = UNUSED;
   c->pass = -1;
 
@@ -245,6 +264,7 @@
   pthread_mutex_lock(&c->lock);
 
   if (c->sock != -1) {
+    uw_really_send(c->sock, on_success, strlen(on_success));
     uw_really_send(c->sock, begin_msgs, sizeof(begin_msgs) - 1);
     uw_really_send(c->sock, msg->start, buf_used(msg));
     close(c->sock);
@@ -1068,6 +1088,20 @@
   return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start);
 }
 
+int uw_print(uw_context ctx, int fd) {
+  int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start);
+
+  if (n < 0)
+    return n;
+
+  n = uw_really_write(fd, "\r\n", 2);
+
+  if (n < 0)
+    return n;
+
+  return uw_really_write(fd, ctx->page.start, ctx->page.front - ctx->page.start);
+}
+
 static void uw_check_headers(uw_context ctx, size_t extra) {
   buf_check(&ctx->outHeaders, extra);
 }
@@ -2549,7 +2583,7 @@
         free_client(c);
       else {
         uw_db_rollback(ctx);
-        printf("Expunge blocked by error: %s\n", uw_error_message(ctx));
+        fprintf(stderr, "Expunge blocked by error: %s\n", uw_error_message(ctx));
       }
     }
     else
@@ -2664,7 +2698,8 @@
   buf_reset(&ctx->outHeaders);
   buf_reset(&ctx->page);
 
-  uw_write_header(ctx, "HTTP/1.1 200 OK\r\nContent-Type: ");
+  uw_write_header(ctx, on_success);
+  uw_write_header(ctx, "Content-Type: ");
   uw_write_header(ctx, mimeType);
   uw_write_header(ctx, "\r\nContent-Length: ");
   buf_check(&ctx->outHeaders, INTS_MAX);