Exemple #1
0
PUBLIC void httpCreateRxPipeline(HttpConn *conn, HttpRoute *route)
{
    HttpTx      *tx;
    HttpRx      *rx;
    HttpQueue   *q;
    HttpStage   *stage, *filter;
    int         next;

    assert(conn);
    assert(route);

    rx = conn->rx;
    tx = conn->tx;
    rx->inputPipeline = mprCreateList(-1, MPR_LIST_STABLE);
    if (route) {
        for (next = 0; (filter = mprGetNextItem(route->inputStages, &next)) != 0; ) {
            if (matchFilter(conn, filter, route, HTTP_STAGE_RX) == HTTP_ROUTE_OK) {
                mprAddItem(rx->inputPipeline, filter);
            }
        }
    }
    mprAddItem(rx->inputPipeline, tx->handler ? tx->handler : conn->http->clientHandler);
    /*  Create the incoming queue heads and open the queues.  */
    q = tx->queue[HTTP_QUEUE_RX];
    for (next = 0; (stage = mprGetNextItem(rx->inputPipeline, &next)) != 0; ) {
        q = httpCreateQueue(conn, stage, HTTP_QUEUE_RX, q);
    }
    if (httpClientConn(conn)) {
        pairQueues(conn);
        openQueues(conn);
    }
}
Exemple #2
0
/*  
    Write upload data. This routine blocks. If you need non-blocking ... cut and paste.
 */
