Esempio n. 1
0
/*
    function passRequest(req: Request, worker: Worker): Void
 */
static EjsVoid *hs_passRequest(Ejs *ejs, EjsHttpServer *server, int argc, EjsAny **argv)
{
    Ejs             *nejs;
    EjsRequest      *req, *nreq;
    EjsWorker       *worker;
    HttpConn        *conn;
    MprEvent        *event;

    req = argv[0];
    worker = argv[1];

    nejs = worker->pair->ejs;
    conn = req->conn;
    conn->ejs = nejs;

    if ((nreq = ejsCloneRequest(nejs, req, 1)) == 0) {
        ejsThrowStateError(ejs, "Cannot clone request");
        return 0;
    }
    httpSetConnContext(conn, nreq);

    if ((nreq->server = ejsCloneHttpServer(nejs, req->server, 1)) == 0) {
        ejsThrowStateError(ejs, "Cannot clone request");
        return 0;
    }
    event = mprCreateEvent(conn->dispatcher, "RequestWorker", 0, receiveRequest, nreq, MPR_EVENT_DONT_QUEUE);
    httpUseWorker(conn, nejs->dispatcher, event);
    return 0;
}
Esempio n. 2
0
/*  
    Read data bytes from a file
    function readBytes(count: Number = -1): ByteArray
 */
static EjsObj *readFileBytes(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsByteArray    *result;
    MprPath         info;
    ssize           count, totalRead;

    if (argc == 0) {
        count = -1;
    } else if (argc != 1) {
        count = 0;
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    } else {
        assert(argc == 1 && ejsIs(ejs, argv[0], Number));
        count = ejsGetInt(ejs, argv[0]);
    }
    if (fp->file == 0) {
        ejsThrowStateError(ejs, "File not open");
        return 0;
    }
    if (!(fp->mode & EJS_FILE_READ)) {
        ejsThrowStateError(ejs, "File not opened for reading");
        return 0;
    }
    if (count < 0) {
        //  TODO OPT could this be cached in fp->info 
        if (mprGetPathInfo(fp->path, &info) == 0) {
            count = (int) info.size;
            count -= (int) mprGetFilePosition(fp->file);
        } else {
            count = ME_MAX_BUFFER;
        }
        assert(count >= 0);
    }
    result = ejsCreateByteArray(ejs, count);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    totalRead = readData(ejs, fp, result, 0, count);
    if (totalRead < 0) {
        ejsThrowIOError(ejs, "Cannot read from file: %s", fp->path);
        return 0;
    } else if (totalRead == 0) {
        return ESV(null);
    }
    ejsSetByteArrayPositions(ejs, result, 0, totalRead);
    return (EjsObj*) result;
}
Esempio n. 3
0
/*  
    Read data bytes from a file. If offset is < 0, then append to the write position.
    function read(buffer: ByteArray, offset: Number = 0, count: Number = -1): Number
 */
static EjsNumber *readFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsByteArray    *buffer;
    MprPath         info;
    ssize           offset, count, totalRead;

    assert(1 <= argc && argc <= 3);

    buffer = (EjsByteArray*) argv[0];
    offset = (argc >= 2) ? ejsGetInt(ejs, argv[1]): 0;
    count = (argc >= 3) ? ejsGetInt(ejs, argv[2]): -1;

    if (fp->file == 0) {
        ejsThrowStateError(ejs, "File not open");
        return 0;
    }
    if (!(fp->mode & EJS_FILE_READ)) {
        ejsThrowStateError(ejs, "File not opened for reading");
        return 0;
    }
    if (offset >= buffer->size) {
        ejsThrowOutOfBoundsError(ejs, "Bad read offset value");
        return 0;
    }
    if (offset < 0) {
        offset = buffer->writePosition;
    } else if (offset == 0) {
        ejsSetByteArrayPositions(ejs, buffer, 0, 0);
    }
    if (count < 0) {
        //  TODO OPT could this be cached in fp->info 
        if (mprGetPathInfo(fp->path, &info) == 0) {
            count = (int) info.size;
            count -= (int) mprGetFilePosition(fp->file);
        } else {
            count = ME_MAX_BUFFER;
        }
        assert(count >= 0);
    }
    totalRead = readData(ejs, fp, buffer, offset, count);
    if (totalRead < 0) {
        return 0;
    } else if (totalRead == 0) {
        return ESV(zero);
    }
    ejsSetByteArrayPositions(ejs, buffer, -1, offset + totalRead);
    return ejsCreateNumber(ejs, (MprNumber) totalRead);
}
Esempio n. 4
0
/*  
    Exit the application
    static function exit(status: Number, how: String = "default"): void
    MOB - status is not implemented
 */
