/* * Create a new virtual host and inherit settings from another host */ MaHost *maCreateVirtualHost(MaServer *server, cchar *ipAddrPort, MaHost *parent) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->parent = parent; host->connections = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } /* * The aliases, dirs and locations are all copy-on-write */ host->aliases = parent->aliases; host->dirs = parent->dirs; host->locations = parent->locations; host->server = parent->server; host->flags = parent->flags; host->httpVersion = parent->httpVersion; host->timeout = parent->timeout; host->limits = parent->limits; host->keepAliveTimeout = parent->keepAliveTimeout; host->maxKeepAlive = parent->maxKeepAlive; host->keepAlive = parent->keepAlive; host->accessLog = parent->accessLog; host->mimeTypes = parent->mimeTypes; host->location = maCreateLocation(host, parent->location); host->logHost = parent->logHost; host->traceMask = parent->traceMask; host->traceLevel = parent->traceLevel; host->traceMaxLength = parent->traceMaxLength; if (parent->traceInclude) { host->traceInclude = mprCopyHash(host, parent->traceInclude); } if (parent->traceExclude) { host->traceExclude = mprCopyHash(host, parent->traceExclude); } maAddLocation(host, host->location); updateCurrentDate(host); #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif return host; }
void maAddConn(MaHost *host, MaConn *conn) { lock(host); mprAddItem(host->connections, conn); conn->started = mprGetTime(conn); if ((host->whenCurrentDate + MPR_TICKS_PER_SEC) < conn->started) { updateCurrentDate(host); } if (mprGetListCount(host->connections) == 1) { startTimer(host); } unlock(host); }
/* * Create a host from scratch */ MaHost *maCreateHost(MaServer *server, cchar *ipAddrPort, MaLocation *location) { MaHost *host; host = mprAllocObjZeroed(server, MaHost); if (host == 0) { return 0; } host->aliases = mprCreateList(host); host->dirs = mprCreateList(host); host->connections = mprCreateList(host); host->locations = mprCreateList(host); if (ipAddrPort) { host->ipAddrPort = mprStrdup(server, ipAddrPort); host->name = mprStrdup(server, ipAddrPort); } else { host->ipAddrPort = 0; host->name = 0; } host->server = server; host->flags = MA_HOST_NO_TRACE; host->httpVersion = MPR_HTTP_1_1; host->timeout = MA_SERVER_TIMEOUT; host->limits = &server->http->limits; host->traceMask = MA_TRACE_REQUEST | MA_TRACE_RESPONSE | MA_TRACE_HEADERS; host->traceLevel = 3; host->traceMaxLength = INT_MAX; host->keepAliveTimeout = MA_KEEP_TIMEOUT; host->maxKeepAlive = MA_MAX_KEEP_ALIVE; host->keepAlive = 1; host->location = (location) ? location : maCreateBareLocation(host); maAddLocation(host, host->location); updateCurrentDate(host); #if BLD_FEATURE_AUTH host->location->auth = maCreateAuth(host->location, host->location->auth); #endif #if BLD_FEATURE_MULTITHREAD host->mutex = mprCreateLock(host); #endif mprSetIdleCallback(host, appwebIsIdle); return host; }
void maAddConn(MaHost *host, MaConn *conn) { lock(host); mprAddItem(host->connections, conn); conn->started = mprGetTime(conn); conn->seqno = host->connCount++; if ((host->now + MPR_TICKS_PER_SEC) < conn->started) { updateCurrentDate(host); } if (host->timer == 0) { startTimer(host); } unlock(host); }
/* * The host timer does maintenance activities and will fire per second while there is active requests. * When multi-threaded, the host timer runs as an event off the service thread. Because we lock the host here, * connections cannot be deleted while we are modifying the list. */ static void hostTimer(MaHost *host, MprEvent *event) { MaConn *conn; int next, connCount; lock(host); updateCurrentDate(host); /* * Check for any expired connections */ for (connCount = 0, next = 0; (conn = mprGetNextItem(host->connections, &next)) != 0; connCount++) { /* * Workaround for a GCC bug when comparing two 64bit numerics directly. Need a temporary. */ int64 diff = conn->expire - host->whenCurrentDate; if (diff < 0) { // thread will have the connection lock and may be trying to get the host lock. // mprFree(conn); // mprCloseSocket( // if (conn->sock && conn->sock->handler) { // mprRecallWaitHandler(conn->sock->handler); // } // closesocket(conn->sock->fd); conn->keepAliveCount = 0; mprSetSocketEventMask(conn->sock, MPR_WRITEABLE); } } if (event) { if (connCount == 0) { mprStopContinuousEvent(event); } mprFree(event); } unlock(host); }
PUBLIC void httpAddConn(HttpConn *conn) { Http *http; http = HTTP; http->now = mprGetTicks(); assert(http->now >= 0); conn->started = http->now; mprAddItem(http->connections, conn); updateCurrentDate(); lock(http); conn->seqno = (int) ++http->totalConnections; if (!http->timer) { #if ME_DEBUG if (!mprGetDebugMode()) #endif { http->timer = mprCreateTimerEvent(NULL, "httpTimer", HTTP_TIMER_PERIOD, httpTimer, http, MPR_EVENT_CONTINUOUS | MPR_EVENT_QUICK); } } unlock(http); }
void DCalendar::showEvent(QShowEvent *) { updateCurrentDate(); }
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; }
/* The http timer does maintenance activities and will fire per second while there are active requests. This routine will also be called by httpTerminate with event == 0 to signify a shutdown. NOTE: Because we lock the http here, connections cannot be deleted while we are modifying the list. */ static void httpTimer(Http *http, MprEvent *event) { HttpConn *conn; HttpStage *stage; HttpLimits *limits; MprModule *module; int next, active, abort; updateCurrentDate(); /* Check for any inactive connections or expired requests (inactivityTimeout and requestTimeout) OPT - could check for expired connections every 10 seconds. */ lock(http->connections); for (active = 0, next = 0; (conn = mprGetNextItem(http->connections, &next)) != 0; active++) { limits = conn->limits; if (!conn->timeoutEvent) { abort = mprIsStopping(); if (httpServerConn(conn) && (HTTP_STATE_CONNECTED < conn->state && conn->state < HTTP_STATE_PARSED) && (http->now - conn->started) > limits->requestParseTimeout) { conn->timeout = HTTP_PARSE_TIMEOUT; abort = 1; } else if ((http->now - conn->lastActivity) > limits->inactivityTimeout) { conn->timeout = HTTP_INACTIVITY_TIMEOUT; abort = 1; } else if ((http->now - conn->started) > limits->requestTimeout) { conn->timeout = HTTP_REQUEST_TIMEOUT; abort = 1; } else if (!event) { /* Called directly from httpStop to stop connections */ if (MPR->exitTimeout > 0) { if (conn->state == HTTP_STATE_COMPLETE || (HTTP_STATE_CONNECTED < conn->state && conn->state < HTTP_STATE_PARSED)) { abort = 1; } } else { abort = 1; } } if (abort && !mprGetDebugMode()) { httpScheduleConnTimeout(conn); } } } /* Check for unloadable modules OPT - could check for modules every minute */ if (mprGetListLength(http->connections) == 0) { for (next = 0; (module = mprGetNextItem(MPR->moduleService->modules, &next)) != 0; ) { if (module->timeout) { if (module->lastActivity + module->timeout < http->now) { mprLog("info http", 2, "Unloading inactive module %s", module->name); if ((stage = httpLookupStage(module->name)) != 0) { if (mprUnloadModule(module) < 0) { active++; } else { stage->flags |= HTTP_STAGE_UNLOADED; } } else { mprUnloadModule(module); } } else { active++; } } } } httpPruneMonitors(); if (active == 0 || mprIsStopping()) { if (event) { mprRemoveEvent(event); } http->timer = 0; /* Going to sleep now, so schedule a GC to free as much as possible. */ mprGC(MPR_GC_FORCE | MPR_GC_NO_BLOCK); } else { mprGC(MPR_GC_NO_BLOCK); } unlock(http->connections); }
/* * The host timer does maintenance activities and will fire per second while there is active requests. * When multi-threaded, the host timer runs as an event off the service thread. Because we lock the host here, * connections cannot be deleted while we are modifying the list. */ static void hostTimer(MaHost *host, MprEvent *event) { Mpr *mpr; MaStage *stage; MaConn *conn; MprModule *module; MaHttp *http; int next, count; mprAssert(event); http = host->server->http; /* * Locking ensures connections won't be deleted */ lock(host); updateCurrentDate(host); mprLog(host, 8, "hostTimer: %d active connections", mprGetListCount(host->connections)); /* * Check for any expired connections */ for (count = 0, next = 0; (conn = mprGetNextItem(host->connections, &next)) != 0; count++) { /* * Workaround for a GCC bug when comparing two 64bit numerics directly. Need a temporary. */ int64 diff = conn->expire - host->now; if (diff < 0 && !mprGetDebugMode(host)) { conn->keepAliveCount = 0; if (!conn->disconnected) { if (conn->request) { mprLog(host, 6, "Open request timed out due to inactivity: %s", conn->request->url); } else { mprLog(host, 6, "Idle connection timed out"); } conn->disconnected = 1; mprDisconnectSocket(conn->sock); } } } /* Check for unloadable modules - must be idle */ mpr = mprGetMpr(http); if (mprGetListCount(host->connections) == 0) { for (next = 0; (module = mprGetNextItem(mpr->moduleService->modules, &next)) != 0; ) { if (module->timeout) { if (module->lastActivity + module->timeout < host->now) { if ((stage = maLookupStage(http, module->name)) != 0) { mprLog(host, 2, "Unloading inactive module %s", module->name); if (stage->match) { mprError(conn, "Can't unload modules with match routines"); module->timeout = 0; } else { maUnloadModule(http, module->name); stage->flags |= MA_STAGE_UNLOADED; } } else { maUnloadModule(http, module->name); } } else { count++; } } } } if (count == 0) { mprFree(event); host->timer = 0; } unlock(host); }