ssize httpWriteUploadData(HttpConn *conn, MprList *fileData, MprList *formData)
{
    char    *path, *pair, *key, *value, *name;
    ssize   rc;
    int     next;

    rc = 0;
    if (formData) {
        for (rc = next = 0; rc >= 0 && (pair = mprGetNextItem(formData, &next)) != 0; ) {
            key = stok(sclone(pair), "=", &value);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"%s\";\r\n", conn->boundary, key);
            rc += httpWrite(conn->writeq, "Content-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n", value);
        }
    }
    if (fileData) {
        for (rc = next = 0; rc >= 0 && (path = mprGetNextItem(fileData, &next)) != 0; ) {
            name = mprGetPathBase(path);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"file%d\"; filename=\"%s\"\r\n", 
                conn->boundary, next - 1, name);
            rc += httpWrite(conn->writeq, "Content-Type: %s\r\n\r\n", mprLookupMime(MPR->mimeTypes, path));
            rc += blockingFileCopy(conn, path);
            rc += httpWrite(conn->writeq, "\r\n");
        }
    }
    rc += httpWrite(conn->writeq, "%s--\r\n--", conn->boundary);
    httpFinalize(conn);
    return rc;
}
Exemple #3
0
static int setContentLength(MprHttp *http, MprList *fields, MprList *files)
{
    MprPath     info;
    char        *path, *pair;
    int64       len;
    int         next;

    len = 0;
    if (upload) {
        /*  Easier to use chunking than to calculate the full multipart-mime upload content */
        mprSetHttpChunked(http, 1);
        mprEnableHttpUpload(http);
        return 0;
    } else {
        for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) {
            if (mprGetPathInfo(http, path, &info) < 0) {
                mprError(http, "Can't access file %s", path);
                return MPR_ERR_CANT_ACCESS;
            }
            len += info.size;
        }
        if (fields) {
            for (next = 0; (pair = mprGetNextItem(fields, &next)) != 0; ) {
                len += strlen(pair);
            }
            len += mprGetListCount(fields) - 1;
        }
    }
    if (len > (16 * MPR_HTTP_BUFSIZE)) {
        mprSetHttpChunked(http, 1);
    } else {
        mprSetHttpBody(http, NULL, (int) len);
    }
    return 0;
}
Exemple #4
0
static void testListIterate(MprTestGroup *gp)
{
    MprList     *lp;
    int         max, i, item, next;

    max = 50;
    lp = mprCreateList(max, 0);
    tassert(lp != 0);

    for (i = 0; i < max; i++) {
        mprAddItem(lp, (void*) (long) (i + 1));
    }
    i = next = 0;
    item = (int) (long) mprGetNextItem(lp, &next);
    while (item > 0) {
        i++;
        item = (int) (long) mprGetNextItem(lp, &next);
    }
    tassert(i == max);


    /*
        Abbreviated form with no GetFirst
     */
    i = 0;
    next = 0;
    while ((item = (int) (long) mprGetNextItem(lp, &next)) != 0) {
        i++;
    }
    tassert(i == max);
}
Exemple #5
0
static void testOrderedInserts(MprTestGroup *gp)
{
    MprList     *lp;
    int         i, item, next;

    lp = mprCreateList(0, 0);
    tassert(lp != 0);

    /*
        Add items such that the final list is ordered
     */
    mprAddItem(lp, (void*) (long) 4);
    mprAddItem(lp, (void*) (long) 5);
    mprInsertItemAtPos(lp, 0, (void*) 2);
    mprInsertItemAtPos(lp, 0, (void*) 1);
    mprInsertItemAtPos(lp, 2, (void*) 3);
    mprAddItem(lp, (void*) (long) 6);

    i = 1;
    next = 0;
    item = (int) (long) mprGetNextItem(lp, &next);
    while (item > 0) {
        tassert(item == i);
        i++;
        item = (int) (long) mprGetNextItem(lp, &next);
    }
}
Exemple #6
0
static int setContentLength(HttpConn *conn, MprList *files)
{
    MprPath     info;
    MprOff      len;
    char        *path, *pair;
    int         next;

    len = 0;
    if (app->upload) {
        httpEnableUpload(conn);
        return 0;
    }
    for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) {
        if (strcmp(path, "-") != 0) {
            if (mprGetPathInfo(path, &info) < 0) {
                mprError("Can't access file %s", path);
                return MPR_ERR_CANT_ACCESS;
            }
            len += info.size;
        }
    }
    if (app->formData) {
        for (next = 0; (pair = mprGetNextItem(app->formData, &next)) != 0; ) {
            len += slen(pair);
        }
        len += mprGetListLength(app->formData) - 1;
    }
    if (app->bodyData) {
        len += mprGetBufLength(app->bodyData);
    }
    if (len > 0) {
        httpSetContentLength(conn, len);
    }
    return 0;
}
Exemple #7
0
void httpCreateRxPipeline(HttpConn *conn, HttpRoute *route)
{
    HttpTx      *tx;
    HttpRx      *rx;
    HttpQueue   *q;
    HttpStage   *stage, *filter;
    int         next;

    mprAssert(conn);
    mprAssert(route);

    rx = conn->rx;
    tx = conn->tx;
    rx->inputPipeline = mprCreateList(-1, 0);
    if (route) {
        for (next = 0; (filter = mprGetNextItem(route->inputStages, &next)) != 0; ) {
            if (matchFilter(conn, filter, route, HTTP_STAGE_RX) == HTTP_ROUTE_OK) {
                mprAddItem(rx->inputPipeline, filter);
            }
        }
    }
    mprAddItem(rx->inputPipeline, tx->handler);

    /*  Create the incoming queue heads and open the queues.  */
    q = tx->queue[HTTP_QUEUE_RX];
    for (next = 0; (stage = mprGetNextItem(rx->inputPipeline, &next)) != 0; ) {
        q = httpCreateQueue(conn, stage, HTTP_QUEUE_RX, q);
    }
    conn->readq = tx->queue[HTTP_QUEUE_RX]->prevQ;
    if (!conn->endpoint) {
        pairQueues(conn);
        openQueues(conn);
    }
}
Exemple #8
0
static bool appwebIsIdle(MprCtx ctx)
{
    MaHost      *host;
    MaConn      *conn;
    MaHttp      *http;
    MprTime     now;
    int         nextHost, next;
    static MprTime lastTrace = 0;

    now = mprGetTime(ctx);
    http = (MaHttp*) mprGetMpr(ctx)->appwebHttpService;
    for (nextHost = 0; (host = mprGetNextItem(http->defaultServer->hosts, &nextHost)) != 0; ) {
        lock(host);
        for (next = 0; (conn = mprGetNextItem(host->connections, &next)) != 0; ) {
            if (conn->state != MPR_HTTP_STATE_BEGIN) {
                if (lastTrace < now) {
                    mprLog(ctx, 0, "Waiting for request %s to complete", 
                           *conn->request->url ? conn->request->url : conn->request->pathInfo);
                    lastTrace = now;
                }
                unlock(host);
                return 0;
            }
        }
        unlock(host);
    }
    if (!mprServicesAreIdle(ctx)) {
        if (lastTrace < now) {
            mprLog(ctx, 0, "Waiting for MPR services complete");
            lastTrace = now;
        }
        return 0;
    }
    return 1;
}
Exemple #9
0
static int writeBody(MprHttp *http, MprList *fields, MprList *files)
{
    MprFile     *file;
    char        buf[MPR_HTTP_BUFSIZE], *path, *pair;
    int         bytes, next, count, rc, len;

    rc = 0;

    mprSetSocketBlockingMode(http->sock, 1);
    if (upload) {
        if (mprWriteHttpUploadData(http, files, fields) < 0) {
            mprError(http, "Can't write upload data %s", mprGetHttpError(http));
            mprSetSocketBlockingMode(http->sock, 0);
            return MPR_ERR_CANT_WRITE;
        }
    } else {
        if (fields) {
            count = mprGetListCount(fields);
            for (next = 0; !rc && (pair = mprGetNextItem(fields, &next)) != 0; ) {
                len = (int) strlen(pair);
                if (next < count) {
                    len = (int) strlen(pair);
                    if (mprWriteSocket(http->sock, pair, len) != len || mprWriteSocket(http->sock, "&", 1) != 1) {
                        return MPR_ERR_CANT_WRITE;
                    }
                } else {
                    if (mprWriteSocket(http->sock, pair, len) != len) {
                        return MPR_ERR_CANT_WRITE;
                    }
                }
            }
        }
        if (files) {
            mprAssert(mprGetListCount(files) == 1);
            for (rc = next = 0; !rc && (path = mprGetNextItem(files, &next)) != 0; ) {
                file = mprOpen(http, path, O_RDONLY | O_BINARY, 0);
                if (file == 0) {
                    mprError(http, "Can't open \"%s\"", path);
                    return MPR_ERR_CANT_OPEN;
                }
                if (verbose && upload) {
                    mprPrintf(http, "uploading: %s\n", path);
                }
                while ((bytes = mprRead(file, buf, sizeof(buf))) > 0) {
                    if (mprWriteHttp(http, buf, bytes) != bytes) {
                        mprFree(file);
                        return MPR_ERR_CANT_WRITE;
                    }
                }
                mprFree(file);
            }
        }
        if (mprFinalizeHttpWriting(http) < 0) {
            return MPR_ERR_CANT_WRITE;
        }
    }
    mprSetSocketBlockingMode(http->sock, 0);
    return rc;
}
Exemple #10
0
static void runDir(MaQueue *q)
{
    MaConn          *conn;
    MaResponse      *resp;
    MaRequest       *req;
    MprList         *list;
    MprDirEntry     *dp;
    Dir             *dir;
    cchar           *filename;
    uint            nameSize;
    int             next;

    conn = q->conn;
    req = conn->request;
    resp = conn->response;
    dir = q->stage->stageData;

    filename = resp->filename;
    mprAssert(filename);

    maDontCacheResponse(conn);
    maSetHeader(conn, 0, "Last-Modified", req->host->currentDate);
    maPutForService(q, maCreateHeaderPacket(q), 0);

    parseQuery(conn);

    list = mprGetPathFiles(conn, filename, 1);
    if (list == 0) {
        maWrite(q, "<h2>Can't get file list</h2>\r\n");
        outputFooter(q);
        return;
    }

    if (dir->pattern) {
        filterDirList(conn, list);
    }

    sortList(conn, list);

    /*
     *  Get max filename
     */
    nameSize = 0;
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        nameSize = max((int) strlen(dp->name), nameSize);
    }
    nameSize = max(nameSize, 22);

    outputHeader(q, req->url, nameSize);
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        outputLine(q, dp, filename, nameSize);
    }
    outputFooter(q);

    maPutForService(q, maCreateEndPacket(conn), 1);

    mprFree(list);
}
Exemple #11
0
static int process(EjsMod *mp, cchar *output, int argc, char **argv)
{
    Ejs         *ejs;
    EjsModule   *module;
    MprFile     *outfile;
    MprList     *depends;
    int         count, i, next, moduleCount;

    ejs = mp->ejs;

    if (output) {
        outfile = mprOpenFile(output, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0664);
    } else {
        outfile = 0;
    }
    ejs->loaderCallback = (mp->listing) ? emListingLoadCallback : 0;
    mp->firstGlobal = ejsGetLength(ejs, ejs->global);

    /*
        For each module on the command line
     */
    for (i = 0; i < argc && !mp->fatalError; i++) {
        moduleCount = mprGetListLength(ejs->modules);
        ejs->loadData = mp;
        if (!mprPathExists(argv[i], R_OK)) {
            mprError("Can't access module %s", argv[i]);
            return EJS_ERR;
        }
        if ((ejsLoadModule(ejs, ejsCreateStringFromAsc(ejs, argv[i]), -1, -1, EJS_LOADER_NO_INIT)) < 0) {
            ejs->loaderCallback = NULL;
            mprError("Can't load module %s\n%s", argv[i], ejsGetErrorMsg(ejs, 0));
            return EJS_ERR;
        }
        if (mp->genSlots) {
            for (next = moduleCount; (module = mprGetNextItem(ejs->modules, &next)) != 0; ) {
                emCreateSlotFiles(mp, module, outfile);
            }
        }
        if (mp->depends) {
            depends = mprCreateList(-1, 0);
            for (next = moduleCount; (module = mprGetNextItem(ejs->modules, &next)) != 0; ) {
                getDepends(ejs, depends, module);
            }
            count = mprGetListLength(depends);
            for (next = 1; (module = mprGetNextItem(depends, &next)) != 0; ) {
                int version = module->version;
                mprPrintf("%@-%d.%d.%d%s", module->name, EJS_MAJOR(version), EJS_MINOR(version), EJS_PATCH(version),
                          (next >= count) ? "" : " ");
            }
            printf("\n");
        }
    }
    if (mp->html || mp->xml) {
        emCreateDoc(mp);
    }
    mprCloseFile(outfile);
    return 0;
}
Exemple #12
0
/*
    Lookup a property by name. There are 7 kinds of lookups:
         prop, @att, [prop], *, @*, .name, .@name
 */