static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    cchar   *how;
    int     status, mode;

    if (ejs->dontExit) {
        ejsThrowStateError(ejs, "App.exit has been disabled");
        return 0;
    }
    status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0;
    how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty));

    if (scmp(how, "default") == 0) {
        mode = MPR_EXIT_DEFAULT;
    } else if (scmp(how, "immediate") == 0) {
        mode = MPR_EXIT_IMMEDIATE;
    } else if (scmp(how, "graceful") == 0) {
        mode = MPR_EXIT_GRACEFUL;
    } else {
        mode = MPR_EXIT_NORMAL;
    }
    mprTerminate(mode, status);
    ejsAttention(ejs);
    return 0;
}
Esempio n. 5
0
/*
 *  Post a message to this worker. Note: the worker is the destination worker which may be the parent.
 *
 *  function postMessage(data: Object, ports: Array = null): Void
 */
static EjsVar *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    EjsVar          *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }

    /*
     *  Create the event with serialized data in the originating interpreter. It owns the data.
     */
    if ((data = ejsSerialize(ejs, argv[0], -1, 0, 0)) == 0) {
        ejsThrowArgError(ejs, "Can't serialize message data");
        return 0;
    }
    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = mprStrdup(target->ejs, ejsGetString(data));
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_ejs_sys_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
    return 0;
}
Esempio n. 6
0
/*
 *  function preload(path: Path): String
 *  NOTE: this blocks. 
 */
static EjsVar *workerPreload(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    Ejs         *inside;
    EjsWorker   *insideWorker;
    EjsVar      *result;

    mprAssert(argc > 0 && ejsIsPath(argv[0]));
    mprAssert(!worker->inside);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    insideWorker = worker->pair;
    inside = insideWorker->ejs;

    loadFile(worker->pair, ((EjsPath*) argv[0])->path);
    if (inside->exception) {
        handleError(ejs, worker, inside->exception);
        return 0;
    }
    result = ejsSerialize(ejs, inside->result, -1, 0, 0);
    if (result == 0) {
        return ejs->nullValue;
    }
    return ejsDeserialize(ejs, (EjsString*) result);
}
Esempio n. 7
0
/*
    function preeval(script: String): Object
    NOTE: this blocks. 
 */
static EjsObj *workerPreeval(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{
    Ejs         *inside;
    EjsWorker   *insideWorker;
    EjsString   *result;

    assert(!worker->inside);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    insideWorker = worker->pair;
    assert(insideWorker->inside);
    inside = insideWorker->ejs;

    (inside->service->loadScriptLiteral)(inside, (EjsString*) argv[0], NULL);
    if (inside->exception) {
        handleError(ejs, worker, inside->exception, 1);
        return 0;
    }
    result = ejsToJSON(inside, inside->result, NULL);
    if (result == 0) {
        return ESV(null);
    }
    return ejsDeserialize(ejs, result);
}
Esempio n. 8
0
static int join(Ejs *ejs, EjsObj *workers, int timeout)
{
    MprTicks    mark;
    int         result, remaining;

    mprTrace(5, "Worker.join: joining %d", ejs->joining);
    
    mark = mprGetTicks();
    remaining = timeout;
    do {
        ejs->joining = !reapJoins(ejs, workers);
        if (!ejs->joining) {
            break;
        }
        if (mprShouldAbortRequests()) {
            ejsThrowStateError(ejs, "Program instructed to exit");
            break;
        }
        mprWaitForEvent(ejs->dispatcher, remaining);
        remaining = (int) mprGetRemainingTicks(mark, timeout);
    } while (remaining > 0 && !ejs->exception);

    if (ejs->exception) {
        return 0;
    }
    result = (ejs->joining) ? MPR_ERR_TIMEOUT: 0;
    ejs->joining = 0;
    mprTrace(7, "Worker.join: result %d", result);
    return result;
}
Esempio n. 9
0
/*
    function preload(path: Path): Object
    NOTE: this blocks. 
 */
static EjsObj *workerPreload(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{
    Ejs         *inside;
    EjsWorker   *insideWorker;
    EjsString   *result;

    assert(argc > 0 && ejsIs(ejs, argv[0], Path));
    assert(!worker->inside);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    insideWorker = worker->pair;
    assert(insideWorker->inside);
    inside = insideWorker->ejs;

    loadFile(worker->pair, ((EjsPath*) argv[0])->value);
    if (inside->exception) {
        handleError(ejs, worker, inside->exception, 1);
        return 0;
    }
    result = ejsToJSON(inside, inside->result, NULL);
    if (result == 0) {
        return ESV(null);
    }
    return ejsDeserialize(ejs, result);
}
Esempio n. 10
0
/*
    Post a message to this worker. Note: the worker is the destination worker which may be the parent.

    function postMessage(data: Object, ports: Array = null): Void
 */
static EjsObj *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{
    EjsString       *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }
    /*
        Create the event with serialized data in the originating interpreter. It owns the data.
     */
    ejsBlockGC(ejs);
    if ((data = ejsToJSON(ejs, argv[0], NULL)) == 0) {
        ejsThrowArgError(ejs, "Cannot serialize message data");
        return 0;
    }
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = ejsToMulti(ejs, data);
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, "postMessage", 0, doMessage, msg, 0);
    return 0;
}
Esempio n. 11
0
/*  
    Get the current I/O position in the file.
    function get position(): Number
 */
