X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=af8b4fbd73f2d982b69561eb4bc8534851e563c8;hb=3dda3cda8acb9c1c4eb227f4780630913ffc633a;hp=d61817e8031c61e7b451dfffa8673fe73d079140;hpb=2dfb099ebb1debfc33600d4bb6029e06f1b27143;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index d61817e80..af8b4fbd7 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -180,6 +180,10 @@ void wDumpContent(int print_standard_html_footer) do_template("trailing"); } + /* If we've been saving it all up for one big output burst, + * go ahead and do that now. + */ + end_burst(); } @@ -345,7 +349,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers int do_room_banner, /* 0=no, 1=yes, */ /* 2 = I'm going to embed my own, so don't open the */ - /*
either. */ + /*
either. */ int unset_cookies, /* 1 = session is terminating, so unset the cookies */ int refresh30, /* 1 = automatically refresh page every 30 seconds */ @@ -359,30 +363,41 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers httpdate(httpnow, time(NULL)); if (do_httpheaders) { - wprintf("Content-type: text/html\n" - "Server: %s / %s\n", SERVER, serv_info.serv_software + wprintf("Content-type: text/html\r\n" + "Server: %s / %s\n" + "Connection: close\r\n", + SERVER, serv_info.serv_software + ); + } + + if (cache) { + wprintf("Pragma: public\r\n" + "Cache-Control: max-age=3600, must-revalidate\r\n" + "Last-modified: %s\r\n", + httpnow + ); + } + else { + wprintf("Pragma: no-cache\r\n" + "Cache-Control: no-store\r\n" ); - if (!cache) - wprintf("Connection: close\n" - "Pragma: no-cache\n" - "Cache-Control: no-store\n" - ); } stuff_to_cookie(cookie, WC->wc_session, WC->wc_username, WC->wc_password, WC->wc_roomname); if (unset_cookies) { - wprintf("Set-cookie: webcit=%s; path=/\n", unset); + wprintf("Set-cookie: webcit=%s; path=/\r\n", unset); } else { - wprintf("Set-cookie: webcit=%s; path=/\n", cookie); + wprintf("Set-cookie: webcit=%s; path=/\r\n", cookie); if (server_cookie != NULL) { wprintf("%s\n", server_cookie); } } if (do_htmlhead) { - wprintf("\n"); + /* wprintf("\n"); */ + begin_burst(); if (refresh30) { svprintf("REFRESHTAG", WCS_STRING, "%s", @@ -416,15 +431,16 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers } } - if (do_room_banner != 2) { + if (do_room_banner == 1) { wprintf("
\n"); - if (strlen(WC->ImportantMessage) > 0) { + wprintf("
\n"); do_template("beginbox_nt"); wprintf("" "%s
\n", WC->ImportantMessage); do_template("endbox"); + wprintf("
\n"); strcpy(WC->ImportantMessage, ""); } @@ -437,9 +453,9 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers */ void http_redirect(char *whichpage) { wprintf("HTTP/1.0 302 Moved Temporarily\n"); - wprintf("Location: %s\n", whichpage); - wprintf("URI: %s\n", whichpage); - wprintf("Content-type: text/html\n\n"); + wprintf("Location: %s\r\n", whichpage); + wprintf("URI: %s\r\n", whichpage); + wprintf("Content-type: text/html\r\n\r\n"); wprintf("\n"); wprintf("you really want to be here now\n", whichpage); @@ -453,7 +469,7 @@ void check_for_instant_messages() char buf[SIZ]; serv_puts("NOOP"); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[3] == '*') WC->HaveInstantMessages = 1; } @@ -465,20 +481,44 @@ void check_for_instant_messages() */ void http_transmit_thing(char *thing, size_t length, char *content_type, int is_static) { - if (is_static) { - output_headers(0, 0, 0, 0, 0, 0, 1); - } - else { - output_headers(0, 0, 0, 0, 0, 0, 0); - } - wprintf("Content-type: %s\n" - "Content-length: %ld\n" - "Server: %s\n" - "Connection: close\n" - "\n", + + output_headers(0, 0, 0, 0, 0, 0, is_static); + + wprintf("Content-type: %s\r\n" + "Server: %s\r\n" + "Connection: close\r\n", content_type, - (long) length, - SERVER + SERVER); + +#ifdef HAVE_ZLIB + /* If we can send the data out compressed, please do so. */ + if (WC->gzip_ok) { + char *compressed_data = NULL; + uLongf compressed_len; + + compressed_len = (uLongf) ((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); } @@ -499,8 +539,8 @@ void output_static(char *what) fp = fopen(buf, "rb"); if (fp == NULL) { wprintf("HTTP/1.0 404 %s\n", strerror(errno)); - wprintf("Content-Type: text/plain\n"); - wprintf("\n"); + wprintf("Content-Type: text/plain\r\n"); + wprintf("\r\n"); wprintf("Cannot open %s: %s\n", what, strerror(errno)); } else { if (!strncasecmp(&what[strlen(what) - 4], ".gif", 4)) @@ -536,7 +576,7 @@ void output_static(char *what) fstat(fileno(fp), &statbuf); bytes = statbuf.st_size; - /* lprintf(3, "Static: %s, (%s; %ld bytes)\n", + /* lprintf(3, "Static: %s, (%s; %ld bytes)\r\n", what, content_type, bytes); */ bigbuffer = malloc(bytes + 2); fread(bigbuffer, bytes, 1, fp); @@ -562,7 +602,7 @@ void output_image() off_t bytes; serv_printf("OIMG %s|%s", bstr("name"), bstr("parm")); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); xferbuf = malloc(bytes + 2); @@ -570,7 +610,7 @@ void output_image() /* Read it from the server */ read_server_binary(xferbuf, bytes); serv_puts("CLOS"); - serv_gets(buf); + serv_getln(buf, sizeof buf); /* Write it to the browser */ http_transmit_thing(xferbuf, (size_t)bytes, "image/gif", 0); @@ -586,8 +626,8 @@ void output_image() /* wprintf("HTTP/1.0 404 %s\n", &buf[4]); output_headers(0, 0, 0, 0, 0, 0, 0); - wprintf("Content-Type: text/plain\n" - "\n" + wprintf("Content-Type: text/plain\r\n" + "\r\n" "Error retrieving image: %s\n", &buf[4] ); @@ -609,22 +649,22 @@ void output_mimepart() char *content = NULL; serv_printf("OPNA %s|%s", bstr("msgnum"), bstr("partnum")); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); content = malloc(bytes + 2); - extract(content_type, &buf[4], 3); + extract_token(content_type, &buf[4], 3, '|', sizeof content_type); output_headers(0, 0, 0, 0, 0, 0, 0); read_server_binary(content, bytes); serv_puts("CLOS"); - serv_gets(buf); + serv_getln(buf, sizeof buf); http_transmit_thing(content, bytes, content_type, 0); free(content); } else { wprintf("HTTP/1.0 404 %s\n", &buf[4]); output_headers(0, 0, 0, 0, 0, 0, 0); - wprintf("Content-Type: text/plain\n"); - wprintf("\n"); + wprintf("Content-Type: text/plain\r\n"); + wprintf("\r\n"); wprintf("Error retrieving part: %s\n", &buf[4]); } @@ -641,16 +681,16 @@ char *load_mimepart(long msgnum, char *partnum) char *content; serv_printf("OPNA %ld|%s", msgnum, partnum); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); - extract(content_type, &buf[4], 3); + extract_token(content_type, &buf[4], 3, '|', sizeof content_type); content = malloc(bytes + 2); read_server_binary(content, bytes); serv_puts("CLOS"); - serv_gets(buf); + serv_getln(buf, sizeof buf); content[bytes] = 0; /* null terminate for good measure */ return(content); } @@ -833,7 +873,7 @@ void session_loop(struct httprequest *req) struct httprequest *hptr; char browser_host[SIZ]; char user_agent[SIZ]; - int body_start; + int body_start = 0; /* We stuff these with the values coming from the client cookies, * so we can use them to reconnect a timed out session if we have to. @@ -850,8 +890,8 @@ void session_loop(struct httprequest *req) strcpy(c_password, ""); strcpy(c_roomname, ""); strcpy(c_httpauth_string, ""); - strcpy(c_httpauth_user, ""); - strcpy(c_httpauth_pass, ""); + strcpy(c_httpauth_user, DEFAULT_HTTPAUTH_USER); + strcpy(c_httpauth_pass, DEFAULT_HTTPAUTH_PASS); WC->upload_length = 0; WC->upload = NULL; @@ -864,7 +904,7 @@ void session_loop(struct httprequest *req) strcpy(cmd, hptr->line); hptr = hptr->next; - extract_token(method, cmd, 0, ' '); + extract_token(method, cmd, 0, ' ', sizeof method); extract_action(action, cmd); while (hptr != NULL) { @@ -874,12 +914,14 @@ void session_loop(struct httprequest *req) if (!strncasecmp(buf, "Cookie: webcit=", 15)) { safestrncpy(cookie, &buf[15], sizeof cookie); cookie_to_stuff(cookie, NULL, - c_username, c_password, c_roomname); + c_username, sizeof c_username, + c_password, sizeof c_password, + c_roomname, sizeof c_roomname); } else if (!strncasecmp(buf, "Authorization: Basic ", 21)) { CtdlDecodeBase64(c_httpauth_string, &buf[21], strlen(&buf[21])); - extract_token(c_httpauth_user, c_httpauth_string, 0, ':'); - extract_token(c_httpauth_pass, c_httpauth_string, 1, ':'); + extract_token(c_httpauth_user, c_httpauth_string, 0, ':', sizeof c_httpauth_user); + extract_token(c_httpauth_pass, c_httpauth_string, 1, ':', sizeof c_httpauth_pass); } else if (!strncasecmp(buf, "Content-length: ", 16)) { ContentLength = atoi(&buf[16]); @@ -970,7 +1012,7 @@ void session_loop(struct httprequest *req) } else { WC->connected = 1; - serv_gets(buf); /* get the server welcome message */ + serv_getln(buf, sizeof buf); /* get the server welcome message */ locate_host(browser_host, WC->http_sock); get_serv_info(browser_host, user_agent); if (serv_info.serv_rev_level < MINIMUM_CIT_VERSION) { @@ -1012,10 +1054,10 @@ void session_loop(struct httprequest *req) && (strlen(c_httpauth_user) > 0) && (strlen(c_httpauth_pass) > 0)) { serv_printf("USER %s", c_httpauth_user); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '3') { serv_printf("PASS %s", c_httpauth_pass); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { become_logged_in(c_httpauth_user, c_httpauth_pass, buf); @@ -1038,7 +1080,18 @@ void session_loop(struct httprequest *req) goto SKIP_ALL_THIS_CRAP; } - check_for_instant_messages(); + + /* + * If this isn't a GroupDAV session, it's an ordinary browser + * connecting to the user interface. Only allow GET and POST + * methods. + */ + if ((strcasecmp(method, "GET")) && (strcasecmp(method, "POST"))) { + wprintf("HTTP/1.1 405 Method Not Allowed\r\n"); + groupdav_common_headers(); + wprintf("Content-Length: 0\r\n\r\n"); + goto SKIP_ALL_THIS_CRAP; + } /* * If we're not logged in, but we have username and password cookies @@ -1048,10 +1101,10 @@ void session_loop(struct httprequest *req) && (strlen(c_username) > 0) && (strlen(c_password) > 0)) { serv_printf("USER %s", c_username); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '3') { serv_printf("PASS %s", c_password); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { become_logged_in(c_username, c_password, buf); } @@ -1063,12 +1116,17 @@ void session_loop(struct httprequest *req) */ if ((strlen(WC->wc_roomname) == 0) && (strlen(c_roomname) > 0)) { serv_printf("GOTO %s", c_roomname); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { strcpy(WC->wc_roomname, c_roomname); } } + /* + * If there are instant messages waiting, retrieve them for display. + */ + check_for_instant_messages(); + if (!strcasecmp(action, "image")) { output_image(); @@ -1092,6 +1150,8 @@ void session_loop(struct httprequest *req) blank_page(); } else if (!strcasecmp(action, "do_template")) { url_do_template(); + } else if (!strcasecmp(action, "display_aide_menu")) { + display_aide_menu(); } else if (!strcasecmp(action, "display_main_menu")) { display_main_menu(); } else if (!strcasecmp(action, "whobbs")) { @@ -1124,10 +1184,10 @@ void session_loop(struct httprequest *req) display_enter(); } else if (!strcasecmp(action, "post")) { post_message(); - } else if (!strcasecmp(action, "do_stuff_to_one_msg")) { - do_stuff_to_one_msg(); } else if (!strcasecmp(action, "move_msg")) { move_msg(); + } else if (!strcasecmp(action, "delete_msg")) { + delete_msg(); } else if (!strcasecmp(action, "userlist")) { userlist(); } else if (!strcasecmp(action, "showuser")) { @@ -1152,14 +1212,16 @@ void session_loop(struct httprequest *req) display_entroom(); } else if (!strcasecmp(action, "entroom")) { entroom(); + } else if (!strcasecmp(action, "display_whok")) { + display_whok(); + } else if (!strcasecmp(action, "do_invt_kick")) { + do_invt_kick(); } else if (!strcasecmp(action, "display_editroom")) { display_editroom(); } else if (!strcasecmp(action, "netedit")) { netedit(); } else if (!strcasecmp(action, "editroom")) { editroom(); - } else if (!strcasecmp(action, "display_whok")) { - display_whok(); } else if (!strcasecmp(action, "display_editinfo")) { display_edit("Room info", "EINF 0", "RINF", "/editinfo", 1); } else if (!strcasecmp(action, "editinfo")) { @@ -1169,8 +1231,8 @@ void session_loop(struct httprequest *req) display_edit("Your bio", "NOOP", buf, "editbio", 3); } else if (!strcasecmp(action, "editbio")) { save_edit("Your bio", "EBIO", 0); - } else if (!strcasecmp(action, "confirm_delete_room")) { - confirm_delete_room(); + } else if (!strcasecmp(action, "confirm_move_msg")) { + confirm_move_msg(); } else if (!strcasecmp(action, "delete_room")) { delete_room(); } else if (!strcasecmp(action, "validate")) { @@ -1294,6 +1356,8 @@ void session_loop(struct httprequest *req) display_inetconf(); } else if (!strcasecmp(action, "save_inetconf")) { save_inetconf(); + } else if (!strcasecmp(action, "setup_wizard")) { + do_setup_wizard(); } else if (!strcasecmp(action, "diagnostics")) { output_headers(1, 1, 1, 0, 0, 0, 0);