Пример #1
0
PUBLIC void httpNetError(HttpNet *net, cchar *fmt, ...)
{
    va_list     args;
    HttpStream  *stream;
    cchar       *msg;
    int         next;

    if (net == 0 || fmt == 0) {
        return;
    }
    va_start(args, fmt);
    if (!net->error) {
        net->error = 1;
        net->errorMsg = msg = sfmtv(fmt, args);
#if ME_HTTP_HTTP2
        if (net->protocol >= 2 && !net->eof) {
            httpSendGoAway(net, HTTP2_INTERNAL_ERROR, "%s", msg);
        }
#endif
        if (httpIsServer(net)) {
            for (ITERATE_ITEMS(net->streams, stream, next)) {
                httpError(stream, HTTP_ABORT | HTTP_CODE_COMMS_ERROR, "%s", msg);
            }
            // TODO httpMonitorNetEvent(net, HTTP_COUNTER_BAD_REQUEST_ERRORS, 1);
        }
    }
Пример #2
0
static void cleanUploadedFiles(HttpConn *conn)
{
    HttpRx          *rx;
    HttpUploadFile  *file;
    cchar           *path, *uploadDir;
    int             index;

    rx = conn->rx;
    uploadDir = getUploadDir(rx->route);

    for (ITERATE_ITEMS(rx->files, file, index)) {
        if (file->filename) {
            if (rx->autoDelete) {
                mprDeletePath(file->filename);

            } else if (rx->renameUploads) {
                path = mprJoinPath(uploadDir, file->clientFilename);
                if (rename(file->filename, path) != 0) {
                    mprLog("http error", 0, "Cannot rename %s to %s", file->filename, path);
                }
            }
            file->filename = 0;
        }
    }
}
Пример #3
0
/*
    Start the command to run (stdIn and stdOut are named from the client's perspective)
 */
PUBLIC int startProcess(MprCmd *cmd)
{
    MprCmdTaskFn    entryFn;
    MprModule       *mp;
    char            *entryPoint, *program, *pair;
    int             pri, next;

    mprLog("info mpr cmd", 4, "Program %s", cmd->program);
    entryPoint = 0;
    if (cmd->env) {
        for (ITERATE_ITEMS(cmd->env, pair, next)) {
            if (sncmp(pair, "entryPoint=", 11) == 0) {
                entryPoint = sclone(&pair[11]);
            }
        }
    }
    program = mprGetPathBase(cmd->program);
    if (entryPoint == 0) {
        program = mprTrimPathExt(program);
        entryPoint = program;
    }
#if ME_CPU_ARCH == MPR_CPU_IX86 || ME_CPU_ARCH == MPR_CPU_IX64 || ME_CPU_ARCH == MPR_CPU_SH
    /*
        A leading underscore is required on some architectures
     */
    entryPoint = sjoin("_", entryPoint, NULL);
#endif
    if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) {
        if ((mp = mprCreateModule(cmd->program, cmd->program, NULL, NULL)) == 0) {
            mprLog("error mpr cmd", 0, "Cannot create module");
            return MPR_ERR_CANT_CREATE;
        }
        if (mprLoadModule(mp) < 0) {
            mprLog("error mpr cmd", 0, "Cannot load DLL %s, errno %d", program, mprGetOsError());
            return MPR_ERR_CANT_READ;
        }
        if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) {
            mprLog("error mpr cmd", 0, "Cannot find symbol %s, errno %d", entryPoint, mprGetOsError());
            return MPR_ERR_CANT_ACCESS;
        }
    }
    taskPriorityGet(taskIdSelf(), &pri);

    cmd->pid = taskSpawn(entryPoint, pri, VX_FP_TASK | VX_PRIVATE_ENV, ME_STACK_SIZE, (FUNCPTR) cmdTaskEntry,
        (int) cmd->program, (int) entryFn, (int) cmd, 0, 0, 0, 0, 0, 0, 0);

    if (cmd->pid < 0) {
        mprLog("error mpr cmd", 0, "Cannot create task %s, errno %d", entryPoint, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (semTake(cmd->startCond, MPR_TIMEOUT_START_TASK) != OK) {
        mprLog("error mpr cmd", 0, "Child %s did not initialize, errno %d", cmd->program, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    semDelete(cmd->startCond);
    cmd->startCond = 0;
    return 0;
}
Пример #4
0
PUBLIC int maSetPlatform(cchar *platformPath)
{
    MaAppweb        *appweb;
    MprDirEntry     *dp;
    cchar           *platform, *dir, *junk, *appwebExe;
    int             next, i, notrace;

    appweb = MPR->appwebService;
    notrace = !platformPath;
    if (!platformPath) {
        platformPath = appweb->localPlatform;
    }
    appweb->platform = appweb->platformDir = 0;
    
    platform = mprGetPathBase(platformPath);

    if (mprPathExists(platformPath, X_OK) && mprIsPathDir(platformPath)) {
        appweb->platform = platform;
        appweb->platformDir = sclone(platformPath);

    } else if (smatch(platform, appweb->localPlatform)) {
        /*
            If running inside an appweb source tree, locate the platform directory 
         */
        appwebExe = mprJoinPath(mprGetAppDir(), "appweb" BIT_EXE);
        if (mprPathExists(appwebExe, R_OK)) {
            appweb->platform = appweb->localPlatform;
            appweb->platformDir = mprGetPathParent(mprGetAppDir());

        } else {
            /*
                Check installed appweb
             */
            appwebExe = BIT_VAPP_PREFIX "/bin/appweb" BIT_EXE;
            if (mprPathExists(appwebExe, R_OK)) {
                appweb->platform = appweb->localPlatform;
                appweb->platformDir = sclone(BIT_VAPP_PREFIX);
            }
        }
    }
    
    /*
        Last chance. Search up the tree for a similar platform directory.
        This permits specifying a partial platform like "vxworks" without architecture and profile.
     */
    if (!appweb->platformDir) {
        dir = mprGetCurrentPath();
        for (i = 0; !mprSamePath(dir, "/") && i < 64; i++) {
            for (ITERATE_ITEMS(mprGetPathFiles(dir, 0), dp, next)) {
                if (dp->isDir && sstarts(mprGetPathBase(dp->name), platform)) {
                    appweb->platform = mprGetPathBase(dp->name);
                    appweb->platformDir = mprJoinPath(dir, dp->name);
                    break;
                }
            }
            dir = mprGetPathParent(dir);
        }
    }
Пример #5
0
/*
    The base procedure is invoked prior to calling any and all actions on this route
 */
PUBLIC void espDefineBase(HttpRoute *route, EspProc baseProc)
{
    HttpRoute   *rp;
    EspRoute    *eroute, *er;
    int         next;

    eroute = route->eroute;
    for (ITERATE_ITEMS(route->host->routes, rp, next)) {
        if ((er = route->eroute) != 0 && smatch(er->controllersDir, eroute->controllersDir)) {
            er->commonController = baseProc;
        }
    }
}
Пример #6
0
void httpStopEndpoint(HttpEndpoint *endpoint)
{
    HttpHost    *host;
    int         next;

    for (ITERATE_ITEMS(endpoint->hosts, host, next)) {
        httpStopHost(host);
    }
    if (endpoint->sock) {
        mprCloseSocket(endpoint->sock, 0);
        endpoint->sock = 0;
    }
}
Пример #7
0
static EdiGrid *mdbReadWhere(Edi *edi, cchar *tableName, cchar *columnName, cchar *operation, cchar *value)
{
    Mdb         *mdb;
    EdiGrid     *grid;
    MdbTable    *table;
    MdbCol      *col;
    MdbRow      *row;
    int         nrows, next, op, r, count;

    assert(edi);
    assert(tableName && *tableName);

    mdb = (Mdb*) edi;
    lock(mdb);
    if ((table = lookupTable(mdb, tableName)) == 0) {
        unlock(mdb);
        return 0;
    }
    nrows = mprGetListLength(table->rows);
    if ((grid = ediCreateBareGrid(edi, tableName, nrows)) == 0) {
        unlock(mdb);
        return 0;
    }
    grid->flags = EDI_GRID_READ_ONLY;
    if (columnName) {
        if ((col = lookupColumn(table, columnName)) == 0) {
            unlock(mdb);
            return 0;
        }
        if ((op = parseOperation(operation)) < 0) {
            unlock(mdb);
            return 0;
        }
        if (col->flags & EDI_INDEX && (op & OP_EQ)) {
            if ((r = lookupRow(table, value)) != 0) {
                row = getRow(table, r);
                grid->records[0] = createRecFromRow(edi, row);
                grid->nrecords = 1;
            }
        } else {
            grid->nrecords = count = 0;
            for (ITERATE_ITEMS(table->rows, row, next)) {
                if (!matchRow(col, row->fields[col->cid], op, value)) {
                    continue;
                }
                grid->records[count++] = createRecFromRow(edi, row);
                grid->nrecords = count;
            }
        }
    } else {
        for (ITERATE_ITEMS(table->rows, row, next)) {
Пример #8
0
/*
    The base procedure is invoked prior to calling any and all actions on this route
 */
PUBLIC void espDefineBase(HttpRoute *route, EspProc baseProc)
{
    HttpRoute   *rp;
    EspRoute    *eroute;
    int         next;

    for (ITERATE_ITEMS(route->host->routes, rp, next)) {
        if ((eroute = route->eroute) != 0) {
            if (smatch(httpGetDir(rp, "CONTROLLERS"), httpGetDir(route, "CONTROLLERS"))) {
                eroute->commonController = baseProc;
            }
        }
    }
}
Пример #9
0
static int blendEnv(MprCmd *cmd, cchar **env, int flags)
{
    cchar       **ep, *prior;
    int         next;

    cmd->env = 0;

    if ((cmd->env = mprCreateList(128, MPR_LIST_STATIC_VALUES | MPR_LIST_STABLE)) == 0) {
        return MPR_ERR_MEMORY;
    }
#if !VXWORKS
    /*
        Add prior environment to the list
     */
    if (!(flags & MPR_CMD_EXACT_ENV)) {
        for (ep = (cchar**) environ; ep && *ep; ep++) {
#if MACOSX
            if (sstarts(*ep, "DYLD_LIBRARY_PATH=")) {
                continue;
            }
#endif
            mprAddItem(cmd->env, *ep);
        }
    }
#endif
    /*
        Add new env keys. Detect and overwrite duplicates
     */
    for (ep = env; ep && *ep; ep++) {
        prior = 0;
        for (ITERATE_ITEMS(cmd->env, prior, next)) {
            if (matchEnvKey(*ep, prior)) {
                mprSetItem(cmd->env, next - 1, *ep);
                break;
            }
        }
        if (prior == 0) {
            mprAddItem(cmd->env, *ep);
        }
    }
#if ME_WIN_LIKE
    /*
        Windows requires a caseless sort with two trailing nulls
     */
    mprSortList(cmd->env, (MprSortProc) sortEnv, 0);
#endif
    mprAddItem(cmd->env, NULL);
    return 0;
}
Пример #10
0
void ejsRemoveModuleFromAll(EjsModule *mp)
{
    Ejs         *ejs;
    EjsService  *sp;
    int         next;

    if ((sp = MPR->ejsService) == 0) {
        return;
    }
    lock(sp);
    for (ITERATE_ITEMS(sp->vmlist, ejs, next)) {
        mprRemoveItem(ejs->modules, mp);
    }
    unlock(sp);
}
Пример #11
0
static cchar *makeWinEnvBlock(MprCmd *cmd)
{
    char    *item, *dp, *ep, *env;
    ssize   len;
    int     next;

    for (len = 2, ITERATE_ITEMS(cmd->env, item, next)) {
        len += slen(item) + 1;
    }
    if ((env = mprAlloc(len)) == 0) {
        return 0;
    }
    ep = &env[len];
    dp = env;
    for (ITERATE_ITEMS(cmd->env, item, next)) {
        strcpy(dp, item);
        dp += slen(item) + 1;
    }
    /* Windows requires two nulls */
    *dp++ = '\0';
    *dp++ = '\0';
    assert(dp <= ep);
    return env;
}
Пример #12
0
static MprWaitHandler *initWaitHandler(MprWaitHandler *wp, int fd, int mask, MprDispatcher *dispatcher, void *proc,
    void *data, int flags)
{
    MprWaitService  *ws;

    assert(fd >= 0);
    ws = MPR->waitService;

#if ME_DEBUG
    {
        MprWaitHandler  *op;
        int             index;

        for (ITERATE_ITEMS(ws->handlers, op, index)) {
            if (op->fd == fd) {
                mprLog("error mpr event", 0, "Duplicate fd in wait handlers");
            }
        }
    }
#endif
    wp->fd              = fd;
    wp->notifierIndex   = -1;
    wp->dispatcher      = dispatcher;
    wp->proc            = proc;
    wp->flags           = 0;
    wp->handlerData     = data;
    wp->service         = ws;
    wp->flags           = flags;

    if (mprGetListLength(ws->handlers) >= FD_SETSIZE) {
        mprLog("error mpr event", 0, "Too many io handlers: %d", FD_SETSIZE);
        return 0;
    }
#if ME_UNIX_LIKE || VXWORKS
#if ME_EVENT_NOTIFIER == MPR_EVENT_SELECT
    if (fd >= FD_SETSIZE) {
        mprLog("error mpr event", 0, "File descriptor %d exceeds max io of %d", fd, FD_SETSIZE);
    }
#endif
#endif
    if (mask) {
        if (mprAddItem(ws->handlers, wp) < 0) {
            return 0;
        }
        mprNotifyOn(wp, mask);
    }
    return wp;
}
Пример #13
0
/*
    Event callback. Invoked for incoming web socket messages and other events of interest.
 */
static void chat_callback(HttpConn *conn, int event, int arg)
{
    HttpPacket  *packet;
    HttpConn    *client;
    Msg         *msg;
    int         next;

    if (event == HTTP_EVENT_READABLE) {
        packet = httpGetPacket(conn->readq);
        if (packet->type == WS_MSG_TEXT || packet->type == WS_MSG_BINARY) {
            for (ITERATE_ITEMS(clients, client, next)) {
                msg = mprAllocObj(Msg, manageMsg);
                msg->conn = client;
                msg->packet = packet;
                mprCreateEvent(client->dispatcher, "chat", 0, chat, msg, 0);
            }
        }
    } else if (event == HTTP_EVENT_APP_CLOSE) {
Пример #14
0
static void filterDirList(HttpConn *conn, MprList *list)
{
    Dir             *dir;
    MprDirEntry     *dp;
    int             next;

    dir = conn->data;
    
    /*
        Do pattern matching. Entries that don't match, free the name to mark
     */
    for (ITERATE_ITEMS(list, dp, next)) {
        if (!matchDirPattern(dir->pattern, dp->name)) {
            mprRemoveItem(list, dp);
            next--;
        }
    }
}
Пример #15
0
PUBLIC int httpStartEndpoints()
{
    HttpEndpoint    *endpoint;
    int             next;

    if (!HTTP) {
        return MPR_ERR_BAD_STATE;
    }
    for (ITERATE_ITEMS(HTTP->endpoints, endpoint, next)) {
        if (httpStartEndpoint(endpoint) < 0) {
            return MPR_ERR_CANT_OPEN;
        }
    }
    if (httpApplyUserGroup() < 0) {
        httpStopEndpoints();
        return MPR_ERR_CANT_OPEN;
    }
    return 0;
}
Пример #16
0
int httpStartEndpoint(HttpEndpoint *endpoint)
{
    HttpHost    *host;
    cchar       *proto, *ip;
    int         next;

    if (!validateEndpoint(endpoint)) {
        return MPR_ERR_BAD_ARGS;
    }
    for (ITERATE_ITEMS(endpoint->hosts, host, next)) {
        httpStartHost(host);
    }
    if ((endpoint->sock = mprCreateSocket(endpoint->ssl)) == 0) {
        return MPR_ERR_MEMORY;
    }
    if (mprListenOnSocket(endpoint->sock, endpoint->ip, endpoint->port, MPR_SOCKET_NODELAY | MPR_SOCKET_THREAD) < 0) {
        mprError("Can't open a socket on %s:%d", *endpoint->ip ? endpoint->ip : "*", endpoint->port);
        return MPR_ERR_CANT_OPEN;
    }
    if (endpoint->http->listenCallback && (endpoint->http->listenCallback)(endpoint) < 0) {
        return MPR_ERR_CANT_OPEN;
    }
    if (endpoint->async && !endpoint->sock->handler) {
        mprAddSocketHandler(endpoint->sock, MPR_SOCKET_READABLE, endpoint->dispatcher, httpAcceptConn, endpoint, 
            (endpoint->dispatcher) ? 0 : MPR_WAIT_NEW_DISPATCHER);
    } else {
        mprSetSocketBlockingMode(endpoint->sock, 1);
    }
    proto = endpoint->ssl ? "HTTPS" : "HTTP ";
    ip = *endpoint->ip ? endpoint->ip : "*";
    if (mprIsSocketV6(endpoint->sock)) {
        mprLog(2, "Started %s service on \"[%s]:%d\"", proto, ip, endpoint->port);
    } else {
        mprLog(2, "Started %s service on \"%s:%d\"", proto, ip, endpoint->port);
    }
    return 0;
}
Пример #17
0
/*
    Set headers for httpWriteHeaders. This defines standard headers.
 */
static void setHeaders(HttpConn *conn, HttpPacket *packet)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpRoute   *route;
    HttpRange   *range;
    MprKeyValue *item;
    MprOff      length;
    cchar       *mimeType;
    int         next;

    assert(packet->flags == HTTP_PACKET_HEADER);

    rx = conn->rx;
    tx = conn->tx;
    route = rx->route;

    /*
        Mandatory headers that must be defined here use httpSetHeader which overwrites existing values. 
     */
    httpAddHeaderString(conn, "Date", conn->http->currentDate);

    if (tx->ext && route) {
        if ((mimeType = (char*) mprLookupMime(route->mimeTypes, tx->ext)) != 0) {
            if (conn->error) {
                httpAddHeaderString(conn, "Content-Type", "text/html");
            } else {
                httpAddHeaderString(conn, "Content-Type", mimeType);
            }
        }
    }
    if (tx->etag) {
        httpAddHeader(conn, "ETag", "%s", tx->etag);
    }
    length = tx->length > 0 ? tx->length : 0;
    if (rx->flags & HTTP_HEAD) {
        conn->tx->flags |= HTTP_TX_NO_BODY;
        httpDiscardData(conn, HTTP_QUEUE_TX);
        if (tx->chunkSize <= 0) {
            httpAddHeader(conn, "Content-Length", "%Ld", length);
        }

    } else if (tx->length < 0 && tx->chunkSize > 0) {
        httpSetHeaderString(conn, "Transfer-Encoding", "chunked");

    } else if (conn->endpoint) {
        /* Server must not emit a content length header for 1XX, 204 and 304 status */
        if (!((100 <= tx->status && tx->status <= 199) || tx->status == 204 || 
                tx->status == 304 || tx->flags & HTTP_TX_NO_LENGTH)) {
            httpAddHeader(conn, "Content-Length", "%Ld", length);
        }

    } else if (tx->length > 0) {
        /* client with body */
        httpAddHeader(conn, "Content-Length", "%Ld", length);
    }
    if (tx->outputRanges) {
        if (tx->outputRanges->next == 0) {
            range = tx->outputRanges;
            if (tx->entityLength > 0) {
                httpSetHeader(conn, "Content-Range", "bytes %Ld-%Ld/%Ld", range->start, range->end - 1, tx->entityLength);
            } else {
                httpSetHeader(conn, "Content-Range", "bytes %Ld-%Ld/*", range->start, range->end - 1);
            }
        } else {
            httpSetHeader(conn, "Content-Type", "multipart/byteranges; boundary=%s", tx->rangeBoundary);
        }
        httpSetHeader(conn, "Accept-Ranges", "bytes");
    }
    if (conn->endpoint) {
        if (!(route->flags & HTTP_ROUTE_STEALTH)) {
            httpAddHeaderString(conn, "Server", conn->http->software);
        }
        /*
            If keepAliveCount == 1
         */
        if (--conn->keepAliveCount > 0) {
            assert(conn->keepAliveCount >= 1);
            httpAddHeaderString(conn, "Connection", "Keep-Alive");
            httpAddHeader(conn, "Keep-Alive", "timeout=%Ld, max=%d", conn->limits->inactivityTimeout / 1000, conn->keepAliveCount);
        } else {
            /* Tell the peer to close the connection */
            httpAddHeaderString(conn, "Connection", "close");
        }
        if (route->flags & HTTP_ROUTE_CORS) {
            setCorsHeaders(conn);
        }
        /* 
            Apply response headers
         */
        for (ITERATE_ITEMS(route->headers, item, next)) {
            if (item->flags == HTTP_ROUTE_ADD_HEADER) {
                httpAddHeaderString(conn, item->key, item->value);
            } else if (item->flags == HTTP_ROUTE_APPEND_HEADER) {
                httpAppendHeaderString(conn, item->key, item->value);
            } else if (item->flags == HTTP_ROUTE_REMOVE_HEADER) {
                httpRemoveHeader(conn, item->key);
            } else if (item->flags == HTTP_ROUTE_SET_HEADER) {
                httpSetHeaderString(conn, item->key, item->value);
            }
        }
    }
}
Пример #18
0
/*
    Start the command to run (stdIn and stdOut are named from the client's perspective). This is the lower-level way to
    run a command. The caller needs to do code like mprRunCmd() themselves to wait for completion and to send/receive data.
    The routine does not wait. Callers must call mprWaitForCmd to wait for the command to complete.
 */
PUBLIC int mprStartCmd(MprCmd *cmd, int argc, cchar **argv, cchar **envp, int flags)
{
    MprPath     info;
    cchar       *pair;
    int         rc, next, i;

    assert(cmd);
    assert(argv);

    if (argc <= 0 || argv == NULL || argv[0] == NULL) {
        return MPR_ERR_BAD_ARGS;
    }
    resetCmd(cmd, 0);

    cmd->flags = flags;
    cmd->argc = argc;
    cmd->argv = mprAlloc((argc + 1) * sizeof(char*));
    for (i = 0; i < argc; i++) {
        cmd->argv[i] = sclone(argv[i]);
    }
    cmd->argv[i] = 0;

    prepWinProgram(cmd);

    if ((cmd->program = mprSearchPath(cmd->argv[0], MPR_SEARCH_EXE, cmd->searchPath, NULL)) == 0) {
        mprLog("error mpr cmd", 0, "Cannot access %s, errno %d", cmd->argv[0], mprGetOsError());
        return MPR_ERR_CANT_ACCESS;
    }
    if (mprGetPathInfo(cmd->program, &info) == 0 && info.isDir) {
        mprLog("error mpr cmd", 0, "Program \"%s\", is a directory", cmd->program);
        return MPR_ERR_CANT_ACCESS;
    }
    mprLog("info mpr cmd", 6, "Program: %s", cmd->program);
    cmd->argv[0] = cmd->program;

    prepWinCommand(cmd);

    if (envp == 0) {
        envp = cmd->defaultEnv;
    }
    if (blendEnv(cmd, envp, flags) < 0) {
        return MPR_ERR_MEMORY;
    }
    for (i = 0; i < cmd->argc; i++) {
        mprLog("info mpr cmd", 6, "    arg[%d]: %s", i, cmd->argv[i]);
    }
    for (ITERATE_ITEMS(cmd->env, pair, next)) {
        mprLog("info mpr cmd", 6, "    env[%d]: %s", next, pair);
    }
    slock(cmd);
    if (makeCmdIO(cmd) < 0) {
        sunlock(cmd);
        return MPR_ERR_CANT_OPEN;
    }
    /*
        Determine how many end-of-files will be seen when the child dies
     */
    cmd->requiredEof = 0;
    if (cmd->flags & MPR_CMD_OUT) {
        cmd->requiredEof++;
    }
    if (cmd->flags & MPR_CMD_ERR) {
        cmd->requiredEof++;
    }
    if (addCmdHandlers(cmd) < 0) {
        mprLog("error mpr cmd", 0, "Cannot open command handlers - insufficient I/O handles");
        return MPR_ERR_CANT_OPEN;
    }
    rc = startProcess(cmd);

    cmd->originalPid = cmd->pid;
    mprAddItem(MPR->cmdService->cmds, cmd);
    sunlock(cmd);
#if ME_WIN_LIKE
    if (!rc) {
        mprCreateTimerEvent(cmd->dispatcher, "pollWinTimer", 10, pollWinTimer, cmd, 0);
    }
#endif
    return rc;
}
Пример #19
0
/*
    Executed by the child process
 */
static void cmdTaskEntry(char *program, MprCmdTaskFn entry, int cmdArg)
{
    MprCmd          *cmd;
    MprCmdFile      *files;
    WIND_TCB        *tcb;
    char            *item;
    int             inFd, outFd, errFd, id, next;

    cmd = (MprCmd*) cmdArg;

    /*
        Open standard I/O files (in/out are from the server's perspective)
     */
    files = cmd->files;
    inFd = open(files[MPR_CMD_STDIN].name, O_RDONLY, 0666);
    outFd = open(files[MPR_CMD_STDOUT].name, O_WRONLY, 0666);
    errFd = open(files[MPR_CMD_STDERR].name, O_WRONLY, 0666);

    if (inFd < 0 || outFd < 0 || errFd < 0) {
        exit(255);
    }
    id = taskIdSelf();
    ioTaskStdSet(id, 0, inFd);
    ioTaskStdSet(id, 1, outFd);
    ioTaskStdSet(id, 2, errFd);

    /*
        Now that we have opened the stdin and stdout, wakeup our parent.
     */
    semGive(cmd->startCond);

    /*
        Create the environment
     */
    if (envPrivateCreate(id, -1) < 0) {
        exit(254);
    }
    for (ITERATE_ITEMS(cmd->env, item, next)) {
        putenv(item);
    }

#if !VXWORKS
{
    char    *dir;
    int     rc;

    /*
        Set current directory if required
        WARNING: Setting working directory on VxWorks is global
     */
    if (cmd->dir) {
        rc = chdir(cmd->dir);
    } else {
        dir = mprGetPathDir(cmd->program);
        rc = chdir(dir);
    }
    if (rc < 0) {
        mprLog("error mpr cmd", 0, "Cannot change directory to %s", cmd->dir);
        exit(255);
    }
}
#endif

    /*
        Call the user's entry point
     */
    (entry)(cmd->argc, (char**) cmd->argv, (char**) cmd->env);

    tcb = taskTcb(id);
    cmd->status = tcb->exitCode;

    /*
        Cleanup
     */
    envPrivateDestroy(id);
    close(inFd);
    close(outFd);
    close(errFd);
    semGive(cmd->exitCond);
}
Пример #20
0
PUBLIC int espEmail(HttpConn *conn, cchar *to, cchar *from, cchar *subject, MprTime date, cchar *mime,
                    cchar *message, MprList *files)
{
    MprList         *lines;
    MprCmd          *cmd;
    cchar           *body, *boundary, *contents, *encoded, *file;
    char            *out, *err;
    ssize           length;
    int             i, next, status;

    if (!from || !*from) {
        from = "anonymous";
    }
    if (!subject || !*subject) {
        subject = "Mail message";
    }
    if (!mime || !*mime) {
        mime = "text/plain";
    }
    if (!date) {
        date = mprGetTime();
    }
    boundary = sjoin("esp.mail=", mprGetMD5("BOUNDARY"), NULL);
    lines = mprCreateList(0, 0);

    mprAddItem(lines, sfmt("To: %s", to));
    mprAddItem(lines, sfmt("From: %s", from));
    mprAddItem(lines, sfmt("Date: %s", mprFormatLocalTime(0, date)));
    mprAddItem(lines, sfmt("Subject: %s", subject));
    mprAddItem(lines, "MIME-Version: 1.0");
    mprAddItem(lines, sfmt("Content-Type: multipart/mixed; boundary=%s", boundary));
    mprAddItem(lines, "");

    boundary = sjoin("--", boundary, NULL);

    mprAddItem(lines, boundary);
    mprAddItem(lines, sfmt("Content-Type: %s", mime));
    mprAddItem(lines, "");
    mprAddItem(lines, "");
    mprAddItem(lines, message);

    for (ITERATE_ITEMS(files, file, next)) {
        mprAddItem(lines, boundary);
        if ((mime = mprLookupMime(NULL, file)) == 0) {
            mime = "application/octet-stream";
        }
        mprAddItem(lines, "Content-Transfer-Encoding: base64");
        mprAddItem(lines, sfmt("Content-Disposition: inline; filename=\"%s\"", mprGetPathBase(file)));
        mprAddItem(lines, sfmt("Content-Type: %s; name=\"%s\"", mime, mprGetPathBase(file)));
        mprAddItem(lines, "");
        contents = mprReadPathContents(file, &length);
        encoded = mprEncode64Block(contents, length);
        for (i = 0; i < length; i += 76) {
            mprAddItem(lines, snclone(&encoded[i], i + 76));
        }
    }
    mprAddItem(lines, sfmt("%s--", boundary));

    body = mprListToString(lines, "\n");
    httpTraceContent(conn, "esp.email", "context", body, slen(body), 0);

    cmd = mprCreateCmd(conn->dispatcher);
    if (mprRunCmd(cmd, "sendmail -t", NULL, body, &out, &err, -1, 0) < 0) {
        mprDestroyCmd(cmd);
        return MPR_ERR_CANT_OPEN;
    }
    if (mprWaitForCmd(cmd, ME_ESP_EMAIL_TIMEOUT) < 0) {
        httpTrace(conn, "esp.email.error", "error",
                  "msg=\"Timeout waiting for command to complete\", timeout=%d, command=\"%s\"",
                  ME_ESP_EMAIL_TIMEOUT, cmd->argv[0]);
        mprDestroyCmd(cmd);
        return MPR_ERR_CANT_COMPLETE;
    }
    if ((status = mprGetCmdExitStatus(cmd)) != 0) {
        httpTrace(conn, "esp.email.error", "error", "msg=\"Sendmail failed\", status=%d, error=\"%s\"", status, err);
        mprDestroyCmd(cmd);
        return MPR_ERR_CANT_WRITE;
    }
    mprDestroyCmd(cmd);
    return 0;
}
Пример #21
0
/*
    Test if the request matches. This may delegate the request to the dirHandler if a directory listing is required.
 */
static int matchFileHandler(HttpConn *conn, HttpRoute *route, int dir)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpUri     *prior;
    MprPath     *info, zipInfo;
    cchar       *index;
    char        *path, *pathInfo, *uri, *zipfile;
    int         next;
    
	printf("\n  matchFileHandler  \n");
    rx = conn->rx;
    tx = conn->tx;
    rx = conn->rx;
    prior = rx->parsedUri;
    info = &tx->fileInfo;

    httpMapFile(conn, route);
    assure(info->checked);

    if (rx->flags & (HTTP_DELETE | HTTP_PUT)) {
        return HTTP_ROUTE_OK;
    }
    if (info->isDir) {
        /*
            Manage requests for directories
         */
        if (!sends(rx->pathInfo, "/")) {
            /* 
               Append "/" and do an external redirect 
             */
            pathInfo = sjoin(rx->pathInfo, "/", NULL);
            uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, prior->query, 0);
            httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri);
            return HTTP_ROUTE_OK;
        } 
        if (route->indicies) {
            /*
                Ends with a "/" so do internal redirection to an index file
             */
            for (ITERATE_ITEMS(route->indicies, index, next)) {
                /*  
                    Internal directory redirections. Transparently append index. Test indicies in order.
                 */
				
                path = mprJoinPath(tx->filename, index);

                if (mprPathExists(path, R_OK)) {
                    pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL);
                    uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, 
                        prior->query, 0);
                    httpSetUri(conn, uri);
                    tx->filename = path;
                    tx->ext = httpGetExt(conn);
                    mprGetPathInfo(tx->filename, info);
                    return HTTP_ROUTE_REROUTE;
                }
            }
        }
        /*
            If a directory, test if a directory listing should be rendered. If so, delegate to the dirHandler.
            Cannot use the sendFile handler and must use the netConnector.
         */
        if (info->isDir && maRenderDirListing(conn)) {
            tx->handler = conn->http->dirHandler;
            tx->connector = conn->http->netConnector;
            return HTTP_ROUTE_OK;
        }
    }
    if (!info->valid && (route->flags & HTTP_ROUTE_GZIP) && rx->acceptEncoding && strstr(rx->acceptEncoding, "gzip") != 0) {
        /*
            If the route accepts zipped data and a zipped file exists, then transparently respond with it.
         */
        zipfile = sfmt("%s.gz", tx->filename);
        if (mprGetPathInfo(zipfile, &zipInfo) == 0) {
            tx->filename = zipfile;
            tx->fileInfo = zipInfo;
            httpSetHeader(conn, "Content-Encoding", "gzip");
        }
    }
    if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST) && info->valid && !info->isDir && tx->length < 0) {
        /*
            The sendFile connector is optimized on some platforms to use the sendfile() system call.
            Set the entity length for the sendFile connector to utilize.
         */
        httpSetEntityLength(conn, tx->fileInfo.size);
    }

	printf("\n-------------------------\n");
	printf("tx->filename:\t%s",tx->filename);
	printf("\n-------------------------\n");


    return HTTP_ROUTE_OK;
}
Пример #22
0
static int handleDirectory(HttpConn *conn)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpRoute   *route;
    HttpUri     *req;
    MprPath     *info;
    cchar       *index, *pathInfo, *uri;
    char        *path;
    int         next;

    rx = conn->rx;
    tx = conn->tx;
    req = rx->parsedUri;
    route = rx->route;
    info = &tx->fileInfo;

    /*
        Manage requests for directories
     */
    if (!sends(req->path, "/")) {
        /*
           Append "/" and do an external redirect. Use the original request URI.
         */
        pathInfo = sjoin(req->path, "/", NULL);
        uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0);
        httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri);
        return HTTP_ROUTE_OK;
    }
    if (route->indexes) {
        /*
            Ends with a "/" so do internal redirection to an index file
         */
        for (ITERATE_ITEMS(route->indexes, index, next)) {
            /*
                Internal directory redirections. Transparently append index. Test indexes in order.
             */
            path = mprJoinPath(tx->filename, index);
            if (mprPathExists(path, R_OK)) {
                pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL);
                uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0);
                httpSetUri(conn, uri);
                tx->filename = path;
                tx->ext = httpGetExt(conn);
                mprGetPathInfo(tx->filename, info);
                return HTTP_ROUTE_REROUTE;
            }
        }
    }
