Example #1
0
/*
    Create an initialized regular expression object. The pattern should include
    the slash delimiters. For example: /abc/ or /abc/g
 */
EjsRegExp *ejsCreateRegExp(Ejs *ejs, EjsString *pattern)
{
    EjsRegExp   *rp;
    cchar       *errMsg;
    MprChar     *flags;
    int         column, errCode;

    if (pattern->length == 0 || pattern->value[0] != '/') {
        ejsThrowArgError(ejs, "Bad regular expression pattern. Must start with '/'");
        return 0;
    }
    rp = ejsCreateObj(ejs, ESV(RegExp), 0);
    if (rp != 0) {
        /*
            Strip off flags for passing to pcre_compile2
         */
        rp->pattern = sclone(&pattern->value[1]);
        if ((flags = wrchr(rp->pattern, '/')) != 0) {
            rp->options = parseFlags(rp, &flags[1]);
            *flags = 0;
        }
        //  TODO - UNICODE is pattern meant to be 
        rp->compiled = pcre_compile2(rp->pattern, rp->options, &errCode, &errMsg, &column, NULL);
        if (rp->compiled == NULL) {
            ejsThrowArgError(ejs, "Can't compile regular expression '%s'. Error %s at column %d", rp->pattern, errMsg, column);
            return 0;
        }
    }
    return rp;
}
Example #2
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);
}
Example #3
0
static void setHttpPipeline(Ejs *ejs, EjsHttpServer *sp) 
{
    EjsString       *vs;
    HttpHost        *host;
    HttpRoute       *route;
    Http            *http;
    HttpStage       *stage;
    cchar           *name;
    int             i;

    assure(sp->endpoint);
    http = sp->endpoint->http;
    host = mprGetFirstItem(sp->endpoint->hosts);
    route = mprGetFirstItem(host->routes);

    if (sp->outgoingStages) {
        httpClearRouteStages(route, HTTP_STAGE_TX);
        for (i = 0; i < sp->outgoingStages->length; i++) {
            vs = ejsGetProperty(ejs, sp->outgoingStages, i);
            if (vs && ejsIs(ejs, vs, String)) {
                name = vs->value;
                if (httpLookupStage(http, name) == 0) {
                    ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", name);
                    return;
                }
                httpAddRouteFilter(route, name, NULL, HTTP_STAGE_TX);
            }
        }
    }
    if (sp->incomingStages) {
        httpClearRouteStages(route, HTTP_STAGE_RX);
        for (i = 0; i < sp->incomingStages->length; i++) {
            vs = ejsGetProperty(ejs, sp->incomingStages, i);
            if (vs && ejsIs(ejs, vs, String)) {
                name = vs->value;
                if (httpLookupStage(http, name) == 0) {
                    ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", name);
                    return;
                }
                httpAddRouteFilter(route, name, NULL, HTTP_STAGE_RX);
            }
        }
    }
    if (sp->connector) {
        if ((stage = httpLookupStage(http, sp->connector)) == 0) {
            ejsThrowArgError(ejs, "Cannot find pipeline stage name %s", sp->connector);
            return;
        }
        route->connector = stage;
    }
}
Example #4
0
/*
    Parse a regular expression string. The string should include the slash delimiters and may contain appended flags. 
    For example: /abc/ or /abc/g
 */