static EjsObj *getFilePosition(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    if (fp->file == 0) {
        ejsThrowStateError(ejs, "File not opened");
        return 0;
    }
    return (EjsObj*) ejsCreateNumber(ejs, (MprNumber) mprGetFilePosition(fp->file));
}
Esempio n. 12
0
/*
    WARNING: the inside interpreter owns the exception object. Must fully extract all fields
 */
static void handleError(Ejs *ejs, EjsWorker *worker, EjsObj *exception, int throwOutside)
{
    Ejs             *inside;
    EjsObj          *e;
    MprDispatcher   *dispatcher;
    Message         *msg;

    assert(!worker->inside);
    assert(exception);
    assert(ejs == worker->ejs);

    ejsBlockGC(ejs);
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }
    msg->worker = worker;
    msg->callback = "onerror";
    msg->callbackSlot = ES_Worker_onerror;
    inside = worker->pair->ejs;
    
    inside->exception = 0;
    e = ejsDeserialize(ejs, ejsSerialize(inside, exception, 0));
    inside->exception = exception;

    /*
        Inside interpreter owns the exception object, so must fully extract all exception. 
        Allocate into the outside worker's interpreter.
     */
    if (ejsIsError(inside, exception)) {
        msg->message = ejsGetPropertyByName(ejs, e, EN("message"));
        msg->stack = ejsGetPropertyByName(ejs, e, EN("stack"));
    } else {
        msg->message = e;
        msg->stack = 0;
    }
    if (throwOutside) {
        if (msg->stack) {
            ejsThrowStateError(ejs, "%@\n%@", ejsToString(ejs, msg->message), ejsToString(ejs, msg->stack));
        } else {
            ejsThrowStateError(ejs, "%@", ejsToString(ejs, msg->message));
        }
    }
    dispatcher = ejs->dispatcher;
    mprCreateEvent(dispatcher, "doMessage-error", 0, (MprEventProc) doMessage, msg, 0);
}
Esempio n. 13
0
/*  
    Read data as a string
    function readString(count: Number = -1): String
 */
static EjsString *readFileString(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsString       *result;
    MprPath         info;
    ssize           totalRead;
    int             count;

    if (argc == 0) {
        count = -1;
    } else if (argc != 1) {
        count = 0;
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    } else {
        assert(argc == 1 && ejsIs(ejs, argv[0], Number));
        count = ejsGetInt(ejs, argv[0]);
    }
    if (fp->file == 0) {
        ejsThrowStateError(ejs, "File not open");
        return 0;
    }
    if (!(fp->mode & EJS_FILE_READ)) {
        ejsThrowStateError(ejs, "File not opened for reading");
        return 0;
    }
    if (count < 0) {
        //  TODO OPT could this be cached in fp->info 
        if (mprGetPathInfo(fp->path, &info) == 0) {
            count = (int) info.size;
            count -= (int) mprGetFilePosition(fp->file);
        } else {
            count = ME_MAX_BUFFER;
        }
        assert(count >= 0);
    }
    if ((result = ejsCreateBareString(ejs, count)) == NULL) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    totalRead = mprReadFile(fp->file, result->value, count);
    if (totalRead != count) {
        ejsThrowIOError(ejs, "Cannot read from file: %s", fp->path);
        return 0;
    }
    return ejsInternString(result);
}
Esempio n. 14
0
/*
    Start a worker thread. This is called by eval() and load(). Not by preload() or by Worker(). It always joins.
 */
