/* * Add a response header */ static void setHeader(void *handle, bool allowMultiple, cchar *key, cchar *fmt, ...) { char *value; va_list vargs; va_start(vargs, fmt); mprAllocVsprintf(mpr, &value, EJS_MAX_HEADERS, fmt, vargs); if (allowMultiple) { mprAddDuplicateHash(responseHeaders, key, value); } else { mprAddHash(responseHeaders, key, value); } }
int mprSetRomFileSystem(MprCtx ctx, MprRomInode *inodeList) { MprRomFileSystem * rfs; MprRomInode *ri; rfs = (MprRomFileSystem*) mprGetMpr(ctx)->fileSystem; rfs->romInodes = inodeList; rfs->fileIndex = mprCreateHash(rfs, MPR_FILES_HASH_SIZE); for (ri = inodeList; ri->path; ri++) { if (mprAddHash(rfs->fileIndex, ri->path, ri) < 0) { return MPR_ERR_NO_MEMORY; } } return 0; }
/* * Decode the query and post form data into formVars */ static void decodeFormData(cchar *data) { char *value, *key, *buf; int buflen; buf = mprStrdup(mpr, data); buflen = strlen(buf); /* * Crack the input into name/value pairs */ for (key = strtok(buf, "&"); key; key = strtok(0, "&")) { if ((value = strchr(key, '=')) != 0) { *value++ = '\0'; mprUrlDecode(value, (int) strlen(value) + 1, value); } mprUrlDecode(key, (int) strlen(key) + 1, key); mprAddHash(formVars, key, value); } }
/* * Get a request and parse environment and request URI. Given: * * http /simple.cgi/abc/def?a=b&c=d * DOCUMENT_ROOT=/Users/mob/hg/appweb/src/server/web * GATEWAY_INTERFACE=CGI/1.1 * CONTENT_LENGTH=NNN * CONTENT_TYPE * PATH_INFO=/abc/def * PATH_TRANSLATED=/Users/mob/hg/appweb/src/server/web/ab/def * QUERY_STRING=a=b&c=d * REMOTE_ADDR=10.0.0.1234 * REMOTE_HOST * REMOTE_PORT * REQUEST_URI=/simple.cgi * REQUEST_METHOD=GET * REQUEST_TRANSPORT=http * SCRIPT_FILENAME=/Users/mob/hg/appweb/src/server/web/simple.cgi * SERVER_NAME=127.0.0.1:7777 * SERVER_PORT=7777 * SERVER_SOFTWARE=Embedthis-Appweb/3.0A.1 * SERVER_PROTOCOL=http * HTTP_ACCEPT= * HTTP_COOKIE= * HTTP_REFERRER= * HTTP_CONNECTION=Keep-Alive * HTTP_HOST=127.0.0.1 * HTTP_USER_AGENT=Embedthis-http/3.0A.1 * HTTPS * HTTP_* * PATH= */ static int getRequest() { char key[MPR_MAX_STRING], *ep, *cp, *value; int len, i; formVars = mprCreateHash(mpr, EJS_CGI_HDR_HASH); requestHeaders = mprCreateHash(mpr, EJS_CGI_HDR_HASH); responseHeaders = mprCreateHash(mpr, EJS_CGI_HDR_HASH); if (debug) { debugFile = fopen("/tmp/ejscgi.log", "w+"); } for (i = 0; environ && environ[i]; i++) { if ((ep = environ[i]) == 0) { continue; } if ((cp = strchr(ep, '=')) != 0) { len = cp - ep; mprMemcpy(key, sizeof(key), ep, len); key[len] = '\0'; mprAddHash(requestHeaders, key, ++cp); if (debugFile) { fprintf(debugFile, "%-20s = %s\n", key, cp); } } } if (debugFile) { fclose(debugFile); debugFile = 0; } #if BLD_DEBUG if (dummy) { mprAddHash(requestHeaders, "SCRIPT_NAME", mprStrdup(mpr, "/cgi/ejscgi")); mprAddHash(requestHeaders, "DOCUMENT_ROOT", mprStrdup(mpr, "/Users/mob/hg/carmen")); mprAddHash(requestHeaders, "PATH_TRANSLATED", mprStrdup(mpr, "/Users/mob/hg/carmen")); mprAddHash(requestHeaders, "QUERY_STRING", mprStrdup(mpr, "a=b&c=d")); mprAddHash(requestHeaders, "PATH_INFO", mprStrdup(mpr, "/carmen/stock/")); mprAddHash(requestHeaders, "REQUEST_URI", mprStrdup(mpr, "/cgi-bin/ejscgi/carmen/stock/")); // mprAddHash(requestHeaders, "PATH_INFO", mprStrdup(mpr, "/carmen/web/style.css")); // mprAddHash(requestHeaders, "REQUEST_URI", mprStrdup(mpr, "/cgi-bin/ejscgi/carmen/web/style.css")); // mprAddHash(requestHeaders, "PATH_INFO", mprStrdup(mpr, "/carmen/web/images/banner.jpg")); // mprAddHash(requestHeaders, "REQUEST_URI", mprStrdup(mpr, "/cgi-bin/ejscgi/carmen/web/images/banner.jpg")); } #endif documentRoot = (char*) mprLookupHash(requestHeaders, "DOCUMENT_ROOT"); cookie = (char*) mprLookupHash(requestHeaders, "HTTP_COOKIE"); contentType = (char*) mprLookupHash(requestHeaders, "CONTENT_TYPE"); query = (char*) mprLookupHash(requestHeaders, "QUERY_STRING"); pathTranslated = (char*) mprLookupHash(requestHeaders, "PATH_TRANSLATED"); pathInfo = (char*) mprLookupHash(requestHeaders, "PATH_INFO"); scriptName = (char*) mprLookupHash(requestHeaders, "SCRIPT_NAME"); uri = (char*) mprLookupHash(requestHeaders, "REQUEST_URI"); if (documentRoot == 0 || pathInfo == 0 || scriptName == 0 || uri == 0) { error(NULL, 0, "CGI environment not setup correctly"); return EJS_ERR; } value = (char*) mprLookupHash(requestHeaders, "CONTENT_LENGTH"); if (value) { contentLength = atoi(value); } ext = strrchr(uri, '.'); if (createFormData() < 0) { return EJS_ERR; } return 0; }
void maRegisterStage(MaHttp *http, MaStage *stage) { mprAddHash(http->stages, stage->name, stage); }
/* Build the command arguments. NOTE: argv is untrusted input. */ static void buildArgs(MaConn *conn, MprCmd *cmd, int *argcp, char ***argvp) { MaRequest *req; MaResponse *resp; char *fileName, **argv, status[8], *indexQuery, *cp, *tok; cchar *actionProgram; int argc, argind, len; req = conn->request; resp = conn->response; fileName = resp->filename; mprAssert(fileName); actionProgram = 0; argind = 0; argc = *argcp; if (resp->extension) { actionProgram = maGetMimeActionProgram(req->host, resp->extension); if (actionProgram != 0) { argc++; } } /* This is an Apache compatible hack for PHP 5.3 */ mprItoa(status, sizeof(status), MPR_HTTP_CODE_MOVED_TEMPORARILY, 10); mprAddHash(req->headers, "REDIRECT_STATUS", mprStrdup(req, status)); /* Count the args for ISINDEX queries. Only valid if there is not a "=" in the query. If this is so, then we must not have these args in the query env also? */ indexQuery = req->parsedUri->query; if (indexQuery && !strchr(indexQuery, '=')) { argc++; for (cp = indexQuery; *cp; cp++) { if (*cp == '+') { argc++; } } } else { indexQuery = 0; } #if BLD_WIN_LIKE || VXWORKS { char *bangScript, *cmdBuf, *program, *cmdScript; /* On windows we attempt to find an executable matching the fileName. We look for *.exe, *.bat and also do unix style processing "#!/program" */ findExecutable(conn, &program, &cmdScript, &bangScript, fileName); mprAssert(program); if (cmdScript) { /* Cmd/Batch script (.bat | .cmd) Convert the command to the form where there are 4 elements in argv that cmd.exe can interpret. argv[0] = cmd.exe argv[1] = /Q argv[2] = /C argv[3] = ""script" args ..." */ argc = 4; len = (argc + 1) * sizeof(char*); argv = (char**) mprAlloc(cmd, len); memset(argv, 0, len); argv[argind++] = program; /* Duped in findExecutable */ argv[argind++] = mprStrdup(cmd, "/Q"); argv[argind++] = mprStrdup(cmd, "/C"); len = (int) strlen(cmdScript) + 2 + 1; cmdBuf = (char*) mprAlloc(cmd, len); mprSprintf(cmdBuf, len, "\"%s\"", cmdScript); argv[argind++] = cmdBuf; mprSetCmdDir(cmd, cmdScript); mprFree(cmdScript); /* program will get freed when argv[] gets freed */ } else if (bangScript) { /* Script used "#!/program". NOTE: this may be overridden by a mime Action directive. */ argc++; /* Adding bangScript arg */ len = (argc + 1) * sizeof(char*); argv = (char**) mprAlloc(cmd, len); memset(argv, 0, len); argv[argind++] = program; /* Will get freed when argv[] is freed */ argv[argind++] = bangScript; /* Will get freed when argv[] is freed */ mprSetCmdDir(cmd, bangScript); } else { /* Either unknown extension or .exe (.out) program. */ len = (argc + 1) * sizeof(char*); argv = (char**) mprAlloc(cmd, len); memset(argv, 0, len); if (actionProgram) { argv[argind++] = mprStrdup(cmd, actionProgram); } argv[argind++] = program; } } #else len = (argc + 1) * (int) sizeof(char*); argv = (char**) mprAlloc(cmd, len); memset(argv, 0, len); if (actionProgram) { argv[argind++] = mprStrdup(cmd, actionProgram); } argv[argind++] = mprStrdup(cmd, fileName); #endif /* ISINDEX queries. Only valid if there is not a "=" in the query. If this is so, then we must not have these args in the query env also? */ if (indexQuery) { indexQuery = mprStrdup(cmd, indexQuery); cp = mprStrTok(indexQuery, "+", &tok); while (cp) { argv[argind++] = mprEscapeCmd(resp, mprUrlDecode(resp, cp), 0); cp = mprStrTok(NULL, "+", &tok); } } mprAssert(argind <= argc); argv[argind] = 0; *argcp = argc; *argvp = argv; }