PUBLIC EjsRegExp *ejsParseRegExp(Ejs *ejs, EjsString *pattern)
{
    EjsRegExp   *rp;
    cchar       *errMsg;
    char        *cp, *dp;
    wchar       *flags;
    int         column, errCode;

    if (pattern->length == 0 || pattern->value[0] != '/') {
        ejsThrowArgError(ejs, "Bad regular expression pattern. Must start with '/'");
        return 0;
    }
    if ((rp = ejsCreateObj(ejs, ESV(RegExp), 0)) == 0) {
        return 0;
    }
    /*
        Strip off flags for passing to pcre_compile2
     */
    if (pattern->value[0] == '/') {
        rp->pattern = sclone(&pattern->value[1]);
        if ((flags = wrchr(rp->pattern, '/')) != 0) {
            if (flags == rp->pattern) {
                ejsThrowArgError(ejs, "Bad regular expression pattern. Must end with '/'");
                return 0;
            }
            rp->options = parseFlags(rp, &flags[1]);
            *flags = 0;
        }
        /*
            NOTE: we don't expect backquotes to be quoted. That only happens when interpreting literal js code and JSON
         */
        for (dp = cp = rp->pattern; *cp; ) {
            if (*cp == '\\' && cp[1] == '/') {
                cp++;
            }
            *dp++ = *cp++;
        }
        *dp++ = '\0';

    } else {
        rp->pattern = sclone(&pattern->value[1]);
    }
    rp->compiled = pcre_compile2(rp->pattern, rp->options, &errCode, &errMsg, &column, NULL);
    if (rp->compiled == NULL) {
        ejsThrowArgError(ejs, "Cannot compile regular expression '%s'. Error %s at column %d", rp->pattern, errMsg, column);
        return 0;
    }
    return rp;
}
Example #5
0
/*
    Set the length. TODO - what does this do?
    public override function set length(value: int): void
 */
static EjsObj *setLength(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    int         length;

    assert(ejsIsXML(ejs, xml));

    if (argc != 1) {
        ejsThrowArgError(ejs, "usage: obj.length = value");
        return 0;
    }
    length = ejsVarToInteger(ejs, argv[0]);

    if (length < ap->length) {
        for (i = length; i < ap->length; i++) {
            if (ejsSetProperty(ejs, ap, i, ESV(undefined)) < 0) {
                //  TODO - DIAG
                return 0;
            }
        }

    } else if (length > ap->length) {
        if (ejsSetProperty(ejs, ap, length - 1, ESV(undefined)) < 0) {
            //  TODO - DIAG
            return 0;
        }
    }

    ap->length = length;
    return 0;
}
Example #6
0
/*  
    Constructor
    function File(path: Object, options: Object = null)
 */
static EjsFile *fileConstructor(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsObj      *pp, *options;
    cchar       *path;

    if (argc < 1 || argc > 2) {
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    }
    pp = argv[0];
    if (ejsIs(ejs, pp, Path)) {
        path = ((EjsPath*) pp)->value;
    } else if (ejsIs(ejs, pp, String)) {
        path = ejsToMulti(ejs, pp);
    } else {
        ejsThrowIOError(ejs, "Bad path");
        return 0;
    }
    fp->path = mprNormalizePath(path);
    if (argc == 2) {
        options = (argc >= 2) ? argv[1] : 0;
        openFile(ejs, fp, 1, &options);
    }
    return fp;
}
Example #7
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;
}
Example #8
0
static EjsObj *xmlListConstructor(Ejs *ejs, EjsObj *thisObj, int argc, EjsObj **argv)
{
#if FUTURE
    EjsObj      *vp;
    cchar       *str;

    if (argc == 1) {
        vp = argv[0];

        if (ejsIsObject(vp)) {
            /* Convert DOM to XML. Not implemented */;

        } else if (ejsIs(ejs, vp, String)) {
            str = ((EjsString*) vp)->value;
            if (str == 0) {
                return 0;
            }
            if (*str == '<') {
                /* XML Literal */
                return loadXmlString(ejs, (EjsXML*) thisObj, str);

            } else {
                /* Load from file */
                return load(ejs, (EjsXML*) thisObj, argc, argv);
            }
        } else {
            ejsThrowArgError(ejs, "Bad type passed to XML constructor");
            return 0;
        }
    }
#endif
    return (EjsObj*) thisObj;
}
Example #9
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;
}
Example #10
0
/*  
    function WebSocket(uri: Uri, protocols = null, options)

    options = {
        certificate: Path,
        verify: Boolean,
    }
 */
