Commit a59fba4a authored by rswindell's avatar rswindell
Browse files

Increase MAX_POST_LEN from 1MB to 4MB (QWK REP packets can be > 1MB) -

  I think that > 1MB post data is supported, but the http_request.post_data
  property won't be created if the length > MAX_POST_LEN. Perhaps would just
  store the post data in a file (uh, it already is?) and expose the filename to
  JS scripts? It'd be a lot cleaner than storing the data in a file and then
  reading (or mem-mapping) the file and then copying the contents into a JS
  property.

Allow the JS http_request.post_data property to contain NULs.

open_post_file() will now open the post file (and return the FILE*) even if
  session->req.post_data is NULL, it just won't try to write to the file if the
  post_data is NULL.

mem-map the large post data files using XPMAP_WRITE (read/write) rather than
  XPMAP_READ (read-only) - without this change, this line in read_post_data()
  would cause an exception:
    session->req.post_data[session->req.post_len]=0;
  Now, we seem to have the potential of an off-by-one here (if the length
  mem-mapped is not post_len + 1), but that isn't happening. <shrug>

Fixed a couple of FILE pointer/descriptor leaks if post_to_file() failed.

Changed name of post data file to SBBS_POST.*.*.data (it's not necessarily
html).

So now, uploads > 1MB work, but questions remain:
- wouldn't PUT be a more appropriate method (than POST) for file uploads?
- how can we support post_data > MAX_POST_LEN (now 4MB) in JS?
parent 2ffc00e8
......@@ -99,7 +99,7 @@ static int len_503 = 0;
#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 */
#define MAX_POST_LEN (4*1048576) /* Max size of body for POSTS */
#define OUTBUF_LEN 20480 /* Size of output thread ring buffer */
enum {
......@@ -2307,7 +2307,7 @@ static void js_add_cookieval(http_session_t * session, char *key, char *value)
JS_SetElement(session->js_cx, keyarray, alen, &val);
}
static void js_add_request_prop_writeable(http_session_t * session, char *key, char *value)
static void js_add_request_property(http_session_t * session, char *key, char *value, size_t len, bool writeable)
{
JSString* js_str;
......@@ -2315,24 +2315,29 @@ static void js_add_request_prop_writeable(http_session_t * session, char *key, c
return;
if(key==NULL || value==NULL)
return;
if((js_str=JS_NewStringCopyZ(session->js_cx, value))==NULL)
if(len)
js_str=JS_NewStringCopyN(session->js_cx, value, len);
else
js_str=JS_NewStringCopyZ(session->js_cx, value);
if(js_str == NULL)
return;
uintN attrs = JSPROP_ENUMERATE;
if(!writeable)
attrs |= JSPROP_READONLY;
JS_DefineProperty(session->js_cx, session->js_request, key, STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE);
,NULL,NULL,attrs);
}
static void js_add_request_prop(http_session_t * session, char *key, char *value)
static void js_add_request_prop_writeable(http_session_t * session, char *key, char *value)
{
JSString* js_str;
js_add_request_property(session, key, value, 0, /* writeable: */true);
}
if(session->js_cx==NULL || session->js_request==NULL)
return;
if(key==NULL || value==NULL)
return;
if((js_str=JS_NewStringCopyZ(session->js_cx, value))==NULL)
return;
JS_DefineProperty(session->js_cx, session->js_request, key, STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
static void js_add_request_prop(http_session_t * session, char *key, char *value)
{
js_add_request_property(session, key, value, 0, /* writeable: */false);
}
static void js_add_header(http_session_t * session, char *key, char *value)
......@@ -3310,7 +3315,7 @@ static BOOL exec_js_webctrl(http_session_t* session, char *name, char* script, c
}
if(session->req.post_data && session->req.post_data[0]) {
if(session->req.post_len <= MAX_POST_LEN) {
js_add_request_prop(session,"post_data",session->req.post_data);
js_add_request_property(session, "post_data", session->req.post_data, session->req.post_len, /*writeable: */false);
js_parse_query(session,session->req.post_data);
}
}
......@@ -5772,7 +5777,7 @@ static BOOL exec_ssjs(http_session_t* session, char* script) {
}
if(session->req.post_data && session->req.post_data[0]) {
if(session->req.post_len <= MAX_POST_LEN) {
js_add_request_prop(session,"post_data",session->req.post_data);
js_add_request_property(session, "post_data", session->req.post_data, session->req.post_len, /* writeable: */false);
js_parse_query(session,session->req.post_data);
}
}
......@@ -5911,13 +5916,8 @@ FILE *open_post_file(http_session_t *session)
char path[MAX_PATH+1];
FILE *fp;
if(session->req.post_data == NULL) {
lprintf(LOG_ERR, "%04d !ERROR no post data allocated?!?", session->socket);
return NULL;
}
// Create temporary file for post data.
SAFEPRINTF3(path,"%sSBBS_POST.%u.%u.html",temp_dir,getpid(),session->socket);
SAFEPRINTF3(path,"%sSBBS_POST.%u.%u.data",temp_dir,getpid(),session->socket);
if((fp=fopen(path,"wb"))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR %d opening/creating %s", session->socket, errno, path);
return fp;
......@@ -5928,12 +5928,14 @@ FILE *open_post_file(http_session_t *session)
}
/* remove()d in close_request() */
session->req.cleanup_file[CLEANUP_POST_DATA]=strdup(path);
if(fwrite(session->req.post_data, session->req.post_len, 1, fp)!=1) {
lprintf(LOG_ERR,"%04d !ERROR writeing to %s", session->socket, path);
fclose(fp);
return(FALSE);
if(session->req.post_data != NULL) {
if(fwrite(session->req.post_data, session->req.post_len, 1, fp)!=1) {
lprintf(LOG_ERR,"%04d !ERROR writeing to %s", session->socket, path);
fclose(fp);
return(FALSE);
}
FREE_AND_NULL(session->req.post_data);
}
FREE_AND_NULL(session->req.post_data);
return fp;
}
......@@ -5975,8 +5977,10 @@ int read_post_data(http_session_t * session)
if(fp==NULL)
return(FALSE);
}
if(!post_to_file(session, fp, ch_len))
if(!post_to_file(session, fp, ch_len)) {
fclose(fp);
return(FALSE);
}
}
else {
/* realloc() to new size */
......@@ -6005,7 +6009,7 @@ int read_post_data(http_session_t * session)
if(fp) {
fclose(fp);
FREE_AND_NULL(session->req.post_data);
session->req.post_map=xpmap(session->req.cleanup_file[CLEANUP_POST_DATA], XPMAP_READ);
session->req.post_map=xpmap(session->req.cleanup_file[CLEANUP_POST_DATA], XPMAP_WRITE);
if(!session->req.post_map)
return(FALSE);
session->req.post_data=session->req.post_map->addr;
......@@ -6027,10 +6031,11 @@ int read_post_data(http_session_t * session)
fp=open_post_file(session);
if(fp==NULL)
return(FALSE);
if(!post_to_file(session, fp, s))
return(FALSE);
BOOL success = post_to_file(session, fp, s);
fclose(fp);
session->req.post_map=xpmap(session->req.cleanup_file[CLEANUP_POST_DATA], XPMAP_READ);
if(!success)
return(FALSE);
session->req.post_map=xpmap(session->req.cleanup_file[CLEANUP_POST_DATA], XPMAP_WRITE);
if(!session->req.post_map)
return(FALSE);
session->req.post_data=session->req.post_map->addr;
......
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