static EjsObj *getXmlPropertyByName(Ejs *ejs, EjsXML *xml, EjsName qname)
{
    EjsXML      *item, *result, *list;
    int         next, nextList;

    result = 0;

    assert(xml->kind < 5);
    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXml(qname.name)) {
        /*
            Consider xml as a list with only one entry == xml. Then return the 0'th entry
         */
        return (EjsObj*) xml;
    }

    if (qname.name->value[0] == '@') {
        /* @ and @* */
        result = ejsCreateXMLList(ejs, xml, qname);
        if (xml->attributes) {
            for (next = 0; (item = mprGetNextItem(xml->attributes, &next)) != 0; ) {
                assert(qname.name->value[0] == '@');
                if (qname.name->value[1] == '*' || wcmp(item->qname.name->value, &qname.name->value[1]) == 0) {
                    result = ejsAppendToXML(ejs, result, item);
                }
            }
        }

    } else if (qname.name->value[0] == '.') {
        /* Decenders (do ..@ also) */
        result = ejsGetXMLDescendants(ejs, xml, qname);

    } else {
        /* name and * */
        result = ejsCreateXMLList(ejs, xml, qname);
        if (xml->elements) {
            for (next = 0; (item = mprGetNextItem(xml->elements, &next)) != 0; ) {
                if (item->kind == EJS_XML_LIST) {
                    list = item;
                    for (nextList = 0; (item = mprGetNextItem(list->elements, &nextList)) != 0; ) {
                        assert(item->qname.name);
                        if (qname.name->value[0] == '*' || ejsCompareString(ejs, item->qname.name, qname.name) == 0) {
                            result = ejsAppendToXML(ejs, result, item);
                        }
                    }

                } else if (item->qname.name) {
                    assert(item->qname.name);
                    if (qname.name->value[0] == '*' || ejsCompareString(ejs, item->qname.name, qname.name) == 0) {
                        result = ejsAppendToXML(ejs, result, item);
                    }
                }
            }
        }
    }
    return (EjsObj*) result;
}
Exemple #13
0
/*
    Start the request (and complete it)
 */
