Example #1
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;
}
Example #2
0
 inline QUrl resolveUrl(const QString &url) const
 { return resolveUrl(QUrl(url)); }
Example #3
0
 inline QUrl resolveUrl(const QString &url) const
 {
     return resolveUrl(QUrl::fromEncoded(url.toUtf8()));
 }
Example #4
0
/*
    Per-thread execution. Called for main thread and helper threads.
 */
static void threadMain(void *data, MprThread *tp)
{
    ThreadData  *td;
    HttpConn    *conn;
    cchar       *path;
    char        *url;
    int         next, count;

    td = tp->data;

    /*
        Create and start a dispatcher. This ensures that all activity on the connection in this thread will
        be serialized with respect to all I/O events and httpProtocol work. This also ensures that I/O events
        will be handled by this thread from httpWait.
     */
    td->dispatcher = mprCreateDispatcher(tp->name, 0);
    mprStartDispatcher(td->dispatcher);

    td->conn = conn = httpCreateConn(NULL, td->dispatcher);

    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->iterations == 1) {
        conn->limits->keepAliveMax = 0;
    }
    if (app->username) {
        if (app->password == 0 && !strchr(app->username, ':')) {
            app->password = getPassword();
        }
        httpSetCredentials(conn, app->username, app->password, app->authType);
    }
    for (count = 0; count < app->iterations; count++) {
        if (mprShouldDenyNewRequests(conn)) {
            break;
        }
        if (!app->success && !app->continueOnErrors) {
            break;
        }
        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 | MPR_LIST_STABLE);
                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 (app->verbose > 1) {
            mprPrintf(".");
        }
    }
    httpDestroyConn(conn);
    mprDestroyDispatcher(conn->dispatcher);
    finishThread(tp);
}
Example #5
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;
}
Example #6
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);
}