When we 503, do it in HTML
[citadel.git] / webcit / webcit.c
index 0396cd408ed6c021b91907b86c1887c7d597dcd1..8f51833deb32a180f9ebced1bc9ddc3177a9c016 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * This is the main transaction loop of the web service.  It maintains a
  * persistent session to the Citadel server, handling HTTP WebCit requests as
  * they arrive and presenting a user interface.
 StrBuf *csslocal = NULL;
 HashList *HandlerHash = NULL;
 
+void PutRequestLocalMem(void *Data, DeleteHashDataFunc DeleteIt)
+{
+        wcsession *WCC = WC;
+       int n;
+       
+       n = GetCount(WCC->Hdr->HTTPHeaders);
+       Put(WCC->Hdr->HTTPHeaders, IKEY(n), Data, DeleteIt);
+}
 
 void DeleteWebcitHandler(void *vHandler)
 {
@@ -48,11 +54,6 @@ void tmplput_HANDLER_DISPLAYNAME(StrBuf *Target, WCTemplputParams *TP)
                StrBufAppendTemplate(Target, TP, WCC->Hdr->HR.Handler->DisplayName, 0);
 }
 
-void tmplput_HOST_DISPLAYNAME(StrBuf *Target, WCTemplputParams *TP) 
-{
-       wcsession *WCC = WC;
-       StrBufAppendTemplate(Target, TP, WCC->Hdr->HR.http_host, 0);
-}
 
 /*
  * web-printing funcion. uses our vsnprintf wrapper
@@ -121,17 +122,17 @@ void wDumpContent(int print_standard_html_footer)
 /*
  * Output HTTP headers and leading HTML for a page
  */
-void output_headers(   int do_httpheaders,     /* 1 = output HTTP headers                          */
+void output_headers(   int do_httpheaders,     /* 1 = output HTTP headers                        */
                        int do_htmlhead,        /* 1 = output HTML <head> section and <body> opener */
 
-                       int do_room_banner,     /* 0=no, 1=yes,                                     
+                       int do_room_banner,     /* 0=no, 1=yes,                              
                                                 * 2 = I'm going to embed my own, so don't open the 
-                                                *     <div id="content"> either.                   
+                                                *     <div id="content"> either.                  
                                                 */
 
                        int unset_cookies,      /* 1 = session is terminating, so unset the cookies */
-                       int suppress_check,     /* 1 = suppress check for instant messages          */
-                       int cache               /* 1 = allow browser to cache this page             */
+                       int suppress_check,     /* 1 = suppress check for instant messages        */
+                       int cache               /* 1 = allow browser to cache this page      */
 ) {
        wcsession *WCC = WC;
        char httpnow[128];
@@ -365,21 +366,21 @@ void begin_ajax_response(void) {
        wcsession *WCC = WC;
 
        FlushStrBuf(WCC->HBuf);
-        output_headers(0, 0, 0, 0, 0, 0);
+       output_headers(0, 0, 0, 0, 0, 0);
 
-        hprintf("Content-type: text/html; charset=UTF-8\r\n"
-                "Server: %s\r\n"
-                "Connection: close\r\n"
+       hprintf("Content-type: text/html; charset=UTF-8\r\n"
+               "Server: %s\r\n"
+               "Connection: close\r\n"
                ,
-                PACKAGE_STRING);
-        begin_burst();
+               PACKAGE_STRING);
+       begin_burst();
 }
 
 /*
  * print ajax response footer 
  */
 void end_ajax_response(void) {
-        wDumpContent(0);
+       wDumpContent(0);
 }
 
 
@@ -481,23 +482,22 @@ void seconds_since_last_gexp(void)
 int ReadPostData(void)
 {
        int rc;
-       int body_start = 0;
+       int urlencoded_post = 0;
        wcsession *WCC = WC;
        StrBuf *content = NULL;
        
+       urlencoded_post = (strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "application/x-www-form-urlencoded", 33) == 0) ;
+
        content = NewStrBufPlain(NULL, WCC->Hdr->HR.ContentLength + 256);
 
-       StrBufPrintf(content, 
+       if (!urlencoded_post)
+       {
+               StrBufPrintf(content, 
                     "Content-type: %s\n"
-                    "Content-length: %ld\n\n",
-                    ChrPtr(WCC->Hdr->HR.ContentType), 
+                            "Content-length: %ld\n\n",
+                            ChrPtr(WCC->Hdr->HR.ContentType), 
                             WCC->Hdr->HR.ContentLength);
-/*
-  hprintf("Content-type: %s\n"
-  "Content-length: %d\n\n",
-  ContentType, ContentLength);
-*/
-       body_start = StrLength(content);
+       }
 
        /** Read the entire input data at once. */
        rc = client_read_to(WCC->Hdr, content, 
@@ -507,8 +507,7 @@ int ReadPostData(void)
                return rc;
                
        
-       if (!strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "application/x-www-form-urlencoded", 33)) {
-               StrBufCutLeft(content, body_start);
+       if (urlencoded_post) {
                ParseURLParams(content);
        } else if (!strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "multipart", 9)) {
                char *Buf;
@@ -626,6 +625,14 @@ void session_loop(void)
        Buf = NewStrBuf();
        WCC->trailing_javascript = NewStrBuf();
 
+       /* Convert base64-encoded URL's back to plain text */
+       if (!strncmp(ChrPtr(WCC->Hdr->this_page), "/B64", 4)) {
+               StrBufCutLeft(WCC->Hdr->this_page, 4);
+               StrBufDecodeBase64(WCC->Hdr->this_page);
+               http_redirect(ChrPtr(WCC->Hdr->this_page));
+               goto SKIP_ALL_THIS_CRAP;
+       }
+
        /* If there are variables in the URL, we must grab them now */
        if (WCC->Hdr->PlainArgs != NULL)
                ParseURLParams(WCC->Hdr->PlainArgs);
@@ -650,7 +657,17 @@ void session_loop(void)
         * connection now.
         */
        if (!WCC->connected) {
-               if (GetConnected ())
+               if (GetConnected()) {
+                       hprintf("HTTP/1.1 503 Service Unavailable\r\n");
+                       hprintf("Content-Type: text/html\r\n");
+                       begin_burst();
+                       wc_printf("<html><head><title>503 Service Unavailable</title></head><body>\n");
+                       wc_printf(_("This program was unable to connect or stay "
+                               "connected to the Citadel server.  Please report "
+                               "this problem to your system administrator.")
+                       );
+                       wc_printf("</body></html>\n");
+                       end_burst();
                        goto SKIP_ALL_THIS_CRAP;
        }
 
@@ -858,7 +875,6 @@ InitModule_WEBCIT
        RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, NULL, CTX_NONE);
        RegisterNamespace("TRAILING_JAVASCRIPT", 0, 0, tmplput_trailing_javascript, NULL, CTX_NONE);
        RegisterNamespace("URL:DISPLAYNAME", 0, 1, tmplput_HANDLER_DISPLAYNAME, NULL, CTX_NONE);
-       RegisterNamespace("URL:HOSTNAME", 0, 1, tmplput_HOST_DISPLAYNAME, NULL, CTX_NONE);
 
        
        snprintf(dir, SIZ, "%s/webcit.css", static_local_dir);