* evade double calls to output_headers
[citadel.git] / webcit / webcit.c
index 8b8450f1dde98273d67ec1b2da0ae65e617c4706..d7beab0c3bd9ca85d17ca3082f3fe0b96740f667 100644 (file)
@@ -283,7 +283,7 @@ void print_menu_box(char* Title, char *Class, int nLines, ...)
 /*
  * dump out static pages from disk
  */
-void output_static(char *what)
+void output_static(const char *what)
 {
        int fd;
        struct stat statbuf;
@@ -346,7 +346,7 @@ void output_static(char *what)
  * titlebarmsg         text to display in the title bar
  * messagetext         body of the box
  */
-void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext)
+void convenience_page(const char *titlebarcolor, const char *titlebarmsg, const char *messagetext)
 {
        hprintf("HTTP/1.1 200 OK\n");
        output_headers(1, 1, 2, 0, 0, 0);
@@ -378,7 +378,6 @@ void url_do_template(void) {
        const StrBuf *MimeType;
        const StrBuf *Tmpl = sbstr("template");
        begin_burst();
-       output_headers(0, 0, 0, 0, 1, 0);
        MimeType = DoTemplate(SKEY(Tmpl), NULL, &NoCtx);
        http_transmit_thing(ChrPtr(MimeType), 0);
 }
@@ -441,44 +440,54 @@ void end_ajax_response(void) {
  */
 void ajax_servcmd(void)
 {
-       char buf[1024];
-       char gcontent[1024];
+       wcsession *WCC = WC;
+       int Done = 0;
+       StrBuf *Buf;
        char *junk;
        size_t len;
 
        begin_ajax_response();
-
-       serv_printf("%s", bstr("g_cmd"));
-       serv_getln(buf, sizeof buf);
-       wprintf("%s\n", buf);
-
-       if (buf[0] == '8') {
-               serv_printf("\n\n000");
-       }
-       if ((buf[0] == '1') || (buf[0] == '8')) {
-               while (serv_getln(gcontent, sizeof gcontent), strcmp(gcontent, "000")) {
-                       wprintf("%s\n", gcontent);
+       Buf = NewStrBuf();
+       serv_puts(bstr("g_cmd"));
+       StrBuf_ServGetln(Buf);
+       StrBufAppendBuf(WCC->WBuf, Buf, 0);
+       StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
+       
+       switch (GetServerStatus(Buf, NULL)) {
+       case 8:
+               serv_puts("\n\n000");
+               if ( (StrLength(Buf)==3) && 
+                    !strcmp(ChrPtr(Buf), "000")) {
+                       StrBufAppendBufPlain(WCC->WBuf, HKEY("\000"), 0);
+                       break;
                }
-               wprintf("000");
-       }
-       if (buf[0] == '4') {
+       case 1:
+               while (!Done) {
+                       StrBuf_ServGetlnBuffered(Buf);
+                       if ( (StrLength(Buf)==3) && 
+                            !strcmp(ChrPtr(Buf), "000")) {
+                               Done = 1;
+                       }
+                       StrBufAppendBuf(WCC->WBuf, Buf, 0);
+                       StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
+               }
+               break;
+       case 4:
                text_to_server(bstr("g_input"));
                serv_puts("000");
-       }
-       if (buf[0] == '6') {
-               len = atol(&buf[4]);
-               junk = malloc(len);
-               serv_read(junk, len);
-               free(junk);
-       }
-       if (buf[0] == '7') {
-               len = atol(&buf[4]);
+               break;
+       case 6:
+               len = atol(&ChrPtr(Buf)[4]);
+               StrBuf_ServGetBLOBBuffered(Buf, len);
+               break;
+       case 7:
+               len = atol(&ChrPtr(Buf)[4]);
                junk = malloc(len);
                memset(junk, 0, len);
                serv_write(junk, len);
                free(junk);
        }
-
+       
        end_ajax_response();
        
        /*
@@ -488,8 +497,9 @@ void ajax_servcmd(void)
         * that page_popup() doesn't try to open it a second time.
         */
        if (!strncasecmp(bstr("g_cmd"), "GEXP", 4)) {
-               WC->last_pager_check = time(NULL);
+               WCC->last_pager_check = time(NULL);
        }
+       FreeStrBuf(&Buf);
 }
 
 
@@ -540,7 +550,11 @@ int is_mobile_ua(char *user_agent) {
 /*
  * Entry point for WebCit transaction
  */
-void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method, StrBuf *ReadBuf)
+void session_loop(HashList *HTTPHeaders, 
+                 StrBuf *ReqLine, 
+                 StrBuf *request_method, 
+                 StrBuf *ReadBuf,
+                 const char **Pos)
 {
        StrBuf *Buf;
        const char *pch, *pchs, *pche;
@@ -564,6 +578,8 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
        int len = 0;
        void *vHandler;
        WebcitHandler *Handler;
+       struct timeval tx_start;
+       struct timeval tx_finish;
 
        /*
         * We stuff these with the values coming from the client cookies,
@@ -576,6 +592,8 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
        StrBuf *c_httpauth_user;
        StrBuf *c_httpauth_pass;
        wcsession *WCC;
+
+       gettimeofday(&tx_start, NULL);          /* start a stopwatch for performance timing */
        
        Buf = NewStrBuf();
        c_username = NewStrBuf();
@@ -608,7 +626,6 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                index[a] = arg[a-1];
                sizes[a] = sizeof arg[a-1];
        }
-/*///  index[9] = &foo; todo */
        nBackDots = 0;
        nEmpty = 0;
        for ( a = 0; a < 9; ++a)
@@ -691,7 +708,11 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                body_start = StrLength(content);
 
                /** Read the entire input data at once. */
-               client_read(&WCC->http_sock, content, ReadBuf, ContentLength + body_start);
+               client_read_to(&WCC->http_sock, 
+                              content, 
+                              ReadBuf, Pos,
+                              ContentLength,
+                              SLEEPING);
 
                if (!strncasecmp(ChrPtr(ContentType), "application/x-www-form-urlencoded", 33)) {
                        StrBufCutLeft(content, body_start);
@@ -789,6 +810,8 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
         * connection now.
         */
        if (!WCC->connected) {
+               if (WCC->ReadBuf == NULL)
+                       WCC->ReadBuf = NewStrBuf();
                if (!strcasecmp(ctdlhost, "uds")) {
                        /* unix domain socket */
                        snprintf(buf, SIZ, "%s/citadel.socket", ctdlport);
@@ -801,6 +824,7 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
 
                if (WCC->serv_sock < 0) {
                        do_logout();
+                       FreeStrBuf(&WCC->ReadBuf);
                        goto SKIP_ALL_THIS_CRAP;
                }
                else {
@@ -829,8 +853,18 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                                }
                                locate_host(browser_host, WCC->http_sock);
                        }
-
-                       WCC->serv_info = get_serv_info(browser_host, user_agent);
+                       if (WCC->serv_info == NULL)
+                               WCC->serv_info = get_serv_info(browser_host, user_agent);
+                       if (WCC->serv_info == NULL){
+                               begin_burst();
+                               wprintf(_("Received unexpected answer from Citadel "
+                                         "server; bailing out."));
+                               hprintf("HTTP/1.1 200 OK\r\n");
+                               hprintf("Content-type: text/plain; charset=utf-8\r\n");
+                               end_burst();
+                               end_webcit_session();
+                               goto SKIP_ALL_THIS_CRAP;
+                       }
                        if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
                                begin_burst();
                                wprintf(_("You are connected to a Citadel "
@@ -843,13 +877,15 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                                                MINIMUM_CIT_VERSION / 100,
                                                MINIMUM_CIT_VERSION % 100
                                        );
+                               hprintf("HTTP/1.1 200 OK\r\n");
+                               hprintf("Content-type: text/plain; charset=utf-8\r\n");
                                end_burst();
                                end_webcit_session();
                                goto SKIP_ALL_THIS_CRAP;
                        }
                }
        }
-/*///////todo: restore language in this case */
+
        /*
         * Functions which can be performed without logging in
         */
@@ -951,12 +987,7 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                        serv_printf("PASS %s", ChrPtr(c_password));
                        StrBuf_ServGetln(Buf);
                        if (GetServerStatus(Buf, NULL) == 2) {
-                               StrBuf *Lang;
                                become_logged_in(c_username, c_password, Buf);
-                               if (get_preference("language", &Lang)) {
-                                       set_selected_language(ChrPtr(Lang));
-                                       go_selected_language();         /* set locale */
-                               }
                                get_preference("default_header_charset", &WCC->DefaultCharset);
                        }
                }
@@ -1002,9 +1033,12 @@ void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method
                                        WCC->UrlFragment2 = NewStrBuf();
                                if (WCC->UrlFragment3 == NULL)
                                        WCC->UrlFragment3 = NewStrBuf();
-                               StrBufPrintf(WCC->UrlFragment1, "%s", index[0]);
-                               StrBufPrintf(WCC->UrlFragment2, "%s", index[1]);
-                               StrBufPrintf(WCC->UrlFragment3, "%s", index[2]);
+                               if (WCC->UrlFragment4 == NULL)
+                                       WCC->UrlFragment4 = NewStrBuf();
+                               StrBufPlain(WCC->UrlFragment1, index[0], -1);
+                               StrBufPlain(WCC->UrlFragment2, index[1], -1);
+                               StrBufPlain(WCC->UrlFragment3, index[2], -1);
+                               StrBufPlain(WCC->UrlFragment4, index[3], -1);
                        }
                        if ((Handler->Flags & AJAX) != 0)
                                begin_ajax_response();
@@ -1045,6 +1079,14 @@ SKIP_ALL_THIS_CRAP:
        }
        FreeStrBuf(&WCC->trailing_javascript);
        WCC->http_host = NULL;
+
+       /* How long did this transaction take? */
+       gettimeofday(&tx_finish, NULL);
+       
+       lprintf(9, "Transaction completed in %ld.%06ld seconds.\n",
+               ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000,
+               ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000
+       );
 }