Clean up the RSS feed. Attempt to read If-Modified-Since header.
authorMichael Hampton <io_error@uncensored.citadel.org>
Fri, 19 Aug 2005 00:52:28 +0000 (00:52 +0000)
committerMichael Hampton <io_error@uncensored.citadel.org>
Fri, 19 Aug 2005 00:52:28 +0000 (00:52 +0000)
webcit/context_loop.c
webcit/fmt_date.c
webcit/rss.c
webcit/webcit.c
webcit/webcit.h

index f64433afd728072f0265b6429a634970d117013d..dec43c579753ab05158fba648d3ce1f736e0b8eb 100644 (file)
@@ -285,6 +285,10 @@ void context_loop(int sock)
                        extract_token(httpauth_pass, httpauth_string, 1, ':', sizeof httpauth_pass);
                }
 
+               if (!strncasecmp(buf, "If-Modified-Since: ", 19)) {
+                       if_modified_since = httpdate_to_timestamp(&buf[19]);
+               }
+
                /*
                 * Read in the request
                 */
index 2b6148954905a90be9d344980a14275a1ffb98a9..70efe6c2879cfb26e42db88cbfb9662d9e127273 100644 (file)
@@ -145,6 +145,86 @@ void httpdate(char *buf, time_t thetime)
 }
 
 
-
-
-
+/*
+ * Break down the timestamp used in HTTP headers
+ * Should read rfc1123 and rfc850 dates OK
+ * FIXME won't read asctime
+ * Doesn't understand timezone, but we only should be using GMT/UTC anyway
+ */
+time_t httpdate_to_timestamp(const char *buf)
+{
+       time_t t = 0;
+       struct tm tt;
+       char *c;
+
+lprintf(3, "datestamp %s\n", buf);
+       /* Skip day of week, to number */
+       for (c = buf; *c < '0' && *c > '9'; c++)
+               ;
+
+       /* Get day of month */
+       tt.tm_mday = 0;
+       for (; *c != ' ' && *c != '-'; c++)
+               tt.tm_mday += 10 * (*c - '0');
+       c++;
+
+       /* Get month */
+       switch (*c) {
+       case 'A':       /* April, August */
+               tt.tm_mon = (c[1] == 'p') ? 3 : 7;
+               break;
+       case 'D':       /* December */
+               tt.tm_mon = 11;
+               break;
+       case 'F':       /* February */
+               tt.tm_mon = 1;
+               break;
+       case 'M':       /* March, May */
+               tt.tm_mon = (c[2] == 'r') ? 2 : 4;
+               break;
+       case 'J':       /* January, June, July */
+               tt.tm_mon = (c[2] == 'n') ? ((c[1] == 'a') ? 0 : 5) : 6;
+               break;
+       case 'N':       /* November */
+               tt.tm_mon = 10;
+               break;
+       case 'O':       /* October */
+               tt.tm_mon = 9;
+               break;
+       case 'S':       /* September */
+               tt.tm_mon = 8;
+               break;
+       default:
+               return 0;
+               break;  /* NOTREACHED */
+       }
+       c += 4;
+
+       /* Get year */
+       for (; *c != ' '; c++)
+               tt.tm_year += 10 * (*c - '0');
+       c++;
+       /* Y2K business for rfc850 dates */
+       if (tt.tm_year > 69)
+               tt.tm_year += 1900;
+       else
+               tt.tm_year += 2000;
+
+       /* Get hour */
+       for (; *c != ':'; c++)
+               tt.tm_hour += 10 * (*c - '0');
+       c++;
+
+       /* Get minute */
+       for (; *c != ':'; c++)
+               tt.tm_min += 10 * (*c - '0');
+       c++;
+
+       /* Get second */
+       for (; *c && *c != ' '; c++)
+               tt.tm_sec += 10 * (*c - '0');
+
+       /* Got everything; let's go */
+       t = mktime(&tt);
+       return t;
+}
index 1c250a91321f6e0894920d8488b9f721ea6cbe5b..e479eb7a718ae8aa1607fa32f8426051fd83978d 100644 (file)
@@ -7,6 +7,10 @@
 #include "webcit.h"
 #include "webserver.h"
 
