* use strbuffer as wprintf backend
authorWilfried Göesgens <willi@citadel.org>
Sun, 27 Jul 2008 21:38:24 +0000 (21:38 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sun, 27 Jul 2008 21:38:24 +0000 (21:38 +0000)
* modify all HTTP Headrs to be sent with hprintf() instead of wprintf()
* end_burst now handles committing the headers and the buffer to the browser
* use strbuf to keep static images

23 files changed:
webcit/autocompletion.c
webcit/availability.c
webcit/calendar.c
webcit/context_loop.c
webcit/crypto.c
webcit/downloads.c
webcit/floors.c
webcit/groupdav_delete.c
webcit/groupdav_get.c
webcit/groupdav_main.c
webcit/groupdav_propfind.c
webcit/groupdav_put.c
webcit/html2html.c
webcit/messages.c
webcit/paging.c
webcit/rss.c
webcit/serv_func.c
webcit/siteconfig.c
webcit/tcp_sockets.c
webcit/webcit.c
webcit/webcit.h
webcit/webserver.c
webcit/webserver.h

index 69564e812488dde771b64444327ce79cf39ea1b6..4cf4ccd6f659ff139fe84df68da623d681c6282e 100644 (file)
@@ -15,7 +15,7 @@ void recp_autocomplete(char *partial) {
 
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/html\r\n"
+       hprintf("Content-type: text/html\r\n"
                "Server: %s\r\n"
                "Connection: close\r\n"
                "Pragma: no-cache\r\n"
index f2b4cdbe766a65875f52931c9fa9f6df1596865d..097725523433ff9be9d7a1fa32158622f5af408c 100644 (file)
  * Utility function to fetch a VFREEBUSY type of thing for any specified user.
  */
 icalcomponent *get_freebusy_for_user(char *who) {
+       long nLines;
        char buf[SIZ];
-       char *serialized_fb = NULL;
+       StrBuf *serialized_fb = NULL;
        icalcomponent *fb = NULL;
 
        serv_printf("ICAL freebusy|%s", who);
        serv_getln(buf, sizeof buf);
        if (buf[0] == '1') {
-               serialized_fb = read_server_text();
+               serialized_fb = read_server_text(&nLines);
        }
 
        if (serialized_fb == NULL) {
                return NULL;
        }
        
-       fb = icalcomponent_new_from_string(serialized_fb);
-       free(serialized_fb);
+       fb = icalcomponent_new_from_string(ChrPtr(serialized_fb));
+       FreeStrBuf(&serialized_fb);
        if (fb == NULL) {
                return NULL;
        }
index 32a3e02f535b7644ab83e7b771abd615edbc6cac..61d621993b99e8d9be63b12518f727adcd1d9398 100644 (file)
@@ -1073,8 +1073,9 @@ void save_event(void) {
 void do_freebusy(char *req) {
        char who[SIZ];
        char buf[SIZ];
-       char *fb;
+       StrBuf *fb;
        int len;
+       long lines;
 
        extract_token(who, req, 1, ' ', sizeof who);
        if (!strncasecmp(who, "/freebusy/", 10)) {
@@ -1094,17 +1095,17 @@ void do_freebusy(char *req) {
        serv_getln(buf, sizeof buf);
 
        if (buf[0] != '1') {
-               wprintf("HTTP/1.1 404 %s\n", &buf[4]);
+               hprintf("HTTP/1.1 404 %s\n", &buf[4]);
                output_headers(0, 0, 0, 0, 0, 0);
-               wprintf("Content-Type: text/plain\r\n");
-               wprintf("\r\n");
+               hprintf("Content-Type: text/plain\r\n");
                wprintf("%s\n", &buf[4]);
+               end_burst();
                return;
        }
 
-       fb = read_server_text();
-       http_transmit_thing(fb, strlen(fb), "text/calendar", 0);
-       free(fb);
+       fb = read_server_text(&lines);
+       http_transmit_thing(fb, "text/calendar", 0);
+       FreeStrBuf(&fb);
 }
 
 
index 27e643093d1c2cdda8b155ab1dc298e09e9c5808..4e10f92b230f08f92779ffe1640daf15e617213b 100644 (file)
@@ -102,6 +102,9 @@ void do_housekeeping(void)
                free_march_list(sessions_to_kill);
                DeleteHash(&(sessions_to_kill->hash_prefs));
                DeleteHash(&(sessions_to_kill->IconBarSetttings));
+               FreeStrBuf(&(sessions_to_kill->UrlFragment1));
+               FreeStrBuf(&(sessions_to_kill->UrlFragment2));
+               FreeStrBuf(&(sessions_to_kill->WBuf));
 
                pthread_mutex_unlock(&sessions_to_kill->SessionMutex);
                sptr = sessions_to_kill->next;
index bfb84cb5de52c9b92bc5372765f76e02cc9e59c4..7db64940e9a57545c454afc463e56e946b9319c3 100644 (file)
@@ -439,7 +439,7 @@ void ssl_lock(int mode, int n, const char *file, int line)
  * \param buf chars to send to the client
  * \param nbytes how many chars
  */
-void client_write_ssl(char *buf, int nbytes)
+void client_write_ssl(const char *buf, int nbytes)
 {
        int retval;
        int nremain;
index f2653746ab1ed4335c32906df94d5b0b8fa49a07..600d89de0769cdf0c9196c02eb31293811725296 100644 (file)
@@ -383,6 +383,7 @@ void display_mime_icon(void)
 
 void download_file(void)
 {
+       StrBuf *Buf;
        char buf[256];
        off_t bytes;
        char content_type[256];
@@ -405,17 +406,17 @@ void download_file(void)
                        extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
                }
                output_headers(0, 0, 0, 0, 0, 0);
-               read_server_binary(content, bytes);
+               Buf = read_server_binary(bytes);
                serv_puts("CLOS");
                serv_getln(buf, sizeof buf);
-               http_transmit_thing(content, bytes, content_type, 0);
+               http_transmit_thing(Buf, content_type, 0);
                free(content);
        } else {
-               wprintf("HTTP/1.1 404 %s\n", &buf[4]);
+               hprintf("HTTP/1.1 404 %s\n", &buf[4]);
                output_headers(0, 0, 0, 0, 0, 0);
-               wprintf("Content-Type: text/plain\r\n");
-               wprintf("\r\n");
+               hprintf("Content-Type: text/plain\r\n");
                wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
+               end_burst();
        }
 
 }
index b5ee4028e52959afbb1967e247b8b64c13243a85..1b52c9aece5ed91bc01fcdae8e30e72042d8c61f 100644 (file)
@@ -19,7 +19,7 @@
  * will be displayed at the top of the screen.
  * \param prepend_html pagetitle to prepend
  */
-void display_floorconfig(char *prepend_html)
+void display_floorconfig(StrBuf *prepend_html)
 {
        char buf[SIZ];
 
@@ -38,7 +38,7 @@ void display_floorconfig(char *prepend_html)
                                                                                                                              
        if (prepend_html != NULL) {
                wprintf("<br /><b><i>");
-               client_write(prepend_html, strlen(prepend_html));
+               StrBufAppendBuf(WC->WBuf, prepend_html, 0);
                wprintf("</i></b><br /><br />\n");
        }
 
@@ -136,64 +136,66 @@ void display_floorconfig(char *prepend_html)
  */
 void delete_floor(void) {
        int floornum;
-       char buf[SIZ];
-       char message[SIZ];
-
+       StrBuf *Buf;
+       const char *Err;
+               
        floornum = ibstr("floornum");
-
+       Buf = NewStrBuf();
        serv_printf("KFLR %d|1", floornum);
-       serv_getln(buf, sizeof buf);
+       
+       StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
 
-       if (buf[0] == '2') {
-               sprintf(message, _("Floor has been deleted."));
+       if (ChrPtr(Buf)[0] == '2') {
+               StrBufPlain(Buf, _("Floor has been deleted."),-1);
        }
        else {
-               sprintf(message, "%s", &buf[4]);
+               StrBufCutLeft(Buf, 4);
        }
 
-       display_floorconfig(message);
+       display_floorconfig(Buf);
+       FreeStrBuf(&Buf);
 }
 
 /**
  * \brief tart creating a new floor
  */
 void create_floor(void) {
-       char buf[SIZ];
-       char message[SIZ];
-       char floorname[SIZ];
+       StrBuf *Buf;
+       const char *Err;
 
-       strcpy(floorname, bstr("floorname"));
-
-       serv_printf("CFLR %s|1", floorname);
-       serv_getln(buf, sizeof buf);
+       Buf = NewStrBuf();
+       serv_printf("CFLR %s|1", bstr("floorname"));
+       StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
 
-       if (buf[0] == '2') {
-               sprintf(message, _("New floor has been created."));
-       } else {
-               sprintf(message, "%s", &buf[4]);
+       if (ChrPtr(Buf)[0] == '2') {
+               StrBufPlain(Buf, _("New floor has been created."),-1);
+       }
+       else {
+               StrBufCutLeft(Buf, 4);
        }
 
-       display_floorconfig(message);
+       display_floorconfig(Buf);
+       FreeStrBuf(&Buf);
 }
 
+
 /**
  * \brief rename this floor
  */
 void rename_floor(void) {
-       int floornum;
-       char buf[SIZ];
-       char message[SIZ];
-       char floorname[SIZ];
+       StrBuf *Buf;
 
-       floornum = ibstr("floornum");
-       strcpy(floorname, bstr("floorname"));
+       Buf = NewStrBuf();
 
-       serv_printf("EFLR %d|%s", floornum, floorname);
-       serv_getln(buf, sizeof buf);
+       serv_printf("EFLR %d|%s", 
+                   ibstr("floornum"), 
+                   bstr("floorname"));
+       StrBuf_ServGetln(Buf);
 
-       sprintf(message, "%s", &buf[4]);
+       StrBufCutLeft(Buf, 4);
 
-       display_floorconfig(message);
+       display_floorconfig(Buf);
+       FreeStrBuf(&Buf);
 }
 
 void _display_floorconfig(void) {display_floorconfig(NULL);}
index f731daa5a7cf6878f9b0d4c323a64c0557cab4a4..8aa9f3b57cd0a85f2162299ba7782cf34cc788b7 100644 (file)
@@ -42,9 +42,9 @@ void groupdav_delete(char *dav_pathname, char *dav_ifmatch) {
                gotoroom(dav_roomname);
        }
        if (strcasecmp(WC->wc_roomname, dav_roomname)) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf("Content-Length: 0\r\n\r\n");
+               hprintf("Content-Length: 0\r\n\r\n");
                return;
        }
 
@@ -54,9 +54,9 @@ void groupdav_delete(char *dav_pathname, char *dav_ifmatch) {
         * If no item exists with the requested uid ... simple error.
         */
        if (dav_msgnum < 0L) {
-               wprintf("HTTP/1.1 404 Not Found\r\n");
+               hprintf("HTTP/1.1 404 Not Found\r\n");
                groupdav_common_headers();
-               wprintf("Content-Length: 0\r\n\r\n");
+               hprintf("Content-Length: 0\r\n\r\n");
                return;
        }
 
@@ -66,9 +66,9 @@ void groupdav_delete(char *dav_pathname, char *dav_ifmatch) {
         */
        if (!IsEmptyStr(dav_ifmatch)) {
                if (atol(dav_ifmatch) != dav_msgnum) {
-                       wprintf("HTTP/1.1 412 Precondition Failed\r\n");
+                       hprintf("HTTP/1.1 412 Precondition Failed\r\n");
                        groupdav_common_headers();
-                       wprintf("Content-Length: 0\r\n\r\n");
+                       hprintf("Content-Length: 0\r\n\r\n");
                        return;
                }
        }
@@ -79,14 +79,14 @@ void groupdav_delete(char *dav_pathname, char *dav_ifmatch) {
        serv_printf("DELE %ld", dav_msgnum);
        serv_getln(buf, sizeof buf);
        if (buf[0] == '2') {
-               wprintf("HTTP/1.1 204 No Content\r\n"); /* success */
+               hprintf("HTTP/1.1 204 No Content\r\n"); /* success */
                groupdav_common_headers();
-               wprintf("Content-Length: 0\r\n\r\n");
+               hprintf("Content-Length: 0\r\n\r\n");
        }
        else {
-               wprintf("HTTP/1.1 403 Forbidden\r\n");  /* access denied */
+               hprintf("HTTP/1.1 403 Forbidden\r\n");  /* access denied */
                groupdav_common_headers();
-               wprintf("Content-Length: 0\r\n\r\n");
+               hprintf("Content-Length: 0\r\n\r\n");
        }
        return;
 }
index 124d44988108cf79f171f4f27d76e1f6b5575159..02d4ea26b2d91f19bcdad55d4e623413ea01c8d0 100644 (file)
@@ -20,20 +20,18 @@ void groupdav_get_big_ics(void) {
        serv_puts("ICAL getics");
        serv_getln(buf, sizeof buf);
        if (buf[0] != '1') {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "%s\r\n",
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("%s\r\n",
                        &buf[4]
-               );
+                       );/// TODO: do we need to end-burst here?
                return;
        }
 
-       wprintf("HTTP/1.1 200 OK\r\n");
+       hprintf("HTTP/1.1 200 OK\r\n");
        groupdav_common_headers();
-       wprintf("Content-type: text/calendar; charset=UTF-8\r\n");
+       hprintf("Content-type: text/calendar; charset=UTF-8\r\n");
        begin_burst();
        while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
                wprintf("%s\r\n", buf);
@@ -74,9 +72,9 @@ void extract_preferred(char *name, char *filename, char *partnum, char *disp,
                if (!IsEmptyStr(cbcharset)) {
                        safestrncpy(epdata->charset, cbcharset, sizeof epdata->charset);
                }
-               wprintf("Content-type: %s; charset=%s\r\n", cbtype, epdata->charset);
+               hprintf("Content-type: %s; charset=%s\r\n", cbtype, epdata->charset);
                begin_burst();
-               client_write(content, length);
+               StrBufAppendBufPlain(WC->WBuf, content, length, 0);
                end_burst();
        }
 }
@@ -107,13 +105,11 @@ void groupdav_get(char *dav_pathname) {
        struct epdata epdata;
 
        if (num_tokens(dav_pathname, '/') < 3) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "The object you requested was not found.\r\n"
-               );
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("The object you requested was not found.\r\n");
+               end_burst();
                return;
        }
 
@@ -128,14 +124,12 @@ void groupdav_get(char *dav_pathname) {
                gotoroom(dav_roomname);
        }
        if (strcasecmp(WC->wc_roomname, dav_roomname)) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "There is no folder called \"%s\" on this server.\r\n",
-                       dav_roomname
-               );
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("There is no folder called \"%s\" on this server.\r\n",
+                       dav_roomname);
+               end_burst();
                return;
        }
 
@@ -150,15 +144,13 @@ void groupdav_get(char *dav_pathname) {
        serv_printf("MSG2 %ld", dav_msgnum);
        serv_getln(buf, sizeof buf);
        if (buf[0] != '1') {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "Object \"%s\" was not found in the \"%s\" folder.\r\n",
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("Object \"%s\" was not found in the \"%s\" folder.\r\n",
                        dav_uid,
-                       dav_roomname
-               );
+                       dav_roomname);
+               end_burst();
                return;
        }
 
@@ -210,10 +202,10 @@ void groupdav_get(char *dav_pathname) {
 
        /* Output headers common to single or multi part messages */
 
-       wprintf("HTTP/1.1 200 OK\r\n");
+       hprintf("HTTP/1.1 200 OK\r\n");
        groupdav_common_headers();
-       wprintf("etag: \"%ld\"\r\n", dav_msgnum);
-       wprintf("Date: %s\r\n", date);
+       hprintf("etag: \"%ld\"\r\n", dav_msgnum);
+       hprintf("Date: %s\r\n", date);
 
        memset(&epdata, 0, sizeof(struct epdata));
        safestrncpy(epdata.charset, charset, sizeof epdata.charset);
@@ -241,7 +233,7 @@ void groupdav_get(char *dav_pathname) {
                ptr = msgtext;
                endptr = &msgtext[msglen];
        
-               wprintf("Content-type: %s; charset=%s\r\n", content_type, charset);
+               hprintf("Content-type: %s; charset=%s\r\n", content_type, charset);
        
                in_body = 0;
                do {
index a05c05ad2dccc2c0fadc8774ee345faaf152f37e..07fb67d3c7ddbf07d6940716badf88df07ab9673 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 void groupdav_common_headers(void) {
-       wprintf(
+       hprintf(
                "Server: %s / %s\r\n"
                "Connection: close\r\n",
                PACKAGE_STRING, serv_info.serv_software
@@ -127,11 +127,12 @@ void groupdav_main(struct httprequest *req,
        }
 
        if (!WC->logged_in) {
-               wprintf("HTTP/1.1 401 Unauthorized\r\n");
+               hprintf("HTTP/1.1 401 Unauthorized\r\n");
                groupdav_common_headers();
-               wprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n",
+               hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n",
                        serv_info.serv_humannode);
-               wprintf("Content-Length: 0\r\n\r\n");
+               hprintf("Content-Length: 0\r\n");
+               end_burst();
                return;
        }
 
@@ -229,13 +230,12 @@ void groupdav_main(struct httprequest *req,
        /*
         * Couldn't find what we were looking for.  Die in a car fire.
         */
-       wprintf("HTTP/1.1 501 Method not implemented\r\n");
+       hprintf("HTTP/1.1 501 Method not implemented\r\n");
        groupdav_common_headers();
-       wprintf("Content-Type: text/plain\r\n"
-               "\r\n"
-               "GroupDAV method \"%s\" is not implemented.\r\n",
-               dav_method
-       );
+       hprintf("Content-Type: text/plain\r\n");
+       wprintf("GroupDAV method \"%s\" is not implemented.\r\n",
+               dav_method);
+       end_burst();
 }
 
 
index 6d3092ae87951ed75033acbe09b675abbdcba9b8..f9b2ce0d71d7c22b8b4ba3d99400f5f454b45078 100644 (file)
@@ -93,11 +93,11 @@ void groupdav_collection_list(char *dav_pathname, int dav_depth)
         * Be rude.  Completely ignore the XML request and simply send them
         * everything we know about.  Let the client sort it out.
         */
-       wprintf("HTTP/1.0 207 Multi-Status\r\n");
+       hprintf("HTTP/1.0 207 Multi-Status\r\n");
        groupdav_common_headers();
-       wprintf("Date: %s\r\n", datestring);
-       wprintf("Content-type: text/xml\r\n");
-       wprintf("Content-encoding: identity\r\n");
+       hprintf("Date: %s\r\n", datestring);
+       hprintf("Content-type: text/xml\r\n");
+       hprintf("Content-encoding: identity\r\n");
 
        begin_burst();
 
@@ -261,15 +261,14 @@ void groupdav_propfind(char *dav_pathname, int dav_depth, char *dav_content_type
                gotoroom(dav_roomname);
        }
        if (strcasecmp(WC->wc_roomname, dav_roomname)) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf("Date: %s\r\n", datestring);
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "There is no folder called \"%s\" on this server.\r\n",
+               hprintf("Date: %s\r\n", datestring);
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("There is no folder called \"%s\" on this server.\r\n",
                        dav_roomname
                );
+               end_burst();
                return;
        }
 
@@ -281,15 +280,14 @@ void groupdav_propfind(char *dav_pathname, int dav_depth, char *dav_content_type
 
                dav_msgnum = locate_message_by_uid(dav_uid);
                if (dav_msgnum < 0) {
-                       wprintf("HTTP/1.1 404 not found\r\n");
+                       hprintf("HTTP/1.1 404 not found\r\n");
                        groupdav_common_headers();
-                       wprintf(
-                               "Content-Type: text/plain\r\n"
-                               "\r\n"
-                               "Object \"%s\" was not found in the \"%s\" folder.\r\n",
+                       hprintf("Content-Type: text/plain\r\n");
+                       wprintf("Object \"%s\" was not found in the \"%s\" folder.\r\n",
                                dav_uid,
                                dav_roomname
                        );
+                       end_burst();
                        return;
                }
 
@@ -297,11 +295,11 @@ void groupdav_propfind(char *dav_pathname, int dav_depth, char *dav_content_type
                 * everything we know about (which is going to simply be the ETag and
                 * nothing else).  Let the client-side parser sort it out.
                 */
-               wprintf("HTTP/1.0 207 Multi-Status\r\n");
+               hprintf("HTTP/1.0 207 Multi-Status\r\n");
                groupdav_common_headers();
-               wprintf("Date: %s\r\n", datestring);
-               wprintf("Content-type: text/xml\r\n");
-               wprintf("Content-encoding: identity\r\n");
+               hprintf("Date: %s\r\n", datestring);
+               hprintf("Content-type: text/xml\r\n");
+               hprintf("Content-encoding: identity\r\n");
        
                begin_burst();
        
@@ -338,11 +336,11 @@ void groupdav_propfind(char *dav_pathname, int dav_depth, char *dav_content_type
         * everything we know about (which is going to simply be the ETag and
         * nothing else).  Let the client-side parser sort it out.
         */
-       wprintf("HTTP/1.0 207 Multi-Status\r\n");
+       hprintf("HTTP/1.0 207 Multi-Status\r\n");
        groupdav_common_headers();
-       wprintf("Date: %s\r\n", datestring);
-       wprintf("Content-type: text/xml\r\n");
-       wprintf("Content-encoding: identity\r\n");
+       hprintf("Date: %s\r\n", datestring);
+       hprintf("Content-type: text/xml\r\n");
+       hprintf("Content-encoding: identity\r\n");
 
        begin_burst();
 
index 7ab6d4cb49ba3a0eaff949d8955c3740e06078e5..dc5121f47c4069ad812db89a77ed1cc9b18975fc 100644 (file)
@@ -29,12 +29,11 @@ void groupdav_put_bigics(char *dav_content, int dav_content_length)
        serv_puts("ICAL putics");
        serv_getln(buf, sizeof buf);
        if (buf[0] != '4') {
-               wprintf("HTTP/1.1 502 Bad Gateway\r\n");
+               hprintf("HTTP/1.1 502 Bad Gateway\r\n");
                groupdav_common_headers();
-               wprintf("Content-type: text/plain\r\n"
-                       "\r\n"
-                       "%s\r\n", &buf[4]
-               );
+               hprintf("Content-type: text/plain\r\n");
+               wprintf("%s\r\n", &buf[4]);
+               end_burst();
                return;
        }
 
@@ -42,10 +41,10 @@ void groupdav_put_bigics(char *dav_content, int dav_content_length)
        serv_printf("\n000");
 
        /* Report success and not much else. */
-       wprintf("HTTP/1.1 204 No Content\r\n");
+       hprintf("HTTP/1.1 204 No Content\r\n");
        lprintf(9, "HTTP/1.1 204 No Content\r\n");
        groupdav_common_headers();
-       wprintf("Content-Length: 0\r\n\r\n");
+       hprintf("Content-Length: 0\r\n");
 }
 
 
@@ -67,13 +66,11 @@ void groupdav_put(char *dav_pathname, char *dav_ifmatch,
        int n = 0;
 
        if (num_tokens(dav_pathname, '/') < 3) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "The object you requested was not found.\r\n"
-               );
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("The object you requested was not found.\r\n");
+               end_burst();
                return;
        }
 
@@ -88,14 +85,12 @@ void groupdav_put(char *dav_pathname, char *dav_ifmatch,
                gotoroom(dav_roomname);
        }
        if (strcasecmp(WC->wc_roomname, dav_roomname)) {
-               wprintf("HTTP/1.1 404 not found\r\n");
+               hprintf("HTTP/1.1 404 not found\r\n");
                groupdav_common_headers();
-               wprintf(
-                       "Content-Type: text/plain\r\n"
-                       "\r\n"
-                       "There is no folder called \"%s\" on this server.\r\n",
-                       dav_roomname
-               );
+               hprintf("Content-Type: text/plain\r\n");
+               wprintf("There is no folder called \"%s\" on this server.\r\n",
+                       dav_roomname);
+               end_burst();
                return;
        }
 
@@ -111,11 +106,12 @@ void groupdav_put(char *dav_pathname, char *dav_ifmatch,
                old_msgnum = locate_message_by_uid(dav_uid);
                lprintf(9, "old_msgnum:  %ld\n", old_msgnum);
                if (atol(dav_ifmatch) != old_msgnum) {
-                       wprintf("HTTP/1.1 412 Precondition Failed\r\n");
+                       hprintf("HTTP/1.1 412 Precondition Failed\r\n");
                        lprintf(9, "HTTP/1.1 412 Precondition Failed (ifmatch=%ld, old_msgnum=%ld)\r\n",
                                atol(dav_ifmatch), old_msgnum);
                        groupdav_common_headers();
-                       wprintf("Content-Length: 0\r\n\r\n");
+                       hprintf("Content-Length: 0\r\n");
+                       end_burst();
                        return;
                }
        }
@@ -135,12 +131,12 @@ void groupdav_put(char *dav_pathname, char *dav_ifmatch,
        serv_puts("ENT0 1|||4|||1|");
        serv_getln(buf, sizeof buf);
        if (buf[0] != '8') {
-               wprintf("HTTP/1.1 502 Bad Gateway\r\n");
+               hprintf("HTTP/1.1 502 Bad Gateway\r\n");
                groupdav_common_headers();
-               wprintf("Content-type: text/plain\r\n"
-                       "\r\n"
-                       "%s\r\n", &buf[4]
-               );
+               hprintf("Content-type: text/plain\r\n");
+
+               wprintf("%s\r\n", &buf[4]);
+               end_burst();
                return;
        }
 
@@ -169,46 +165,44 @@ void groupdav_put(char *dav_pathname, char *dav_ifmatch,
 
        /* Citadel failed in some way? */
        if (new_msgnum < 0L) {
-               wprintf("HTTP/1.1 502 Bad Gateway\r\n");
+               hprintf("HTTP/1.1 502 Bad Gateway\r\n");
                groupdav_common_headers();
-               wprintf("Content-type: text/plain\r\n"
-                       "\r\n"
-                       "new_msgnum is %ld\r\n"
-                       "\r\n", new_msgnum
-               );
+               hprintf("Content-type: text/plain\r\n");
+               wprintf("new_msgnum is %ld\r\n"
+                       "\r\n", new_msgnum);
+               end_burst();
                return;
        }
 
        /* We created this item for the first time. */
        if (old_msgnum < 0L) {
-               wprintf("HTTP/1.1 201 Created\r\n");
+               hprintf("HTTP/1.1 201 Created\r\n");
                lprintf(9, "HTTP/1.1 201 Created\r\n");
                groupdav_common_headers();
-               wprintf("etag: \"%ld\"\r\n", new_msgnum);
-               wprintf("Content-Length: 0\r\n");
-               wprintf("Location: ");
+               hprintf("etag: \"%ld\"\r\n", new_msgnum);
+               hprintf("Content-Length: 0\r\n");
+               hprintf("Location: ");
                groupdav_identify_host();
-               wprintf("/groupdav/");
+               hprintf("/groupdav/");/////TODO
                urlescputs(dav_roomname);
                char escaped_uid[1024];
                euid_escapize(escaped_uid, dav_uid);
                wprintf("/%s\r\n", escaped_uid);
-               wprintf("\r\n");
                return;
        }
 
        /* We modified an existing item. */
-       wprintf("HTTP/1.1 204 No Content\r\n");
+       hprintf("HTTP/1.1 204 No Content\r\n");
        lprintf(9, "HTTP/1.1 204 No Content\r\n");
        groupdav_common_headers();
-       wprintf("etag: \"%ld\"\r\n", new_msgnum);
-       wprintf("Content-Length: 0\r\n\r\n");
+       hprintf("etag: \"%ld\"\r\n", new_msgnum);
+       hprintf("Content-Length: 0\r\n");
 
        /* The item we replaced has probably already been deleted by
         * the Citadel server, but we'll do this anyway, just in case.
         */
        serv_printf("DELE %ld", old_msgnum);
        serv_getln(buf, sizeof buf);
-
+       end_burst();
        return;
 }
index c65e674bcd69c649c65d3248fb9dcf66b829129f..0db2374a1f7df9338ab2de4e82240076ebfac0fc 100644 (file)
@@ -467,7 +467,7 @@ void output_html(char *supplied_charset, int treat_as_wiki) {
        /**     output_length = content_length;                         */
 
        /** Output our big pile of markup */
-       client_write(converted_msg, output_length);
+       StrBufAppendBufPlain(WC->WBuf, converted_msg, output_length, 0);
 
 BAIL:  /** A little trailing vertical whitespace... */
        wprintf("<br /><br />\n");
index 06ca707ca861a22195615e1f9483552adbb9d778..90340896472e3686b4485c4fbbe558f4a8594816 100644 (file)
@@ -1411,13 +1411,13 @@ void print_message(void) {
        msgnum = StrTol(WC->UrlFragment1);
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/html\r\n"
+       hprintf("Content-type: text/html\r\n"
                "Server: %s\r\n"
-               "Connection: close\r\n",
+               "Connection: close\r\n"
                PACKAGE_STRING);
        begin_burst();
 
-       wprintf("\r\n\r\n<html>\n<head><title>");
+       wprintf("\r\n<html>\n<head><title>");
        escputs(WC->wc_fullname);
        wprintf("</title></head>\n"
                "<body onLoad=\" window.print(); window.close(); \">\n"
@@ -1443,7 +1443,7 @@ void display_headers(void) {
        msgnum = StrTol(WC->UrlFragment1);
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/plain\r\n"
+       hprintf("Content-type: text/plain\r\n"
                "Server: %s\r\n"
                "Connection: close\r\n",
                PACKAGE_STRING);
index 1d79cddf5dc4343386efbf5c2b8ffbf71fe1bb01..502f9c069a1ff1a28a58de88e98b271d291a4717 100644 (file)
@@ -277,8 +277,7 @@ void chat_recv(void) {
 
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/html; charset=utf-8\n");
-       wprintf("\n");
+       hprintf("Content-type: text/html; charset=utf-8\r\n");
        wprintf("<html>\n"
                "<head>\n"
                "<meta http-equiv=\"refresh\" content=\"3\" />\n"
@@ -425,8 +424,7 @@ void chat_send(void) {
        char buf[SIZ];
 
        output_headers(0, 0, 0, 0, 0, 0);
-       wprintf("Content-type: text/html; charset=utf-8\n");
-       wprintf("\n");
+       hprintf("Content-type: text/html; charset=utf-8\r\n");
        wprintf("<HTML>"
                "<BODY onLoad=\"document.chatsendform.send_this.focus();\" >"
        );
index 73297a54991fd844dcc5c90c7a041581d4d1714d..062227d1839d2915b84a3195aaf6e9b00bb58a94 100644 (file)
@@ -91,20 +91,20 @@ void display_rss(char *roomname, char *request_method)
 
        if (gotoroom((char *)roomname)) {
                lprintf(3, "RSS: Can't goto requested room\n");
-               wprintf("HTTP/1.1 404 Not Found\r\n");
-               wprintf("Content-Type: text/html\r\n");
-               wprintf("\r\n");
+               hprintf("HTTP/1.1 404 Not Found\r\n");
+               hprintf("Content-Type: text/html\r\n");
                wprintf("Error retrieving RSS feed: couldn't find room\n");
+               end_burst();
                return;
        }
 
         nummsgs = load_msg_ptrs("MSGS LAST|15", 0);
        if (nummsgs == 0) {
                lprintf(3, "RSS: No messages found\n");
-               wprintf("HTTP/1.1 404 Not Found\r\n");
-               wprintf("Content-Type: text/html\r\n");
-               wprintf("\r\n");
+               hprintf("HTTP/1.1 404 Not Found\r\n");
+               hprintf("Content-Type: text/html\r\n");
                wprintf(_("Error retrieving RSS feed: couldn't find messages\n"));
+               end_burst();
                return;
        } 
        
@@ -127,26 +127,25 @@ void display_rss(char *roomname, char *request_method)
        // Commented out. Play dumb for now, also doesn't work with anonrss hack
        /* if (if_modified_since > 0 && if_modified_since > now) {
                lprintf(3, "RSS: Feed not updated since the last time you looked\n");
-               wprintf("HTTP/1.1 304 Not Modified\r\n");
-               wprintf("Last-Modified: %s\r\n", date);
+               hprintf("HTTP/1.1 304 Not Modified\r\n");
+               hprintf("Last-Modified: %s\r\n", date);
                now = time(NULL);
                gmtime_r(&now, &now_tm);
                strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
-               wprintf("Date: %s\r\n", date);
-               if (*msgn) wprintf("ETag: %s\r\n\r\n", msgn); */
+               hprintf("Date: %s\r\n", date);
+               if (*msgn) hprintf("ETag: %s\r\n", msgn); */
                // wDumpContent(0);
                // return;
        //} 
 
        /* Do RSS header */
        lprintf(3, "RSS: Yum yum! This feed is tasty!\n");
-       wprintf("HTTP/1.1 200 OK\r\n");
-       wprintf("Last-Modified: %s\r\n", date);
+       hprintf("HTTP/1.1 200 OK\r\n");
+       hprintf("Last-Modified: %s\r\n", date);
 /*     if (*msgn) wprintf("ETag: %s\r\n\r\n", msgn); */
-       wprintf("Content-Type: application/rss+xml\r\n");
-       wprintf("Server: %s\r\n", PACKAGE_STRING);
-       wprintf("Connection: close\r\n");
-       wprintf("\r\n");
+       hprintf("Content-Type: application/rss+xml\r\n");
+       hprintf("Server: %s\r\n", PACKAGE_STRING);
+       hprintf("Connection: close\r\n");
        if (!strcasecmp(request_method, "HEAD"))
                return;
 
index 9e7f0524fc816e27aaf46317e5d8d363b71423e2..a5604c2257fa1c93bf36b733a68ab3a804720b0c 100644 (file)
@@ -339,34 +339,52 @@ void server_to_text()
 /**
  * Read binary data from server into memory using a series of
  * server READ commands.
- * \param buffer the output buffer
- * \param total_len the maximal length of buffer
+ * \return the read content as StrBuf
  */
-void read_server_binary(char *buffer, size_t total_len) {
+StrBuf *read_server_binary(size_t total_len) 
+{
        char buf[SIZ];
        size_t bytes = 0;
        size_t thisblock = 0;
+       StrBuf *Buf;
+       StrBuf *Ret = NULL;
 
-       memset(buffer, 0, total_len);
+       Buf = NewStrBuf();
+       
        while (bytes < total_len) {
                thisblock = 4095;
                if ((total_len - bytes) < thisblock) {
                        thisblock = total_len - bytes;
-                       if (thisblock == 0) return;
+                       if (thisblock == 0) {
+                               FreeStrBuf(&Ret); 
+                               FreeStrBuf(&Buf);
+                               return NULL; 
+                       }
                }
                serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
-               serv_getln(buf, sizeof buf);
-               if (buf[0] == '6') {
-                       thisblock = (size_t)atoi(&buf[4]);
-                       if (!WC->connected) return;
-                       serv_read(&buffer[bytes], thisblock);
-                       bytes += thisblock;
-               }
-               else {
-                       lprintf(3, "Error: %s\n", &buf[4]);
-                       return;
+               if (StrBuf_ServGetln(Buf) > 0)
+               {
+                   if (ChrPtr(Buf)[0] == '6')
+                   {
+                           StrBufCutLeft(Buf, 4); //thisblock = (size_t)atoi(&buf[4]);
+                           thisblock = StrTol(Buf);
+                           if (!WC->connected) {
+                                   FreeStrBuf(&Ret);
+                                   FreeStrBuf(&Buf); 
+                                   return NULL; 
+                           }
+                           if (Ret == NULL) Ret = NewStrBuf();
+                           StrBuf_ServGetBLOB(Ret, thisblock);
+                           bytes += thisblock;
+                   }
+                   else {
+                           FreeStrBuf(&Buf);
+                           lprintf(3, "Error: %s\n", &buf[4]);
+                           return NULL;
+                   }
                }
        }
+       return Ret;
 }
 
 
@@ -375,36 +393,27 @@ void read_server_binary(char *buffer, size_t total_len) {
  * usual 000 terminator is found.  Caller is responsible for freeing
  * the returned pointer.
  */
-char *read_server_text(void) {
-       char *text = NULL;
-       size_t bytes_allocated = 0;
-       size_t bytes_read = 0;
-       int linelen;
-       char buf[SIZ];
-
-       text = malloc(SIZ);
-       if (text == NULL) {
-               return(NULL);
-       }
-       text[0] = 0;
-       bytes_allocated = SIZ;
-
-       while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
-               linelen = strlen(buf);
-               buf[linelen] = '\n';
-               buf[linelen+1] = 0;
-               ++linelen;
-
-               if ((bytes_read + linelen) >= (bytes_allocated - 2)) {
-                       bytes_allocated = 2 * bytes_allocated;
-                       text = realloc(text, bytes_allocated);
-               }
-
-               strcpy(&text[bytes_read], buf);
-               bytes_read += linelen;
+StrBuf *read_server_text(long *nLines)
+{
+       struct wcsession *WCC = WC;
+       StrBuf *Buf;
+       long nRead;
+       long nlines;
+       const char *buf;
+       
+       Buf = NewStrBuf();
+       buf = ChrPtr(Buf);
+       nlines = 0;
+       while ((WCC->serv_sock!=-1) &&
+              (nRead = StrBuf_ServGetln(Buf)), 
+              (nRead >= 0) && 
+              (buf += nRead), (strcmp(buf, "000") != 0)) {
+               
+               nlines ++;
        }
 
-       return(text);
+       *nLines = nlines;
+       return Buf;
 }
 
 
index 5a2ee2e6f4f780db460788e1d6513f24fe9ad12c..de3e640debed5661e5e81c32a5905d0030e89174 100644 (file)
@@ -15,6 +15,7 @@ void display_siteconfig(void)
 {
        char buf[SIZ];
        int i, j;
+       struct wcsession *WCC = WC;
 
        char general[65536];
        char access[SIZ];
@@ -113,7 +114,7 @@ void display_siteconfig(void)
                );
                
        wprintf("<form method=\"post\" action=\"siteconfig\">\n");
-       wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
+       wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WCC->nonce);
        
        sprintf(&general[strlen(general)], "<tr><td><a href=\"display_edithello\"> %s </a></td>",           _("Change Login Logo"));
        sprintf(&general[strlen(general)],     "<td><a href=\"display_editgoodbuye\"> %s </a></td></tr>\n", _("Change Logout Logo"));
@@ -729,15 +730,15 @@ void display_siteconfig(void)
 
        tabbed_dialog(9, tabnames);
 
-       begin_tab(0, 9);        client_write(general, strlen(general));          end_tab(0, 9);
-       begin_tab(1, 9);        client_write(access, strlen(access));            end_tab(1, 9);
-       begin_tab(2, 9);        client_write(network, strlen(network));          end_tab(2, 9);
-       begin_tab(3, 9);        client_write(tuning, strlen(tuning));            end_tab(3, 9);
-       begin_tab(4, 9);        client_write(directory, strlen(directory));      end_tab(4, 9);
-       begin_tab(5, 9);        client_write(purger, strlen(purger));            end_tab(5, 9);
-       begin_tab(6, 9);        client_write(idxjnl, strlen(idxjnl));            end_tab(6, 9);
-       begin_tab(7, 9);        client_write(funambol, strlen(funambol));        end_tab(7, 9);
-       begin_tab(8, 9);        client_write(pop3, strlen(pop3));                end_tab(8, 9);
+       begin_tab(0, 9);        StrBufAppendBufPlain(WCC->WBuf, general, strlen(general), 0);            end_tab(0, 9);
+       begin_tab(1, 9);        StrBufAppendBufPlain(WCC->WBuf, access, strlen(access), 0);              end_tab(1, 9);
+       begin_tab(2, 9);        StrBufAppendBufPlain(WCC->WBuf, network, strlen(network), 0);            end_tab(2, 9);
+       begin_tab(3, 9);        StrBufAppendBufPlain(WCC->WBuf, tuning, strlen(tuning), 0);              end_tab(3, 9);
+       begin_tab(4, 9);        StrBufAppendBufPlain(WCC->WBuf, directory, strlen(directory), 0);        end_tab(4, 9);
+       begin_tab(5, 9);        StrBufAppendBufPlain(WCC->WBuf, purger, strlen(purger), 0);              end_tab(5, 9);
+       begin_tab(6, 9);        StrBufAppendBufPlain(WCC->WBuf, idxjnl, strlen(idxjnl), 0);              end_tab(6, 9);
+       begin_tab(7, 9);        StrBufAppendBufPlain(WCC->WBuf, funambol, strlen(funambol), 0);  end_tab(7, 9);
+       begin_tab(8, 9);        StrBufAppendBufPlain(WCC->WBuf, pop3, strlen(pop3), 0);          end_tab(8, 9);
        wprintf("<div class=\"tabcontent_submit\">");
        wprintf("<input type=\"submit\" NAME=\"ok_button\" VALUE=\"%s\">", _("Save changes"));
        wprintf("&nbsp;");
index e94c8a5fac36e78813049fc2d1df811de7f77017..fa5429d32b8099f4381af5d51e4863fe9b5ece04 100644 (file)
@@ -182,7 +182,7 @@ int StrBuf_ServGetln(StrBuf *buf)
        const char *ErrStr;
        int rc;
 
-       rc = StrBufTCP_read_line(buf, WC->serv_sock, 0, &ErrStr);
+       rc = StrBufTCP_read_line(buf, &WC->serv_sock, 0, &ErrStr);
        if (rc < 0)
        {
                lprintf(1, "Server connection broken: %s\n",
@@ -195,6 +195,24 @@ int StrBuf_ServGetln(StrBuf *buf)
        return rc;
 }
 
+int StrBuf_ServGetBLOB(StrBuf *buf, long BlobSize)
+{
+       const char *Err;
+       int rc;
+       
+       rc = StrBufReadBLOB(buf, &WC->serv_sock, 1, BlobSize, &Err);
+       if (rc < 0)
+       {
+               lprintf(1, "Server connection broken: %s\n",
+                       Err);
+               wc_backtrace();
+               WC->serv_sock = (-1);
+               WC->connected = 0;
+               WC->logged_in = 0;
+       }
+       return rc;
+}
+
 /**
  * \brief send binary to server
  * \param buf the buffer to write to citadel server
index 2660b3d2f0c883ae68a6b348cc162f337309e083..27edb1a3d3aeef1d12fdfb511c7182cb5930f50d 100644 (file)
@@ -5,7 +5,8 @@
  * persistent session to the Citadel server, handling HTTP WebCit requests as
  * they arrive and presenting a user interface.
  */
-
+#include <stdarg.h>
+#define SHOW_ME_VAPPEND_PRINTF
 #include "webcit.h"
 #include "groupdav.h"
 #include "webserver.h"
@@ -326,14 +327,34 @@ int YESBSTR(char *key)
  */
 void wprintf(const char *format,...)
 {
+       struct wcsession *WCC = WC;
+       va_list arg_ptr;
+
+       if (WCC->WBuf == NULL)
+               WCC->WBuf = NewStrBuf();
+
+       va_start(arg_ptr, format);
+       StrBufVAppendPrintf(WCC->WBuf, format, arg_ptr);
+       va_end(arg_ptr);
+
+///    if (StrLength(WCC-WBuf) > 2048)
+               ///client_write(wbuf, strlen(wbuf));
+}
+
+/*
+ * http-header-printing funcion. uses our vsnprintf wrapper
+ */
+void hprintf(const char *format,...)
+{
+       struct wcsession *WCC = WC;
        va_list arg_ptr;
-       char wbuf[4096];
 
        va_start(arg_ptr, format);
-       vsnprintf(wbuf, sizeof wbuf, format, arg_ptr);
+       StrBufVAppendPrintf(WCC->HBuf, format, arg_ptr);
        va_end(arg_ptr);
 
-       client_write(wbuf, strlen(wbuf));
+///    if (StrLength(WCC-WBuf) > 2048)
+               ///client_write(wbuf, strlen(wbuf));
 }
 
 
@@ -632,11 +653,11 @@ void output_headers(      int do_httpheaders,     /* 1 = output HTTP headers
        char cookie[1024];
        char httpnow[128];
 
-       wprintf("HTTP/1.1 200 OK\n");
+       hprintf("HTTP/1.1 200 OK\n");
        http_datestring(httpnow, sizeof httpnow, time(NULL));
 
        if (do_httpheaders) {
-               wprintf("Content-type: text/html; charset=utf-8\r\n"
+               hprintf("Content-type: text/html; charset=utf-8\r\n"
                        "Server: %s / %s\n"
                        "Connection: close\r\n",
                        PACKAGE_STRING, serv_info.serv_software
@@ -649,7 +670,7 @@ void output_headers(        int do_httpheaders,     /* 1 = output HTTP headers
                http_datestring(httpTomorow, sizeof httpTomorow, 
                                time(NULL) + 60 * 60 * 24 * 2);
 
-               wprintf("Pragma: public\r\n"
+               hprintf("Pragma: public\r\n"
                        "Cache-Control: max-age=3600, must-revalidate\r\n"
                        "Last-modified: %s\r\n"
                        "Expires: %s\r\n",
@@ -658,7 +679,7 @@ void output_headers(        int do_httpheaders,     /* 1 = output HTTP headers
                );
        }
        else {
-               wprintf("Pragma: no-cache\r\n"
+               hprintf("Pragma: no-cache\r\n"
                        "Cache-Control: no-store\r\n"
                        "Expires: -1\r\n"
                );
@@ -668,11 +689,11 @@ void output_headers(      int do_httpheaders,     /* 1 = output HTTP headers
                        WC->wc_password, WC->wc_roomname);
 
        if (unset_cookies) {
-               wprintf("Set-cookie: webcit=%s; path=/\r\n", unset);
+               hprintf("Set-cookie: webcit=%s; path=/\r\n", unset);
        } else {
-               wprintf("Set-cookie: webcit=%s; path=/\r\n", cookie);
+               hprintf("Set-cookie: webcit=%s; path=/\r\n", cookie);
                if (server_cookie != NULL) {
-                       wprintf("%s\n", server_cookie);
+                       hprintf("%s\n", server_cookie);
                }
        }
 
@@ -728,13 +749,14 @@ void output_headers(      int do_httpheaders,     /* 1 = output HTTP headers
  * Generic function to do an HTTP redirect.  Easy and fun.
  */
 void http_redirect(const char *whichpage) {
-       wprintf("HTTP/1.1 302 Moved Temporarily\n");
-       wprintf("Location: %s\r\n", whichpage);
-       wprintf("URI: %s\r\n", whichpage);
-       wprintf("Content-type: text/html; charset=utf-8\r\n\r\n");
+       hprintf("HTTP/1.1 302 Moved Temporarily\n");
+       hprintf("Location: %s\r\n", whichpage);
+       hprintf("URI: %s\r\n", whichpage);
+       hprintf("Content-type: text/html; charset=utf-8\r\n");
        wprintf("<html><body>");
        wprintf("Go <a href=\"%s\">here</A>.", whichpage);
        wprintf("</body></html>\n");
+       end_burst();
 }
 
 
@@ -742,48 +764,20 @@ void http_redirect(const char *whichpage) {
 /*
  * Output a piece of content to the web browser using conformant HTTP and MIME semantics
  */
-void http_transmit_thing(char *thing, size_t length, const char *content_type,
+void http_transmit_thing(StrBuf *thing, const char *content_type,
                         int is_static) {
 
        output_headers(0, 0, 0, 0, 0, is_static);
 
-       wprintf("Content-type: %s\r\n"
+       hprintf("Content-type: %s\r\n"
                "Server: %s\r\n"
                "Connection: close\r\n",
                content_type,
                PACKAGE_STRING);
 
-#ifdef HAVE_ZLIB
-       /* If we can send the data out compressed, please do so. */
-       if (WC->gzip_ok) {
-               char *compressed_data = NULL;
-               size_t compressed_len;
-
-               compressed_len =  ((length * 101) / 100) + 100;
-               compressed_data = malloc(compressed_len);
-
-               if (compress_gzip((Bytef *) compressed_data,
-                                 &compressed_len,
-                                 (Bytef *) thing,
-                                 (uLongf) length, Z_BEST_SPEED) == Z_OK) {
-                       wprintf("Content-encoding: gzip\r\n"
-                               "Content-length: %ld\r\n"
-                               "\r\n",
-                               (long) compressed_len
-                       );
-                       client_write(compressed_data, (size_t)compressed_len);
-                       free(compressed_data);
-                       return;
-               }
-       }
-#endif
-
-       /* No compression ... just send it out as-is */
-       wprintf("Content-length: %ld\r\n"
-               "\r\n",
-               (long) length
-       );
-       client_write(thing, (size_t)length);
+       WC->WBuf = thing;
+       end_burst();
+       WC->WBuf = NULL;
 }
 
 /*
@@ -826,60 +820,60 @@ void print_menu_box(char* Title, char *Class, int nLines, ...)
  */
 void output_static(char *what)
 {
-       FILE *fp;
+       int fd;
        struct stat statbuf;
        off_t bytes;
        off_t count = 0;
-       size_t res;
-       char *bigbuffer;
+       StrBuf *Buf;
        const char *content_type;
        int len;
+       const char *Err;
 
-       fp = fopen(what, "rb");
-       if (fp == NULL) {
+       fd = open(what, O_RDONLY);
+       if (fd <= 0) {
                lprintf(9, "output_static('%s')  -- NOT FOUND --\n", what);
-               wprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
-               wprintf("Content-Type: text/plain\r\n");
-               wprintf("\r\n");
+               hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
+               hprintf("Content-Type: text/plain\r\n");
                wprintf("Cannot open %s: %s\r\n", what, strerror(errno));
+               end_burst();
        } else {
                len = strlen (what);
                content_type = GuessMimeByFilename(what, len);
 
-               if (fstat(fileno(fp), &statbuf) == -1) {
+               if (fstat(fd, &statbuf) == -1) {
                        lprintf(9, "output_static('%s')  -- FSTAT FAILED --\n", what);
-                       wprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
-                       wprintf("Content-Type: text/plain\r\n");
-                       wprintf("\r\n");
+                       hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
+                       hprintf("Content-Type: text/plain\r\n");
                        wprintf("Cannot fstat %s: %s\n", what, strerror(errno));
+                       end_burst();
                        return;
                }
 
                count = 0;
                bytes = statbuf.st_size;
-               if ((bigbuffer = malloc(bytes + 2)) == NULL) {
+               Buf = NewStrBufPlain(NULL, bytes + 2);
+               if (Buf == NULL) {
                        lprintf(9, "output_static('%s')  -- MALLOC FAILED (%s) --\n", what, strerror(errno));
-                       wprintf("HTTP/1.1 500 internal server error\r\n");
-                       wprintf("Content-Type: text/plain\r\n");
-                       wprintf("\r\n");
+                       hprintf("HTTP/1.1 500 internal server error\r\n");
+                       hprintf("Content-Type: text/plain\r\n");
+                       end_burst();
                        return;
                }
-               while (count < bytes) {
-                       if ((res = fread(bigbuffer + count, 1, bytes - count, fp)) == 0) {
-                               lprintf(9, "output_static('%s')  -- FREAD FAILED (%s) %zu bytes of %zu --\n", what, strerror(errno), bytes - count, bytes);
-                               wprintf("HTTP/1.1 500 internal server error \r\n");
-                               wprintf("Content-Type: text/plain\r\n");
-                               wprintf("\r\n");
+///            StrBufAppendBuf(Buf, WC->WBuf, 0);
+               if (StrBufReadBLOB(Buf, &fd, 1, bytes, &Err) < 0)
+               {
+                       lprintf(9, "output_static('%s')  -- FREAD FAILED (%s) --\n", what, strerror(errno));
+                               hprintf("HTTP/1.1 500 internal server error \r\n");
+                               hprintf("Content-Type: text/plain\r\n");
+                               end_burst();
                                return;
-                       }
-                       count += res;
                }
 
-               fclose(fp);
 
+               close(fd);
                lprintf(9, "output_static('%s')  %s\n", what, content_type);
-               http_transmit_thing(bigbuffer, (size_t)bytes, content_type, 1);
-               free(bigbuffer);
+               http_transmit_thing(Buf, content_type, 1);
+               FreeStrBuf(&Buf);
        }
        if (yesbstr("force_close_session")) {
                end_webcit_session();
@@ -896,6 +890,7 @@ void output_image()
        char *xferbuf = NULL;
        off_t bytes;
        const char *MimeType;
+       StrBuf *Buf;
 
        serv_printf("OIMG %s|%s", bstr("name"), bstr("parm"));
        serv_getln(buf, sizeof buf);
@@ -904,23 +899,22 @@ void output_image()
                xferbuf = malloc(bytes + 2);
 
                /** Read it from the server */
-               read_server_binary(xferbuf, bytes);
+               
+               Buf = read_server_binary(bytes);
                serv_puts("CLOS");
                serv_getln(buf, sizeof buf);
 
-               MimeType = GuessMimeType (xferbuf, bytes);
+               MimeType = GuessMimeType (ChrPtr(Buf), StrLength(Buf));
                /** Write it to the browser */
                if (!IsEmptyStr(MimeType))
                {
-                       http_transmit_thing(xferbuf, 
-                                           (size_t)bytes, 
+                       http_transmit_thing(Buf, 
                                            MimeType, 
                                            0);
-                       free(xferbuf);
+                       FreeStrBuf(&Buf);
                        return;
                }
                /* hm... unknown mimetype? fallback to blank gif */
-               free(xferbuf);
        } 
 
        
@@ -942,9 +936,10 @@ void display_vcard_photo_img(void)
        char *vcard;
        struct vCard *v;
        char *xferbuf;
-    char *photosrc;
+       char *photosrc;
        int decoded;
        const char *contentType;
+       StrBuf *Buf;
 
        msgnum = StrTol(WC->UrlFragment1);
        
@@ -963,10 +958,12 @@ void display_vcard_photo_img(void)
                photosrc,
                strlen(photosrc));
        contentType = GuessMimeType(xferbuf, decoded);
-       http_transmit_thing(xferbuf, decoded, contentType, 0);
+       Buf = _NewConstStrBuf(xferbuf, decoded);
+       http_transmit_thing(Buf, contentType, 0);
        free(v);
        free(photosrc);
        free(xferbuf);
+       FreeStrBuf(&Buf);
 }
 
 /*
@@ -987,6 +984,7 @@ void mimepart(const char *msgnum, const char *partnum, int force_download)
        serv_printf("OPNA %s|%s", msgnum, partnum);
        serv_getln(buf, sizeof buf);
        if (buf[0] == '2') {
+               StrBuf *Buf;
                bytes = extract_long(&buf[4], 0);
                content = malloc(bytes + 2);
                if (force_download) {
@@ -996,17 +994,18 @@ void mimepart(const char *msgnum, const char *partnum, int force_download)
                        extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
                }
                output_headers(0, 0, 0, 0, 0, 0);
-               read_server_binary(content, bytes);
+
+               Buf = read_server_binary(bytes);
                serv_puts("CLOS");
                serv_getln(buf, sizeof buf);
-               http_transmit_thing(content, bytes, content_type, 0);
-               free(content);
+               http_transmit_thing(Buf, content_type, 0);
+               FreeStrBuf(&Buf);
        } else {
-               wprintf("HTTP/1.1 404 %s\n", &buf[4]);
+               hprintf("HTTP/1.1 404 %s\n", &buf[4]);
                output_headers(0, 0, 0, 0, 0, 0);
-               wprintf("Content-Type: text/plain\r\n");
-               wprintf("\r\n");
+               hprintf("Content-Type: text/plain\r\n");
                wprintf(_("An error occurred while retrieving this part: %s\n"), &buf[4]);
+               end_burst();
        }
 
 }
@@ -1050,7 +1049,7 @@ char *load_mimepart(long msgnum, char *partnum)
  */
 void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext)
 {
-       wprintf("HTTP/1.1 200 OK\n");
+       hprintf("HTTP/1.1 200 OK\n");
        output_headers(1, 1, 2, 0, 0, 0);
        wprintf("<div id=\"banner\">\n");
        wprintf("<table width=100%% border=0 bgcolor=\"#%s\"><tr><td>", titlebarcolor);
@@ -1138,15 +1137,16 @@ void display_success(char *successmessage)
  */
 void authorization_required(const char *message)
 {
-       wprintf("HTTP/1.1 401 Authorization Required\r\n");
-       wprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", serv_info.serv_humannode);
-       wprintf("Content-Type: text/html\r\n\r\n");
+       hprintf("HTTP/1.1 401 Authorization Required\r\n");
+       hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", serv_info.serv_humannode);
+       hprintf("Content-Type: text/html\r\n");
        wprintf("<h1>");
        wprintf(_("Authorization Required"));
        wprintf("</h1>\r\n");
        wprintf(_("The resource you requested requires a valid username and password. "
                "You could not be logged in: %s\n"), message);
        wDumpContent(0);
+       
 }
 
 /*
@@ -1215,7 +1215,7 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp,
 void begin_ajax_response(void) {
         output_headers(0, 0, 0, 0, 0, 0);
 
-        wprintf("Content-type: text/html; charset=UTF-8\r\n"
+        hprintf("Content-type: text/html; charset=UTF-8\r\n"
                 "Server: %s\r\n"
                 "Connection: close\r\n"
                 "Pragma: no-cache\r\n"
@@ -1230,7 +1230,7 @@ void begin_ajax_response(void) {
  * print ajax response footer 
  */
 void end_ajax_response(void) {
-        wprintf("\r\n");
+        ///hprintf("\r\n");///// todo: is this right?
         wDumpContent(0);
 }
 
@@ -1367,8 +1367,8 @@ void session_loop(struct httprequest *req)
        char c_httpauth_user[SIZ];
        char c_httpauth_pass[SIZ];
        char cookie[SIZ];
-       struct wcsession *WCC = WC;
-
+       struct wcsession *WCC;
+       
        safestrncpy(c_username, "", sizeof c_username);
        safestrncpy(c_password, "", sizeof c_password);
        safestrncpy(c_roomname, "", sizeof c_roomname);
@@ -1377,6 +1377,10 @@ void session_loop(struct httprequest *req)
        safestrncpy(c_httpauth_pass, DEFAULT_HTTPAUTH_PASS, sizeof c_httpauth_pass);
        strcpy(browser_host, "");
 
+       WCC= WC;
+       if (WCC->HBuf == NULL)
+               WCC->HBuf = NewStrBuf();
+       FlushStrBuf(WCC->HBuf);
        WCC->upload_length = 0;
        WCC->upload = NULL;
        WCC->is_mobile = 0;
@@ -1507,10 +1511,10 @@ void session_loop(struct httprequest *req)
 
        /* If it's a "force 404" situation then display the error and bail. */
        if (!strcmp(action, "404")) {
-               wprintf("HTTP/1.1 404 Not found\r\n");
-               wprintf("Content-Type: text/plain\r\n");
-               wprintf("\r\n");
+               hprintf("HTTP/1.1 404 Not found\r\n");
+               hprintf("Content-Type: text/plain\r\n");
                wprintf("Not found\r\n");
+               end_burst();
                goto SKIP_ALL_THIS_CRAP;
        }
 
@@ -1543,10 +1547,10 @@ void session_loop(struct httprequest *req)
                else 
                {
                        lprintf(9, "Suspicious request. Ignoring.");
-                       wprintf("HTTP/1.1 404 Security check failed\r\n");
-                       wprintf("Content-Type: text/plain\r\n");
-                       wprintf("\r\n");
+                       hprintf("HTTP/1.1 404 Security check failed\r\n");
+                       hprintf("Content-Type: text/plain\r\n");
                        wprintf("You have sent a malformed or invalid request.\r\n");
+                       end_burst();
                }
                goto SKIP_ALL_THIS_CRAP;        /* Don't try to connect */
        }
@@ -1557,10 +1561,10 @@ void session_loop(struct httprequest *req)
                        bstr("nonce"), WCC->nonce);
                if (ibstr("nonce") != WCC->nonce) {
                        lprintf(9, "Ignoring request with mismatched nonce.\n");
-                       wprintf("HTTP/1.1 404 Security check failed\r\n");
-                       wprintf("Content-Type: text/plain\r\n");
-                       wprintf("\r\n");
+                       hprintf("HTTP/1.1 404 Security check failed\r\n");
+                       hprintf("Content-Type: text/plain\r\n");
                        wprintf("Security check failed.\r\n");
+                       end_burst();
                        goto SKIP_ALL_THIS_CRAP;
                }
        }
index b8353a90b7a1aef7cc67969c5e384f3cae327a29..d57b838086793f059dfe913d33d458779b50a83f 100644 (file)
@@ -410,9 +410,6 @@ struct wcsession {
        int ctdl_pid;                           /**< Session ID on the Citadel server */
        char httpauth_user[256];                /**< only for GroupDAV sessions */
        char httpauth_pass[256];                /**< only for GroupDAV sessions */
-       size_t burst_len;                       /** <??? todo */
-       size_t burst_alloc;                     /** <??? todo */
-       char *burst;                            /** <??? todo */
        int gzip_ok;                            /**< Nonzero if Accept-encoding: gzip */
        int is_mailbox;                         /**< the current room is a private mailbox */
        struct folder *cache_fold;              /**< cache the iconbar room list */
@@ -428,6 +425,8 @@ struct wcsession {
        int time_format_cache;                  /**< which timeformat does our user like? */
        StrBuf *UrlFragment1;                   /**< first urlfragment, if NEED_URL is specified by the handler*/
        StrBuf *UrlFragment2;                   /**< second urlfragment, if NEED_URL is specified by the handler*/
+       StrBuf *WBuf;                           /**< Our output buffer */
+       StrBuf *HBuf;                           /**< Our HeaderBuffer */
 };
 
 /** values for WC->current_iconbar */
@@ -543,6 +542,7 @@ void output_headers(    int do_httpheaders,
                        int suppress_check,
                        int cache);
 void wprintf(const char *format,...)__attribute__((__format__(__printf__,1,2)));
+void hprintf(const char *format,...)__attribute__((__format__(__printf__,1,2)));
 void output_static(char *what);
 void display_mime_icon(void);
 void print_menu_box(char* Title, char *Class, int nLines, ...);
@@ -703,13 +703,13 @@ void initialize_locales(void);
 
 extern char *months[];
 extern char *days[];
-void read_server_binary(char *buffer, size_t total_len);
-char *read_server_text(void);
+StrBuf *read_server_binary(size_t total_len);
+int StrBuf_ServGetBLOB(StrBuf *buf, long BlobSize);
+StrBuf *read_server_text(long *nLines);
 int goto_config_room(void);
 long locate_user_vcard(char *username, long usernum);
 void sleeeeeeeeeep(int);
-void http_transmit_thing(char *thing, size_t length, const char *content_type,
-                        int is_static);
+void http_transmit_thing(StrBuf *thing, const char *content_type, int is_static);
 long unescape_input(char *buf);
 void do_selected_iconbar(void);
 int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
@@ -752,7 +752,7 @@ void ssl_lock(int mode, int n, const char *file, int line);
 int starttls(int sock);
 extern SSL_CTX *ssl_ctx;  
 int client_read_ssl(char *buf, int bytes, int timeout);
-void client_write_ssl(char *buf, int nbytes);
+void client_write_ssl(const char *buf, int nbytes);
 #endif
 
 #ifdef HAVE_ZLIB
@@ -764,7 +764,7 @@ int ZEXPORT compress_gzip(Bytef * dest, size_t * destLen,
 void utf8ify_rfc822_string(char *buf);
 
 void begin_burst(void);
-void end_burst(void);
+long end_burst(void);
 
 extern char *hourname[];       /**< Names of hours (12am, 1am, etc.) */
 
index 4f360512725148b14b284636bbd78dbf11e0e8bf..99cdfc2569344c7523fa0e3fa9423e9d83cff818 100644 (file)
@@ -238,210 +238,126 @@ int client_read_to(int sock, char *buf, int bytes, int timeout)
 }
 
 /*
- * write data to the client
+ * \brief Begin buffering HTTP output so we can transmit it all in one write operation later.
  */
-ssize_t client_write(const void *buf, size_t count)
+void begin_burst(void)
+{
+       WC->WBuf = NewStrBufPlain(NULL, 32768);
+}
+
+
+/*
+ * \brief Finish buffering HTTP output.  [Compress using zlib and] output with a Content-Length: header.
+ */
+long end_burst(void)
 {
-        char *newptr;
-        size_t newalloc;
-        size_t bytesWritten = 0;
-        ssize_t res;
+       struct wcsession *WCC = WC;
+        const char *ptr, *eptr;
+        long count;
+       ssize_t res;
         fd_set wset;
         int fdflags;
 
-       if (WC->burst != NULL) {
-               if ((WC->burst_len + count) >= WC->burst_alloc) {
-                       newalloc = (WC->burst_alloc * 2);
-                       if ((WC->burst_len + count) >= newalloc) {
-                               newalloc += count;
-                       }
-                       newptr = realloc(WC->burst, newalloc);
-                       if (newptr != NULL) {
-                               WC->burst = newptr;
-                               WC->burst_alloc = newalloc;
-                       }
-               }
-               if ((WC->burst_len + count) < WC->burst_alloc) {
-                       memcpy(&WC->burst[WC->burst_len], buf, count);
-                       WC->burst_len += count;
-                       return (count);
-               }
-               else {
-                       return(-1);
-               }
+#ifdef HAVE_ZLIB
+       /* Perform gzip compression, if enabled and supported by client */
+       if ((WCC->gzip_ok) && CompressBuffer(WCC->WBuf))
+       {
+               hprintf("Content-encoding: gzip\r\n");
        }
+#endif /* HAVE_ZLIB */
+
+       hprintf("Content-length: %d\r\n\r\n", StrLength(WCC->WBuf));
+
+       ptr = ChrPtr(WCC->HBuf);
+       count = StrLength(WCC->HBuf);
+       eptr = ptr + count;
+
 #ifdef HAVE_OPENSSL
        if (is_https) {
-               client_write_ssl((char *) buf, count);
+               client_write_ssl(ptr, StrLength(WCC->HBuf));
                return (count);
        }
 #endif
+
+       
 #ifdef HTTP_TRACING
+       
        write(2, "\033[34m", 5);
-       write(2, buf, count);
+       write(2, ptr, StrLength(WCC->WBuf));
        write(2, "\033[30m", 5);
 #endif
        fdflags = fcntl(WC->http_sock, F_GETFL);
 
-        while (bytesWritten < count) {
+        while (ptr < eptr) {
                 if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
                         FD_ZERO(&wset);
-                        FD_SET(WC->http_sock, &wset);
-                        if (select(WC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+                        FD_SET(WCC->http_sock, &wset);
+                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
                                 lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
                                 return -1;
                         }
                 }
 
-                if ((res = write(WC->http_sock, (char*)buf + bytesWritten,
-                  count - bytesWritten)) == -1) {
+                if ((res = write(WCC->http_sock, 
+                                ptr,
+                                count)) == -1) {
                         lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
                         return res;
                 }
-                bytesWritten += res;
+                count -= res;
+               ptr += res;
         }
 
-       return bytesWritten;
-}
-
-/*
- * Begin buffering HTTP output so we can transmit it all in one write operation later.
- *
- * We do this in userspace instead of using TCP_CORK for two reasons:
- *  1. We need to calculate the Content-length: header
- *  2. We may want to compress the data before sending it
- *
- */
-void begin_burst(void)
-{
-       if (WC->burst != NULL) {
-               free(WC->burst);
-               WC->burst = NULL;
-       }
-       WC->burst_len = 0;
-       WC->burst_alloc = 32768;
-       WC->burst = malloc(WC->burst_alloc);
-}
-
+       ptr = ChrPtr(WCC->WBuf);
+       count = StrLength(WCC->WBuf);
+       eptr = ptr + count;
 
-/*
- * uses the same calling syntax as compress2(), but it
- * creates a stream compatible with HTTP "Content-encoding: gzip"
- */
-#ifdef HAVE_ZLIB
-#define DEF_MEM_LEVEL 8
-#define OS_CODE 0x03   /* unix */
-int ZEXPORT compress_gzip(Bytef * dest,         /* compressed buffer */
-                         size_t * destLen,     /* length of the compresed data */
-                         const Bytef * source, /* source to encode */
-                         uLong sourceLen,      /* length of source to encode */
-                         int level)            /* compression level */
-{
-       const int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
-
-       /* write gzip header */
-       snprintf((char *) dest, *destLen, 
-                "%c%c%c%c%c%c%c%c%c%c",
-                gz_magic[0], gz_magic[1], Z_DEFLATED,
-                0 /*flags */ , 0, 0, 0, 0 /*time */ , 0 /* xflags */ ,
-                OS_CODE);
-
-       /* normal deflate */
-       z_stream stream;
-       int err;
-       stream.next_in = (Bytef *) source;
-       stream.avail_in = (uInt) sourceLen;
-       stream.next_out = dest + 10L;   // after header
-       stream.avail_out = (uInt) * destLen;
-       if ((uLong) stream.avail_out != *destLen)
-               return Z_BUF_ERROR;
-
-       stream.zalloc = (alloc_func) 0;
-       stream.zfree = (free_func) 0;
-       stream.opaque = (voidpf) 0;
-
-       err = deflateInit2(&stream, level, Z_DEFLATED, -MAX_WBITS,
-                          DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-       if (err != Z_OK)
-               return err;
-
-       err = deflate(&stream, Z_FINISH);
-       if (err != Z_STREAM_END) {
-               deflateEnd(&stream);
-               return err == Z_OK ? Z_BUF_ERROR : err;
-       }
-       *destLen = stream.total_out + 10L;
-
-       /* write CRC and Length */
-       uLong crc = crc32(0L, source, sourceLen);
-       int n;
-       for (n = 0; n < 4; ++n, ++*destLen) {
-               dest[*destLen] = (int) (crc & 0xff);
-               crc >>= 8;
-       }
-       uLong len = stream.total_in;
-       for (n = 0; n < 4; ++n, ++*destLen) {
-               dest[*destLen] = (int) (len & 0xff);
-               len >>= 8;
+#ifdef HAVE_OPENSSL
+       if (is_https) {
+               client_write_ssl(ptr, StrLength(WCC->HBuf));
+               return (count);
        }
-       err = deflateEnd(&stream);
-       return err;
-}
 #endif
 
-/*
- * Finish buffering HTTP output.  [Compress using zlib and] output with a Content-Length: header.
- */
-void end_burst(void)
-{
-       size_t the_len;
-       char *the_data;
-
-       if (WC->burst == NULL)
-               return;
-
-       the_len = WC->burst_len;
-       the_data = WC->burst;
+#ifdef HTTP_TRACING
+       
+       write(2, "\033[34m", 5);
+       write(2, ptr, StrLength(WCC->WBuf));
+       write(2, "\033[30m", 5);
+#endif
 
-       WC->burst_len = 0;
-       WC->burst_alloc = 0;
-       WC->burst = NULL;
+        while (ptr < eptr) {
+                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+                        FD_ZERO(&wset);
+                        FD_SET(WCC->http_sock, &wset);
+                        if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+                                lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
+                                return -1;
+                        }
+                }
 
-#ifdef HAVE_ZLIB
-       /* Perform gzip compression, if enabled and supported by client */
-       if (WC->gzip_ok) {
-               char *compressed_data = NULL;
-               size_t compressed_len;
-
-               compressed_len = ((the_len * 101) / 100) + 100;
-               compressed_data = malloc(compressed_len);
-
-               if (compress_gzip((Bytef *) compressed_data,
-                                 &compressed_len,
-                                 (Bytef *) the_data,
-                                 (uLongf) the_len, Z_BEST_SPEED) == Z_OK) {
-                       wprintf("Content-encoding: gzip\r\n");
-                       free(the_data);
-                       the_data = compressed_data;
-                       the_len = compressed_len;
-               } else {
-                       free(compressed_data);
-               }
-       }
-#endif /* HAVE_ZLIB */
+                if ((res = write(WCC->http_sock, 
+                                ptr,
+                                count)) == -1) {
+                        lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
+                        return res;
+                }
+                count -= res;
+               ptr += res;
+        }
 
-       wprintf("Content-length: %d\r\n\r\n", the_len);
-       client_write(the_data, the_len);
-       free(the_data);
-       return;
+       return StrLength(WCC->WBuf);
 }
 
 
 
 /*
- * Read data from the client socket with default timeout.
+ * \brief Read data from the client socket with default timeout.
  * (This is implemented in terms of client_read_to() and could be
  * justifiably moved out of sysdep.c)
+ * \param sock the socket fd to read from
+ * \param buf the buffer to write to
+ * \param bytes Number of bytes to read
  */
 int client_read(int sock, char *buf, int bytes)
 {
@@ -450,9 +366,13 @@ int client_read(int sock, char *buf, int bytes)
 
 
 /*
- * Get a LF-terminated line of text from the client.
+ * \brief Get a LF-terminated line of text from the client.
  * (This is implemented in terms of client_read() and could be
  * justifiably moved out of sysdep.c)
+ * \param sock socket fd to get client line from
+ * \param buf buffer to write read data to
+ * \param bufsiz how many bytes to read
+ * \return  number of bytes read???
  */
 int client_getln(int sock, char *buf, int bufsiz)
 {
@@ -485,8 +405,8 @@ int client_getln(int sock, char *buf, int bufsiz)
 }
 
 /*
- * Shut us down the regular way.
- * signum is the signal we want to forward
+ * \brief Shut us down the regular way.
+ * \param signum the signal we want to forward
  */
 pid_t current_child;
 void graceful_shutdown_watcher(int signum) {
@@ -497,8 +417,8 @@ void graceful_shutdown_watcher(int signum) {
 }
 
 /*
- * shut us down the regular way.
- * signum is the signal we want to forward
+ * \brief shut us down the regular way.
+ * \param signum the signal we want to forward
  */
 pid_t current_child;
 void graceful_shutdown(int signum) {
@@ -518,6 +438,12 @@ void graceful_shutdown(int signum) {
 }
 
 
+/*
+ * \brief      Start running as a daemon.  
+ *
+ * param       do_close_stdio          Only close stdio if set.
+ */
+
 /*
  * Start running as a daemon.
  */
@@ -619,12 +545,12 @@ void start_daemon(char *pid_file)
 }
 
 /*
- * Spawn an additional worker thread into the pool.
+ * \brief      Spawn an additional worker thread into the pool.
  */
 void spawn_another_worker_thread()
 {
-       pthread_t SessThread;   /* Thread descriptor */
-       pthread_attr_t attr;    /* Thread attributes */
+       pthread_t SessThread;   /*< Thread descriptor */
+       pthread_attr_t attr;    /*< Thread attributes */
        int ret;
 
        lprintf(3, "Creating a new thread\n");
@@ -657,15 +583,16 @@ void spawn_another_worker_thread()
 
 const char foobuf[32];
 const char *nix(void *vptr) {snprintf(foobuf, 32, "%0x", (long) vptr); return foobuf;}
-
 /*
- * Main entry point for server program.
+ * \brief Here's where it all begins.
+ * \param argc number of commandline args
+ * \param argv the commandline arguments
  */
 int main(int argc, char **argv)
 {
-       pthread_t SessThread;           /* Thread descriptor */
-       pthread_attr_t attr;            /* Thread attributes */
-       int a, i;                       /* General-purpose variables */
+       pthread_t SessThread;   /*< Thread descriptor */
+       pthread_attr_t attr;    /*< Thread attributes */
+       int a, i;                       /*< General-purpose variables */
        char tracefile[PATH_MAX];
        char ip_addr[256]="0.0.0.0";
        char dirbuffer[PATH_MAX]="";
@@ -1051,8 +978,11 @@ void worker_entry(void)
 }
 
 /*
- * print log messages 
+ * \brief print log messages 
  * logs to stderr if loglevel is lower than the verbosity set at startup
+ * \param loglevel level of the message
+ * \param format the printf like format string
+ * \param ... the strings to put into format
  */
 int lprintf(int loglevel, const char *format, ...)
 {
@@ -1069,7 +999,7 @@ int lprintf(int loglevel, const char *format, ...)
 
 
 /*
- * print the actual stack frame.
+ * \brief print the actual stack frame.
  */
 void wc_backtrace(void)
 {
@@ -1091,3 +1021,4 @@ void wc_backtrace(void)
 #endif
 }
 
+/*@}*/
index 47bb4f860dc2009a946cbbd454dcdd2d25ddcc71..f190ddd94208404ff3d74ce891f0c2312b87a5ca 100644 (file)
@@ -8,6 +8,5 @@ extern char socket_dir[PATH_MAX];
 int client_getln(int sock, char *buf, int bufsiz);
 int client_read(int sock, char *buf, int bytes);
 int client_read_to(int sock, char *buf, int bytes, int timeout);
-ssize_t client_write(const void *buf, size_t count);
 int lprintf(int loglevel, const char *format, ...);
 void wc_backtrace(void);