static void startDir(HttpQueue *q)
{
    HttpConn        *conn;
    HttpTx          *tx;
    HttpRx          *rx;
    MprList         *list;
    MprDirEntry     *dp;
    HttpDir         *dir;
    cchar           *path;
    uint            nameSize;
    int             next;

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    if ((dir = conn->reqData) == 0) {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot get directory listing");
        return;
    }
    assert(tx->filename);

    if (!(rx->flags & (HTTP_GET | HTTP_HEAD))) {
        httpError(conn, HTTP_CODE_BAD_METHOD, "Bad method");
        return;
    }
    httpSetContentType(conn, "text/html");
    httpSetHeaderString(conn, "Cache-Control", "no-cache");
    httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate);
    parseQuery(conn);

    if ((list = mprGetPathFiles(tx->filename, MPR_PATH_RELATIVE)) == 0) {
        httpWrite(q, "<h2>Cannot get file list</h2>\r\n");
        outputFooter(q);
        return;
    }
    if (dir->pattern) {
        filterDirList(conn, list);
    }
    sortList(conn, list);
    /*
        Get max filename size
     */
    nameSize = 0;
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        nameSize = max((int) strlen(dp->name), nameSize);
    }
    nameSize = max(nameSize, 22);

    path = rx->route->prefix ? sjoin(rx->route->prefix, rx->pathInfo, NULL) : rx->pathInfo;
    outputHeader(q, path, nameSize);
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        outputLine(q, dp, tx->filename, nameSize);
    }
    outputFooter(q);
    httpFinalize(conn);
}
Exemple #14
0
static void processDir(HttpQueue *q)
{
    HttpConn        *conn;
    HttpTx          *tx;
    HttpRx          *rx;
    MprList         *list;
    MprDirEntry     *dp;
    Dir             *dir;
    uint            nameSize;
    int             next;

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    dir = conn->data;

    mprLog(5, "processDir");
    mprAssert(tx->filename);

    httpSetHeaderString(conn, "Cache-Control", "no-cache");
    httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate);
    parseQuery(conn);

    list = mprGetPathFiles(tx->filename, 1);
    if (list == 0) {
        httpWrite(q, "<h2>Can't get file list</h2>\r\n");
        outputFooter(q);
        return;
    }
    if (dir->pattern) {
        filterDirList(conn, list);
    }
    sortList(conn, list);

    /*
        Get max filename
     */
    nameSize = 0;
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        nameSize = max((int) strlen(dp->name), nameSize);
    }
    nameSize = max(nameSize, 22);

    outputHeader(q, rx->pathInfo, nameSize);
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        outputLine(q, dp, tx->filename, nameSize);
    }
    outputFooter(q);
    httpFinalize(conn);
}
Exemple #15
0
/*
 *  Stop the server and stop listening on all ports
 */
