Commit 656b326a authored by rswindell's avatar rswindell
Browse files

Added TODO comment regarding the lack of a Content-Length header field

in GET responses when Connection: Keep-Alive is not enabled.
parent 6919a3a2
......@@ -42,13 +42,13 @@
* Add in support to pass connections through to a different webserver...
* probobly in access.ars... with like a simplified mod_rewrite.
* This would allow people to run apache and Synchronet as the same site.
*
*
* Add support for multipart/form-data
*
* Add support for UNIX-domain sockets for FastCGI
*
* Improved Win32 support for POST data... currently will read past Content-Length
*
*
*/
/* Headers for CGI stuff */
......@@ -96,7 +96,7 @@ static int len_503 = 0;
#define TIMEOUT_THREAD_WAIT 60 /* Seconds */
#define MAX_REQUEST_LINE 1024 /* NOT including terminator */
#define MAX_HEADERS_SIZE 16384 /* Maximum total size of all headers
#define MAX_HEADERS_SIZE 16384 /* Maximum total size of all headers
(Including terminator )*/
#define MAX_REDIR_LOOPS 20 /* Max. times to follow internal redirects for a single request */
#define MAX_POST_LEN 1048576 /* Max size of body for POSTS */
......@@ -307,7 +307,7 @@ static char* http_vers[] = {
,NULL /* terminator */
};
enum {
enum {
HTTP_HEAD
,HTTP_GET
,HTTP_POST
......@@ -656,9 +656,9 @@ static int sess_sendbuf(http_session_t *session, const char *buf, size_t len, BO
else {
result=sendsocket(session->socket,buf+sent,len-sent);
if(result==SOCKET_ERROR) {
if(ERROR_VALUE==ECONNRESET)
if(ERROR_VALUE==ECONNRESET)
lprintf(LOG_NOTICE,"%04d Connection reset by peer on send",session->socket);
else if(ERROR_VALUE==ECONNABORTED)
else if(ERROR_VALUE==ECONNABORTED)
lprintf(LOG_NOTICE,"%04d Connection aborted by peer on send",session->socket);
#ifdef EPIPE
else if(ERROR_VALUE==EPIPE)
......@@ -1132,7 +1132,7 @@ static int get_header_type(char *header)
}
/* Opposite of get_header_type() */
static char *get_header(int id)
static char *get_header(int id)
{
int i;
if(headers[id].id==id)
......@@ -1339,6 +1339,10 @@ static BOOL send_headers(http_session_t *session, const char *status, int chunke
}
/* DO NOT send a content-length for chunked */
/* TODO: Why aren't we sending a Content-Length header for GET responses?
* Per RFC 2068 (HTTP/1.1):
* "it SHOULD be sent whenever the message's length can be determined prior to being transferred"
*/
if(send_entity) {
if((session->req.keep_alive || session->req.method == HTTP_HEAD) && session->req.dynamic!=IS_CGI&& session->req.dynamic!=IS_FASTCGI && (!chunked)) {
if(ret) {
......@@ -1809,7 +1813,7 @@ static void badlogin(SOCKET sock, const char* prot, const char* user, const char
if(startup->login_attempt.hack_threshold && count>=startup->login_attempt.hack_threshold) {
hacklog(&scfg, reason, user, passwd, host, addr);
#ifdef _WIN32
if(startup->hack_sound[0] && !(startup->options&BBS_OPT_MUTE))
if(startup->hack_sound[0] && !(startup->options&BBS_OPT_MUTE))
PlaySound(startup->hack_sound, NULL, SND_ASYNC|SND_FILENAME);
#endif
}
......@@ -1977,7 +1981,7 @@ static BOOL check_ars(http_session_t * session)
,session->socket,session->req.auth.username,session->req.ars);
#ifdef _WIN32
if(startup->hack_sound[0] && !(startup->options&BBS_OPT_MUTE))
if(startup->hack_sound[0] && !(startup->options&BBS_OPT_MUTE))
PlaySound(startup->hack_sound, NULL, SND_ASYNC|SND_FILENAME);
#endif
......@@ -2222,7 +2226,7 @@ static void unescape(char *p)
{
char * dst;
char code[3];
dst=p;
for(;*p;p++) {
if(*p=='%' && isxdigit((uchar)*(p+1)) && isxdigit((uchar)*(p+2))) {
......@@ -2332,7 +2336,7 @@ static void js_add_request_prop(http_session_t * session, char *key, char *value
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
}
static void js_add_header(http_session_t * session, char *key, char *value)
static void js_add_header(http_session_t * session, char *key, char *value)
{
JSString* js_str;
char *lckey;
......@@ -2743,29 +2747,29 @@ static BOOL parse_js_headers(http_session_t * session)
*
* And example reponse looks like this:
* Content-type: multipart/form-data, boundary=AaB03x
*
*
* --AaB03x
* content-disposition: form-data; name="field1"
*
*
* Joe Blow
* --AaB03x
* content-disposition: form-data; name="pics"
* Content-type: multipart/mixed, boundary=BbC04y
*
*
* --BbC04y
* Content-disposition: attachment; filename="file1.txt"
*
*
* Content-Type: text/plain
*
*
* ... contents of file1.txt ...
* --BbC04y
* Content-disposition: attachment; filename="file2.gif"
* Content-type: image/gif
* Content-Transfer-Encoding: binary
*
*
* ...contents of file2.gif...
* --BbC04y--
* --AaB03x--
* --AaB03x--
*/
}
break;
......@@ -2948,7 +2952,7 @@ static char *get_request(http_session_t * session, char *req_line)
/* Sets p to point to the first character after the first slash */
p=strchr(session->req.physical_path, '/');
/*
* If we have a slash, make it the first char in the string.
* otherwise, set path to "/"
......@@ -3150,7 +3154,7 @@ static BOOL get_req(http_session_t * session, char *request_line)
add_env(session,"QUERY_STRING",session->req.query_str);
add_env(session,"REQUEST_METHOD",methods[session->req.method]);
add_env(session,"SERVER_PROTOCOL",session->http_ver ?
add_env(session,"SERVER_PROTOCOL",session->http_ver ?
http_vers[session->http_ver] : "HTTP/0.9");
return(TRUE);
}
......@@ -3366,7 +3370,7 @@ static void read_webctrl_section(FILE *file, char *section, http_session_t *sess
p = iniReadExistingString(file, section, "AccessRequirements", session->req.ars, str);
/*
* If p == NULL, the key doesn't exist, retain default
* If p == NULL, the key doesn't exist, retain default
* If p == default, zero-length string present, truncate req.ars
* Otherwise, p is new value and is updated
*/
......@@ -3607,7 +3611,7 @@ static BOOL check_request(http_session_t * session)
if(!check_ars(session)) {
unsigned *auth_list;
unsigned auth_list_len;
/* No authentication provided */
strcpy(str,"401 Unauthorized");
auth_list=parseEnumList(session->req.auth_list?session->req.auth_list:default_auth_list, ",", auth_type_names, &auth_list_len);
......@@ -4715,7 +4719,7 @@ static BOOL exec_cgi(http_session_t *session)
}
}
/* Drain STDERR & STDOUT */
/* Drain STDERR & STDOUT */
tv.tv_sec=1;
tv.tv_usec=0;
FD_ZERO(&read_set);
......@@ -4869,7 +4873,7 @@ static BOOL exec_cgi(http_session_t *session)
);
strListFreeBlock(env_block);
if(!success) {
lprintf(LOG_ERR,"%04d !ERROR %d running %s",session->socket,GetLastError(),cmdline);
return(FALSE);
......@@ -4894,7 +4898,7 @@ static BOOL exec_cgi(http_session_t *session)
lprintf(LOG_WARNING,"%04d Terminating CGI process: %s"
,session->socket,getfname(cmdline));
TerminateProcess(process_info.hProcess, GetLastError());
}
}
if(rdpipe!=INVALID_HANDLE_VALUE)
CloseHandle(rdpipe);
......@@ -4905,7 +4909,7 @@ static BOOL exec_cgi(http_session_t *session)
if(!got_valid_headers)
lprintf(LOG_WARNING,"%04d !CGI Process %s did not generate valid headers"
,session->socket,getfname(cmdline));
if(!done_parsing_headers)
lprintf(LOG_WARNING,"%04d !CGI Process %s did not send data header termination"
,session->socket,getfname(cmdline));
......@@ -4925,7 +4929,7 @@ JSObject* DLLCALL js_CreateHttpReplyObject(JSContext* cx
JSObject* headers;
jsval val;
JSString* js_str;
/* Return existing object if it's already been created */
if(JS_GetProperty(cx,parent,"http_reply",&val) && val!=JSVAL_VOID) {
reply = JSVAL_TO_OBJECT(val);
......@@ -5017,7 +5021,7 @@ js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
if((session=(http_session_t*)JS_GetContextPrivate(cx))==NULL)
return;
if(report==NULL) {
lprintf(LOG_ERR,"%04d !JavaScript: %s", session->socket, message);
if(session->req.fp!=NULL)
......@@ -5269,7 +5273,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
/* User name */
JSVALUE_TO_ASTRING(cx, argv[0], p, (LEN_ALIAS > LEN_NAME) ? LEN_ALIAS+2 : LEN_NAME+2, NULL);
if(p==NULL)
if(p==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
......@@ -5299,7 +5303,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
/* Password */
if(user.pass[0]) {
JSVALUE_TO_ASTRING(cx, argv[1], p, LEN_PASS+2, NULL);
if(p==NULL)
if(p==NULL)
return(JS_FALSE);
if(stricmp(user.pass,p)) { /* Wrong password */
......@@ -5565,7 +5569,7 @@ js_OperationCallback(JSContext *cx)
return ret;
}
static JSContext*
static JSContext*
js_initcx(http_session_t *session)
{
JSContext* js_cx;
......@@ -5644,7 +5648,7 @@ static BOOL js_setup_cx(http_session_t* session)
}
else
JS_BEGINREQUEST(session->js_cx);
lprintf(LOG_DEBUG,"%04d JavaScript: Initializing HttpRequest object",session->socket);
if(js_CreateHttpRequestObject(session->js_cx, session->js_glob, session)==NULL) {
lprintf(LOG_ERR,"%04d !ERROR initializing JavaScript HttpRequest object",session->socket);
......@@ -5812,7 +5816,7 @@ static BOOL exec_ssjs(http_session_t* session, char* script) {
session->req.dynamic=IS_SSJS;
JS_ENDREQUEST(session->js_cx);
return(retval);
}
......@@ -6131,7 +6135,7 @@ void http_output_thread(void *arg)
if(avail>mss)
len=(avail=mss);
/*
/*
* Read the current value of write_chunked... since we wait until the
* ring buffer is empty before fiddling with it.
*/
......@@ -6213,7 +6217,7 @@ void http_session_thread(void* arg)
lprintf(LOG_DEBUG,"%04d !!! DANGER WILL ROBINSON, DANGER !!!", session.socket);
#ifdef _WIN32
if(startup->answer_sound[0] && !(startup->options&BBS_OPT_MUTE))
if(startup->answer_sound[0] && !(startup->options&BBS_OPT_MUTE))
PlaySound(startup->answer_sound, NULL, SND_ASYNC|SND_FILENAME);
#endif
......@@ -6279,7 +6283,7 @@ void http_session_thread(void* arg)
lprintf(LOG_INFO,"%04d Hostname: %s", session.socket, session.host_name);
#if 0 /* gethostbyaddr() is apparently not (always) thread-safe
and getnameinfo() doesn't return alias information */
for(i=0;host!=NULL && host->h_aliases!=NULL
for(i=0;host!=NULL && host->h_aliases!=NULL
&& host->h_aliases[i]!=NULL;i++)
lprintf(LOG_INFO,"%04d HostAlias: %s", session.socket, host->h_aliases[i]);
#endif
......@@ -6365,7 +6369,7 @@ void http_session_thread(void* arg)
session.req.ld->hostname=strdup(session.host_name);
}
while((redirp==NULL || session.req.send_location >= MOVED_TEMP)
&& !session.finished && !session.req.finished
&& !session.finished && !session.req.finished
&& session.socket!=INVALID_SOCKET) {
SAFECOPY(session.req.status,"200 OK");
session.req.send_location=NO_LOCATION;
......@@ -6441,7 +6445,7 @@ void http_session_thread(void* arg)
}
#ifdef _WIN32
if(startup->hangup_sound[0] && !(startup->options&BBS_OPT_MUTE))
if(startup->hangup_sound[0] && !(startup->options&BBS_OPT_MUTE))
PlaySound(startup->hangup_sound, NULL, SND_ASYNC|SND_FILENAME);
#endif
......@@ -6493,7 +6497,7 @@ static void cleanup(int code)
semfile_list_free(&recycle_semfiles);
semfile_list_free(&shutdown_semfiles);
if(!terminated) { /* Can this be changed to a if(ws_set!=NULL) check instead? */
xpms_destroy(ws_set, close_socket_cb, NULL);
ws_set=NULL;
......@@ -6508,7 +6512,7 @@ static void cleanup(int code)
protected_uint32_destroy(active_clients);
#ifdef _WINSOCKAPI_
if(WSAInitialized && WSACleanup()!=0)
if(WSAInitialized && WSACleanup()!=0)
lprintf(LOG_ERR,"0000 !WSACleanup ERROR %d",ERROR_VALUE);
#endif
......@@ -6837,7 +6841,7 @@ void DLLCALL web_server(void* arg)
/* open a socket and wait for a client */
ws_set = xpms_create(startup->bind_retry_count, startup->bind_retry_delay, lprintf);
if(ws_set == NULL) {
lprintf(LOG_CRIT,"!ERROR %d creating HTTP socket set", ERROR_VALUE);
cleanup(1);
......@@ -6922,7 +6926,7 @@ void DLLCALL web_server(void* arg)
}
break;
}
}
}
/* Startup next session thread */
if(session==NULL) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment