Beispiel #1
0
/*  
    function send(...content): Number
 */
static EjsNumber *ws_send(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ba;
    EjsAny          *arg;
    ssize           nbytes;
    int             i;

    args = (EjsArray*) argv[0];
    if (ws->conn->state < HTTP_STATE_PARSED && !waitForHttpState(ws, HTTP_STATE_PARSED, -1, 1)) {
        return ESV(null);
    }
    nbytes = 0;
    for (i = 0; i < args->length; i++) {
        if ((arg = ejsGetProperty(ejs, args, i)) != 0) {
            if (ejsIs(ejs, arg, ByteArray)) {
                ba = (EjsByteArray*) arg;
                nbytes = ejsGetByteArrayAvailableData(ba);
                nbytes = httpSendBlock(ws->conn, WS_MSG_BINARY, (cchar*) &ba->value[ba->readPosition], nbytes, HTTP_BLOCK);
            } else {
                nbytes = httpSend(ws->conn, ejsToMulti(ejs, arg));
            }
            if (nbytes < 0) {
                return ESV(null);
            }
        }
    }
    return ejsCreateNumber(ejs, (MprNumber) nbytes);
}
Beispiel #2
0
/* 
    Write another block of data
 */
static ssize writeHttpData(Ejs *ejs, EjsHttp *hp)
{
    EjsByteArray    *ba;
    HttpConn        *conn;
    ssize           count, nbytes;

    conn = hp->conn;
    ba = hp->data;
    nbytes = 0;
    if (ba && (count = ejsGetByteArrayAvailableData(ba)) > 0) {
        if (conn->tx->finalizedOutput) {
            ejsThrowIOError(ejs, "Cannot write to socket");
            return 0;
        }
        //  MOB - or should this be non-blocking
        nbytes = httpWriteBlock(conn->writeq, (cchar*) &ba->value[ba->readPosition], count, HTTP_BLOCK);
        if (nbytes < 0) {
            ejsThrowIOError(ejs, "Cannot write to socket");
            return 0;
        }
        ba->readPosition += nbytes;
    }
    httpServiceQueues(conn);
    return nbytes;
}
Beispiel #3
0
/*
    uncompressBytes(data: ByteArray): ByteArray
 */