static EjsWebSocket *wsConstructor(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    EjsAny      *certificate;
    bool        verify;

    assert(ejsIsPot(ejs, ws));

    ejsLoadHttpService(ejs);
    ws->ejs = ejs;
    verify = 0;

    ws->uri = httpUriToString(((EjsUri*) argv[0])->uri, 0);
    if (argc >= 2) {
        if (ejsIs(ejs, argv[1], Array)) {
            ws->protocols = sclone((ejsToString(ejs, argv[1]))->value);
        } else if (ejsIs(ejs, argv[1], String)) {
            ws->protocols = sclone(((EjsString*) argv[1])->value);
        } else {
            ws->protocols = sclone("chat");
        }
    } else {
        ws->protocols = sclone("chat");
    }
    if (*ws->protocols == '\0') {
        ejsThrowArgError(ejs, "Bad protocol");
        return 0;
    }
    if (argc >= 3) {
        ws->frames = ejsGetPropertyByName(ejs, argv[2], EN("frames")) == ESV(true);
        verify = ejsGetPropertyByName(ejs, argv[2], EN("verify")) == ESV(true);
        if ((certificate = ejsGetPropertyByName(ejs, argv[2], EN("certificate"))) != 0) {
            ws->certFile = ejsToMulti(ejs, argv[0]);
        }
    }
    if ((ws->conn = httpCreateConn(MPR->httpService, NULL, ejs->dispatcher)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    httpSetAsync(ws->conn, 1);
    httpPrepClientConn(ws->conn, 0);
    httpSetConnNotifier(ws->conn, webSocketNotify);
    httpSetWebSocketProtocols(ws->conn, ws->protocols);
    httpSetConnContext(ws->conn, ws);
    if (sstarts(ws->uri, "wss")) {
        ws->ssl = mprCreateSsl(0);
        mprVerifySslIssuer(ws->ssl, verify);
        mprVerifySslPeer(ws->ssl, verify);
#if FUTURE
        if (!hp->caFile) {
            //MOB - Some define for this.
            hp->caFile = mprJoinPath(mprGetAppDir(), "http-ca.crt");
        }
        mprSetSslCaFile(hp->ssl, hp->caFile);
        mprSetSslCaFile(hp->ssl, mprJoinPath(mprGetAppDir(), "http-ca.crt"));
#endif
    }
    startWebSocketRequest(ejs, ws);
    return ws;
}
Example #11
0
static void setupTrace(Ejs *ejs, HttpTrace *trace, int dir, EjsObj *options)
{
    EjsArray    *extensions;
    EjsObj      *ext;
    HttpTrace   *tp;
    int         i, level, *levels;

    tp = &trace[dir];
    levels = tp->levels;
    if ((level = getNumOption(ejs, options, "all")) >= 0) {
        for (i = 0; i < HTTP_TRACE_MAX_ITEM; i++) {
            levels[i] = level;
        }
    } else {
        levels[HTTP_TRACE_CONN] = getNumOption(ejs, options, "conn");
        levels[HTTP_TRACE_FIRST] = getNumOption(ejs, options, "first");
        levels[HTTP_TRACE_HEADER] = getNumOption(ejs, options, "headers");
        levels[HTTP_TRACE_BODY] = getNumOption(ejs, options, "body");
    }
    tp->size = getNumOption(ejs, options, "size");
    if ((extensions = (EjsArray*) ejsGetPropertyByName(ejs, options, EN("include"))) != 0) {
        if (!ejsIs(ejs, extensions, Array)) {
            ejsThrowArgError(ejs, "include is not an array");
            return;
        }
        tp->include = mprCreateHash(0, 0);
        for (i = 0; i < extensions->length; i++) {
            if ((ext = ejsGetProperty(ejs, extensions, i)) != 0) {
                mprAddKey(tp->include, ejsToMulti(ejs, ejsToString(ejs, ext)), "");
            }
        }
    }
    if ((extensions = (EjsArray*) ejsGetPropertyByName(ejs, options, EN("exclude"))) != 0) {
        if (!ejsIs(ejs, extensions, Array)) {
            ejsThrowArgError(ejs, "exclude is not an array");
            return;
        }
        tp->exclude = mprCreateHash(0, 0);
        for (i = 0; i < extensions->length; i++) {
            if ((ext = ejsGetProperty(ejs, extensions, i)) != 0) {
                mprAddKey(tp->exclude, ejsToMulti(ejs, ejsToString(ejs, ext)), MPR->emptyString);
            }
        }
    }
}
Example #12
0
/*  
    Constructor
    function open(options: Object = null): File
    NOTE: options can be an options hash or as mode string
 */
static EjsObj *openFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsObj  *options;
    cchar   *mode;
    int     perms, omode;

    if (argc < 0 || argc > 1) {
        ejsThrowArgError(ejs, "Bad args");
        return 0;
    }
    options = argv[0];
    if (argc == 0 || !ejsIsDefined(ejs, options)) {
        omode = O_RDONLY | O_BINARY;
        perms = EJS_FILE_PERMS;
        fp->mode = EJS_FILE_READ;
        mode = "r";
    } else {
        if (ejsIs(ejs, options, String)) {
            mode = ejsToMulti(ejs, options);
            perms = EJS_FILE_PERMS;
        } else {
            perms = ejsGetNumOption(ejs, options, "permissions", EJS_FILE_PERMS, 1);
            mode = getStrOption(ejs, options, "mode", "r", 1);
            if (ejs->exception) {
                return 0;
            }
        }
        omode = mapMode(mode);
        if (!(omode & O_WRONLY)) {
            fp->mode |= EJS_FILE_READ;
        }
        if (omode & (O_WRONLY | O_RDWR)) {
            fp->mode |= EJS_FILE_WRITE;
        }
    }
    fp->modeString = sclone(mode);
    fp->perms = perms;

    if (fp->file) {
        mprCloseFile(fp->file);
    }
    fp->file = mprOpenFile(fp->path, omode, perms);
    if (fp->file == 0) {
        ejsThrowIOError(ejs, "Cannot open %s", fp->path);
        return 0;
    }
    if (options) {
        ejsSetPathAttributes(ejs, fp->path, options);
    }
#if ME_CC_MMU && FUTURE
    mprGetPathInfo(&fp->info);
    fp->mapped = mapFile(fp, fp->info.size, MPR_MAP_READ | MPR_MAP_WRITE);
#endif
    fp->mode |= EJS_FILE_OPEN;
    return (EjsObj*) fp;
}
Example #13
0
static cchar *getStrOption(Ejs *ejs, EjsObj *options, cchar *field, cchar *defaultValue, bool optional)
{
    EjsObj      *vp;
    EjsString   *str;

    vp = ejsGetPropertyByName(ejs, options, EN(field));
    if (vp == 0) {
        if (optional) {
            return sclone(defaultValue);
        }
        ejsThrowArgError(ejs, "Required option %s is missing", field);
        return 0;
    }
    str = ejsToString(ejs, vp);
    if (!ejsIs(ejs, str, String)) {
        ejsThrowArgError(ejs, "Bad option type for field \"%s\"", field);
        return 0;
    }
    return ejsToMulti(ejs, str);
}
Example #14
0
//  TODO - rename
static int ejsGetNumOption(Ejs *ejs, EjsObj *options, cchar *field, int defaultValue, bool optional)
{
    EjsObj      *vp;
    EjsNumber   *num;

    vp = ejsGetPropertyByName(ejs, options, EN(field));
    if (vp == 0) {
        if (optional) {
            return defaultValue;
        }
        ejsThrowArgError(ejs, "Required option \"%s\" is missing", field);
        return 0;
    }
    num = ejsToNumber(ejs, vp);
    if (!ejsIs(ejs, num, Number)) {
        ejsThrowArgError(ejs, "Bad option type for field \"%s\"", field);
        return 0;
    }
    return (int) num->value;
}
Example #15
0
/*
 *  native static function callback(fn: Function): Void
 */
static EjsVar *setRedlineCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
{
    mprAssert(argc == 1 && ejsIsFunction(argv[0]));

    if (!ejsIsFunction(argv[0])) {
        ejsThrowArgError(ejs, "Callaback is not a function");
        return 0;
    }
    ejs->memoryCallback = (EjsFunction*) argv[0];
    return 0;
}
Example #16
0
/*
    native function XML(value: Object = null)
 */
static EjsObj *xmlConstructor(Ejs *ejs, EjsXML *thisObj, int argc, EjsObj **argv)
{
    EjsObj      *arg, *vp;
    wchar       *str;

    //  TODO - should be also able to handle a File object

    if (thisObj == 0) {
        /*
            Called as a function - cast the arg
         */
        if (argc > 0) {
            if ((arg = ejsCast(ejs, argv[0], String)) == 0) {
                return 0;
            }
        }
        thisObj = ejsCreateXML(ejs, 0, N(NULL, NULL), NULL, NULL);
    }
    if (argc == 0) {
        return (EjsObj*) thisObj;
    }

    arg = argv[0];
    assert(arg);

    if (!ejsIsDefined(ejs, arg)) {
        return (EjsObj*) thisObj;
    }
    arg = ejsCast(ejs, argv[0], String);
    if (arg && ejsIs(ejs, arg, String)) {
        str = ((EjsString*) arg)->value;
        if (str == 0) {
            return 0;
        }
        while (isspace((uchar) *str)) str++;
        if (*str == '<') {
            /* XML Literal */
            ejsLoadXMLString(ejs, thisObj, (EjsString*) arg);

        } else {
            /* Load from file */
            loadXml(ejs, thisObj, argc, argv);
        }
    } else if (arg && ejsIsXML(ejs, arg)) {
        if ((vp = xmlToString(ejs, argv[0], 0, NULL)) != 0) {
            ejsLoadXMLString(ejs, thisObj, (EjsString*) vp);
        }

    } else {
        ejsThrowArgError(ejs, "Bad type passed to XML constructor");
        return 0;
    }
    return (EjsObj*) thisObj;
}
Example #17
0
/*
    Constructor to create an iterator using a scripted next().

    public function Iterator(obj, f, deep, ...namespaces)
 */
static EjsObj *iteratorConstructor(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv)
{
    if (argc != 2 || !ejsIsFunction(ejs, argv[1])) {
        ejsThrowArgError(ejs, "usage: Iterator(obj, function)");
        return 0;
    }
    ip->target = argv[0];
    ip->next = (EjsFunction*) argv[1];
    mprAssert(ip->nativeNext == 0);

    return ip;
}
Example #18
0
/*  
    function close(status: Number = 1000, reason: String? = ""): Void
 */
static EjsObj *ws_close(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv)
{
    HttpConn    *conn;
    char        *reason;
    int         status;

    conn = ws->conn;
    if (conn) {
        status = argc == 0 ? WS_STATUS_OK : ejsGetInt(ejs, argv[0]);
        if (status <= 999 || status >= WS_STATUS_MAX || status == WS_STATUS_NO_STATUS || status == WS_STATUS_COMMS_ERROR) {
            ejsThrowArgError(ejs, "Bad status");
            return 0;
        }
        reason = (argc >= 1) ? ejsToMulti(ejs, argv[1]): 0; 
        if (slen(reason) >= 124) {
            ejsThrowArgError(ejs, "Close reason is too long. Must be less than 124 bytes");
            return 0;
        }
        httpSendClose(conn, status, reason);
    }
    return 0;
}
Example #19
0
/*
    native static function set newQuota(quota: Number): Void
 */
static EjsObj *gc_set_newQuota(Ejs *ejs, EjsObj *thisObj, int argc, EjsObj **argv)
{
    int     quota;

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

    if (quota < MPR_NEW_QUOTA && quota != 0) {
        ejsThrowArgError(ejs, "Bad work quota");
        return 0;
    }
    mprGetMpr()->heap->newQuota = quota;
    return 0;
}
Example #20
0
/*  
    function set method(value: String): Void
 */
static EjsObj *http_set_method(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    cchar    *method;

    method = ejsToMulti(ejs, argv[0]);
    if (strcmp(method, "DELETE") != 0 && strcmp(method, "GET") != 0 &&  strcmp(method, "HEAD") != 0 &&
            strcmp(method, "OPTIONS") != 0 && strcmp(method, "POST") != 0 && strcmp(method, "PUT") != 0 &&
            strcmp(method, "TRACE") != 0) {
        ejsThrowArgError(ejs, "Unknown HTTP method");
        return 0;
    }
    hp->method = ejsToMulti(ejs, argv[0]);
    return 0;
}
Example #21
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;
}
Example #22
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);
}
Example #23
0
/*
    Create an initialized regular expression object. The pattern should NOT include the slash delimiters. 
 */
