Beispiel #1
0
/*
 *  Just like simpleGet but with an explicit port number
 */
static bool get(MprTestGroup *gp, cchar *host, int port, cchar *uri, int expectCode)
{
    MprHttp     *http;
    int         code;

    http = getHttp(gp);

    if (expectCode <= 0) {
        expectCode = 200;
    }
    if (host) {
        mprSetHttpDefaultHost(http, host);
    }
    if (port > 0) {
        mprSetHttpDefaultPort(http, getDefaultPort(gp) + port);
    }

    if (mprHttpRequest(http, "GET", uri, 0) < 0) {
        return 0;
    }

    code = mprGetHttpCode(http);
    assert(code == expectCode);

    if (code != expectCode) {
        mprLog(gp, 0, "get: HTTP response code %d, expected %d", code, expectCode);
        return 0;
    }

    assert(mprGetHttpError(http) != 0);
    assert(mprGetHttpContent(http) != 0);

    return 1;
}
Beispiel #2
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;
}
Beispiel #3
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;
}