int maStopServer(MaServer *server)
{
    MaHost      *host;
    MaListen    *listen;
    int         next;

    for (next = 0; (listen = mprGetNextItem(server->listens, &next)) != 0; ) {
        maStopListening(listen);
    }
    for (next = 0; (host = mprGetNextItem(server->hosts, &next)) != 0; ) {
        maStopHost(host);
    }
    return 0;
}
Exemple #16
0
int maStartServer(MaServer *server)
{
    MaHost      *host;
    MaListen    *listen;
    int         next, count, warned;

    /*
     *  Start the hosts
     */
    for (next = 0; (host = mprGetNextItem(server->hosts, &next)) != 0; ) {
        mprLog(server, 1, "Starting host named: \"%s\"", host->name);
        if (maStartHost(host) < 0) {
            return MPR_ERR_CANT_INITIALIZE;
        }
    }

    /*
     *  Listen to all required ipAddr:ports
     */
    warned = 0;
    count = 0;
    for (next = 0; (listen = mprGetNextItem(server->listens, &next)) != 0; ) {
        if (maStartListening(listen) < 0) {
            mprError(server, "Can't listen for HTTP on %s:%d", listen->ipAddr, listen->port);
            warned++;
            break;

        } else {
            count++;
        }
    }

    if (count == 0) {
        if (! warned) {
            mprError(server, "Server is not listening on any addresses");
        }
        return MPR_ERR_CANT_OPEN;
    }

    /*
     *  Now change user and group to the desired identities (user must be last)
     */
    if (maApplyChangedGroup(server->http) < 0 || maApplyChangedUser(server->http) < 0) {
        return MPR_ERR_CANT_COMPLETE;
    }

    return 0;
}
Exemple #17
0
static int deleteXmlListPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname)
{
    EjsXML      *elt;
    int         index, next;

    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXmlList(qname.name)) {
        index = ejsAtoi(ejs, qname.name, 10);

        elt = (EjsXML*) mprGetItem(list->elements, index);
        if (elt) {
            if (elt->parent) {
                if (elt->kind == EJS_XML_ATTRIBUTE) {
                    ejsDeletePropertyByName(ejs, (EjsObj*) elt->parent, elt->qname);
                } else {
                    //  TODO - let q be the property of parent where parent[q] == x[i]
                    mprRemoveItem(elt->parent->elements, elt);
                    elt->parent = 0;
                }
            }
        }
        //  Spec says return true even if index is out of range. We return 0 for true and < 0 for false.
        //  TODO - should ejs throw?
        return 0;
    }

    for (next = 0; (elt = mprGetNextItem(list->elements, &next)) != 0; ) {
        if (elt->kind == EJS_XML_ELEMENT /* && elt->parent */) {
            ejsDeletePropertyByName(ejs, (EjsObj*) elt /* TODO was elt->parent */, qname);
        }
    }
    return 0;
}
Exemple #18
0
void maSecureHost(MaHost *host, struct MprSsl *ssl)
{
    MaListen    *lp;
    cchar       *hostIp;
    char        *ipAddr;
    int         port, next;

    host->secure = 1;

    hostIp = host->ipAddrPort;
    if (mprStrcmpAnyCase(hostIp, "_default_") == 0) {
        hostIp = (char*) "*:*";
    }

    mprParseIp(host, hostIp, &ipAddr, &port, -1);
   
    for (next = 0; (lp = mprGetNextItem(host->server->listens, &next)) != 0; ) {
        if (port > 0 && port != lp->port) {
            continue;
        }
        if (*lp->ipAddr && ipAddr && ipAddr[0] != '*' && strcmp(ipAddr, lp->ipAddr) != 0) {
            continue;
        }
#if BLD_FEATURE_SSL
        if (host->secure) {
            if (host->flags & MA_HOST_NAMED_VHOST) {
                mprError(host, "SSL does not support named virtual hosts");
                return;
            }
            lp->ssl = ssl;
        }
#endif
    }
}
Exemple #19
0
int maInsertAlias(MaHost *host, MaAlias *newAlias)
{
    MaAlias     *alias, *old;
    int         rc, next, index;

    if (mprGetParent(host->aliases) == host->parent) {
        host->aliases = mprDupList(host, host->parent->aliases);
    }

    /*
     *  Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc. But we sort redirects with
     *  status codes first.
     */
    for (next = 0; (alias = mprGetNextItem(host->aliases, &next)) != 0; ) {
        rc = strcmp(newAlias->prefix, alias->prefix);
        if (rc == 0) {
            index = mprLookupItem(host->aliases, alias);
            old = (MaAlias*) mprGetItem(host->aliases, index);
            mprRemoveItem(host->aliases, alias);
            mprInsertItemAtPos(host->aliases, next - 1, newAlias);
            return 0;
            
        } else if (rc > 0) {
            if (newAlias->redirectCode >= alias->redirectCode) {
                mprInsertItemAtPos(host->aliases, next - 1, newAlias);
                return 0;
            }
        }
    }
    mprAddItem(host->aliases, newAlias);
    return 0;
}
Exemple #20
0
int maInsertDir(MaHost *host, MaDir *newDir)
{
    MaDir       *dir;
    int         rc, next;

    mprAssert(newDir);
    mprAssert(newDir->path);
    
    if (mprGetParent(host->dirs) == host->parent) {
        host->dirs = mprDupList(host, host->parent->dirs);
    }

    /*
     *  Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc
     */
    for (next = 0; (dir = mprGetNextItem(host->dirs, &next)) != 0; ) {
        mprAssert(dir->path);
        rc = strcmp(newDir->path, dir->path);
        if (rc == 0) {
            mprRemoveItem(host->dirs, dir);
            mprInsertItemAtPos(host->dirs, next, newDir);
            return 0;

        } else if (rc > 0) {
            mprInsertItemAtPos(host->dirs, next - 1, newDir);
            return 0;
        }
    }

    mprAddItem(host->dirs, newDir);
    return 0;
}
Exemple #21
0
PUBLIC EjsXML *ejsAppendToXML(Ejs *ejs, EjsXML *xml, EjsXML *node)
{
    EjsXML      *elt;
    int         next;

    if (xml == 0 || node == 0) {
        return 0;
    }
    if (xml->elements == 0) {
        xml->elements = mprCreateList(-1, 0);
    }
    if (node->kind == EJS_XML_LIST) {
        for (next = 0; (elt = mprGetNextItem(node->elements, &next)) != 0; ) {
            if (xml->kind != EJS_XML_LIST) {
                elt->parent = xml;
            }
            mprAddItem(xml->elements, elt);
        }
        xml->targetObject = node->targetObject;
        xml->targetProperty = node->targetProperty;

    } else {
        if (xml->kind != EJS_XML_LIST) {
            node->parent = xml;
        }
        mprAddItem(xml->elements, node);
    }
    return xml;
}
Exemple #22
0
int maAddLocation(MaHost *host, MaLocation *newLocation)
{
    MaLocation  *location;
    int         next, rc;

    mprAssert(newLocation);
    mprAssert(newLocation->prefix);
    
    if (mprGetParent(host->locations) == host->parent) {
        host->locations = mprDupList(host, host->parent->locations);
    }

    /*
     *  Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc
     */
    for (next = 0; (location = mprGetNextItem(host->locations, &next)) != 0; ) {
        rc = strcmp(newLocation->prefix, location->prefix);
        if (rc == 0) {
            mprRemoveItem(host->locations, location);
            mprInsertItemAtPos(host->locations, next - 1, newLocation);
            return 0;
        }
        if (strcmp(newLocation->prefix, location->prefix) > 0) {
            mprInsertItemAtPos(host->locations, next - 1, newLocation);
            return 0;
        }
    }
    mprAddItem(host->locations, newLocation);

    return 0;
}
Exemple #23
0
/*
    Test if the http service (including MPR) is idle with no running requests
 */
