Exemple #1
0
/*
 *  function waitForMessage(timeout: Number = -1): Boolean
 */
static EjsVar *workerWaitForMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    MprTime     mark, remaining;
    int         timeout;

    timeout = (argc > 0) ? ejsGetInt(argv[0]): MAXINT;
    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTime(ejs);
    do {
        if (mprServiceEvents(ejs->dispatcher, timeout, MPR_SERVICE_EVENTS | MPR_SERVICE_ONE_THING) > 0) {
            return (EjsVar*) ejs->trueValue;
        }
        remaining = mprGetRemainingTime(ejs, mark, timeout);
    } while (remaining > 0 && !mprIsExiting(ejs) && !ejs->exiting);
    return (EjsVar*) ejs->falseValue;
}
Exemple #2
0
EjsVar *ejsServiceEvents(Ejs *ejs, int count, int timeout, int flags)
{
    MprTime     mark, remaining;
    int         rc;

    if (count < 0) {
        count = MAXINT;
    }
    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTime(ejs);
    do {
        rc = mprServiceEvents(ejs->dispatcher, timeout, MPR_SERVICE_EVENTS | MPR_SERVICE_ONE_THING);
        if (rc > 0) {
            count -= rc;
        }
        remaining = mprGetRemainingTime(ejs, mark, timeout);
    } while (count > 0 && remaining > 0 && !mprIsExiting(ejs) && !ejs->exiting);
    return 0;
}
Exemple #3
0
/*
 *  Sample main event loop. This demonstrates how to integrate Mpr with your
 *  applications event loop using select()
 */
