📄 minihttp.c
字号:
/* Initialize command handlers. */ rv = http_init_handlers(); if (rv != SSM_SUCCESS) goto loser;#ifdef ALLOW_STANDALONE if (standalone) { SSM_DEBUG("*** STANDALONE MODE ***\n"); SSM_DEBUG("Opening a socket on port %d.\n", SSM_STANDALONE_HTTP_PORT); httpListenPort = SSM_STANDALONE_HTTP_PORT; httpListenSocket = PR_NewTCPSocket(); if (!httpListenSocket) goto loser; rv = PR_InitializeNetAddr(PR_IpAddrAny, (PRUint16) SSM_STANDALONE_HTTP_PORT, &httpAddr); if (rv != PR_SUCCESS) goto loser; rv = PR_Bind(httpListenSocket, &httpAddr); if (rv != PR_SUCCESS) goto loser; rv = PR_Listen(httpListenSocket, MAX_CONNECTIONS); if (rv != PR_SUCCESS) goto loser; SSM_DEBUG("Creating a control connection for standalone mode.\n"); rv = SSMControlConnection_Create(NULL, NULL, (SSMResource **) &standalone_conn); if (rv != PR_SUCCESS) goto loser; /* We have to invoke the Hello handler ourselves, since there will be no Hello message forthcoming. */ /* Set up profile and password information. */ if (standalone_conn->m_profileName == NULL) { /* For now, use a default of "PSM". */ standalone_conn->m_profileName = PL_strdup("PSM"); PR_ASSERT(standalone_conn->m_profileName); } rv = SSMControlConnection_SetupNSS(standalone_conn); if (rv != PR_SUCCESS) goto loser; } else {#endif /* Open a port for HTTP connections. Can be any port. */ httpListenSocket = SSM_OpenPort(); if (!httpListenSocket) goto loser; /* Publish the port number for client use */ rv = PR_GetSockName(httpListenSocket, &httpAddr); if (rv != PR_SUCCESS) goto loser; httpListenPort = (PRUint32) PR_ntohs(httpAddr.inet.port);#ifdef ALLOW_STANDALONE }#endif /* Start listening for HTTP connections. */ httpListenThread = PR_CreateThread(PR_USER_THREAD, SSM_HTTPThread, (void *)httpListenSocket, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (!httpListenThread) goto loser; goto done; loser: if (rv == SSM_SUCCESS) rv = SSM_FAILURE; if (httpListenSocket) PR_Close(httpListenSocket); if (httpListenPort) httpListenPort = 0; done: return rv;}PRUint32 SSM_GetHTTPPort(void){ return httpListenPort;}SSMStatusSSM_AccessPtToURL(SSMDialogSelector sel, char *url){ return PR_SUCCESS;}SSMStatusSSM_GenerateURL(SSMControlConnection *conn, char *command, char *baseRef, /* can pass NULL for this (but don't do that) */ SSMResource *target, /* can pass NULL for this */ char *otherParams, /* can pass NULL for this */ PRUint32 *width, PRUint32 *height, char **url){ char *result = NULL; char *targetParam = NULL; char *baseRefParam = NULL; char *auth = NULL; char * htmlParams = NULL; SSMStatus rv = SSM_SUCCESS; SSMTextGenContext *cx=NULL; /* in case we fail */ *url = NULL; *width = 0; *height = 0; if (conn) { auth = PR_smprintf("%d:%s@", conn->super.super.m_id, conn->m_nonce); if (!auth) goto loser; } rv = SSMTextGen_NewTopLevelContext(NULL, &cx); if (rv != SSM_SUCCESS) goto loser; if ((!target) && (conn)) /* target == control connection by default */ target = &conn->super.super; if (baseRef) baseRefParam = PR_smprintf("baseRef=%s", baseRef); if (target) targetParam = PR_smprintf("%starget=%ld", baseRefParam ? "&" : "", target->m_id); if (otherParams) { char * params = PL_strdup(otherParams); char * name = NULL, * value = NULL; char * result = NULL, * tmp; char * htmlname=NULL, * htmlvalue=NULL; name = strtok(params, "="); value = strtok(NULL, "&"); while (name && value) { htmlname = SSM_ConvertStringToHTMLString(name); htmlvalue = SSM_ConvertStringToHTMLString(value); if (!htmlname || !htmlvalue) { PR_FREEIF(htmlname); PR_FREEIF(htmlvalue); goto loser; } tmp = PR_smprintf("%s%s%s=%s", result?result:"", result?"&":"", htmlname, htmlvalue); PR_FREEIF(result); result = tmp; name = strtok(NULL, "="); value = strtok(NULL, "&"); } PR_Free(params); htmlParams = result; } /* ### mwelch - We should do a gethost* to figure out the real IP address. */ result = PR_smprintf("http://%s127.0.0.1:%d/%s?%s%s%s%s", auth ? auth : "", httpListenPort, command, baseRefParam ? baseRefParam : "", targetParam ? targetParam : "", ((baseRefParam || targetParam) && otherParams) ? "&" : "", otherParams ? htmlParams : ""); if (!result) goto loser; SSM_DEBUG("Generated URL %s\n", result); /* Get width and height, if they are available. We look for strings (baseRef)_width and (baseRef)_height in the properties file. */ if (baseRef && conn) { char key[256]; PR_snprintf(key, 256, "%s_width", baseRef); rv = SSM_GetNumber(cx, key, (PRInt32 *) width); if (rv != SSM_SUCCESS) goto loser; PR_snprintf(key, 256, "%s_height", baseRef); rv = SSM_GetNumber(cx, key, (PRInt32 *) height); if (rv != SSM_SUCCESS) goto loser; } goto done; loser: if (rv == SSM_SUCCESS) rv = PR_OUT_OF_MEMORY_ERROR; PR_FREEIF(result); done: PR_FREEIF(htmlParams); PR_FREEIF(baseRefParam); PR_FREEIF(targetParam); if (url) *url = result; if (cx != NULL) { SSMTextGen_DestroyContext(cx); } PR_FREEIF(auth); return rv;}voidSSM_HTTPReportSpecificError(HTTPRequest *req, char *fmt, ...){ char *msg = NULL; va_list argp; PRExplodedTime exploded; char* timeStamp = NULL; char *finalmsg = NULL; char *tmp = NULL; va_start(argp, fmt); msg = PR_vsmprintf(fmt, argp); va_end(argp); if (!msg) goto loser; PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &exploded); timeStamp = PR_smprintf("%02i:%02i:%02i", exploded.tm_hour, exploded.tm_min, exploded.tm_sec); if (!timeStamp) goto loser; /* Check (req) param after getting the specific message and timestamp, because we can still report it in the log. */ if (!req) goto loser; finalmsg = PR_smprintf("[%s] %s", timeStamp, msg); if (!finalmsg) goto loser; tmp = req->errormsg; req->errormsg = PR_smprintf("%s%s", (tmp) ? tmp : "", finalmsg); if (req->errormsg == NULL) { goto loser; } PR_FREEIF(tmp); tmp = NULL; goto done;loser: SSM_DEBUG("Couldn't report the following error message to the HTTP client.\n");done: if (msg) { SSM_DEBUG("HTTP error msg: %s\n", msg); PR_smprintf_free(msg); } if (timeStamp) PR_smprintf_free(timeStamp); if (finalmsg) PR_smprintf_free(finalmsg); if (tmp != NULL) PR_smprintf_free(tmp);}SSMStatus SSM_HTTPHandleOKCancelClick(HTTPRequest *req, PRBool closeIfCancel){ SSMResource *res = NULL; char *buttonValue; SSMStatus rv; res = (req->target) ? req->target : (SSMResource *)req->ctrlconn; /* First let's figure out which button was pressed */ rv = SSM_HTTPParamValue(req, "OK", &buttonValue); if (rv == SSM_SUCCESS) { res->m_buttonType = SSM_BUTTON_OK; } else { rv = SSM_HTTPParamValue(req, "Cancel", &buttonValue); if (rv == SSM_SUCCESS) { res->m_buttonType = SSM_BUTTON_CANCEL; } } if (rv != SSM_SUCCESS) { /* Could not find either OK or Cancel, something went really * wrong */ rv = SSM_ERR_NO_BUTTON; goto loser; } rv = SSM_HTTPParamValue(req, "formName", &buttonValue); if (rv != SSM_SUCCESS || buttonValue == NULL) { /* * The form name was not included in the form to submit. */ rv = SSM_ERR_NO_FORM_NAME; } if (res->m_formName != NULL) { /* Free any previously allocated strings. */ PR_Free(res->m_formName); } res->m_formName = PL_strdup(buttonValue); /* Fall thru on success */ loser: if (res->m_buttonType == SSM_BUTTON_CANCEL && closeIfCancel) { rv = SSM_HTTPCloseWindow(req); /* * Usually some other function is called to notify the resource, * but this makes that no longer true, so let's do it here. */ SSM_LockResource(res); SSM_NotifyResource(res); SSM_UnlockResource(res); } else { rv = SSM_HTTPDefaultCommandHandler(req); } /* There should be some thread waiting on this event, notify it * now that we've processed the button press */ SSM_NotifyOKCancelEvent(res); return rv; }SSMStatus SSM_HTTPOKCancelHandler(HTTPRequest *req){ SSMResource *target = NULL; SSMStatus rv=SSM_ERR_NO_TARGET; target = (req->target) ? req->target : (SSMResource *)req->ctrlconn; if (target) { /* Get a reference on the target object so that it doesn't get deleted from underneath us. */ rv = SSM_HTTPHandleOKCancelClick(req, PR_FALSE); } return rv;}SSMStatus SSM_HTTPFormSubmitHandler(HTTPRequest *req){ if (req->target != NULL) { return(*req->target->m_submit_func)(req->target, req); } return SSM_FAILURE;}SSMStatus SSM_HTTPCloseWindow(HTTPRequest *req){ SSMTextGenContext * cx = NULL; SSMResource * target; char * redirectHTML = NULL; SSMStatus rv = SSM_FAILURE; /* Get the target resource. */ target = (req->target ? req->target : (SSMResource *) req->ctrlconn); PR_ASSERT(target); rv = SSMTextGen_NewTopLevelContext(req, &cx); rv = SSM_GetAndExpandText(cx, "windowclose_doclose_js_content", &redirectHTML); if (rv != SSM_SUCCESS) SSM_DEBUG("HTTPCloseWindow: can't create redirectHTML"); req->sentResponse = PR_TRUE; SSMTextGen_DestroyContext(cx); rv = SSM_HTTPSendOKHeader(req, NULL, "text/html"); rv = SSM_HTTPSendUTF8String(req, redirectHTML); PR_Free(redirectHTML); return rv;}char *SSM_ConvertStringToHTMLString(char * string){ char * result = NULL, * resultptr, * ptr; PRIntn len; PR_ASSERT(string); len = strlen(string); ptr = string; while (*ptr) if (ispunct(*ptr++)) len += 2; result = (char *) PORT_ZAlloc(len+1); if (!result) { SSM_DEBUG("ConvertStringToHTMLString: can't allocate memory!\n"); goto loser; } /* no special character, just copy the string */ if (len == strlen(string)) { PL_strcpy(result, string); goto done; } ptr = string; resultptr = result; /* copy by character, substituting ascii value for special characters */ while (*ptr) { if (ispunct(*ptr)) { sprintf(resultptr,"%%%2x", *ptr); resultptr += 3; } else *resultptr++ = *ptr; ptr++; } done: return result;loser: PR_FREEIF(result); return NULL;}SSMStatus SSM_HTTPCloseIfCancel(HTTPRequest *req){ return SSM_HTTPHandleOKCancelClick(req, PR_TRUE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -