From a212a392bd36d6f5b0c2ad8a5895386f700c44db Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sat, 5 Mar 2005 06:48:42 +0000 Subject: [PATCH] Add support for streaming-style .ssjs files. If you set http_reply.fast to true BEFORE the first write, the first write will send the headers and every write will go throug the socket immediately. This will make large .ssjs files appear to be faster (ie: Large user lists etc.) --- src/sbbs3/websrvr.c | 112 +++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 7e581b0e0a..d861a09f5b 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -192,6 +192,8 @@ typedef struct { /* Dynamically (sever-side JS) generated HTML parameters */ FILE* fp; char *cleanup_file; + BOOL sent_headers; + BOOL prev_write; } http_request_t; typedef struct { @@ -313,6 +315,7 @@ static BOOL js_setup(http_session_t* session); static char *find_last_slash(char *str); static BOOL check_extra_path(http_session_t * session); static BOOL exec_ssjs(http_session_t* session, char *script); +static BOOL ssjs_send_headers(http_session_t* session); static time_t sub_mkgmt(struct tm *tm) @@ -998,7 +1001,7 @@ static void send_error(http_session_t * session, const char* message) lprintf(LOG_INFO,"%04d Using SSJS error page",session->socket); if(js_setup(session)) { sent_ssjs=exec_ssjs(session,sbuf); - if(sent_ssjs && send_headers(session,session->req.status)) { + if(sent_ssjs) { int snt=0; lprintf(LOG_INFO,"%04d Sending generated error page",session->socket); @@ -2450,16 +2453,29 @@ js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if(session->req.fp==NULL) return(JS_FALSE); + if((!session->req.prev_write) && (!session->req.sent_headers)) { + /* "Fast Mode" requested? */ + jsval val; + JSObject* reply; + + JS_GetProperty(cx, session->js_glob, "http_reply", &val); + reply=JSVAL_TO_OBJECT(val); + JS_GetProperty(cx, reply, "fast", &val); + if(JSVAL_IS_BOOLEAN(val) && JSVAL_TO_BOOLEAN(val)) { + if(!ssjs_send_headers(session)) + return(JS_FALSE); + } + } + + session->req.prev_write=TRUE; + for(i=0; i<argc; i++) { -#if 0 if((str=JS_ValueToString(cx, argv[i]))==NULL) continue; - fprintf(session->req.fp,"%s",JS_GetStringBytes(str)); -#else - if((str=JS_ValueToString(cx, argv[i]))==NULL) - continue; - fwrite(JS_GetStringBytes(str),1,JS_GetStringLength(str),session->req.fp); -#endif + if(session->req.sent_headers) + sendsocket(session->socket, JS_GetStringBytes(str), JS_GetStringLength(str)); + else + fwrite(JS_GetStringBytes(str),1,JS_GetStringLength(str),session->req.fp); } return(JS_TRUE); @@ -2468,29 +2484,18 @@ js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - uintN i; - JSString * str; http_session_t* session; if((session=(http_session_t*)JS_GetContextPrivate(cx))==NULL) return(JS_FALSE); - if(session->req.fp==NULL) - return(JS_FALSE); + js_write(cx, obj, argc, argv, rval); - for (i=0; i<argc;i++) { -#if 0 - if((str=JS_ValueToString(cx, argv[i]))==NULL) - continue; - fprintf(session->req.fp,"%s",JS_GetStringBytes(str)); -#else - if((str=JS_ValueToString(cx, argv[i]))==NULL) - continue; - fwrite(JS_GetStringBytes(str),1,JS_GetStringLength(str),session->req.fp); -#endif - } - - fprintf(session->req.fp,"\n"); + /* Should this do the whole \r\n thing for Win32 *shudder* */ + if(session->req.sent_headers) + sendsocket(session->socket, "\n", 1); + else + fprintf(session->req.fp,"\n"); return(JS_TRUE); } @@ -2714,17 +2719,42 @@ static BOOL js_setup(http_session_t* session) return(TRUE); } -static BOOL exec_ssjs(http_session_t* session, char *script) { - JSString* js_str; - JSScript* js_script; - jsval rval; +static BOOL ssjs_send_headers(http_session_t* session) +{ jsval val; JSObject* reply; JSIdArray* heads; JSObject* headers; - char path[MAX_PATH+1]; - char str[MAX_REQUEST_LINE+1]; int i; + JSString* js_str; + char str[MAX_REQUEST_LINE+1]; + + JS_GetProperty(session->js_cx,session->js_glob,"http_reply",&val); + reply = JSVAL_TO_OBJECT(val); + JS_GetProperty(session->js_cx,reply,"status",&val); + SAFECOPY(session->req.status,JS_GetStringBytes(JSVAL_TO_STRING(val))); + JS_GetProperty(session->js_cx,reply,"header",&val); + headers = JSVAL_TO_OBJECT(val); + heads=JS_Enumerate(session->js_cx,headers); + for(i=0;i<heads->length;i++) { + JS_IdToValue(session->js_cx,heads->vector[i],&val); + js_str=JSVAL_TO_STRING(val); + JS_GetProperty(session->js_cx,headers,JS_GetStringBytes(js_str),&val); + safe_snprintf(str,sizeof(str),"%s: %s" + ,JS_GetStringBytes(js_str),JS_GetStringBytes(JSVAL_TO_STRING(val))); + listPushNodeString(&session->req.dynamic_heads,str); + } + JS_DestroyIdArray(session->js_cx, heads); + session->req.sent_headers=TRUE; + return(send_headers(session,session->req.status)); +} + +static BOOL exec_ssjs(http_session_t* session, char *script) { + JSScript* js_script; + jsval rval; + jsval val; + char path[MAX_PATH+1]; + BOOL retval=TRUE; sprintf(path,"%sSBBS_SSJS.%u.%u.html",temp_dir,getpid(),session->socket); if((session->req.fp=fopen(path,"wb"))==NULL) { @@ -2756,26 +2786,12 @@ static BOOL exec_ssjs(http_session_t* session, char *script) { } JS_ExecuteScript(session->js_cx, session->js_glob, js_script, &rval); - } while(0); /* Read http_reply object */ - JS_GetProperty(session->js_cx,session->js_glob,"http_reply",&val); - reply = JSVAL_TO_OBJECT(val); - JS_GetProperty(session->js_cx,reply,"status",&val); - SAFECOPY(session->req.status,JS_GetStringBytes(JSVAL_TO_STRING(val))); - JS_GetProperty(session->js_cx,reply,"header",&val); - headers = JSVAL_TO_OBJECT(val); - heads=JS_Enumerate(session->js_cx,headers); - for(i=0;i<heads->length;i++) { - JS_IdToValue(session->js_cx,heads->vector[i],&val); - js_str=JSVAL_TO_STRING(val); - JS_GetProperty(session->js_cx,headers,JS_GetStringBytes(js_str),&val); - safe_snprintf(str,sizeof(str),"%s: %s" - ,JS_GetStringBytes(js_str),JS_GetStringBytes(JSVAL_TO_STRING(val))); - listPushNodeString(&session->req.dynamic_heads,str); + if(!session->req.sent_headers) { + retval=ssjs_send_headers(session); } - JS_DestroyIdArray(session->js_cx, heads); /* Free up temporary resources here */ @@ -2789,7 +2805,7 @@ static BOOL exec_ssjs(http_session_t* session, char *script) { SAFECOPY(session->req.physical_path, path); session->req.dynamic=IS_SSJS; - return(TRUE); + return(retval); } static void respond(http_session_t * session) -- GitLab