PUBLIC EjsRegExp *ejsCreateRegExp(Ejs *ejs, cchar *pattern, cchar *flags)
{
    EjsRegExp   *rp;
    cchar       *errMsg;
    int         column, errCode;

    if ((rp = ejsCreateObj(ejs, ESV(RegExp), 0)) == 0) {
        return 0;
    }
    rp->pattern = sclone(pattern);
    rp->options = parseFlags(rp, (wchar*) flags);
    rp->compiled = pcre_compile2(rp->pattern, rp->options, &errCode, &errMsg, &column, NULL);
    if (rp->compiled == NULL) {
        ejsThrowArgError(ejs, "Cannot compile regular expression '%s'. Error %s at column %d", rp->pattern, errMsg, column);
        return 0;
    }
    return rp;
}
Example #24
0
static EjsRegExp *regex_Constructor(Ejs *ejs, EjsRegExp *rp, int argc, EjsObj **argv)
{
    cchar       *errMsg;
    int         column, errCode;

    rp->pattern = wclone(ejsToString(ejs, argv[0])->value);
    rp->options = PCRE_JAVASCRIPT_COMPAT;

    if (argc == 2) {
        rp->options |= parseFlags(rp, ejsToString(ejs, argv[1])->value);
    }
    if (rp->compiled) {
        free(rp->compiled);
    }
    if ((rp->compiled = pcre_compile2(rp->pattern, rp->options, &errCode, &errMsg, &column, NULL)) == 0) {
        ejsThrowArgError(ejs, "Cannot compile regular expression '%s'. Error %s at column %d", rp->pattern, errMsg, column);
        return 0;
    }
    return rp;
}
Example #25
0
/**
    Sort the array using the supplied compare function

    function sort(compare: Function = null, direction: Number = 1): Array

    Where compare is defined as:
        function compare(a,b): Number
 */
