[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/sony/easyhttpcpp/master/src/HttpRequestExecutor.cpp [Back]  [Original]

/*
 * Copyright 2017 Sony Corporation
 */

#include "easyhttpcpp/common/CoreLogger.h"
#include "easyhttpcpp/common/StringUtil.h"
#include "easyhttpcpp/HttpException.h"
#include "easyhttpcpp/Interceptor.h"

#include "CallInterceptorChain.h"
#include "HttpRequestExecutor.h"
#include "ResponseBodyStreamInternal.h"

using easyhttpcpp::common::StringUtil;

namespace easyhttpcpp {

static const std::string Tag = "HttpRequestExecutor";
static const int MaxRetryCount = 5;

HttpRequestExecutor::HttpRequestExecutor(EasyHttpContext::Ptr pContext, Request::Ptr pRequest) : m_pContext(pContext),
        m_pUserRequest(pRequest), m_cancelled(false)
{
}

HttpRequestExecutor::~HttpRequestExecutor()
{
}

Response::Ptr HttpRequestExecutor::execute()
{
    EasyHttpContext::InterceptorList& callInterceptors = m_pContext->getCallInterceptors();
    EasyHttpContext::InterceptorList::iterator it = callInterceptors.begin();
    EasyHttpContext::InterceptorList::const_iterator itEnd = callInterceptors.end();
    if (it == itEnd) {
        return executeWithRetry(m_pUserRequest);
    } else {
        CallInterceptorChain::Ptr chain(new CallInterceptorChain(HttpRequestExecutor::Ptr(this, true), m_pUserRequest,
                it, itEnd));
        return (*it)->intercept(*chain);
    }
}

Response::Ptr HttpRequestExecutor::executeAfterIntercept(Request::Ptr pRequest)
{
    return executeWithRetry(pRequest);
}

bool HttpRequestExecutor::cancel()
{
    Poco::FastMutex::ScopedLock lock(m_cancelMutex);

    EASYHTTPCPP_LOG_D(Tag, "cancel: cancelled");
    m_cancelled = true;

    bool ret = true;
    if (m_pHttpEngine) {
        if (!m_pHttpEngine->cancel()) {
            ret = false;
        }
    }
    if (m_pUserResponse) {
        ResponseBody::Ptr pResponseBody = m_pUserResponse->getBody();
        if (pResponseBody) {
            ResponseBodyStream::Ptr pResponseBodyStream = pResponseBody->getByteStream();
            if (pResponseBodyStream) {
                // When call the ResponseBodyStream::close, ResponseBodyStream::read will fail.
                // If you have not read to the end, not also written to the cache.
                EASYHTTPCPP_LOG_D(Tag, "cancel: close stream");
                pResponseBodyStream->close();
            }
        }
    }
    return ret;
}

bool HttpRequestExecutor::isCancelled() const
{
    return m_cancelled;
}

HttpEngine::Ptr HttpRequestExecutor::getHttpEngine()
{
    return m_pHttpEngine;
}

Response::Ptr HttpRequestExecutor::executeWithRetry(Request::Ptr pRequest)
{
    Response::Ptr pPriorResponse;
    Request::Ptr pCurrentRequest = pRequest;

    int retryCount = 0;
    do {
        {
            Poco::FastMutex::ScopedLock lock(m_cancelMutex);
            if (m_cancelled) {
                EASYHTTPCPP_LOG_D(Tag, "executeWithRetry: request is cancelled before create HttpEngine.");
                throw HttpExecutionException("http request is cancelled.");
            }
            m_pHttpEngine = new HttpEngine(m_pContext, pCurrentRequest, pPriorResponse);
        }
        Response::Ptr pUserResponse = m_pHttpEngine->execute();

        // check retry
        Request::Ptr pRetryRequest = HttpEngine::getRetryRequest(pUserResponse);
        if (pRetryRequest) {
            m_pHttpEngine->readAllResponseBodyForCache(pUserResponse);
            pPriorResponse = pUserResponse;
            pCurrentRequest = pRetryRequest;
            retryCount++;
            continue;
        }

        {
            Poco::FastMutex::ScopedLock lock(m_cancelMutex);
            m_pUserResponse = pUserResponse;
        }

        return m_pUserResponse;

    } while (retryCount 

Web Proxy Viewer  |  New URL  |  Original Page