static EjsObj *startWorker(Ejs *ejs, EjsWorker *outsideWorker, int timeout)
{
    EjsWorker   *insideWorker;
    Ejs         *inside;
    EjsString   *result;

    assert(ejs);
    assert(outsideWorker);
    assert(!outsideWorker->inside);
    assert(outsideWorker->state == EJS_WORKER_BEGIN);
    assert(outsideWorker->pair);
    assert(outsideWorker->pair->ejs);

    mprTrace(5, "Worker.startWorker");

    if (outsideWorker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    insideWorker = outsideWorker->pair;
    assert(insideWorker->inside);
    assert(insideWorker->state == EJS_WORKER_BEGIN);
    inside = insideWorker->ejs;

    outsideWorker->state = EJS_WORKER_STARTED;

    if (mprCreateEvent(inside->dispatcher, "workerMain", 0, (MprEventProc) workerMain, insideWorker, 0) < 0) {
        ejsThrowStateError(ejs, "Cannot create worker event");
        return 0;
    }
    if (timeout == 0) {
        return ESV(undefined);
    } 
    if (timeout < 0) {
        timeout = MAXINT;
    }
    if (join(ejs, (EjsObj*) outsideWorker, timeout) < 0) {
        return ESV(undefined);
    }
    result = ejsToJSON(inside, inside->result, NULL);
    if (result == 0) {
        return ESV(null);
    }
    return ejsDeserialize(ejs, result);
}
Esempio n. 15
0
/*
 *  Start a worker thread. This is called by eval() and load(). Not by preload() or by Worker()
 *  It always joins.
 */
static EjsVar *startWorker(Ejs *ejs, EjsWorker *worker, int timeout)
{
    Ejs     *inside;
    EjsVar  *result;

    mprAssert(ejs);
    mprAssert(worker);
    mprAssert(worker->state == EJS_WORKER_BEGIN);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    mprAssert(worker->pair->state == EJS_WORKER_BEGIN);

    addWorker(ejs, worker);
    worker->state = EJS_WORKER_STARTED;

    worker->obj.var.permanent = 1;
    if (mprStartWorker(ejs, (MprWorkerProc) workerMain, (void*) worker, MPR_NORMAL_PRIORITY) < 0) {
        ejsThrowStateError(ejs, "Can't start worker");
        worker->obj.var.permanent = 0;
        return 0;
    }
    if (timeout == 0) {
        return ejs->undefinedValue;
    } 
    if (timeout < 0) {
        timeout = MAXINT;
    }
    if (join(ejs, (EjsVar*) worker, timeout) < 0) {
        ejsThrowStateError(ejs, "Timeout (%d)", timeout);
        return ejs->undefinedValue;
    }
    mprAssert(worker->pair);
    mprAssert(worker->pair->ejs);
    inside = worker->pair->ejs;
    result = ejsSerialize(ejs, inside->result, -1, 0, 0);
    if (result == 0) {
        return ejs->nullValue;
    }
    return ejsDeserialize(ejs, (EjsString*) result);
}
Esempio n. 16
0
/*  
    Write data to the file
    function write(data: Object): Number
 */
PUBLIC EjsObj *writeFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ap;
    EjsObj          *vp;
    EjsString       *str;
    cchar           *buf;
    ssize           len, written;
    int             i;

    assert(argc == 1 && ejsIs(ejs, argv[0], Array));

    args = (EjsArray*) argv[0];

    if (!(fp->mode & EJS_FILE_WRITE)) {
        ejsThrowStateError(ejs, "File not opened for writing");
        return 0;
    }
    written = 0;

    for (i = 0; i < args->length; i++) {
        vp = ejsGetProperty(ejs, (EjsObj*) args, i);
        assert(vp);
        switch (TYPE(vp)->sid) {
        case S_ByteArray:
            ap = (EjsByteArray*) vp;
            //  TODO UNICODE ENCODING
            buf = (cchar*) &ap->value[ap->readPosition];
            len = ap->writePosition - ap->readPosition;
            break;

        case S_String: // UNICODE
#if UNICODE && FUTURE
            buf = awtom(((EjsString*) vp)->value, &len);
#else
            buf = ((EjsString*) vp)->value;
            len = ((EjsString*) vp)->length;
#endif
            break;

        default:
            str = ejsToString(ejs, vp);
            buf = awtom(((EjsString*) str)->value, &len);
            break;
        }
        if (mprWriteFile(fp->file, buf, len) != len) {
            ejsThrowIOError(ejs, "Cannot write to %s", fp->path);
            return 0;
        }
        written += len;
        /* Use GC to free buf as it may not be allocated */
    }
    return (EjsObj*) ejsCreateNumber(ejs, (MprNumber) written);
}
Esempio n. 17
0
/*  
    Seek to a new location in the file and set the File marker to a new read/write position.
    function set position(value: Number): void
 */