static bool isIdle(bool traceRequests)
{
    HttpConn        *conn;
    Http            *http;
    MprTicks        now;
    int             next;
    static MprTicks lastTrace = 0;

    if ((http = MPR->httpService) != 0) {
        now = http->now;
        lock(http->connections);
        for (next = 0; (conn = mprGetNextItem(http->connections, &next)) != 0; ) {
            if (conn->state != HTTP_STATE_BEGIN && conn->state != HTTP_STATE_COMPLETE) {
                if (traceRequests && lastTrace < now) {
                    if (conn->rx) {
                        mprLog("info http", 2, "Request for \"%s\" is still active", 
                            conn->rx->uri ? conn->rx->uri : conn->rx->pathInfo);
                    }
                    lastTrace = now;
                }
                unlock(http->connections);
                return 0;
            }
        }
        unlock(http->connections);
    } else {
        now = mprGetTicks();
    }
    return mprServicesAreIdle(traceRequests);
}
Exemple #24
0
/*
 *  Find an exact dir match. May be called with raw file names. ie. D:\myDir
 */
MaDir *maLookupDir(MaHost *host, cchar *path)
{
    MaDir       *dir;
    char        *absPath, buf[MPR_MAX_FNAME];
    int         next, len;

    /*
     *  Cannonicalize and ensure path has a trailing "/"
     */
    absPath = mprGetAbsFilename(host, path);
    mprStrcpy(buf, sizeof(buf), absPath);
    len = (int) strlen(buf);
    if (buf[len - 1] != '/') {
        buf[len] = '/';
        buf[++len] = '\0';
    }

    for (next = 0; (dir = mprGetNextItem(host->dirs, &next)) != 0; ) {
        if (dir->path != 0) {
#if WIN
            if (mprStrcmpAnyCase(dir->path, buf) == 0)
#else
            if (strcmp(dir->path, buf) == 0)
#endif
                return dir;
        }
    }
    return 0;
}
Exemple #25
0
/*
 *  Find the directory entry that this file (path) resides in. path is a physical file path. We find the most specific
 *  (longest) directory that matches. The directory must match or be a parent of path. Not called with raw files names.
 *  They will be lower case and only have forward slashes. For windows, the will be in cannonical format with drive
 *  specifiers.
 */