PUBLIC EjsArray *ejsSortArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsFunction     *compare;
    int             direction;

    if (ap->length <= 1) {
        return ap;
    }
    compare = (EjsFunction*) ((argc >= 1) ? argv[0]: NULL);
    if (compare == ESV(null)) {
        compare = 0;
    }
    if (compare && !ejsIsFunction(ejs, compare)) {
        ejsThrowArgError(ejs, "Compare argument is not a function");
        return 0;
    }
    direction = (argc >= 2) ? ejsGetInt(ejs, argv[1]) : 1;
    quickSort(ejs, ap, compare, direction, 0, ap->length - 1);
    return ap;
}
Example #26
0
static EjsObj *saveXml(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    MprBuf      *buf;
    MprFile     *file;
    char        *filename;
    ssize       bytes, len;

    if (argc != 1 || !ejsIs(ejs, argv[0], String)) {
        ejsThrowArgError(ejs, "Bad args. Usage: save(filename);");
        return 0;
    }
    filename = awtom(((EjsString*) argv[0])->value, NULL);

    /*
        Create a buffer to hold the output. All in memory.
     */
    buf = mprCreateBuf(ME_MAX_BUFFER, -1);
    mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>\n");

    if (ejsXMLToBuf(ejs, buf, xml, 0) < 0) {
        return 0;
    }
    file = mprOpenFile(filename,  O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
    if (file == 0) {
        ejsThrowIOError(ejs, "Cannot open: %s, %d", filename, mprGetOsError(ejs));
        return 0;
    }
    len = mprGetBufLength(buf);
    bytes = mprWriteFile(file, buf->start, len);
    if (bytes != len) {
        ejsThrowIOError(ejs, "Cannot write to: %s", filename);
        mprCloseFile(file);
        return 0;
    }
    mprWriteFile(file, "\n", 1);
    mprCloseFile(file);
    return 0;
}
Example #27
0
/*  
    function setHeader(key: String, value: String, overwrite: Boolean = true): Void
 */
static EjsObj *http_setHeader(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    HttpConn    *conn;
    cchar       *key, *value;
    bool        overwrite;

    assert(argc >= 2);

    conn = hp->conn;
    if (conn->state >= HTTP_STATE_CONNECTED) {
        ejsThrowArgError(ejs, "Cannot update request headers once the request has started");
        return 0;
    }
    key = ejsToMulti(ejs, argv[0]);
    value = ejsToMulti(ejs, argv[1]);
    overwrite = (argc == 3) ? ejsGetBoolean(ejs, argv[2]) : 1;
    if (overwrite) {
        httpSetHeaderString(hp->conn, key, value);
    } else {
        httpAppendHeaderString(hp->conn, key, value);
    }
    return 0;
}
Example #28
0
/*
 *  Insert, remove or replace array elements. Return the removed elements.
 *
 *  function splice(start: Number, deleteCount: Number, ...values): Array
 *
 */
static EjsVar *spliceArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *result, *values;
    EjsVar      **data, **dest, **items;
    int         start, deleteCount, i, delta, endInsert, oldLen;

    mprAssert(1 <= argc && argc <= 3);
    
    start = ejsGetInt(argv[0]);
    deleteCount = ejsGetInt(argv[1]);
    values = (EjsArray*) argv[2];

    if (ap->length == 0) {
        if (deleteCount <= 0) {
            return (EjsVar*) ap;
        }
        ejsThrowArgError(ejs, "Array is empty");
        return 0;
    }
    if (start < 0) {
        start += ap->length;
    }
    if (start < 0) {
        start = 0;
    }
    if (start >= ap->length) {
        start = ap->length - 1;
    }

    if (deleteCount < 0) {
        deleteCount = ap->length - start + 1;
    }
    if (deleteCount > ap->length) {
        deleteCount = ap->length;
    }

    result = ejsCreateArray(ejs, deleteCount);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    data = ap->data;
    dest = result->data;
    items = values->data;

    /*
     *  Copy removed items to the result
     */
    for (i = 0; i < deleteCount; i++) {
        dest[i] = data[i + start];
    }

    oldLen = ap->length;
    delta = values->length - deleteCount;
    
    if (delta > 0) {
        /*
         *  Make room for items to insert
         */
        if (growArray(ejs, ap, ap->length + delta) < 0) {
            return 0;
        }
        data = ap->data;
        endInsert = start + delta;
        for (i = ap->length - 1; i >= endInsert; i--) {
            data[i] = data[i - delta];
        }
        
    } else {
        ap->length += delta;
    }

    /*
     *  Copy in new values
     */
    for (i = 0; i < values->length; i++) {
        data[start + i] = items[i];
    }

    /*
     *  Remove holes
     */
    if (delta < 0) {
        for (i = start + values->length; i < oldLen; i++) {
            data[i] = data[i - delta];
        }
    }
    return (EjsVar*) result;
}
Example #29
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;
}
Example #30
0
/*
    function listen(endpoint): Void

    An endpoint can be either a "port" or "ip:port", or null. If hosted, this call does little -- just add to the
    ejs->httpServers list.
 */