static EjsObj *setFilePosition(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    MprOff      pos;

    assert(argc == 1 && ejsIs(ejs, argv[0], Number));
    pos = ejsGetInt(ejs, argv[0]);

    if (fp->file == 0) {
        ejsThrowStateError(ejs, "File not opened");
        return 0;
    }
    pos = ejsGetInt(ejs, argv[0]);
    if (mprSeekFile(fp->file, SEEK_SET, pos) != pos) {
        ejsThrowIOError(ejs, "Cannot seek to %Ld", pos);
    }
    return 0;
}
Esempio n. 18
0
/*
    function terminate(): Void
 */
static EjsObj *workerTerminate(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{    
    if (worker->state == EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has not yet started");
        return 0;
    }
    if (worker->state >= EJS_WORKER_COMPLETE) {
        return 0;
    }
    /*
        Switch to the inside worker if called from outside
     */
    assert(worker->pair && worker->pair->ejs);
    ejs = (!worker->inside) ? worker->pair->ejs : ejs;
    ejs->exiting = 1;
    mprSignalDispatcher(ejs->dispatcher);
    return 0;
}
Esempio n. 19
0
/*  
    Exit the application
    static function exit(status: Number, how: String = "immediate"): void
    TODO - status is not implemented
 */
static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprTicks    timeout;
    cchar       *how;
    int         status, mode;

    if (ejs->dontExit) {
        ejsThrowStateError(ejs, "App.exit has been disabled");
        return 0;
    }
    status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0;
    timeout = argc >= 2 ? ejsGetInt(ejs, argv[1]) : 0;
    how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty));

    if (scmp(how, "normal") == 0) {
        mode = 0;
    } else if (scmp(how, "abort") == 0) {
        mode = MPR_EXIT_ABORT;
    } else if (scmp(how, "safe") == 0) {
        mode = MPR_EXIT_SAFE;
    } else if (scmp(how, "restart") == 0) {
        mode = MPR_EXIT_RESTART;
#if DEPRECATED || 1
    } else if (scmp(how, "immediate") == 0) {
        mode = 0;
    } else if (scmp(how, "graceful") == 0) {
        mode = 0;
        if (argc <= 2) {
            timeout = 30 * 3000;
        }
    } else if (scmp(how, "default") == 0) {
        mode = 0;
#endif
    } else {
        mode = 0;
    }
    mprShutdown(mode, status, timeout);
    ejsAttention(ejs);
    return 0;
}
Esempio n. 20
0
static void receiveRequest(EjsRequest *req, MprEvent *event)
{
    Ejs             *ejs;
    EjsAny          *argv[1];
    EjsFunction     *onrequest;
    HttpConn        *conn;

    conn = req->conn;
    ejs = req->ejs;
    assert(ejs);

    onrequest = ejsGetProperty(ejs, req->server, ES_ejs_web_HttpServer_onrequest);
    if (!ejsIsFunction(ejs, onrequest)) {
        ejsThrowStateError(ejs, "HttpServer.onrequest is not a function");
        return;
    }
    argv[0] = req;
    ejsRunFunction(ejs, onrequest, req->server, 1, argv);
    if (conn->state == HTTP_STATE_BEGIN) {
        conn->ejs = 0;
        httpUsePrimary(conn);
    }
    httpEnableConnEvents(conn);
}
Esempio n. 21
0
/*
    function [get|put|delete|post...](uri = null, ...data): Http
 */
