X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=7220a5d7eae9eaf010e3bf3129cfa4e6563dfc10;hb=d120028b4c45f3c26d05186c8ba488fd2feef13f;hp=71d748f6c0a2f5212fa6270b1d931eda18c5d18b;hpb=305a367fdeba3107280f4ef7ca80a855ddf6c3d2;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index 71d748f6c..7220a5d7e 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -12,7 +12,13 @@ #include "webserver.h" #include "mime_parser.h" -char request_method[128]; +/* + * Subdirectories from which the client may request static content + */ +char *static_content_dirs[] = { + "static", + "tiny_mce" +}; /* * String to unset the cookie. @@ -229,7 +235,7 @@ void escputs(char *strbuf) void urlesc(char *outbuf, char *strbuf) { int a, b, c; - char *ec = " #&;`'|*?-~<>^()[]{}$\\"; + char *ec = " #&;`'|*?-~<>^()[]{}$\"\\"; strcpy(outbuf, ""); @@ -298,9 +304,7 @@ void msgesc(char *target, char *strbuf) strcpy(target, ""); for (a = 0; a < strlen(strbuf); ++a) { - if (strbuf[a] == '\'') - strcat(target, "\\'"); - else if (strbuf[a] == '\n') + if (strbuf[a] == '\n') strcat(target, " "); else if (strbuf[a] == '\r') strcat(target, " "); @@ -336,14 +340,13 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers /*
either. */ int unset_cookies, /* 1 = session is terminating, so unset the cookies */ - int refresh30, /* 1 = automatically refresh page every 30 seconds */ int suppress_check, /* 1 = suppress check for instant messages */ int cache /* 1 = allow browser to cache this page */ ) { char cookie[SIZ]; char httpnow[SIZ]; - wprintf("HTTP/1.0 200 OK\n"); + wprintf("HTTP/1.1 200 OK\n"); httpdate(httpnow, time(NULL)); if (do_httpheaders) { @@ -380,29 +383,15 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers } if (do_htmlhead) { - /* wprintf("\n"); */ begin_burst(); - - if (refresh30) { - svprintf("REFRESHTAG", WCS_STRING, "%s", - "\n"); - } - else { - svprintf("REFRESHTAG", WCS_STRING, "%s", - "\n"); - } - do_template("head"); } /* ICONBAR */ if (do_htmlhead) { - if (WC->HaveInstantMessages) { - wprintf("
\n"); - page_popup(); - wprintf("
\n"); - } + + /* check for ImportantMessages (these display in a div overlaying the main screen) */ if (strlen(WC->ImportantMessage) > 0) { wprintf("
\n"); wprintf("" @@ -413,11 +402,15 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers "\n"); safestrncpy(WC->ImportantMessage, "", sizeof WC->ImportantMessage); } + if ( (WC->logged_in) && (!unset_cookies) ) { wprintf("
"); - do_iconbar(); - wprintf("
\n"); + do_selected_iconbar(); + /* check for instant messages (these display in a new window) + page_popup(); */ + wprintf("
"); } + if (do_room_banner == 1) { wprintf("
\n"); embed_room_banner(NULL, navbar_default); @@ -435,36 +428,24 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers * Generic function to do an HTTP redirect. Easy and fun. */ void http_redirect(char *whichpage) { - wprintf("HTTP/1.0 302 Moved Temporarily\n"); + wprintf("HTTP/1.1 302 Moved Temporarily\n"); wprintf("Location: %s\r\n", whichpage); wprintf("URI: %s\r\n", whichpage); wprintf("Content-type: text/html; charset=utf-8\r\n\r\n"); wprintf(""); - wprintf("Go here.", whichpage); + wprintf("Go here.", whichpage); wprintf("\n"); } -void check_for_instant_messages() -{ - char buf[SIZ]; - - serv_puts("NOOP"); - serv_getln(buf, sizeof buf); - if (buf[3] == '*') WC->HaveInstantMessages = 1; -} - - - - /* * Output a piece of content to the web browser */ void http_transmit_thing(char *thing, size_t length, char *content_type, int is_static) { - output_headers(0, 0, 0, 0, 0, 0, is_static); + output_headers(0, 0, 0, 0, 0, is_static); wprintf("Content-type: %s\r\n" "Server: %s\r\n" @@ -510,17 +491,16 @@ void http_transmit_thing(char *thing, size_t length, char *content_type, void output_static(char *what) { - char buf[256]; FILE *fp; struct stat statbuf; off_t bytes; char *bigbuffer; char content_type[128]; - sprintf(buf, "static/%s", what); - fp = fopen(buf, "rb"); + fp = fopen(what, "rb"); if (fp == NULL) { - wprintf("HTTP/1.0 404 %s\n", strerror(errno)); + lprintf(9, "output_static('%s') -- NOT FOUND --\n", what); + wprintf("HTTP/1.1 404 %s\n", strerror(errno)); wprintf("Content-Type: text/plain\r\n"); wprintf("\r\n"); wprintf("Cannot open %s: %s\n", what, strerror(errno)); @@ -562,6 +542,7 @@ void output_static(char *what) fread(bigbuffer, bytes, 1, fp); fclose(fp); + lprintf(9, "output_static('%s') %s\n", what, content_type); http_transmit_thing(bigbuffer, (size_t)bytes, content_type, 1); free(bigbuffer); } @@ -600,7 +581,7 @@ void output_image() /* Instead of an ugly 404, send a 1x1 transparent GIF * when there's no such image on the server. */ - output_static("blank.gif"); + output_static("static/blank.gif"); } @@ -611,28 +592,28 @@ void output_image() * Generic function to output an arbitrary MIME part from an arbitrary * message number on the server. */ -void output_mimepart() +void mimepart(char *msgnum, char *partnum) { char buf[SIZ]; off_t bytes; char content_type[SIZ]; char *content = NULL; - serv_printf("OPNA %s|%s", bstr("msgnum"), bstr("partnum")); + serv_printf("OPNA %s|%s", msgnum, partnum); serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); content = malloc(bytes + 2); extract_token(content_type, &buf[4], 3, '|', sizeof content_type); - output_headers(0, 0, 0, 0, 0, 0, 0); + output_headers(0, 0, 0, 0, 0, 0); read_server_binary(content, bytes); serv_puts("CLOS"); 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("HTTP/1.1 404 %s\n", &buf[4]); + output_headers(0, 0, 0, 0, 0, 0); wprintf("Content-Type: text/plain\r\n"); wprintf("\r\n"); wprintf(_("An error occurred while retrieving this part: %s\n"), &buf[4]); @@ -677,8 +658,8 @@ char *load_mimepart(long msgnum, char *partnum) */ void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext) { - wprintf("HTTP/1.0 200 OK\n"); - output_headers(1, 1, 2, 0, 0, 0, 0); + wprintf("HTTP/1.1 200 OK\n"); + output_headers(1, 1, 2, 0, 0, 0); wprintf("
\n"); wprintf("
", titlebarcolor); wprintf("%s\n", titlebarmsg); @@ -695,7 +676,7 @@ void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext) * Display a blank page. */ void blank_page(void) { - output_headers(1, 1, 0, 0, 1, 0, 0); + output_headers(1, 1, 0, 0, 0, 0); wDumpContent(2); } @@ -713,11 +694,18 @@ void url_do_template(void) { * Offer to make any page the user's "start page." */ void offer_start_page(void) { - wprintf("this_page); wprintf("\">"); wprintf(_("Make this my start page")); wprintf(""); +/* + wprintf("
wc_roomname); + wprintf("\" title=\"RSS 2.0 feed for "); + escputs(WC->wc_roomname); + wprintf("\">\"RSS\"\n"); +*/ } @@ -736,7 +724,7 @@ void change_start_page(void) { set_preference("startpage", bstr("startpage"), 1); - output_headers(1, 1, 0, 0, 0, 0, 0); + output_headers(1, 1, 0, 0, 0, 0); do_template("newstartpage"); wDumpContent(1); } @@ -754,7 +742,7 @@ void display_success(char *successmessage) /* This is probably temporary and should be revisited */ void authorization_required(const char *message) { - wprintf("HTTP/1.0 401 Authorization Required\r\n"); + wprintf("HTTP/1.1 401 Authorization Required\r\n"); wprintf("WWW-Authenticate: Basic realm=\"\"\r\n", serv_info.serv_humannode); wprintf("Content-Type: text/html\r\n\r\n"); wprintf("

"); @@ -772,8 +760,8 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, { struct urlcontent *u; - lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", - name, cbtype, length); + /* lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", + name, cbtype, length); */ /* Form fields */ if ( (length > 0) && (strlen(cbtype) == 0) ) { @@ -804,6 +792,104 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, } +/* + * Convenience functions to wrap around asynchronous ajax responses + */ +void begin_ajax_response(void) { + output_headers(0, 0, 0, 0, 0, 0); + + wprintf("Content-type: text/html; charset=UTF-8\r\n" + "Server: %s\r\n" + "Connection: close\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n", + SERVER); + begin_burst(); +} + +void end_ajax_response(void) { + wprintf("\r\n"); + wDumpContent(0); +} + +void ajax_servcmd(void) +{ + char buf[1024]; + char gcontent[1024]; + 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); + } + wprintf("000"); + } + if (buf[0] == '4') { + text_to_server(bstr("g_input"), 0); + 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]); + junk = malloc(len); + memset(junk, 0, len); + serv_write(junk, len); + free(junk); + } + + end_ajax_response(); + + /* This is kind of an ugly hack, but this is the only place it can go. + * If the command was GEXP, then the instant messenger window must be + * running, so reset the "last_pager_check" watchdog timer so + * 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); + } +} + + +/* + * Helper function for the asynchronous check to see if we need + * to open the instant messenger window. + */ +void seconds_since_last_gexp(void) +{ + char buf[256]; + + begin_ajax_response(); + if ( (time(NULL) - WC->last_pager_check) < 30) { + wprintf("NO\n"); + } + else { + serv_puts("NOOP"); + serv_getln(buf, sizeof buf); + if (buf[3] == '*') { + wprintf("YES"); + } + else { + wprintf("NO"); + } + } + end_ajax_response(); +} + @@ -813,11 +899,17 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, void session_loop(struct httprequest *req) { char cmd[1024]; - char action[128]; + char action[1024]; char arg1[128]; char arg2[128]; char arg3[128]; + char arg4[128]; + char arg5[128]; + char arg6[128]; + char arg7[128]; char buf[SIZ]; + char request_method[128]; + char pathname[1024]; int a, b; int ContentLength = 0; int BytesRead = 0; @@ -825,9 +917,10 @@ void session_loop(struct httprequest *req) char *content = NULL; char *content_end = NULL; struct httprequest *hptr; - char browser_host[SIZ]; - char user_agent[SIZ]; + char browser_host[256]; + char user_agent[256]; int body_start = 0; + int is_static = 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. @@ -846,11 +939,11 @@ void session_loop(struct httprequest *req) safestrncpy(c_httpauth_string, "", sizeof c_httpauth_string); safestrncpy(c_httpauth_user, DEFAULT_HTTPAUTH_USER, sizeof c_httpauth_user); safestrncpy(c_httpauth_pass, DEFAULT_HTTPAUTH_PASS, sizeof c_httpauth_pass); + strcpy(browser_host, ""); WC->upload_length = 0; WC->upload = NULL; WC->vars = NULL; - WC->is_wap = 0; hptr = req; @@ -859,28 +952,49 @@ void session_loop(struct httprequest *req) safestrncpy(cmd, hptr->line, sizeof cmd); hptr = hptr->next; extract_token(request_method, cmd, 0, ' ', sizeof request_method); + extract_token(pathname, cmd, 1, ' ', sizeof pathname); /* Figure out the action */ - extract_token(action, cmd, 1, '/', sizeof action); + extract_token(action, pathname, 1, '/', sizeof action); if (strstr(action, "?")) *strstr(action, "?") = 0; if (strstr(action, "&")) *strstr(action, "&") = 0; if (strstr(action, " ")) *strstr(action, " ") = 0; - extract_token(arg1, cmd, 2, '/', sizeof arg1); + extract_token(arg1, pathname, 2, '/', sizeof arg1); if (strstr(arg1, "?")) *strstr(arg1, "?") = 0; if (strstr(arg1, "&")) *strstr(arg1, "&") = 0; if (strstr(arg1, " ")) *strstr(arg1, " ") = 0; - extract_token(arg2, cmd, 3, '/', sizeof arg2); + extract_token(arg2, pathname, 3, '/', sizeof arg2); if (strstr(arg2, "?")) *strstr(arg2, "?") = 0; if (strstr(arg2, "&")) *strstr(arg2, "&") = 0; if (strstr(arg2, " ")) *strstr(arg2, " ") = 0; - extract_token(arg3, cmd, 4, '/', sizeof arg3); + extract_token(arg3, pathname, 4, '/', sizeof arg3); if (strstr(arg3, "?")) *strstr(arg3, "?") = 0; if (strstr(arg3, "&")) *strstr(arg3, "&") = 0; if (strstr(arg3, " ")) *strstr(arg3, " ") = 0; + extract_token(arg4, pathname, 5, '/', sizeof arg4); + if (strstr(arg4, "?")) *strstr(arg4, "?") = 0; + if (strstr(arg4, "&")) *strstr(arg4, "&") = 0; + if (strstr(arg4, " ")) *strstr(arg4, " ") = 0; + + extract_token(arg5, pathname, 6, '/', sizeof arg5); + if (strstr(arg5, "?")) *strstr(arg5, "?") = 0; + if (strstr(arg5, "&")) *strstr(arg5, "&") = 0; + if (strstr(arg5, " ")) *strstr(arg5, " ") = 0; + + extract_token(arg6, pathname, 7, '/', sizeof arg6); + if (strstr(arg6, "?")) *strstr(arg6, "?") = 0; + if (strstr(arg6, "&")) *strstr(arg6, "&") = 0; + if (strstr(arg6, " ")) *strstr(arg6, " ") = 0; + + extract_token(arg7, pathname, 8, '/', sizeof arg7); + if (strstr(arg7, "?")) *strstr(arg7, "?") = 0; + if (strstr(arg7, "&")) *strstr(arg7, "&") = 0; + if (strstr(arg7, " ")) *strstr(arg7, " ") = 0; + while (hptr != NULL) { safestrncpy(buf, hptr->line, sizeof buf); hptr = hptr->next; @@ -909,6 +1023,13 @@ void session_loop(struct httprequest *req) else if (!strncasecmp(buf, "Host: ", 6)) { safestrncpy(WC->http_host, &buf[6], sizeof WC->http_host); } + else if (!strncasecmp(buf, "X-Forwarded-For: ", 17)) { + safestrncpy(browser_host, &buf[17], sizeof browser_host); + while (num_tokens(browser_host, ',') > 1) { + remove_token(browser_host, 0, ','); + } + striplt(browser_host); + } /* Only WAP gateways explicitly name this content-type */ else if (strstr(buf, "text/vnd.wap.wml")) { WC->is_wap = 1; @@ -957,11 +1078,25 @@ void session_loop(struct httprequest *req) /* Static content can be sent without connecting to Citadel. */ - if (!strcasecmp(action, "static")) { - safestrncpy(buf, arg1, sizeof buf); - for (a = 0; a < strlen(buf); ++a) - if (isspace(buf[a])) + is_static = 0; + for (a=0; a<(sizeof(static_content_dirs) / sizeof(char *)); ++a) { + if (!strcasecmp(action, static_content_dirs[a])) { + is_static = 1; + } + } + if (is_static) { + snprintf(buf, sizeof buf, "%s/%s/%s/%s/%s/%s/%s/%s", + action, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + for (a=0; a<8; ++a) { + if (buf[strlen(buf)-1] == '/') { + buf[strlen(buf)-1] = 0; + } + } + for (a = 0; a < strlen(buf); ++a) { + if (isspace(buf[a])) { buf[a] = 0; + } + } output_static(buf); goto SKIP_ALL_THIS_CRAP; /* Don't try to connect */ } @@ -988,7 +1123,16 @@ void session_loop(struct httprequest *req) else { WC->connected = 1; serv_getln(buf, sizeof buf); /* get the server welcome message */ - locate_host(browser_host, WC->http_sock); + + /* From what host is our user connecting? Go with + * the host at the other end of the HTTP socket, + * unless we are following X-Forwarded-For: headers + * and such a header has already turned up something. + */ + if ( (!follow_xff) || (strlen(browser_host) == 0) ) { + locate_host(browser_host, WC->http_sock); + } + get_serv_info(browser_host, user_agent); if (serv_info.serv_rev_level < MINIMUM_CIT_VERSION) { wprintf(_("You are connected to a Citadel " @@ -1048,7 +1192,7 @@ void session_loop(struct httprequest *req) /* This needs to run early */ if (!strcasecmp(action, "rss")) { - display_rss(bstr("room")); + display_rss(bstr("room"), request_method); goto SKIP_ALL_THIS_CRAP; } @@ -1108,11 +1252,6 @@ void session_loop(struct httprequest *req) } } - /* - * If there are instant messages waiting, retrieve them for display. - */ - check_for_instant_messages(); - if (!strcasecmp(action, "image")) { output_image(); @@ -1142,8 +1281,20 @@ void session_loop(struct httprequest *req) display_main_menu(); } else if (!strcasecmp(action, "who")) { who(); + } else if (!strcasecmp(action, "sslg")) { + seconds_since_last_gexp(); } else if (!strcasecmp(action, "who_inner_html")) { - who_inner_html(); + begin_ajax_response(); + who_inner_div(); + end_ajax_response(); + } else if (!strcasecmp(action, "iconbar_ajax_menu")) { + begin_ajax_response(); + do_iconbar(); + end_ajax_response(); + } else if (!strcasecmp(action, "iconbar_ajax_rooms")) { + begin_ajax_response(); + do_iconbar_roomlist(); + end_ajax_response(); } else if (!strcasecmp(action, "knrooms")) { knrooms(); } else if (!strcasecmp(action, "gotonext")) { @@ -1171,7 +1322,11 @@ void session_loop(struct httprequest *req) } else if (!strcasecmp(action, "headers")) { readloop("headers"); } else if (!strcasecmp(action, "msg")) { - embed_message(); + embed_message(arg1); + } else if (!strcasecmp(action, "printmsg")) { + print_message(arg1); + } else if (!strcasecmp(action, "msgheaders")) { + display_headers(arg1); } else if (!strcasecmp(action, "display_enter")) { display_enter(); } else if (!strcasecmp(action, "post")) { @@ -1219,7 +1374,7 @@ void session_loop(struct httprequest *req) } else if (!strcasecmp(action, "editinfo")) { save_edit(_("Room info"), "EINF 1", 1); } else if (!strcasecmp(action, "display_editbio")) { - sprintf(buf, "RBIO %s", WC->wc_username); + sprintf(buf, "RBIO %s", WC->wc_fullname); display_edit(_("Your bio"), "NOOP", buf, "editbio", 3); } else if (!strcasecmp(action, "editbio")) { save_edit(_("Your bio"), "EBIO", 0); @@ -1232,13 +1387,13 @@ void session_loop(struct httprequest *req) } else if (!strcasecmp(action, "display_editpic")) { display_graphics_upload(_("your photo"), "UIMG 0|_userpic_", - "/editpic"); + "editpic"); } else if (!strcasecmp(action, "editpic")) { do_graphics_upload("UIMG 1|_userpic_"); } else if (!strcasecmp(action, "display_editroompic")) { display_graphics_upload(_("the icon for this room"), "UIMG 0|_roompic_", - "/editroompic"); + "editroompic"); } else if (!strcasecmp(action, "editroompic")) { do_graphics_upload("UIMG 1|_roompic_"); } else if (!strcasecmp(action, "delete_floor")) { @@ -1252,7 +1407,7 @@ void session_loop(struct httprequest *req) bstr("which_floor")); display_graphics_upload(_("the icon for this floor"), buf, - "/editfloorpic"); + "editfloorpic"); } else if (!strcasecmp(action, "editfloorpic")) { sprintf(buf, "UIMG 1|_floorpic_|%s", bstr("which_floor")); @@ -1294,10 +1449,12 @@ void session_loop(struct httprequest *req) display_generic(); } else if (!strcasecmp(action, "do_generic")) { do_generic(); + } else if (!strcasecmp(action, "ajax_servcmd")) { + ajax_servcmd(); } else if (!strcasecmp(action, "display_menubar")) { display_menubar(1); - } else if (!strcasecmp(action, "output_mimepart")) { - output_mimepart(); + } else if (!strcasecmp(action, "mimepart")) { + mimepart(arg1, arg2); } else if (!strcasecmp(action, "edit_vcard")) { edit_vcard(); } else if (!strcasecmp(action, "submit_vcard")) { @@ -1312,8 +1469,6 @@ void session_loop(struct httprequest *req) create_user(); } else if (!strcasecmp(action, "changeview")) { change_view(); - } else if (!strcasecmp(action, "do_stuff_to_msgs")) { - do_stuff_to_msgs(); } else if (!strcasecmp(action, "change_start_page")) { change_start_page(); } else if (!strcasecmp(action, "display_floorconfig")) { @@ -1336,8 +1491,10 @@ void session_loop(struct httprequest *req) #endif } else if (!strcasecmp(action, "summary")) { summary(); - } else if (!strcasecmp(action, "iconbar")) { - do_iconbar(); + } else if (!strcasecmp(action, "summary_inner_div")) { + begin_ajax_response(); + summary_inner_div(); + end_ajax_response(); } else if (!strcasecmp(action, "display_customize_iconbar")) { display_customize_iconbar(); } else if (!strcasecmp(action, "commit_iconbar")) { @@ -1355,9 +1512,15 @@ void session_loop(struct httprequest *req) } else if (!strcasecmp(action, "set_preferences")) { set_preferences(); } else if (!strcasecmp(action, "recp_autocomplete")) { - recp_autocomplete(); + recp_autocomplete(bstr("recp")); + } else if (!strcasecmp(action, "cc_autocomplete")) { + recp_autocomplete(bstr("cc")); + } else if (!strcasecmp(action, "bcc_autocomplete")) { + recp_autocomplete(bstr("bcc")); + } else if (!strcasecmp(action, "set_floordiv_expanded")) { + set_floordiv_expanded(arg1); } else if (!strcasecmp(action, "diagnostics")) { - output_headers(1, 1, 1, 0, 0, 0, 0); + output_headers(1, 1, 1, 0, 0, 0); wprintf("Session: %d
\n", WC->wc_session); wprintf("Command:
\n");
 		escputs(cmd);
@@ -1384,5 +1547,4 @@ SKIP_ALL_THIS_CRAP:
 		free(WC->upload);
 		WC->upload_length = 0;
 	}
-
 }