Exemplo n.º 1
0
bool CetonStreamHandler::HttpRequest(
    const QString &method, const QString &script, const QUrl &params,
    QString &response, uint &status_code) const
{
    QHttp http;
    http.setHost(_ip_address);

    QByteArray request_params(params.encodedQuery());

    if (method == "GET")
    {
        QString path = script + "?" + QString(request_params);
        QHttpRequestHeader header(method, path);
        header.setValue("Host", _ip_address);
        http.request(header);
    }
    else
    {
        QHttpRequestHeader header(method, script);
        header.setValue("Host", _ip_address);
        header.setContentType("application/x-www-form-urlencoded");
        http.request(header, request_params);
    }

    while (http.hasPendingRequests() || http.currentId())
    {
        usleep(5000);
        qApp->processEvents();
    }

    if (http.error() != QHttp::NoError)
    {
        status_code = 0;
        response = http.errorString();
        return false;
    }

    QHttpResponseHeader resp_header = http.lastResponse();
    if (!resp_header.isValid())
    {
        status_code = 0;
        response = "Completed but response object was not valid";
        return false;
    }

    status_code = resp_header.statusCode();
    response = QString(http.readAll());
    return true;
}
Exemplo n.º 2
0
// do a multi-range on selected ranges
MultirangeResult HttpIOVecOps::performMultirange(IOChainContext & iocontext,
                                                 const IntervalTree<ElemChunk> &tree,
                                                 const SortedRanges & ranges) {

    DavixError * tmp_err=NULL;
    dav_ssize_t tmp_ret=-1, ret = 0;
    ptrdiff_t p_diff=0;
    dav_size_t counter = 0;
    MultirangeResult::OperationResult opresult = MultirangeResult::SUCCESS;

    // calculate total bytes to be read (approximate, since ranges could overlap)
    dav_ssize_t bytes_to_read = 0;
    for(dav_size_t i = 0; i < ranges.size(); i++) {
        bytes_to_read += (ranges[i].second - ranges[i].first + 1);
    }

    std::function<int (dav_off_t &, dav_off_t &)> offsetProvider = std::bind(&davIOVecProvider, ranges, std::ref(counter), std::placeholders::_1, std::placeholders::_2);

    // header line need to be inferior to 8K on Apache2 / ngnix
    // in Addition, some S3 implementation limit the total header size to 4k....
    // 3900 bytes maximum for the range seems to be a ood compromise
    std::vector< std::pair<dav_size_t, std::string> > vecRanges = generateRangeHeaders(3900, offsetProvider);

    DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> getPartialVec operation for {} vectors", ranges.size());

    for(std::vector< std::pair<dav_size_t, std::string> >::iterator it = vecRanges.begin(); it < vecRanges.end(); ++it){
        DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> getPartialVec request for {} chunks", it->first);

        if(it->first == 1){ // one chunk only : no need of multi part
            ret += singleRangeRequest(iocontext, tree, ranges[p_diff].first, ranges[p_diff].second - ranges[p_diff].first + 1);
            p_diff += 1;
        }else{
            GetRequest req (iocontext._context, iocontext._uri, &tmp_err);
            if(tmp_err == NULL){
                RequestParams request_params(iocontext._reqparams);
                req.setParameters(request_params);
                req.addHeaderField(req_header_byte_range, it->second);

                if( req.beginRequest(&tmp_err) == 0){
                    const int retcode = req.getRequestCode();

                    // looks like the server supports multi-range requests.. yay
                    if(retcode == 206) {
                        ret = parseMultipartRequest(req, tree, &tmp_err);

                        // could not parse multipart response - server's broken?
                        // known to happen with ceph - return code is 206, but only
                        // returns the first range
                        if(ret == -1) {
                            opresult = MultirangeResult::NOMULTIRANGE;
                            req.endRequest(&tmp_err);
                            break;
                        }
                    }
                    // no multi-range.. bad server, bad
                    else if(retcode == 200) {
                        DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Multi-range request resulted in getting the whole file.");
                        // we have two options: read the entire file or abort current
                        // request and start a multi-range simulation

                        // if this is a huge file, reading the entire contents is
                        // definitely not an option
                        if(req.getAnswerSize() > 1000000 && req.getAnswerSize() > 2*bytes_to_read) {
                            DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "File is too large; will not waste bandwidth, bailing out");
                            opresult = MultirangeResult::NOMULTIRANGE;
                            req.endRequest(&tmp_err);
                        }
                        else {
                            DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Simulating multi-part response from the contents of the entire file");
                            opresult = MultirangeResult::SUCCESS_BUT_NO_MULTIRANGE;
                            ret = simulateMultiPartRequest(req, tree, &tmp_err);
                        }
                        break;
                    }
                    else if(retcode == 416) {
                      ret = 0;
                      DavixError::clearError(&tmp_err);
                    }
                    else {
                        httpcodeToDavixError(req.getRequestCode(),davix_scope_http_request(),", ", &tmp_err);
                        ret = -1;
                        break;
                    }

                    p_diff += it->first;
                    ret += tmp_ret;
                } else {
                   ret = -1;
                   break;
                }
            }
        }
    }

    DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " <- getPartialVec operation for {} vectors", ranges.size());
    checkDavixError(&tmp_err);
    return MultirangeResult(opresult, ret);
}