Пример #1
0
/*
    Notification callback. This routine is called from the Http pipeline on connection state changes.
 */
static void stateChangeNotifier(HttpConn *conn, int event, int arg)
{
    Ejs             *ejs;
    EjsRequest      *req;

    assert(conn);

    ejs = 0;
    if ((req = httpGetConnContext(conn)) != 0) {
        ejs = req->ejs;
    }
    switch (event) {
    case HTTP_EVENT_STATE:
        if (arg == HTTP_STATE_BEGIN) {
            setupConnTrace(conn);
        } else if (arg == HTTP_STATE_FINALIZED) {
            if (req) {
                if (conn->error) {
                    ejsSendRequestErrorEvent(ejs, req);
                }
                ejsSendRequestCloseEvent(ejs, req);
                if (req->cloned) {
                    ejsSendRequestCloseEvent(req->ejs, req->cloned);
                }
            }
        }
        break;

    case HTTP_EVENT_READABLE:
        /*  IO event notification for the request.  */
        if (req && req->emitter) {
            ejsSendEvent(ejs, req->emitter, "readable", NULL, req);
        }
        break;

    case HTTP_EVENT_WRITABLE:
        if (req && req->emitter) {
            ejsSendEvent(ejs, req->emitter, "writable", NULL, req);
        }
        break;

    case HTTP_EVENT_APP_CLOSE:
        /* Connection close */
        if (req && req->conn) {
            req->conn = 0;
        }
        break;
    }
}
Пример #2
0
static void httpEventChange(HttpConn *conn, int event, int arg)
{
    Ejs         *ejs;
    EjsHttp     *hp;
    HttpTx      *tx;
    MprOff      lastWritten;

    hp = httpGetConnContext(conn);
    ejs = hp->ejs;
    tx = conn->tx;

    switch (event) {
    case HTTP_EVENT_STATE:
        switch (arg) {
        case HTTP_STATE_PARSED:
            if (hp->emitter) {
                ejsSendEvent(ejs, hp->emitter, "headers", NULL, hp);
            }
            break;

        case HTTP_STATE_FINALIZED:
            if (hp->emitter) {
                if (conn->error) {
                    sendHttpErrorEvent(ejs, hp);
                }
                sendHttpCloseEvent(ejs, hp);
            }
            break;
        }
        break;

    case HTTP_EVENT_READABLE:
        if (hp && hp->emitter) {
            ejsSendEvent(ejs, hp->emitter, "readable", NULL, hp);
        }
        break;

    case HTTP_EVENT_WRITABLE:
        if (hp && hp->emitter) {
            do {
                lastWritten = tx->bytesWritten;
                ejsSendEvent(ejs, hp->emitter, "writable", NULL, hp);
            } while (tx->bytesWritten > lastWritten && !tx->writeBlocked);
        }
        break;
    }
}
Пример #3
0
/*
    function close(): Void
 */
static EjsObj *hs_close(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv)
{
    if (sp->endpoint) {
        ejsSendEvent(ejs, sp->emitter, "close", NULL, sp);
        httpDestroyEndpoint(sp->endpoint);
        sp->endpoint = 0;
    }
    return 0;
}
Пример #4
0
/*  
    function on(name, observer: function): Http
 */
static EjsHttp *http_on(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    EjsFunction     *observer;
    HttpConn        *conn;

    observer = (EjsFunction*) argv[1];
    if (observer->boundThis == 0 || observer->boundThis == ejs->global) {
        observer->boundThis = hp;
    }
    ejsAddObserver(ejs, &hp->emitter, argv[0], observer);

    conn = hp->conn;
    if (conn->readq && conn->readq->count > 0) {
        ejsSendEvent(ejs, hp->emitter, "readable", NULL, hp);
    }
    //  TODO - don't need to test finalizedConnector
    if (!conn->tx->finalizedConnector && !conn->error && HTTP_STATE_CONNECTED <= conn->state && 
            conn->state < HTTP_STATE_FINALIZED && conn->writeq->ioCount == 0) {
        httpNotify(conn, HTTP_EVENT_WRITABLE, 0);
    }
    return hp;
}
Пример #5
0
static void onWebSocketEvent(EjsWebSocket *ws, int event, EjsAny *data, HttpPacket *packet)
{
    Ejs             *ejs;
    EjsAny          *eobj;
    EjsFunction     *fn;
    HttpRx          *rx;
    cchar           *eventName, *reason;
    int             slot, status;

    ejs = ws->ejs;
    rx = ws->conn->rx;
    eobj = ejsCreateObj(ejs, ESV(Object), 0);
    slot = -1;
    eventName = 0;

    switch(event) {
    case HTTP_EVENT_READABLE:
        slot = ES_WebSocket_onmessage;
        eventName = "readable";
        assert(data);
        ejsSetPropertyByName(ejs, eobj, EN("data"), data);
        ejsSetPropertyByName(ejs, eobj, EN("last"), ejsCreateBoolean(ejs, packet->last));
        ejsSetPropertyByName(ejs, eobj, EN("type"), ejsCreateNumber(ejs, packet->type));
        break;

    case HTTP_EVENT_ERROR:
        eventName = "error";
        slot = ES_WebSocket_onerror;
        break;

    case HTTP_EVENT_APP_OPEN:
        slot = ES_WebSocket_onopen;
        eventName = "headers";
        if (rx->webSocket) {
            httpSetWebSocketPreserveFrames(ws->conn, ws->frames);
        }
        break;

    case HTTP_EVENT_DESTROY:
        if (ws->closed) {
            break;
        }
        ws->closed = 1;
        /* Fall through to close */

    case HTTP_EVENT_APP_CLOSE:
        eventName = "complete";
        slot = ES_WebSocket_onclose;
        status = rx ? rx->webSocket->closeStatus: WS_STATUS_COMMS_ERROR;
        reason = rx ? rx->webSocket->closeReason: 0;
        ejsSetPropertyByName(ejs, eobj, EN("code"), ejsCreateNumber(ejs, status));
        ejsSetPropertyByName(ejs, eobj, EN("reason"), ejsCreateStringFromAsc(ejs, reason));
        ejsSetPropertyByName(ejs, eobj, EN("wasClean"), ejsCreateBoolean(ejs, status != WS_STATUS_COMMS_ERROR));
        break;
    }
    if (slot >= 0) {
        if (ws->emitter) {
            ejsSendEvent(ejs, ws->emitter, eventName, ws, data);
        }
        fn = ejsGetProperty(ejs, ws, slot);
        if (ejsIsFunction(ejs, fn) && !ejs->exception) {
            ejsRunFunction(ejs, fn, ws, 1, &eobj);
        }
    }
}