}
-
-
-
+/*
+ * 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;
+}
#include "webcit.h"
#include "webserver.h"
+
+time_t if_modified_since;
+
+
void display_rss(const char *roomname)
{
int nummsgs;
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");
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");
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);
}
}
+ 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");
}
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");
/* 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);
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]);
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)) {
ENDBODY:
wprintf(" </item>\n");
ENDITEM:
- lprintf(3, "Finished message %d of %d\n", a+1, nummsgs);
now = 0L;
}
#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
void session_loop(struct httprequest *req)
{
char cmd[1024];
- char method[128];
char action[128];
char arg1[128];
char arg2[128];
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);
* 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) {
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,
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);
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);