void eventLoop()
{
    MSG     msg;

    /*
     *  If single threaded or if you desire control over the event loop, you 
     *  should code an event loop similar to that below:
     */
    while (!mprIsExiting(mpr)) {

        // SetTimer(appHwnd, 0, till, NULL);

        /*
         *  Socket events will be serviced in the msgProc
         */
        if (GetMessage(&msg, NULL, 0, 0) == 0) {
            /*  WM_QUIT received */
            break;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
Exemple #4
0
static void eventLoop()
{
	int		timeout, till;

	/*
	 *	We will nap for 50 milliseconds to avoid busy waiting
	 */
	timeout = 50;

	while (!mprIsExiting()) {

		if (mprRunTimers() > 0) {
			till = 0;
		} else {
			till = mprGetIdleTime();
		}

		/*
		 *	This will run tasks if maxThreads == 0 (single threaded). If 
		 *	multithreaded, the thread pool will run tasks
		 */
		if (mprRunTasks() > 0) {		/* Returns > 0 if more work to do */
			till = 0;
		}

		/*
		 *	Do some work here
		 */
		

		/*
		 *	Now service any pending I/O
		 */
		mprServiceEvents(1, min(timeout, till));
	}
}
Exemple #5
0
MAIN(appweb, int argc, char **argv)
{
    Mpr         *mpr;
    MaHttp      *http;
    cchar       *ipAddrPort, *documentRoot, *argp, *logSpec;
    char        *configFile, *ipAddr, *homeDir, *timeText, *ejsPrefix, *ejsPath, *changeRoot;
    int         workers, outputVersion, argind, port;
    
    documentRoot = 0;
    changeRoot = ejsPrefix = ejsPath = 0;
    ipAddrPort = 0;
    ipAddr = 0;
    port = -1;
    logSpec = 0;
    server = 0;
    outputVersion = 0;
    workers = -1;

    configFile = BLD_FEATURE_CONFIG_FILE;
    homeDir = BLD_FEATURE_SERVER_ROOT;

    mpr = mprCreate(argc, argv, memoryFailure);
    argc = mpr->argc;
    argv = mpr->argv;

#if BLD_FEATURE_ROMFS
    extern MprRomInode romFiles[];
    mprSetRomFileSystem(mpr, romFiles);
#endif

    if (osInit(mpr) < 0) {
        exit(2);
    }
    if (mprStart(mpr, 0) < 0) {
        mprUserError(mpr, "Can't start MPR for %s", mprGetAppName(mpr));
        mprFree(mpr);
        return MPR_ERR_CANT_INITIALIZE;
    }

    for (argind = 1; argind < argc; argind++) {
        argp = argv[argind];
        if (*argp != '-') {
            break;
        }
        if (strcmp(argp, "--config") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            configFile = argv[++argind];

#if BLD_UNIX_LIKE
        } else if (strcmp(argp, "--chroot") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            changeRoot = mprGetAbsPath(mpr, argv[++argind]);
#endif

        } else if (strcmp(argp, "--debug") == 0 || strcmp(argp, "-D") == 0 || 
                strcmp(argp, "-d") == 0 || strcmp(argp, "--debugger") == 0) {
            mprSetDebugMode(mpr, 1);

        } else if (strcmp(argp, "--ejs") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            ejsPrefix = mprStrdup(mpr, argv[++argind]);
            if ((ejsPath = strchr(ejsPrefix, ':')) != 0) {
                *ejsPath++ = '\0';
            }
            ejsPath = mprGetAbsPath(mpr, ejsPath);

        } else if (strcmp(argp, "--home") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            homeDir = mprGetAbsPath(mpr, argv[++argind]);
            if (chdir((char*) homeDir) < 0) {
                mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir);
                exit(2);
            }

        } else if (strcmp(argp, "--log") == 0 || strcmp(argp, "-l") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            logSpec = argv[++argind];
            maStartLogging(mpr, logSpec);

        } else if (strcmp(argp, "--name") == 0 || strcmp(argp, "-n") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            mprSetAppName(mpr, argv[++argind], 0, 0);

        } else if (strcmp(argp, "--threads") == 0) {
            if (argind >= argc) {
                return printUsage(mpr);
            }
            workers = atoi(argv[++argind]);

        } else if (strcmp(argp, "--verbose") == 0 || strcmp(argp, "-v") == 0) {
            maStartLogging(mpr, "stdout:2");

        } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) {
            outputVersion++;

        } else {
            mprPrintfError(mpr, "Unknown switch \"%s\"\n", argp);
            printUsage(mpr);
            exit(2);
        }
    }

    if (argc > argind) {
        if (argc > (argind + 2)) {
            return printUsage(mpr);
        }
        ipAddrPort = argv[argind++];
        if (argc > argind) {
            documentRoot = argv[argind++];
        } else {
            documentRoot = ".";
        }
    }

    if (outputVersion) {
        mprPrintf(mpr, "%s %s-%s\n", mprGetAppTitle(mpr), BLD_VERSION, BLD_NUMBER);
        exit(0);
    }

    if (ipAddrPort) {
        mprParseIp(mpr, ipAddrPort, &ipAddr, &port, MA_SERVER_DEFAULT_PORT_NUM);
    } else {
#if BLD_FEATURE_CONFIG_PARSE
        if (configFile == 0) {
            configFile = mprStrcat(mpr, -1, mprGetAppName(mpr), ".conf", NULL);
        }
        if (!mprPathExists(mpr, configFile, R_OK)) {
            mprPrintfError(mpr, "Can't open config file %s\n", configFile);
            exit(2);
        }
#else
        return printUsage(mpr);
#endif
#if !BLD_FEATURE_ROMFS
        if (homeDir == 0) {
            homeDir = mprGetPathParent(mpr, configFile);
            if (chdir((char*) homeDir) < 0) {
                mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir);
                exit(2);
            }
        }
#endif
    }
    homeDir = mprGetCurrentPath(mpr);
    if (checkEnvironment(mpr, argv[0], homeDir) < 0) {
        exit(3);
    }

#if BLD_UNIX_LIKE
    if (changeRoot) {
        homeDir = mprGetAbsPath(mpr, changeRoot);
        if (chdir(homeDir) < 0) {
            mprError(mpr, "%s: Can't change directory to %s", homeDir);
            exit(4);
        }
        if (chroot(homeDir) < 0) {
            if (errno == EPERM) {
                mprError(mpr, "%s: Must be super user to use the --chroot option", mprGetAppName(mpr));
            } else {
                mprError(mpr, "%s: Can't change change root directory to %s, errno %d",
                    mprGetAppName(mpr), homeDir, errno);
            }
            exit(5);
        }
    }
#endif

    /*
     *  Create the top level HTTP service and default HTTP server. Set the initial server root to "."
     */
    http = maCreateHttp(mpr);
    if (http == 0) {
        mprUserError(mpr, "Can't create HTTP service for %s", mprGetAppName(mpr));
        return MPR_ERR_CANT_INITIALIZE;
    }
    server = maCreateServer(http, "default", ".", 0, -1);
    if (server == 0) {
        mprUserError(mpr, "Can't create HTTP server for %s", mprGetAppName(mpr));
        return MPR_ERR_CANT_INITIALIZE;
    }
    if (maConfigureServer(mpr, http, server, configFile, ipAddr, port, documentRoot) < 0) {
        /* mprUserError(mpr, "Can't configure the server, exiting."); */
        exit(6);
    }
    if (mpr->ipAddr) {
        mprLog(mpr, 2, "Server IP address %s", mpr->ipAddr);
    }
    timeText = mprFormatLocalTime(mpr, mprGetTime(mpr));
    mprLog(mpr, 1, "Started at %s", timeText);
    mprFree(timeText);

#if BLD_FEATURE_EJS
    if (ejsPrefix) {
        createEjsAlias(mpr, http, server, ejsPrefix, ejsPath);
    }
#endif

#if BLD_FEATURE_MULTITHREAD
    if (workers >= 0) {
        mprSetMaxWorkers(http, workers);
    }
#endif
#if BLD_WIN_LIKE
    if (!ejsPrefix) {
        writePort(server->defaultHost);
    }
#endif

    if (maStartHttp(http) < 0) {
        mprUserError(mpr, "Can't start HTTP service, exiting.");
        exit(7);
    }

#if BLD_FEATURE_MULTITHREAD
    mprLog(mpr, 1, "HTTP services are ready with max %d worker threads", mprGetMaxWorkers(mpr));
#else
    mprLog(mpr, 1, "HTTP services are ready (single-threaded)");
#endif

    /*
     *  Service I/O events until instructed to exit
     */
    while (!mprIsExiting(mpr)) {
        mprServiceEvents(mpr->dispatcher, -1, MPR_SERVICE_EVENTS | MPR_SERVICE_IO);
    }

    /*
     *  Signal a graceful shutdown
     */
    mprLog(http, 1, "Exiting ...");
    maStopHttp(http);
    mprLog(http, 1, "Exit complete");

#if VXWORKS
    if (mprStop(mpr)) {
        mprFree(mpr);
    }
#endif
    return 0;
}
Exemple #6
0
static int doRequest(MprHttp *http, cchar *url, MprList *fields, MprList *files)
{
    MprHttpResponse *resp;
    MprKeyValue     *header;
    char            buf[MPR_HTTP_BUFSIZE], seqBuf[16], *responseHeaders, *redirect;
    int64           contentLen;
    int             code, next, count, bytes, transCount;

    mprAssert(url && *url);

    mprLog(http, MPR_DEBUG, "fetch: %s %s", method, url);

    /*
     *  Send the request
     */
    count = -1;
    transCount = 0;
    do {
        for (next = 0; (header = mprGetNextItem(headers, &next)) != 0; ) {
            mprSetHttpHeader(http, 0, header->key, header->value);
        }
        if (sequence) {
            static int next = 0;
            mprItoa(seqBuf, sizeof(seqBuf), next++, 10);
            mprSetHttpHeader(http, 1, "X-Http-Seq", seqBuf);
        }
        if (ranges) {
            mprSetHttpHeader(http, 1, "Range", ranges);
        }
        if (fields) {
            mprSetHttpHeader(http, 1, "Content-Type", "application/x-www-form-urlencoded");
        }
        if (chunkSize) {
            mprSetHttpChunked(http, 1);
        }
        if (setContentLength(http, fields, files) < 0) {
            return MPR_ERR_CANT_OPEN;
        }
        if (mprStartHttpRequest(http, method, url) < 0) {
            mprError(http, "Can't process request for \"%s\". %s", url, mprGetHttpError(http));
            return MPR_ERR_CANT_OPEN;
        }
        /*
         *  This program does not do full-duplex writes with reads. ie. if you have a request that sends and receives
         *  data in parallel -- http will do the writes first then read the response.
         */
        if (files || fields) {
            if (writeBody(http, fields, files) < 0) {
                mprError(http, "Can't write body data to \"%s\". %s", url, mprGetHttpError(http));
                return MPR_ERR_CANT_WRITE;
            }
        } else {
            if (chunkSize) {
                mprFinalizeHttpWriting(http);
            }
            mprWaitForHttpResponse(http, -1);
        }
#if WIN
        _setmode(fileno(stdout), O_BINARY);
#endif
        while ((bytes = mprReadHttp(http, buf, sizeof(buf))) > 0) {
            showOutput(http, buf, bytes);
        }
        mprWaitForHttp(http, MPR_HTTP_STATE_COMPLETE, -1);
        /* May not be complete if a disconnect occurs */
        if (http->state >= MPR_HTTP_STATE_CONTENT) {
            if (mprNeedHttpRetry(http, &redirect)) {
                if (redirect) {
                    url = resolveUrl(http, redirect);
                }
                count--;
                transCount++;
                continue;
            }
            break;
        }
    } while (++count < http->retries && transCount < 4 && !mprIsExiting(http));

    if (count >= http->retries) {
        mprError(http, "http: failed \"%s\" request for %s after %d attempt(s)", method, url, count);
        return MPR_ERR_TOO_MANY;
    }
    if (mprIsExiting(http)) {
        return MPR_ERR_BAD_STATE;
    }

    /*
     *  Request now complete
     */
    code = mprGetHttpCode(http);
    contentLen = mprGetHttpContentLength(http);

    mprLog(http, 6, "Response code %d, content len %d", code, contentLen);

    if (http->response) {
        if (showCode) {
            mprPrintf(http, "%d\n", code);
        }
        if (showHeaders) {
            responseHeaders = mprGetHttpHeaders(http);
            resp = http->response;
            mprPrintf(http, "%s %d %s\n", resp->protocol, resp->code, resp->message);
            mprPrintf(http, "%s\n", responseHeaders);
            mprFree(responseHeaders);
        }
    }

    if (code < 0) {
        mprError(http, "Can't process request for \"%s\" %s", url, mprGetHttpError(http));
        return MPR_ERR_CANT_READ;

    } else if (code == 0 && http->protocolVersion == 0) {
        ;

    } else if (!(200 <= code && code <= 206) && !(301 <= code && code <= 304)) {
        if (!showCode) {
            mprError(http, "Can't process request for \"%s\" (%d) %s", url, code, mprGetHttpError(http));
            return MPR_ERR_CANT_READ;
        }
    }

    lock();
    if (verbose && noout) {
        trace(http, url, fetchCount, method, code, (int) contentLen);
    }
    unlock();
    return 0;
}
Exemple #7
0
static void processThread(MprCtx ctx)
{
    MprHttp     *http;
    MprList     *files;
    cchar       *path;
    char        *url;
    int         next;

    http = mprCreateHttp(ctx);
    mprSetHttpTimeout(http, timeout);
    mprSetHttpFollowRedirects(http, !nofollow);

    if (chunkSize) {
        mprSetHttpChunked(http, 1);
    }
    if (httpVersion == 0) {
        mprSetHttpKeepAlive(http, 0);
        mprSetHttpProtocol(http, "HTTP/1.0");
    }
    if (username) {
        if (password == 0 && !strchr(username, ':')) {
            password = getPassword(http);
        }
        mprSetHttpCredentials(http, username, password);
    }
    while (!mprIsExiting(http) && (success || continueOnErrors)) {
        if (singleStep) waitForUser(http);
        if (fileData && !upload) {
            for (next = 0; (path = mprGetNextItem(fileData, &next)) != 0; ) {
                if (target[strlen(target) - 1] == '/') {
                    url = mprJoinPath(http, target, mprGetPathBase(http, path));
                } else {
                    url = target;
                }
                files = mprCreateList(http);
                mprAddItem(files, path);
                url = resolveUrl(http, url);
                if (verbose) {
                    mprPrintf(http, "putting: %s to %s\n", path, url);
                }
                if (doRequest(http, url, formData, files) < 0) {
                    success = 0;
                    mprFree(files);
                    mprFree(url);
                    break;
                }
                mprFree(files);
                mprFree(url);
            }
        } else {
            url = resolveUrl(http, target);
            if (doRequest(http, url, formData, fileData) < 0) {
                success = 0;
                mprFree(url);
                break;
            }
        }
        if (iterationsComplete(http)) 
            break;
    }
    mprFree(http);
}