+
+time_t if_modified_since;
+
+
 void display_rss(const char *roomname)
 {
        int nummsgs;
@@ -33,13 +37,11 @@ void display_rss(const char *roomname)
        char content_type[256];
        char charset[256];
 
-       lprintf(3, "Running RSS reader\n");
        if (!WC->logged_in) {
-               authorization_required();
+               authorization_required("Not logged in");
                return;
        }
 
-       lprintf(3, "Going to a room %s\n", roomname);
        if (gotoroom(roomname)) {
                wprintf("HTTP/1.0 404 Not Found\r\n");
                wprintf("Content-Type: text/html\r\n");
@@ -48,7 +50,6 @@ void display_rss(const char *roomname)
                return;
        }
 
-       lprintf(3, "Loading up all the messages\n");
        nummsgs = load_msg_ptrs("MSGS LAST|50", 0);
        if (nummsgs == 0) {
                wprintf("HTTP/1.0 404 Not Found\r\n");
@@ -58,12 +59,14 @@ void display_rss(const char *roomname)
                return;
        }
 
-       lprintf(3, "Getting date of the last one\n");
        /* Read time of last message immediately */
        serv_printf("MSG4 %ld", WC->msgarr[nummsgs - 1]);
        serv_getln(buf, sizeof buf);
        if (buf[0] == '1') {
                while (serv_getln(buf, sizeof buf), strcasecmp(buf, "000")) {
+                       if (!strncasecmp(buf, "msgn=", 5)) {
+                               strcpy(msgn, &buf[5]);
+                       }
                        if (!strncasecmp(buf, "time=", 5)) {
                                now = atol(&buf[5]);
                                gmtime_r(&now, &now_tm);
@@ -72,14 +75,37 @@ void display_rss(const char *roomname)
                }
        }
 
+       lprintf(3, "If modified since %ld Last modified %ld\n", if_modified_since, now);
+       if (if_modified_since > 0 && if_modified_since > now) {
+               wprintf("HTTP/1.0 304 Not Modified\r\n");
+               wprintf("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); */
+               wDumpContent(0);
+               return;
+       }
+
        /* Do RSS header */
-       output_headers(0, 0, 0, 0, 0, 0, 0);
+       wprintf("HTTP/1.0 200 OK\r\n");
+       wprintf("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("$erver: %s\r\n", SERVER);
+       wprintf("Connection: close\r\n");
        wprintf("\r\n");
+       if (!strcasecmp(request_method, "HEAD"))
+               return;
+
        wprintf("<?xml version=\"1.0\"?>\n");
        wprintf("<rss version=\"2.0\">\n");
        wprintf("   <channel>\n");
        wprintf("   <title>%s - %s</title>\n", WC->wc_roomname, serv_info.serv_humannode);
+       wprintf("   <link>%s://%s:%d/dotgoto?room=", (is_https ? "https" : "http"), WC->http_host, PORT_NUM);
+       escputs(roomname);
+       wprintf("</link>\n");
        wprintf("   <description>");
        /* Get room info for description */
        serv_puts("RINF");
@@ -94,7 +120,7 @@ void display_rss(const char *roomname)
        }
        wprintf("</description>\n");
        if (now) {
-               wprintf("   <pubDate>%s</pubDate>\n", buf);
+               wprintf("   <pubDate>%s</pubDate>\n", date);
        }
        wprintf("   <generator>%s</generator>\n", SERVER);
        wprintf("   <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n");
@@ -102,7 +128,6 @@ void display_rss(const char *roomname)
 
        /* Read all messages and output as RSS items */
        for (a = 0; a < nummsgs; ++a) {
-               lprintf(3, "Sending message %d of %d\n", a+1, nummsgs);
                /* Read message and output each as RSS item */
                serv_printf("MSG4 %ld", WC->msgarr[a]);
                serv_getln(buf, sizeof buf);
@@ -119,7 +144,6 @@ void display_rss(const char *roomname)
 
                while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
                        if (!strcmp(buf, "000")) {
-                               lprintf(3, "ENDITEM 1\n");
                                goto ENDITEM;   /* screw it */
                        } else if (!strncasecmp(buf, "from=", 5)) {
                                strcpy(from, &buf[5]);
@@ -167,7 +191,6 @@ void display_rss(const char *roomname)
                strcpy(content_type, "text/plain");
                while (serv_getln(buf, sizeof buf), strlen(buf) > 0) {
                        if (!strcmp(buf, "000")) {
-                               lprintf(3, "ENDBODY 1\n");
                                goto ENDBODY;
                        }
                        if (!strncasecmp(buf, "Content-type: ", 14)) {
@@ -275,7 +298,6 @@ void display_rss(const char *roomname)
 ENDBODY:
                wprintf("   </item>\n");
 ENDITEM:
-               lprintf(3, "Finished message %d of %d\n", a+1, nummsgs);
                now = 0L;
        }
 
index aa9af913a7004ee28bd9ebb78303b7fbb0d618a4..61769d691bb7ca1222014beb41ac12947d1ae2a2 100644 (file)
@@ -12,6 +12,8 @@
 #include "webserver.h"
 #include "mime_parser.h"
 
+char request_method[128];
+
 /*
  * String to unset the cookie.
  * Any date "in the past" will work, so I chose my birthday, right down to
@@ -818,7 +820,6 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp,
 void session_loop(struct httprequest *req)
 {
        char cmd[1024];
-       char method[128];
        char action[128];
        char arg1[128];
        char arg2[128];
@@ -864,7 +865,7 @@ void session_loop(struct httprequest *req)
 
        safestrncpy(cmd, hptr->line, sizeof cmd);
        hptr = hptr->next;
-       extract_token(method, cmd, 0, ' ', sizeof method);
+       extract_token(request_method, cmd, 0, ' ', sizeof request_method);
 
        /* Figure out the action */
        extract_token(action, cmd, 1, '/', sizeof action);
@@ -1076,7 +1077,7 @@ void session_loop(struct httprequest *req)
         * Automatically send requests with any method other than GET or
         * POST to the GroupDAV code as well.
         */
-       if ((strcasecmp(method, "GET")) && (strcasecmp(method, "POST"))) {
+       if ((strcasecmp(request_method, "GET")) && (strcasecmp(request_method, "POST"))) {
                groupdav_main(req, ContentType, /* do GroupDAV methods */
                        ContentLength, content+body_start);
                if (!WC->logged_in) {
index b8986d98eefec043c68b4f637e22caa2d19476b5..23d5574b5d32509f604463caf36e051c33ede22d 100644 (file)
@@ -324,8 +324,10 @@ extern char *axdefs[];
 extern char *ctdlhost, *ctdlport;
 extern char *server_cookie;
 extern int is_https;
+extern char request_method[];
 extern int setup_wizard;
 extern char wizard_filename[];
+extern time_t if_modified_since;
 void do_setup_wizard(void);
 
 void stuff_to_cookie(char *cookie, int session,
@@ -405,6 +407,7 @@ void zapped_list(void);
 void display_zap(void);
 void zap(void);
 void display_success(char *);
+void authorization_required(const char *message);
 void display_entroom(void);
 void entroom(void);
 void display_editroom(void);
@@ -451,6 +454,7 @@ void session_loop(struct httprequest *);
 void fmt_date(char *buf, time_t thetime, int brief);
 void fmt_time(char *buf, time_t thetime);
 void httpdate(char *buf, time_t thetime);
+time_t httpdate_to_timestamp(const char *buf);
 void end_webcit_session(void);
 void page_popup(void);
 void chat_recv(void);