diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 7e581b0e0ae1b1257eec3512042aead4d270a6d8..d861a09f5b410b3a54275936ca1e713f167eb32a 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)