void httpMatchHost(HttpConn *conn) { MprSocket *listenSock; HttpEndpoint *endpoint; HttpHost *host; Http *http; http = conn->http; listenSock = conn->sock->listenSock; if ((endpoint = httpLookupEndpoint(http, listenSock->ip, listenSock->port)) == 0) { mprError("No listening endpoint for request from %s:%d", listenSock->ip, listenSock->port); mprCloseSocket(conn->sock, 0); return; } if (httpHasNamedVirtualHosts(endpoint)) { host = httpLookupHostOnEndpoint(endpoint, conn->rx->hostHeader); } else { host = mprGetFirstItem(endpoint->hosts); } if (host == 0) { httpSetConnHost(conn, 0); httpError(conn, HTTP_CODE_NOT_FOUND, "No host to serve request. Searching for %s", conn->rx->hostHeader); conn->host = mprGetFirstItem(endpoint->hosts); return; } if (conn->rx->traceLevel >= 0) { mprLog(conn->rx->traceLevel, "Select host: \"%s\"", host->name); } conn->host = host; }
/* This will restart the default server on a new IP:PORT. It will stop listening on the default endpoint on the default server, optionally modify the IP:PORT and resume listening. NOTE: running requests will be unaffected. WARNING: this is demonstration code and has no error checking. */ void maRestartServer(cchar *ip, int port) { MaAppweb *appweb; MaServer *server; HttpEndpoint *endpoint; appweb = MPR->appwebService; server = mprGetFirstItem(appweb->servers); lock(appweb->servers); endpoint = mprGetFirstItem(server->endpoints); httpStopEndpoint(endpoint); /* Alternatively, iterate over all endpoints by Http *http = MPR->httpService; int next; for (ITERATE_ITEMS(http->endpoints, endpoint, next)) { ... } */ if (port) { endpoint->port = port; } if (ip) { endpoint->ip = sclone(ip); } httpStartEndpoint(endpoint); unlock(appweb->servers); }
/* Cast the object operand to a primitive type */ static EjsObj *xlCast(Ejs *ejs, EjsXML *vp, EjsType *type) { MprBuf *buf; EjsObj *result; EjsXML *elt, *item; int next; if (type == ESV(XML)) { return (EjsObj*) vp; } switch (type->sid) { case S_Object: case S_Boolean: return (EjsObj*) ejsCreateBoolean(ejs, 1); case S_Number: result = xlCast(ejs, vp, ESV(String)); result = (EjsObj*) ejsToNumber(ejs, result); return result; case S_String: buf = mprCreateBuf(MPR_BUFSIZE, -1); if (mprGetListLength(vp->elements) == 1) { elt = mprGetFirstItem(vp->elements); if (elt->kind == EJS_XML_ELEMENT) { if (elt->elements == 0) { return (EjsObj*) ESV(empty); } if (elt->elements && mprGetListLength(elt->elements) == 1) { // TODO - what about PI and comments? item = mprGetFirstItem(elt->elements); if (item->kind == EJS_XML_TEXT) { return (EjsObj*) item->value; } } } } for (next = 0; (elt = mprGetNextItem(vp->elements, &next)) != 0; ) { if (ejsXMLToBuf(ejs, buf, elt, -1) < 0) { return 0; } if (next < vp->elements->length) { mprPutStringToBuf(buf, " "); } } return (EjsObj*) ejsCreateStringFromAsc(ejs, (char*) buf->start); default: ejsThrowTypeError(ejs, "Cannot cast to this type"); return 0; } }
static void setHttpPipeline(Ejs *ejs, EjsHttpServer *sp) { EjsString *vs; HttpHost *host; HttpRoute *route; Http *http; HttpStage *stage; cchar *name; int i; assure(sp->endpoint); http = sp->endpoint->http; host = mprGetFirstItem(sp->endpoint->hosts); route = mprGetFirstItem(host->routes); if (sp->outgoingStages) { httpClearRouteStages(route, HTTP_STAGE_TX); for (i = 0; i < sp->outgoingStages->length; i++) { vs = ejsGetProperty(ejs, sp->outgoingStages, i); if (vs && ejsIs(ejs, vs, String)) { name = vs->value; if (httpLookupStage(http, name) == 0) { ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", name); return; } httpAddRouteFilter(route, name, NULL, HTTP_STAGE_TX); } } } if (sp->incomingStages) { httpClearRouteStages(route, HTTP_STAGE_RX); for (i = 0; i < sp->incomingStages->length; i++) { vs = ejsGetProperty(ejs, sp->incomingStages, i); if (vs && ejsIs(ejs, vs, String)) { name = vs->value; if (httpLookupStage(http, name) == 0) { ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", name); return; } httpAddRouteFilter(route, name, NULL, HTTP_STAGE_RX); } } } if (sp->connector) { if ((stage = httpLookupStage(http, sp->connector)) == 0) { ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", sp->connector); return; } route->connector = stage; } }
/* * Convenience function to create a new default host */ MaHost *maCreateDefaultHost(MaServer *server, cchar *docRoot, cchar *ipAddr, int port) { MaHost *host; MaListen *listen; MaHostAddress *address; if (ipAddr == 0) { /* * If no IP:PORT specified, find the first listening endpoint. In this case, we expect the caller to * have setup the lisenting endponts and to have added them to the host address hash. */ listen = mprGetFirstItem(server->listens); if (listen) { ipAddr = listen->ipAddr; port = listen->port; } else { listen = maCreateListen(server, "localhost", MA_SERVER_DEFAULT_PORT_NUM, 0); maAddListen(server, listen); ipAddr = "localhost"; port = MA_SERVER_DEFAULT_PORT_NUM; } host = maCreateHost(server, ipAddr, NULL); } else { /* * Create a new listening endpoint */ listen = maCreateListen(server, ipAddr, port, 0); maAddListen(server, listen); host = maCreateHost(server, ipAddr, NULL); } if (maOpenMimeTypes(host, "mime.types") < 0) { maAddStandardMimeTypes(host); } /* * Insert the host and create a directory object for the docRoot */ maAddHost(server, host); maInsertDir(host, maCreateBareDir(host, docRoot)); maSetDocumentRoot(host, docRoot); /* * Ensure we are in the hash lookup of all the addresses to listen to acceptWrapper uses this hash to find * the host to serve the request. */ address = maLookupHostAddress(server, ipAddr, port); if (address == 0) { address = maCreateHostAddress(server, ipAddr, port); mprAddItem(server->hostAddresses, address); } maInsertVirtualHost(address, host); if (server->defaultHost == 0) { server->defaultHost = host; } return host; }
/* Create a value node. If the value is an XML node already, we are done. Otherwise, cast the value to a string and create a text child node containing the string value. */ static EjsXML *createValueNode(Ejs *ejs, EjsXML *elt, EjsObj *value) { EjsXML *text; EjsString *str; if (ejsIsXML(ejs, value)) { return (EjsXML*) value; } if ((str = (EjsString*) ejsCast(ejs, value, String)) == NULL) { return 0; } if (mprGetListLength(elt->elements) == 1) { /* Update an existing text element */ text = mprGetFirstItem(elt->elements); if (text->kind == EJS_XML_TEXT) { text->value = str; return elt; } } /* Create a new text element */ if (str->value[0] != '\0') { text = ejsCreateXML(ejs, EJS_XML_TEXT, N(NULL, NULL), elt, str); elt = ejsAppendToXML(ejs, elt, text); } return elt; }
static void restart() { MaAppweb *appweb; MaServer *server; HttpEndpoint *endpoint; render("Restarting"); flush(); finalize(); appweb = MPR->appwebService; server = mprGetFirstItem(appweb->servers); endpoint = mprGetFirstItem(server->endpoints); httpStopEndpoint(endpoint); endpoint->port = 5555; httpStartEndpoint(endpoint); print("RESTARTING ON PORT 5555"); }
void ejsDestroyVM(Ejs *ejs) { EjsService *sp; EjsState *state; EjsModule *mp; ejs->destroying = 1; sp = ejs->service; if (sp) { while ((mp = mprGetFirstItem(ejs->modules)) != 0) { ejsRemoveModule(ejs, mp); } assure(ejs->modules->length == 0); ejsRemoveWorkers(ejs); state = ejs->state; if (state && state->stackBase) { mprVirtFree(state->stackBase, state->stackSize); state->stackBase = 0; ejs->state = 0; } mprRemoveItem(sp->vmlist, ejs); ejs->service = 0; ejs->result = 0; if (ejs->dispatcher) { mprDisableDispatcher(ejs->dispatcher); } } mprLog(6, "ejs: destroy VM"); }
/* Write the port so the monitor can manage */ static int writePort(MaServer *server) { HttpEndpoint *endpoint; char numBuf[16], *path; int fd, len; if ((endpoint = mprGetFirstItem(server->http->endpoints)) == 0) { mprLog("error appweb", 0, "No configured endpoints"); return MPR_ERR_CANT_ACCESS; } // FUTURE - should really go to a ME_LOG_DIR (then fix uninstall.sh) path = mprJoinPath(mprGetAppDir(), "../.port.log"); if ((fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0) { mprLog("error appweb", 0, "Could not create port file %s", path); return MPR_ERR_CANT_CREATE; } fmt(numBuf, sizeof(numBuf), "%d", endpoint->port); len = (int) strlen(numBuf); numBuf[len++] = '\n'; if (write(fd, numBuf, len) != len) { mprLog("error appweb", 0, "Write to file %s failed", path); return MPR_ERR_CANT_WRITE; } close(fd); return 0; }
/* * Accept a new client connection. If multithreaded, this will come in on a worker thread dedicated to this connection. * This is called from the listen wait handler. */ int maAcceptConn(MprSocket *sock, MaServer *server, cchar *ip, int port) { MaHostAddress *address; MaHost *host; MaConn *conn; MprSocket *listenSock; MprHeap *arena; int rc; mprAssert(server); mprAssert(sock); mprAssert(ip); mprAssert(port > 0); rc = 0; listenSock = sock->listenSock; mprLog(server, 4, "New connection from %s:%d for %s:%d %s", ip, port, listenSock->ipAddr, listenSock->port, listenSock->sslSocket ? "(secure)" : ""); /* * Map the address onto a suitable host to initially serve the request initially until we can parse the Host header. */ address = (MaHostAddress*) maLookupHostAddress(server, listenSock->ipAddr, listenSock->port); if (address == 0 || (host = mprGetFirstItem(address->vhosts)) == 0) { mprError(server, "No host configured for request %s:%d", listenSock->ipAddr, listenSock->port); mprFree(sock); return 1; } arena = mprAllocHeap(host, "conn", 1, 0, NULL); if (arena == 0) { mprError(server, "Can't create connect arena object. Insufficient memory."); mprFree(sock); return 1; } conn = createConn(arena, host, sock, ip, port, address); if (conn == 0) { mprError(server, "Can't create connect object. Insufficient memory."); mprFree(sock); mprFree(arena); return 1; } conn->arena = arena; if (maAddConn(host, conn) < 0) { mprFree(sock); #if BLD_FEATURE_MULTITHREAD mprEnableSocketEvents(listenSock); #endif mprFree(arena); return 1; } mprSetSocketCallback(conn->sock, (MprSocketProc) ioEvent, conn, MPR_READABLE, MPR_NORMAL_PRIORITY); #if BLD_FEATURE_MULTITHREAD mprEnableSocketEvents(listenSock); #endif return rc; }
static bool validateEndpoint(HttpEndpoint *endpoint) { HttpHost *host; if ((host = mprGetFirstItem(endpoint->hosts)) == 0) { mprError("Missing host object on endpoint"); return 0; } return 1; }
static void testIsListEmpty(MprTestGroup *gp) { MprList *lp; lp = mprCreateList(0, 0); tassert(lp != 0); tassert(mprGetListLength(lp) == 0); tassert(mprGetFirstItem(lp) == 0); }
/* function set name(hostname: String): Void */ static EjsObj *hs_set_name(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv) { HttpHost *host; sp->name = ejsToMulti(ejs, argv[0]); if (sp->endpoint && sp->name) { host = mprGetFirstItem(sp->endpoint->hosts); httpSetHostName(host, sp->name); } return 0; }
static int parseCgi(MaHttp *http, cchar *key, char *value, MaConfigState *state) { MaLocation *location; MaServer *server; MaHost *host; MaAlias *alias; MaDir *dir, *parent; char *program, *mimeType, *prefix, *path; host = state->host; server = state->server; location = state->location; if (mprStrcmpAnyCase(key, "Action") == 0) { if (maSplitConfigValue(http, &mimeType, &program, value, 1) < 0) { return MPR_ERR_BAD_SYNTAX; } maSetMimeActionProgram(host, mimeType, program); return 1; } else if (mprStrcmpAnyCase(key, "ScriptAlias") == 0) { if (maSplitConfigValue(server, &prefix, &path, value, 1) < 0 || path == 0 || prefix == 0) { return MPR_ERR_BAD_SYNTAX; } /* Create an alias and location with a cgiHandler and pathInfo processing */ path = maMakePath(host, path); dir = maLookupDir(host, path); if (maLookupDir(host, path) == 0) { parent = mprGetFirstItem(host->dirs); dir = maCreateDir(host, path, parent); } alias = maCreateAlias(host, prefix, path, 0); mprLog(server, 4, "ScriptAlias \"%s\" for \"%s\"", prefix, path); mprFree(path); maInsertAlias(host, alias); if ((location = maLookupLocation(host, prefix)) == 0) { location = maCreateLocation(host, state->location); maSetLocationAuth(location, state->dir->auth); maSetLocationPrefix(location, prefix); maAddLocation(host, location); } else { maSetLocationPrefix(location, prefix); } maSetHandler(http, host, location, "cgiHandler"); return 1; } return 0; }
/* This will restart the default server on a new IP:PORT. It will stop listening on the default endpoint on the default server, optionally modify the IP:PORT and resume listening. NOTE: running requests will be unaffected. WARNING: this is demonstration code and has no error checking. */ PUBLIC void maRestartServer(cchar *ip, int port) { MaAppweb *appweb; MaServer *server; HttpEndpoint *endpoint; appweb = MPR->appwebService; server = mprGetFirstItem(appweb->servers); lock(appweb->servers); endpoint = mprGetFirstItem(server->endpoints); httpStopEndpoint(endpoint); if (port) { endpoint->port = port; } if (ip) { endpoint->ip = sclone(ip); } httpStartEndpoint(endpoint); unlock(appweb->servers); }
/* * Create an ejs application location block and alias */ static void createEjsAlias(Mpr *mpr, MaHttp *http, MaServer *server, cchar *ejsPrefix, cchar *ejsPath) { MaAlias *alias; MaHost *host; MaDir *dir, *parent; MaLocation *location; int flags; host = server->defaultHost; flags = host->location->flags & (MA_LOC_BROWSER | MA_LOC_AUTO_SESSION); alias = maCreateAlias(host, ejsPrefix, ejsPath, 0); maInsertAlias(host, alias); mprLog(http, 4, "Alias \"%s\" for \"%s\"", ejsPrefix, ejsPath); if (maLookupLocation(host, ejsPrefix)) { mprError(http, "Location block already exists for \"%s\"", ejsPrefix); return; } location = maCreateLocation(host, host->location); maSetLocationAuth(location, host->location->auth); maSetLocationPrefix(location, ejsPrefix); maAddLocation(host, location); maSetLocationFlags(location, MA_LOC_APP | flags); maSetHandler(http, host, location, "ejsHandler"); #if BLD_FEATURE_UPLOAD /* Upload configuration */ location->autoDelete = 1; if (maAddFilter(http, location, "chunkFilter", "", MA_FILTER_INCOMING) < 0) { mprError(server, "Can't add chunkFilter for ejs"); } if (maAddFilter(http, location, "uploadFilter", "", MA_FILTER_INCOMING) < 0) { mprError(server, "Can't add uploadFilter for ejs"); } #endif /* * Make sure there is a directory for the alias target */ dir = maLookupBestDir(host, ejsPath); if (dir == 0) { parent = mprGetFirstItem(host->dirs); dir = maCreateDir(host, alias->filename, parent); maInsertDir(host, dir); } }
/* Cast the object operand to a primitive type */ static EjsAny *castXml(Ejs *ejs, EjsXML *xml, EjsType *type) { EjsXML *item; EjsObj *result; MprBuf *buf; assert(ejsIsXML(ejs, xml)); if (type == ESV(XMLList)) { return xml; } switch (type->sid) { case S_Object: case S_Boolean: return ejsCreateBoolean(ejs, 1); case S_Number: result = castXml(ejs, xml, ESV(String)); return ejsToNumber(ejs, result); case S_String: if (xml->kind == EJS_XML_ELEMENT) { if (xml->elements == 0) { return ESV(empty); } if (xml->elements && mprGetListLength(xml->elements) == 1) { // TODO - what about PI and comments? item = mprGetFirstItem(xml->elements); if (item->kind == EJS_XML_TEXT) { return item->value; } } } buf = mprCreateBuf(BIT_MAX_BUFFER, -1); if (ejsXMLToBuf(ejs, buf, xml, -1) < 0) { return 0; } return ejsCreateStringFromAsc(ejs, (char*) buf->start); default: ejsThrowTypeError(ejs, "Cannot cast to this type"); return 0; } return 0; }
/* Create a new connection object */ PUBLIC HttpConn *httpCreateConn(HttpEndpoint *endpoint, MprDispatcher *dispatcher) { HttpConn *conn; HttpHost *host; HttpRoute *route; if ((conn = mprAllocObj(HttpConn, manageConn)) == 0) { return 0; } conn->protocol = HTTP->protocol; conn->http = HTTP; conn->port = -1; conn->retries = HTTP_RETRIES; conn->endpoint = endpoint; conn->lastActivity = HTTP->now; conn->ioCallback = httpIOEvent; if (endpoint) { conn->notifier = endpoint->notifier; host = mprGetFirstItem(endpoint->hosts); if (host && (route = host->defaultRoute) != 0) { conn->limits = route->limits; conn->trace = route->trace; } else { conn->limits = HTTP->serverLimits; conn->trace = HTTP->trace; } } else { conn->limits = HTTP->clientLimits; conn->trace = HTTP->trace; } conn->keepAliveCount = conn->limits->keepAliveMax; conn->serviceq = httpCreateQueueHead(conn, "serviceq"); if (dispatcher) { conn->dispatcher = dispatcher; } else if (endpoint) { conn->dispatcher = endpoint->dispatcher; } else { conn->dispatcher = mprGetDispatcher(); } conn->rx = httpCreateRx(conn); conn->tx = httpCreateTx(conn, NULL); httpSetState(conn, HTTP_STATE_BEGIN); httpAddConn(conn); return conn; }
/* Convenience function to create and configure a new endpoint without using a config file. */ HttpEndpoint *httpCreateConfiguredEndpoint(cchar *home, cchar *documents, cchar *ip, int port) { Http *http; HttpHost *host; HttpEndpoint *endpoint; HttpRoute *route; http = MPR->httpService; if (ip == 0) { /* If no IP:PORT specified, find the first endpoint */ if ((endpoint = mprGetFirstItem(http->endpoints)) != 0) { ip = endpoint->ip; port = endpoint->port; } else { ip = "localhost"; if (port <= 0) { port = HTTP_DEFAULT_PORT; } if ((endpoint = httpCreateEndpoint(ip, port, NULL)) == 0) { return 0; } } } else { if ((endpoint = httpCreateEndpoint(ip, port, NULL)) == 0) { return 0; } } if ((host = httpCreateHost(home)) == 0) { return 0; } if ((route = httpCreateRoute(host)) == 0) { return 0; } httpSetHostDefaultRoute(host, route); httpSetHostIpAddr(host, ip, port); httpAddHostToEndpoint(endpoint, host); httpSetRouteDir(route, documents); httpFinalizeRoute(route); return endpoint; }
HttpHost *httpLookupHostOnEndpoint(HttpEndpoint *endpoint, cchar *name) { HttpHost *host; int next; if (name == 0 || *name == '\0') { return mprGetFirstItem(endpoint->hosts); } for (next = 0; (host = mprGetNextItem(endpoint->hosts, &next)) != 0; ) { if (smatch(host->name, name)) { return host; } if (*host->name == '*') { if (host->name[1] == '\0') { return host; } if (scontains(name, &host->name[1])) { return host; } } } return 0; }
/* Write the port so the monitor can manage */ static int writePort(MaServer *server) { HttpHost *host; char numBuf[16], *path; int fd, len; host = mprGetFirstItem(server->http->hosts); // TODO - should really go to a BLD_LOG_DIR path = mprJoinPath(mprGetAppDir(), "../.port.log"); if ((fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0) { mprError("Could not create port file %s", path); return MPR_ERR_CANT_CREATE; } mprSprintf(numBuf, sizeof(numBuf), "%d", host->port); len = (int) strlen(numBuf); numBuf[len++] = '\n'; if (write(fd, numBuf, len) != len) { mprError("Write to file %s failed", path); return MPR_ERR_CANT_WRITE; } close(fd); return 0; }
static EjsXML *createElement(Ejs *ejs, EjsXML *list, EjsXML *targetObject, EjsName qname, EjsObj *value) { EjsXML *elt, *last, *attList; int index; int j; if (targetObject && ejsIsXML(ejs, targetObject) && targetObject->kind == EJS_XML_LIST) { /* If the target is a list it must have 1 element. So switch to it. TODO - could we get resolve to do this? */ if (mprGetListLength(targetObject->elements) != 1) { /* Spec says so - TODO why no error? */ return 0; } targetObject = mprGetFirstItem(targetObject->elements); } /* Return if the target object is not an XML element */ if (!ejsIsXML(ejs, targetObject) || targetObject->kind != EJS_XML_ELEMENT) { /* Spec says so - TODO why no error? */ return 0; } elt = ejsCreateXML(ejs, EJS_XML_ELEMENT, list->targetProperty, targetObject, NULL); if (list->targetProperty.name && list->targetProperty.name->value[0] == '@') { elt->kind = EJS_XML_ATTRIBUTE; attList = ejsGetPropertyByName(ejs, (EjsObj*) targetObject, list->targetProperty); if (attList && mprGetListLength(attList->elements) > 0) { /* Spec says so. But this surely means you can't update an attribute? */ return 0; } } else if (list->targetProperty.name == NULL || qname.name->value[0] == '*') { elt->kind = EJS_XML_TEXT; elt->qname.name = 0; } index = mprGetListLength(list->elements); if (elt->kind != EJS_XML_ATTRIBUTE) { if (targetObject) { if (index > 0) { /* Find the place of the last list item in the resolved target object. */ last = mprGetItem(list->elements, index - 1); j = mprLookupItem(targetObject->elements, last); } else { j = -1; } if (j < 0) { j = mprGetListLength(targetObject->elements) - 1; } // TODO - really need to wrap this ejsInsertXML(EjsXML *xml, int index, EjsXML *node) if (targetObject->elements == 0) { targetObject->elements = mprCreateList(-1, 0); } /* Insert into the target object */ mprInsertItemAtPos(targetObject->elements, j + 1, elt); } if (ejsIsXML(ejs, value)) { if (((EjsXML*) value)->kind == EJS_XML_LIST) { elt->qname = ((EjsXML*) value)->targetProperty; } else { elt->qname = ((EjsXML*) value)->qname; } } /* Insert into the XML list */ mprSetItem(list->elements, index, elt); } return (EjsXML*) mprGetItem(list->elements, index); }
PUBLIC HttpEndpoint *httpGetFirstEndpoint() { return mprGetFirstItem(HTTP->endpoints); }
/* Configure the server. If the configFile is defined, use it. If not, then consider home, documents, ip and port. */ int maConfigureServer(MaServer *server, cchar *configFile, cchar *home, cchar *documents, cchar *ip, int port) { MaAppweb *appweb; Http *http; HttpEndpoint *endpoint; HttpHost *host; HttpRoute *route; char *path; appweb = server->appweb; http = appweb->http; if (configFile) { path = mprGetAbsPath(configFile); if (maParseConfig(server, path, 0) < 0) { /* mprUserError("Can't configure server using %s", path); */ return MPR_ERR_CANT_INITIALIZE; } return 0; } else { mprLog(2, "DocumentRoot %s", documents); if ((endpoint = httpCreateConfiguredEndpoint(home, documents, ip, port)) == 0) { return MPR_ERR_CANT_OPEN; } maAddEndpoint(server, endpoint); host = mprGetFirstItem(endpoint->hosts); mprAssert(host); route = mprGetFirstItem(host->routes); mprAssert(route); #if UNUSED searchPath = getSearchPath(dir); mprSetModuleSearchPath(searchPath); #endif #if BLD_FEATURE_CGI maLoadModule(appweb, "cgiHandler", "mod_cgi"); if (httpLookupStage(http, "cgiHandler")) { httpAddRouteHandler(route, "cgiHandler", "cgi cgi-nph bat cmd pl py"); /* Add cgi-bin with a route for the /cgi-bin URL prefix. */ path = "cgi-bin"; if (mprPathExists(path, X_OK)) { HttpRoute *cgiRoute; cgiRoute = httpCreateAliasRoute(route, "/cgi-bin/", path, 0); mprLog(4, "ScriptAlias \"/cgi-bin/\":\"%s\"", path); httpSetRouteHandler(cgiRoute, "cgiHandler"); httpFinalizeRoute(cgiRoute); } } #endif #if BLD_FEATURE_ESP maLoadModule(appweb, "espHandler", "mod_esp"); if (httpLookupStage(http, "espHandler")) { httpAddRouteHandler(route, "espHandler", "esp"); } #endif #if BLD_FEATURE_EJSCRIPT maLoadModule(appweb, "ejsHandler", "mod_ejs"); if (httpLookupStage(http, "ejsHandler")) { httpAddRouteHandler(route, "ejsHandler", "ejs"); } #endif #if BLD_FEATURE_PHP maLoadModule(appweb, "phpHandler", "mod_php"); if (httpLookupStage(http, "phpHandler")) { httpAddRouteHandler(route, "phpHandler", "php"); } #endif httpAddRouteHandler(route, "fileHandler", ""); httpFinalizeRoute(route); } if (home) { maSetServerHome(server, home); } if (ip || port > 0) { maSetServerAddress(server, ip, port); } return 0; }