static void startProxy(HttpQueue *q) { #if UNUSED HttpConn *conn, *target; MprHash *hp; conn = q->conn; rx = conn->rx; loc = rx->loc; httpo uri = httpJoinUriPath(NULL, rx->parsedUri, loc->prefix); pp->target = getConnection(conn); - how to hook into the pipeline for the target if (httpConnect(pp->target, rx->method, httpUriToString(uri)) < 0) { for (mprGetFirstHash(rx->headers); hp; hp = mprGetNextHash(rx->headers, hp)) { httpSetHeader(target, hp->key, hp->data); } httpSetHeader(target, "X-Forwarded-Host", ); httpSetHeader(target, "Host", ); httpSetHeader(target, "X-Forwarded-Server", ); httpSetHeader(target, "X-Forwarded-For", ); } // Push headers out - this may not work httpFlush(conn); #endif }
/* * Define params[] using query and post form data */ static void defineParams(void *handle) { MprHash *hp; hp = mprGetFirstHash(formVars); while (hp) { ejsDefineWebParam(ejs, hp->key, hp->data); hp = mprGetNextHash(formVars, hp); } }
/* * Define params[] */ static void defineParams(void *handle) { Ejs *ejs; MaConn *conn; MprHashTable *formVars; MprHash *hp; conn = (MaConn*) handle; formVars = conn->request->formVars; ejs = ((EjsWeb*) maGetHandlerQueueData(conn))->ejs; hp = mprGetFirstHash(formVars); while (hp) { ejsDefineWebParam(ejs, hp->key, hp->data); hp = mprGetNextHash(formVars, hp); } }
/* * Define form variables using any query data */ static void defineFormVars(void *handle) { MprHash *hp; MaConn *conn; MaRequest *req; Ejs *ejs; conn = (MaConn*) handle; req = conn->request; mprAssert(req->formVars); ejs = ((EjsWeb*) maGetHandlerQueueData(conn))->ejs; hp = mprGetFirstHash(req->formVars); while (hp) { ejsDefineWebParam(ejs, hp->key, hp->data); hp = mprGetNextHash(req->formVars, hp); } }
/* * Emit all headers */ static void emitHeaders() { MprHash *hp; int len; hp = mprGetFirstHash(responseHeaders); while (hp) { len = strlen(hp->key) + strlen(hp->data) + 4; if (mprGetBufSpace(headerOutput) < len) { flushOutput(headerOutput); } mprPutStringToBuf(headerOutput, hp->key); mprPutStringToBuf(headerOutput, ": "); mprPutStringToBuf(headerOutput, hp->data); mprPutStringToBuf(headerOutput, "\r\n"); hp = mprGetNextHash(responseHeaders, hp); } mprPutStringToBuf(headerOutput, "\r\n"); flushOutput(headerOutput); headersEmitted = 1; }
static void startCgi(MaQueue *q) { MaRequest *req; MaConn *conn; MprCmd *cmd; MprHash *hp; cchar *baseName; char **argv, **envv, *fileName; int index, argc, varCount; argv = 0; argc = 0; conn = q->conn; req = conn->request; if ((req->form || req->flags & MA_REQ_UPLOADING) && conn->state <= MPR_HTTP_STATE_CONTENT) { /* Delay starting the CGI process if uploading files or a form request. This enables env vars to be defined with file upload and form data before starting the CGI gateway. */ return; } cmd = q->queueData = mprCreateCmd(req); if (conn->http->forkCallback) { cmd->forkCallback = conn->http->forkCallback; cmd->forkData = conn->http->forkData; } /* Build the commmand line arguments */ argc = 1; /* argv[0] == programName */ buildArgs(conn, cmd, &argc, &argv); fileName = argv[0]; baseName = mprGetPathBase(q, fileName); if (strncmp(baseName, "nph-", 4) == 0 || (strlen(baseName) > 4 && strcmp(&baseName[strlen(baseName) - 4], "-nph") == 0)) { /* Pretend we've seen the header for Non-parsed Header CGI programs */ cmd->userFlags |= MA_CGI_SEEN_HEADER; } /* Build environment variables */ varCount = mprGetHashCount(req->headers) + mprGetHashCount(req->formVars); envv = (char**) mprAlloc(cmd, (varCount + 1) * (int) sizeof(char*)); index = 0; hp = mprGetFirstHash(req->headers); while (hp) { if (hp->data) { envv[index] = mprStrcat(cmd, -1, hp->key, "=", (char*) hp->data, NULL); index++; } hp = mprGetNextHash(req->headers, hp); } hp = mprGetFirstHash(req->formVars); while (hp) { if (hp->data) { envv[index] = mprStrcat(cmd, -1, hp->key, "=", (char*) hp->data, NULL); index++; } hp = mprGetNextHash(req->formVars, hp); } envv[index] = 0; mprAssert(index <= varCount); cmd->stdoutBuf = mprCreateBuf(cmd, MA_BUFSIZE, -1); cmd->stderrBuf = mprCreateBuf(cmd, MA_BUFSIZE, -1); cmd->lastActivity = mprGetTime(cmd); mprSetCmdDir(cmd, mprGetPathDir(q, fileName)); mprSetCmdCallback(cmd, cgiCallback, conn); maSetHeader(conn, 0, "Last-Modified", req->host->currentDate); maDontCacheResponse(conn); maPutForService(q, maCreateHeaderPacket(q), 0); if (mprStartCmd(cmd, argc, argv, envv, MPR_CMD_IN | MPR_CMD_OUT | MPR_CMD_ERR) < 0) { maFailRequest(conn, MPR_HTTP_CODE_SERVICE_UNAVAILABLE, "Can't run CGI process: %s, URI %s", fileName, req->url); return; } /* This will dedicate this thread to the connection. It will also put the socket into blocking mode. */ maDedicateThreadToConn(conn); }
static void runPhp(MaQueue *q) { MaConn *conn; MaRequest *req; MaResponse *resp; MprHash *hp; MaPhp *php; FILE *fp; char shebang[MPR_MAX_STRING]; zend_file_handle file_handle; TSRMLS_FETCH(); conn = q->conn; req = conn->request; resp = conn->response; php = q->queueData; maPutForService(q, maCreateHeaderPacket(q), 0); /* * Set the request context */ zend_first_try { php->var_array = 0; SG(server_context) = conn; if (req->user) { SG(request_info).auth_user = estrdup(req->user); } if (req->password) { SG(request_info).auth_password = estrdup(req->password); } if (req->authType && req->authDetails) { SG(request_info).auth_digest = estrdup(mprAsprintf(req, -1, "%s %s", req->authType, req->authDetails)); } SG(request_info).auth_password = req->password; SG(request_info).content_type = req->mimeType; SG(request_info).content_length = req->length; SG(sapi_headers).http_response_code = MPR_HTTP_CODE_OK; SG(request_info).path_translated = resp->filename; SG(request_info).query_string = req->parsedUri->query; SG(request_info).request_method = req->methodName; SG(request_info).request_uri = req->url; /* * Workaround on MAC OS X where the SIGPROF is given to the wrong thread */ PG(max_input_time) = -1; EG(timeout_seconds) = 0; /* The readPostData callback may be invoked during startup */ php_request_startup(TSRMLS_C); CG(zend_lineno) = 0; } zend_catch { mprError(q, "Can't start PHP request"); zend_try { php_request_shutdown(0); } zend_end_try(); maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP initialization failed"); return; } zend_end_try(); /* * Define header variables */ zend_try { hp = mprGetFirstHash(req->headers); while (hp) { if (hp->data) { php_register_variable(hp->key, (char*) hp->data, php->var_array TSRMLS_CC); mprLog(q, 6, "php: header var %s = %s", hp->key, hp->data); } hp = mprGetNextHash(req->headers, hp); } hp = mprGetFirstHash(req->formVars); while (hp) { if (hp->data) { php_register_variable(hp->key, (char*) hp->data, php->var_array TSRMLS_CC); mprLog(q, 6, "php: form var %s = %s", hp->key, hp->data); } hp = mprGetNextHash(req->formVars, hp); } } zend_end_try(); /* * Execute the script file */ file_handle.filename = resp->filename; file_handle.free_filename = 0; file_handle.opened_path = 0; #if LOAD_FROM_FILE file_handle.type = ZEND_HANDLE_FILENAME; #else file_handle.type = ZEND_HANDLE_FP; if ((fp = fopen(resp->filename, "r")) == NULL) { maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP can't open script"); return; } /* Check for shebang and skip */ file_handle.handle.fp = fp; shebang[0] = '\0'; if (fgets(shebang, sizeof(shebang), file_handle.handle.fp) != 0) { if (shebang[0] != '#' || shebang[1] != '!') { fseek(fp, 0L, SEEK_SET); } } #endif zend_try { php_execute_script(&file_handle TSRMLS_CC); if (!SG(headers_sent)) { sapi_send_headers(TSRMLS_C); } } zend_catch { php_request_shutdown(0); maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP script execution failed"); return; } zend_end_try(); zend_try { php_request_shutdown(0); } zend_end_try(); maPutForService(q, maCreateEndPacket(q), 1); }