#if ME_COM_DIR
    /*
        Directory Listing. If a directory, test if a directory listing should be rendered. If so, delegate to the
        dirHandler. Cannot use the sendFile handler and must use the netConnector.
     */
    if (info->isDir && httpRenderDirListing(conn)) {
        tx->handler = conn->http->dirHandler;
        tx->connector = conn->http->netConnector;
        return HTTP_ROUTE_OK;
    }
#endif
    return HTTP_ROUTE_OK;
}
Пример #23
0
/*
    <% stylesheets(patterns); %>

    Where patterns may contain *, ** and !pattern for exclusion
 */
PUBLIC void stylesheets(cchar *patterns)
{
    HttpStream    *stream;
    HttpRx      *rx;
    HttpRoute   *route;
    EspRoute    *eroute;
    MprList     *files;
    cchar       *filename, *ext, *uri, *path, *kind, *version, *clientDir;
    int         next;

    stream = getStream();
    rx = stream->rx;
    route = rx->route;
    eroute = route->eroute;
    patterns = httpExpandRouteVars(route, patterns);
    clientDir = httpGetDir(route, "documents");

    if (!patterns || !*patterns) {
        version = espGetConfig(route, "version", "1.0.0");
        if (eroute->combineSheet) {
            /* Previously computed combined stylesheet filename */
            stylesheets(eroute->combineSheet);

        } else if (espGetConfig(route, "http.content.combine[@=css]", 0)) {
            if (espGetConfig(route, "http.content.minify[@=css]", 0)) {
                eroute->combineSheet = sfmt("css/all-%s.min.css", version);
            } else {
                eroute->combineSheet = sfmt("css/all-%s.css", version);
            }
            stylesheets(eroute->combineSheet);

        } else {
            /*
                Not combining into a single stylesheet, so give priority to all.less over all.css if present
                Load a pure CSS incase some styles need to be applied before the lesssheet is parsed
             */
            ext = espGetConfig(route, "http.content.stylesheets", "css");
            filename = mprJoinPathExt("css/all", ext);
            path = mprJoinPath(clientDir, filename);
            if (mprPathExists(path, R_OK)) {
                stylesheets(filename);
            } else if (!smatch(ext, "less")) {
                path = mprJoinPath(clientDir, "css/all.less");
                if (mprPathExists(path, R_OK)) {
                    stylesheets("css/all.less");
                }
            }
        }
    } else {
        if (sends(patterns, "all.less")) {
            path = mprJoinPath(clientDir, "css/fix.css");
            if (mprPathExists(path, R_OK)) {
                stylesheets("css/fix.css");
            }
        }
        if ((files = mprGlobPathFiles(clientDir, patterns, MPR_PATH_RELATIVE)) == 0 || mprGetListLength(files) == 0) {
            files = mprCreateList(0, 0);
            mprAddItem(files, patterns);
        }
        for (ITERATE_ITEMS(files, path, next)) {
            path = sjoin("~/", strim(path, ".gz", MPR_TRIM_END), NULL);
            uri = httpLink(stream, path);
            kind = mprGetPathExt(path);
            if (smatch(kind, "css")) {
                espRender(stream, "<link rel='stylesheet' type='text/css' href='%s' />\n", uri);
            } else {
                espRender(stream, "<link rel='stylesheet/%s' type='text/css' href='%s' />\n", kind, uri);
            }
        }
    }
}