static int createEndpoints(int argc, char **argv) { HttpHost *host; HttpRoute *route; host = httpCreateHost(); httpSetDefaultHost(host); route = httpCreateRoute(host); httpSetHostDefaultRoute(host, route); httpFinalizeRoute(route); httpInitConfig(route); if (httpLoadConfig(route, app->configFile) < 0) { return MPR_ERR_CANT_CREATE; } mprGC(MPR_GC_FORCE | MPR_GC_COMPLETE); return 0; }
/* 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; }
/* Create a new server. A server may manage may multiple servers and virtual hosts. If ip/port endpoint is supplied, this call will create a Server on that endpoint. Otherwise, maConfigureServer should be called later. A default route is created with the document root set to "." */ PUBLIC MaServer *maCreateServer(MaAppweb *appweb, cchar *name) { MaServer *server; HttpHost *host; HttpRoute *route; assert(appweb); if ((server = mprAllocObj(MaServer, manageServer)) == NULL) { return 0; } if (name == 0 || *name == '\0') { name = "default"; } server->name = sclone(name); server->endpoints = mprCreateList(-1, 0); server->limits = httpCreateLimits(1); server->appweb = appweb; server->http = appweb->http; server->defaultHost = host = httpCreateHost(NULL); if (!httpGetDefaultHost()) { httpSetDefaultHost(host); } route = httpCreateRoute(host); httpSetRouteName(route, "default"); //UNUSED httpSetRoutePrefix(route, ""); httpSetHostDefaultRoute(host, route); route->limits = server->limits; maAddServer(appweb, server); if (appweb->defaultServer == 0) { maSetDefaultServer(appweb, server); } return server; }
/* 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; }