MaDir *maLookupBestDir(MaHost *host, cchar *path)
{
    MaDir   *dir;
    int     next, len, dlen;

    len = (int) strlen(path);

    for (next = 0; (dir = mprGetNextItem(host->dirs, &next)) != 0; ) {
        dlen = dir->pathLen;
        /*
         *  Special case where the Directory has a trailing "/" and we match all the letters before that.
         */
        if (len == (dlen - 1) && dir->path[len] == '/') {
            dlen--;
        }
#if WIN
        //  TODO - must make this generic and use something like:  host->caseMatters
        //  TODO - but this must be per-file system.
        if (mprCompareFilename(host, dir->path, path, dlen) == 0)
#else
        if (strncmp(dir->path, path, dlen) == 0)
#endif
        {
            if (dlen >= 0) {
                return dir;
            }
        }
    }
    return 0;
}
Exemple #26
0
static EjsXML *shallowCopy(Ejs *ejs, EjsXML *xml)
{
    EjsXML      *root, *elt;
    int         next;

    assure(xml->kind == EJS_XML_LIST);

    if (xml == 0) {
        return 0;
    }
    if ((root = ejsCreateXMLList(ejs, xml->targetObject, xml->targetProperty)) == NULL) {
        return 0;
    }
    if (xml->elements) {
        root->elements = mprCreateList(-1, 0);
        for (next = 0; (elt = mprGetNextItem(xml->elements, &next)) != 0; ) {
            assure(ejsIsXML(ejs, elt));
            if (elt) {
                mprAddItem(root->elements, elt);
            }
        }
    }
    if (mprHasMemError(ejs)) {
        return 0;
    }
    return root;
}
Exemple #27
0
/*
    Lookup a property by name. There are 7 kinds of lookups:
         prop, @att, [prop], *, @*, .name, .@name
 */