static EjsObj *zlib_uncompressBytes(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsByteArray    *in, *out;
    z_stream        zs;
    uchar           outbuf[ZBUFSIZE];
    ssize           nbytes, size;
    int             rc;

    in = (EjsByteArray*) argv[0];
    if ((out = ejsCreateByteArray(ejs, in->size)) == 0) {
        return 0;
    }
    if ((size = (int) ejsGetByteArrayAvailableData(in)) == 0) {
        return (EjsObj*) out;
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    zs.avail_in = 0;
    rc = inflateInit(&zs);
    zs.next_in = &in->value[in->readPosition];
    zs.avail_in = (int) size;

    do {
        if (zs.avail_in == 0) {
            break;
        }
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = (uchar*) outbuf;
            if ((rc = inflate(&zs, Z_NO_FLUSH)) == Z_NEED_DICT) {
                inflateEnd(&zs);
                return 0;
            } else if (rc == Z_DATA_ERROR || rc == Z_MEM_ERROR) {
                inflateEnd(&zs);
                return 0;
            } else {
                nbytes = ZBUFSIZE - zs.avail_out;
            }
            if (ejsCopyToByteArray(ejs, out, -1, (char*) outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to byte array");
                inflateEnd(&zs);
                return 0;
            }
            out->writePosition += nbytes;
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (rc != Z_STREAM_END);

    deflateEnd(&zs);
    return (EjsObj*) out;
}
Beispiel #4
0
/*  
    function sendBlock(content, options): Number
 */
static EjsNumber *ws_sendBlock(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    EjsByteArray    *ba;
    EjsAny          *content, *vp;
    ssize           nbytes;
    cchar           *str;
    int             last, mode, type, flags;

    assert(argc == 2);

    if (ws->conn->state < HTTP_STATE_PARSED && !waitForHttpState(ws, HTTP_STATE_PARSED, -1, 1)) {
        return ESV(null);
    }
    content = argv[0];
    last = ejsGetPropertyByName(ejs, argv[1], EN("last")) != ESV(false);
    if ((vp = ejsGetPropertyByName(ejs, argv[1], EN("mode"))) != 0) {
        mode = (int) ejsGetNumber(ejs, vp);
        if (mode != HTTP_BUFFER && mode != HTTP_BLOCK && mode != HTTP_NON_BLOCK) {
            ejsThrowArgError(ejs, "Bad message mode");
            return 0;
        }
    } else {
        mode = HTTP_BUFFER;
    }
    if ((vp = ejsGetPropertyByName(ejs, argv[1], EN("type"))) != 0) {
        type = (int) ejsGetNumber(ejs, vp);
        if (type != WS_MSG_CONT && type != WS_MSG_TEXT && type != WS_MSG_BINARY) {
            ejsThrowArgError(ejs, "Bad message type");
            return 0;
        }
    } else {
        type = WS_MSG_TEXT;
    }
    flags = mode;
    if (!last) {
        flags |= HTTP_MORE;
    }
    if (ejsIs(ejs, content, ByteArray)) {
        ba = (EjsByteArray*) content;
        nbytes = ejsGetByteArrayAvailableData(ba);
        nbytes = httpSendBlock(ws->conn, type, (cchar*) &ba->value[ba->readPosition], nbytes, flags);
    } else {
        str = ejsToMulti(ejs, content);
        nbytes = httpSendBlock(ws->conn, type, str, slen(str), flags);
    }
    if (nbytes < 0) {
        ejsThrowIOError(ejs, "Cannot send block");
        return 0;
    }
    return ejsCreateNumber(ejs, (MprNumber) nbytes);
}
Beispiel #5
0
/*
    function write(...data): Void
 */
static EjsNumber *http_write(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    ssize     nbytes;

    hp->data = ejsCreateByteArray(ejs, -1);
    if (ejsWriteToByteArray(ejs, hp->data, 1, &argv[0]) < 0) {
        return 0;
    }
    if ((nbytes = writeHttpData(ejs, hp)) < 0) {
        return 0;
    }
    hp->writeCount += nbytes;
    if (hp->conn->async) {
        if (ejsGetByteArrayAvailableData(hp->data) > 0) {
            httpEnableConnEvents(hp->conn);
        }
    }
    return ejsCreateNumber(ejs, (MprNumber) nbytes);
}
Beispiel #6
0
/*
    compressBytes(data: ByteArray): ByteArray
 */
static EjsObj *zlib_compressBytes(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsByteArray    *in, *out;
    z_stream        zs;
    char            outbuf[ZBUFSIZE];
    ssize           nbytes;
    int             level, flush;

    in = (EjsByteArray*) argv[0];
    if ((out = ejsCreateByteArray(ejs, in->size)) == 0) {
        return 0;
    }
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    level = Z_DEFAULT_COMPRESSION;
    deflateInit(&zs, level);
    zs.avail_in = (int) ejsGetByteArrayAvailableData(in);
    zs.next_in = (uchar*) &in->value[in->readPosition];
    do {
        flush = (zs.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH;
        do {
            zs.avail_out = ZBUFSIZE;
            zs.next_out = (uchar*) outbuf;
            deflate(&zs, flush);
            nbytes = ZBUFSIZE - zs.avail_out;
            if (ejsCopyToByteArray(ejs, out, -1, outbuf, nbytes) != nbytes) {
                ejsThrowIOError(ejs, "Cannot copy to byte array");
                deflateEnd(&zs);
                return 0;
            }
            out->writePosition += nbytes;
        } while (zs.avail_out == 0);
        assure(zs.avail_in == 0);
    } while (flush != Z_FINISH);
    deflateEnd(&zs);
    return (EjsObj*) out;
}