static EjsHttp *startHttpRequest(Ejs *ejs, EjsHttp *hp, char *method, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *data;
    EjsNumber       *written;
    EjsUri          *uriObj;
    HttpConn        *conn;
    ssize           nbytes;

    conn = hp->conn;
    hp->responseCache = 0;
    hp->requestContentCount = 0;
    mprFlushBuf(hp->responseContent);

    if (argc >= 1 && !ejsIs(ejs, argv[0], Null)) {
        uriObj = (EjsUri*) argv[0];
        hp->uri = httpUriToString(uriObj->uri, HTTP_COMPLETE_URI);
    }
    if (argc == 2 && ejsIs(ejs, argv[1], Array)) {
        args = (EjsArray*) argv[1];
        if (args->length > 0) {
            data = ejsCreateByteArray(ejs, -1);
            written = ejsWriteToByteArray(ejs, data, 1, &argv[1]);
            mprPutBlockToBuf(hp->requestContent, (char*) data->value, (int) written->value);
            mprAddNullToBuf(hp->requestContent);
            assert(written > 0);
        }
    }
    if (hp->uri == 0) {
        ejsThrowArgError(ejs, "URL is not defined");
        return 0;
    }
    if (method && strcmp(hp->method, method) != 0) {
        hp->method = sclone(method);
    }
    if (hp->method == 0) {
        ejsThrowArgError(ejs, "HTTP Method is not defined");
        return 0;
    }
    if (hp->certFile) {
        if (!hp->ssl) {
            hp->ssl = mprCreateSsl(0);
        }
        mprSetSslCertFile(hp->ssl, hp->certFile);
        if (!hp->keyFile) {
            ejsThrowStateError(ejs, "Must define a Http.key to use with a certificate");
        }
        mprSetSslKeyFile(hp->ssl, hp->keyFile);
    }
    if (hp->caFile) {
        if (!hp->ssl) {
            hp->ssl = mprCreateSsl(0);
        }
        mprSetSslCaFile(hp->ssl, hp->caFile);
    }
    if (httpConnect(conn, hp->method, hp->uri, hp->ssl) < 0) {
        ejsThrowIOError(ejs, "Cannot issue request for \"%s\"", hp->uri);
        return 0;
    }
    if (mprGetBufLength(hp->requestContent) > 0) {
        nbytes = httpWriteBlock(conn->writeq, mprGetBufStart(hp->requestContent), mprGetBufLength(hp->requestContent),
            HTTP_BLOCK);
        if (nbytes < 0) {
            ejsThrowIOError(ejs, "Cannot write request data for \"%s\"", hp->uri);
            return 0;
        } else if (nbytes > 0) {
            assert(nbytes == mprGetBufLength(hp->requestContent));
            mprAdjustBufStart(hp->requestContent, nbytes);
            hp->requestContentCount += nbytes;
        }
        httpFinalize(conn);
    }
    httpNotify(conn, HTTP_EVENT_WRITABLE, 0);
    if (conn->async) {
        httpEnableConnEvents(hp->conn);
    }
    return hp;
}
Esempio n. 22
0
/*
 *  function Worker(script: String = null, options: Object = null)
 *
 *  Script is optional. If supplied, the script is run immediately by a worker thread. This call
 *  does not block. Options are: search and name.
 */
