/* function listen(endpoint): Void An endpoint can be either a "port" or "ip:port", or null. If hosted, this call does little -- just add to the ejs->httpServers list. */ static EjsVoid *hs_listen(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv) { HttpEndpoint *endpoint; HttpHost *host; HttpRoute *route; EjsString *address; EjsObj *loc; EjsPath *documents; if (!sp->hosted) { loc = (argc >= 1) ? argv[0] : ESV(null); if (loc != ESV(null)) { address = ejsToString(ejs, loc); // TODO should permit https://IP:PORT mprParseSocketAddress(address->value, &sp->ip, &sp->port, NULL, 0); } else { address = 0; } if (address == 0) { ejsThrowArgError(ejs, "Missing listen endpoint"); return 0; } if (sp->endpoint) { httpDestroyEndpoint(sp->endpoint); sp->endpoint = 0; } /* The endpoint uses the ejsDispatcher. This is VERY important. All connections will inherit this also. This serializes all activity on one dispatcher. */ if ((endpoint = httpCreateEndpoint(sp->ip, sp->port, ejs->dispatcher)) == 0) { ejsThrowIOError(ejs, "Cannot create Http endpoint object"); return 0; } sp->endpoint = endpoint; host = httpCreateHost(NULL); httpSetHostName(host, sfmt("%s:%d", sp->ip, sp->port)); route = httpCreateConfiguredRoute(host, 1); httpAddRouteMethods(route, "DELETE, HEAD, OPTIONS, PUT"); httpAddRouteHandler(route, "ejsHandler", ""); httpSetRouteTarget(route, "run", 0); httpFinalizeRoute(route); httpSetHostDefaultRoute(host, route); httpAddHostToEndpoint(endpoint, host); if (sp->limits) { ejsSetHttpLimits(ejs, endpoint->limits, sp->limits, 1); } if (sp->incomingStages || sp->outgoingStages || sp->connector) { setHttpPipeline(ejs, sp); } if (sp->ssl) { httpSecureEndpoint(endpoint, sp->ssl); } if (sp->name) { httpSetHostName(host, sp->name); } httpSetSoftware(EJS_HTTPSERVER_NAME); httpSetEndpointAsync(endpoint, sp->async); httpSetEndpointContext(endpoint, sp); httpSetEndpointNotifier(endpoint, stateChangeNotifier); /* This is only required when http is using non-ejs handlers and/or filters */ documents = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_documents); if (ejsIs(ejs, documents, Path)) { httpSetRouteDocuments(route, documents->value); } #if KEEP // TODO -- what to do with home? // TODO - if removed, then the "home" property should be removed? home = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_home); if (ejsIs(ejs, home, Path)) { httpSetRoutDir(host, home->value); } #endif if (httpStartEndpoint(endpoint) < 0) { httpDestroyEndpoint(sp->endpoint); sp->endpoint = 0; ejsThrowIOError(ejs, "Cannot listen on %s", address->value); } } if (ejs->httpServers == 0) { ejs->httpServers = mprCreateList(-1, MPR_LIST_STATIC_VALUES); } /* Remove to make sure old listening() registrations are removed */ mprRemoveItem(ejs->httpServers, sp); mprAddItem(ejs->httpServers, sp); return 0; }
PUBLIC Http *httpCreate(int flags) { Http *http; HttpStatusCode *code; mprGlobalLock(); if (MPR->httpService) { mprGlobalUnlock(); return MPR->httpService; } if ((http = mprAllocObj(Http, manageHttp)) == 0) { mprGlobalUnlock(); return 0; } MPR->httpService = HTTP = http; http->software = sclone(ME_HTTP_SOFTWARE); http->protocol = sclone("HTTP/1.1"); http->mutex = mprCreateLock(); http->stages = mprCreateHash(-1, MPR_HASH_STABLE); http->hosts = mprCreateList(-1, MPR_LIST_STABLE); http->connections = mprCreateList(-1, MPR_LIST_STATIC_VALUES); http->authTypes = mprCreateHash(-1, MPR_HASH_CASELESS | MPR_HASH_UNIQUE | MPR_HASH_STABLE); http->authStores = mprCreateHash(-1, MPR_HASH_CASELESS | MPR_HASH_UNIQUE | MPR_HASH_STABLE); http->routeSets = mprCreateHash(-1, MPR_HASH_STATIC_VALUES | MPR_HASH_STABLE); http->booted = mprGetTime(); http->flags = flags; http->monitorPeriod = ME_HTTP_MONITOR_PERIOD; http->secret = mprGetRandomString(HTTP_MAX_SECRET); http->trace = httpCreateTrace(0); http->startLevel = 2; http->localPlatform = slower(sfmt("%s-%s-%s", ME_OS, ME_CPU, ME_PROFILE)); httpSetPlatform(http->localPlatform); httpSetPlatformDir(NULL); updateCurrentDate(); http->statusCodes = mprCreateHash(41, MPR_HASH_STATIC_VALUES | MPR_HASH_STATIC_KEYS | MPR_HASH_STABLE); for (code = HttpStatusCodes; code->code; code++) { mprAddKey(http->statusCodes, code->codeString, code); } httpGetUserGroup(); httpInitParser(); httpInitAuth(); httpOpenNetConnector(); httpOpenSendConnector(); httpOpenRangeFilter(); httpOpenChunkFilter(); #if ME_HTTP_WEB_SOCKETS httpOpenWebSockFilter(); #endif mprSetIdleCallback(isIdle); mprAddTerminator(terminateHttp); if (flags & HTTP_SERVER_SIDE) { http->endpoints = mprCreateList(-1, MPR_LIST_STABLE); http->counters = mprCreateList(-1, MPR_LIST_STABLE); http->monitors = mprCreateList(-1, MPR_LIST_STABLE); http->routeTargets = mprCreateHash(-1, MPR_HASH_STATIC_VALUES | MPR_HASH_STABLE); http->routeConditions = mprCreateHash(-1, MPR_HASH_STATIC_VALUES | MPR_HASH_STABLE); http->routeUpdates = mprCreateHash(-1, MPR_HASH_STATIC_VALUES | MPR_HASH_STABLE); http->sessionCache = mprCreateCache(MPR_CACHE_SHARED | MPR_HASH_STABLE); http->addresses = mprCreateHash(-1, MPR_HASH_STABLE); http->defenses = mprCreateHash(-1, MPR_HASH_STABLE); http->remedies = mprCreateHash(-1, MPR_HASH_CASELESS | MPR_HASH_STATIC_VALUES | MPR_HASH_STABLE); httpOpenUploadFilter(); httpOpenCacheHandler(); httpOpenPassHandler(); httpOpenActionHandler(); httpOpenDirHandler(); httpOpenFileHandler(); http->serverLimits = httpCreateLimits(1); httpDefineRouteBuiltins(); httpAddCounters(); httpAddRemedies(); httpCreateDefaultHost(); } if (flags & HTTP_CLIENT_SIDE) { http->defaultClientHost = sclone("127.0.0.1"); http->defaultClientPort = 80; http->clientLimits = httpCreateLimits(0); http->clientRoute = httpCreateConfiguredRoute(0, 0); http->clientHandler = httpCreateHandler("client", 0); } mprGlobalUnlock(); return http; }