Beispiel #1
0
/*
 *  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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
/*
 *  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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
/*
 *  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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
void DCalendar::showEvent(QShowEvent *)
{
    updateCurrentDate();
}
Beispiel #8
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;
}
Beispiel #9
0
/*
    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);
}
Beispiel #10
0
/*
 *  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);
}