static EjsVoid *hs_listen(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv)
{
    HttpEndpoint    *endpoint;
    HttpHost        *host;
    HttpRoute       *route;
    EjsString       *address;
    EjsObj          *loc;
    EjsPath         *documents;

    if (!sp->hosted) {
        loc = (argc >= 1) ? argv[0] : ESV(null);
        if (loc != ESV(null)) {
            address = ejsToString(ejs, loc);
            //  TODO should permit https://IP:PORT
            mprParseSocketAddress(address->value, &sp->ip, &sp->port, NULL, 0);
        } else {
            address = 0;
        }
        if (address == 0) {
            ejsThrowArgError(ejs, "Missing listen endpoint");
            return 0;
        }
        if (sp->endpoint) {
            httpDestroyEndpoint(sp->endpoint);
            sp->endpoint = 0;
        }
        /*
            The endpoint uses the ejsDispatcher. This is VERY important. All connections will inherit this also.
            This serializes all activity on one dispatcher.
         */
        if ((endpoint = httpCreateEndpoint(sp->ip, sp->port, ejs->dispatcher)) == 0) {
            ejsThrowIOError(ejs, "Cannot create Http endpoint object");
            return 0;
        }
        sp->endpoint = endpoint;
        host = httpCreateHost(NULL);
        httpSetHostName(host, sfmt("%s:%d", sp->ip, sp->port));
        route = httpCreateConfiguredRoute(host, 1);

        httpAddRouteMethods(route, "DELETE, HEAD, OPTIONS, PUT");
        httpAddRouteHandler(route, "ejsHandler", "");
        httpSetRouteTarget(route, "run", 0);
        httpFinalizeRoute(route);

        httpSetHostDefaultRoute(host, route);
        httpAddHostToEndpoint(endpoint, host);

        if (sp->limits) {
            ejsSetHttpLimits(ejs, endpoint->limits, sp->limits, 1);
        }
        if (sp->incomingStages || sp->outgoingStages || sp->connector) {
            setHttpPipeline(ejs, sp);
        }
        if (sp->ssl) {
            httpSecureEndpoint(endpoint, sp->ssl);
        }
        if (sp->name) {
            httpSetHostName(host, sp->name);
        }
        httpSetSoftware(EJS_HTTPSERVER_NAME);
        httpSetEndpointAsync(endpoint, sp->async);
        httpSetEndpointContext(endpoint, sp);
        httpSetEndpointNotifier(endpoint, stateChangeNotifier);

        /*
            This is only required when http is using non-ejs handlers and/or filters
         */
        documents = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_documents);
        if (ejsIs(ejs, documents, Path)) {
            httpSetRouteDocuments(route, documents->value);
        }
#if KEEP
        //  TODO -- what to do with home?
        //  TODO - if removed, then the "home" property should be removed?
        home = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_home);
        if (ejsIs(ejs, home, Path)) {
            httpSetRoutDir(host, home->value);
        }
#endif
        if (httpStartEndpoint(endpoint) < 0) {
            httpDestroyEndpoint(sp->endpoint);
            sp->endpoint = 0;
            ejsThrowIOError(ejs, "Cannot listen on %s", address->value);
        }
    }
    if (ejs->httpServers == 0) {
        ejs->httpServers = mprCreateList(-1, MPR_LIST_STATIC_VALUES);
    }
    /* Remove to make sure old listening() registrations are removed */
    mprRemoveItem(ejs->httpServers, sp);
    mprAddItem(ejs->httpServers, sp);
    return 0;
}