static EjsObj *getXmlListPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname)
{
    EjsXML      *result, *subList, *item;
    int         nextItem;

    /*
        Get the n'th item in the list
     */
    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXmlList(qname.name)) {
        return mprGetItem(list->elements, ejsAtoi(ejs, qname.name, 10));
    }

    result = ejsCreateXMLList(ejs, list, qname);

    /*
        Build a list of all the elements that themselves have a property qname
     */
    for (nextItem = 0; (item = mprGetNextItem(list->elements, &nextItem)) != 0; ) {
        if (item->kind == EJS_XML_ELEMENT) {
            subList = ejsGetPropertyByName(ejs, (EjsObj*) item, qname);
            assure(ejsIsXML(ejs, subList));
            ejsAppendToXML(ejs, result, subList);

        } else {
            //  TODO - do we ever get a list in a list?
            assure(0);
        }
    }
    return (EjsObj*) result;
}
Exemple #28
0
/*
 *  Find an exact dir match
 */
MaDir *maLookupDir(MaHost *host, cchar *pathArg)
{
    MaDir       *dir;
    char        *path, *tmpPath;
    int         next, len;

    if (!mprIsAbsPath(host, pathArg)) {
        path = tmpPath = mprGetAbsPath(host, pathArg);
    } else {
        path = (char*) pathArg;
        tmpPath = 0;
    }
    len = (int) strlen(path);

    for (next = 0; (dir = mprGetNextItem(host->dirs, &next)) != 0; ) {
        if (dir->path != 0) {
            if (mprSamePath(host, dir->path, path)) {
                mprFree(tmpPath);
                return dir;
            }
        }
    }
    mprFree(tmpPath);
    return 0;
}
Exemple #29
0
static int prepRequest(HttpConn *conn, MprList *files, int retry)
{
    MprKeyValue     *header;
    char            *seq;
    int             next;

    httpPrepClientConn(conn, retry);

    for (next = 0; (header = mprGetNextItem(app->headers, &next)) != 0; ) {
        if (scaselessmatch(header->key, "User-Agent")) {
            httpSetHeader(conn, header->key, header->value);
        } else {
            httpAppendHeader(conn, header->key, header->value);
        }
    }
    if (app->text) {
        httpSetHeader(conn, "Accept", "text/plain");
    }
    if (app->sequence) {
        static int next = 0;
        seq = itos(next++);
        httpSetHeader(conn, "X-Http-Seq", seq);
    }
    if (app->ranges) {
        httpSetHeader(conn, "Range", app->ranges);
    }
    if (app->formData) {
        httpSetHeader(conn, "Content-Type", "application/x-www-form-urlencoded");
    }
    if (setContentLength(conn, files) < 0) {
        return MPR_ERR_CANT_OPEN;
    }
    return 0;
}
Exemple #30
0
static int processThread(HttpConn *conn, MprEvent *event)
{
    ThreadData  *td;
    cchar       *path;
    char        *url;
    int         next;

    td = mprGetCurrentThread()->data;
    httpFollowRedirects(conn, !app->nofollow);
    httpSetTimeout(conn, app->timeout, app->timeout);

    if (strcmp(app->protocol, "HTTP/1.0") == 0) {
        httpSetKeepAliveCount(conn, 0);
        httpSetProtocol(conn, "HTTP/1.0");
    }
    if (app->username) {
        if (app->password == 0 && !strchr(app->username, ':')) {
            app->password = getPassword();
        }
        httpSetCredentials(conn, app->username, app->password);
    }
    while (!mprShouldDenyNewRequests(conn) && (app->success || app->continueOnErrors)) {
        if (app->singleStep) waitForUser();
        if (app->files && !app->upload) {
            for (next = 0; (path = mprGetNextItem(app->files, &next)) != 0; ) {
                /*
                    If URL ends with "/", assume it is a directory on the target and append each file name 
                 */
                if (app->target[strlen(app->target) - 1] == '/') {
                    url = mprJoinPath(app->target, mprGetPathBase(path));
                } else {
                    url = app->target;
                }
                app->requestFiles = mprCreateList(-1, MPR_LIST_STATIC_VALUES);
                mprAddItem(app->requestFiles, path);
                td->url = url = resolveUrl(conn, url);
                if (app->verbose) {
                    mprPrintf("putting: %s to %s\n", path, url);
                }
                if (doRequest(conn, url, app->requestFiles) < 0) {
                    app->success = 0;
                    break;
                }
            }
        } else {
            td->url = url = resolveUrl(conn, app->target);
            if (doRequest(conn, url, app->files) < 0) {
                app->success = 0;
                break;
            }
        }
        if (iterationsComplete()) {
            break;
        }
    }
    httpDestroyConn(conn);
    finishThread((MprThread*) event->data);
    return -1;
}