static EjsVar *workerConstructor(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    Ejs             *wejs;
    EjsVar          *options, *value;
    EjsName         qname;
    EjsWorker       *self;
    cchar           *search, *name;

    worker->ejs = ejs;
    worker->state = EJS_WORKER_BEGIN;

    options = (argc == 2) ? (EjsVar*) argv[1]: NULL;
    name = 0;

    search = ejs->ejsPath;
    if (options) {
        value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "search"));
        if (ejsIsString(value)) {
            search = ejsGetString(value);
        }
        value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "name"));
        if (ejsIsString(value)) {
            name = ejsGetString(value);
        }
    }

    if (name) {
        worker->name = mprStrdup(worker, name);
    } else {
        worker->name = mprAsprintf(worker, -1, "worker-%d", mprGetListCount(ejs->workers));
    }

    /*
     *  Create a new interpreter and an "inside" worker object and pair it with the current "outside" worker.
     */
    wejs = ejsCreate(ejs->service, NULL, search, 0);
    if (wejs == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    worker->pair = self = ejsCreateWorker(wejs);
    self->state = EJS_WORKER_BEGIN;
    self->ejs = wejs;
    self->inside = 1;
    self->pair = worker;
    self->name = mprStrcat(self, -1, "inside-", worker->name, NULL);

    ejsSetProperty(ejs,  (EjsVar*) worker, ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(ejs, self->name));
    ejsSetProperty(wejs, (EjsVar*) self,   ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(wejs, self->name));
    ejsSetProperty(wejs, wejs->global, ES_ejs_sys_worker_self, (EjsVar*) self);

    /*
     *  Workers have a dedicated namespace to enable viewing of the worker globals (self, onmessage, postMessage...)
     */
    ejsDefineReservedNamespace(wejs, wejs->globalBlock, 0, EJS_WORKER_NAMESPACE);

    /*
     *  Make the inside worker permanent so we don't need to worry about whether worker->pair->ejs is valid
     */
    self->obj.var.permanent = 1;
    
    if (argc > 0 && ejsIsPath(argv[0])) {
        addWorker(ejs, worker);
        worker->scriptFile = mprStrdup(worker, ((EjsPath*) argv[0])->path);
        worker->state = EJS_WORKER_STARTED;
        worker->obj.var.permanent = 1;
        if (mprStartWorker(ejs, (MprWorkerProc) workerMain, (void*) worker, MPR_NORMAL_PRIORITY) < 0) {
            ejsThrowStateError(ejs, "Can't start worker");
            worker->obj.var.permanent = 0;
            return 0;
        }
    }
    return (EjsVar*) worker;
}
Esempio n. 23
0
static EjsWorker *initWorker(Ejs *ejs, EjsWorker *worker, Ejs *baseVM, cchar *name, EjsArray *search, cchar *scriptFile)
{
    Ejs             *wejs;
    EjsWorker       *self;
    EjsName         sname;
    static int      workerSeqno = 0;

    ejsBlockGC(ejs);
    if (worker == 0) {
        worker = ejsCreateWorker(ejs);
    }
    worker->ejs = ejs;
    worker->state = EJS_WORKER_BEGIN;

    if (name) {
        worker->name = sclone(name);
    } else {
        lock(ejs);
        worker->name = sfmt("worker-%d", workerSeqno++);
        unlock(ejs);
    }
    /*
        Create a new interpreter and an "inside" worker object and pair it with the current "outside" worker.
        The worker interpreter gets a new dispatcher
     */
    if (baseVM) {
        if ((wejs = ejsCloneVM(baseVM)) == 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    } else {
        if ((wejs = ejsCreateVM(0, 0, ejs->flags)) == 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
        if (ejsLoadModules(wejs, 0, 0) < 0) {
            return 0;
        }
    }
    worker->pair = self = ejsCreateWorker(wejs);
    self->state = EJS_WORKER_BEGIN;
    self->ejs = wejs;
    self->inside = 1;
    self->pair = worker;
    self->name = sjoin("inside-", worker->name, NULL);
#if MOB
    mprEnableDispatcher(wejs->dispatcher);
#endif
    if (search) {
        ejsSetSearchPath(ejs, (EjsArray*) search);
    }

    //  TODO - these should be don't delete
    ejsSetProperty(ejs, worker, ES_Worker_name, ejsCreateStringFromAsc(ejs, self->name));
    ejsSetProperty(wejs, self,  ES_Worker_name, ejsCreateStringFromAsc(wejs, self->name));

    sname = ejsName(wejs, EJS_WORKER_NAMESPACE, "self");
    ejsSetPropertyByName(wejs, wejs->global, sname, self);

    /*
        Workers have a dedicated namespace to enable viewing of the worker globals (self, onmessage, postMessage...)
     */
    ejsDefineReservedNamespace(wejs, wejs->global, NULL, EJS_WORKER_NAMESPACE);
    
    addWorker(ejs, worker);

    if (scriptFile) {
        worker->scriptFile = sclone(scriptFile);
        worker->state = EJS_WORKER_STARTED;
        if (mprCreateEvent(wejs->dispatcher, "workerMain", 0, (MprEventProc) workerMain, self, 0) < 0) {
            mprRemoveItem(ejs->workers, worker);
            ejsThrowStateError(ejs, "Cannot create worker event");
            return 0;
        }
    }
    return worker;
}