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; }
inline QUrl resolveUrl(const QString &url) const { return resolveUrl(QUrl(url)); }
inline QUrl resolveUrl(const QString &url) const { return resolveUrl(QUrl::fromEncoded(url.toUtf8())); }
/* 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); }
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; }
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); }