/* * 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; }
/* * 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; }
/* * Create the host addresses for a host. Called for hosts or for NameVirtualHost directives (host == 0). */ int maCreateHostAddresses(MaServer *server, MaHost *host, cchar *configValue) { MaListen *listen; MaHostAddress *address; char *ipAddrPort, *ipAddr, *value, *tok; char addrBuf[MPR_MAX_IP_ADDR_PORT]; int next, port; address = 0; value = mprStrdup(server, configValue); ipAddrPort = mprStrTok(value, " \t", &tok); while (ipAddrPort) { if (mprStrcmpAnyCase(ipAddrPort, "_default_") == 0) { mprAssert(0); ipAddrPort = "*:*"; } if (mprParseIp(server, ipAddrPort, &ipAddr, &port, -1) < 0) { mprError(server, "Can't parse ipAddr %s", ipAddrPort); continue; } mprAssert(ipAddr && *ipAddr); if (ipAddr[0] == '*') { ipAddr = mprStrdup(server, ""); } /* * For each listening endpiont, */ for (next = 0; (listen = mprGetNextItem(server->listens, &next)) != 0; ) { if (port > 0 && port != listen->port) { continue; } if (listen->ipAddr[0] != '\0' && ipAddr[0] != '\0' && strcmp(ipAddr, listen->ipAddr) != 0) { continue; } /* * Find the matching host address or create a new one */ if ((address = maLookupHostAddress(server, listen->ipAddr, listen->port)) == 0) { address = maCreateHostAddress(server, listen->ipAddr, listen->port); mprAddItem(server->hostAddresses, address); } /* * If a host is specified */ if (host == 0) { maSetNamedVirtualHostAddress(address); } else { maInsertVirtualHost(address, host); if (listen->ipAddr[0] != '\0') { mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", listen->ipAddr, listen->port); } else { mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", ipAddr, listen->port); } maSetHostName(host, addrBuf); } } mprFree(ipAddr); ipAddrPort = mprStrTok(0, " \t", &tok); } if (host) { if (address == 0) { mprError(server, "No valid IP address for host %s", host->name); mprFree(value); return MPR_ERR_CANT_INITIALIZE; } if (maIsNamedVirtualHostAddress(address)) { maSetNamedVirtualHost(host); } } mprFree(value); return 0; }