Proper use of the classes CefURLRequest, CefURLRequestClient

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Proper use of the classes CefURLRequest, CefURLRequestClient

Postby senya » Thu Sep 19, 2019 2:38 pm

Greetings.
Please tell me where it is best to look for an example of the correct use of the classes CefURLRequest, CefURLRequestClient, CefResourceHandler and CefSchemeHandlerFactory.
I need this to solve the problem of managing the request header.
I sometimes get errors when managing requests - I can’t figure out why.

Errors that occur.
[0919 / 172819.917322: FATAL: url_fetcher_core.cc (587)] Check failed: is_chunked_upload_ || upload_content_set_.
[0919 / 164753.093795: FATAL: resource_request_job.cc (223)] Check failed: dest_size! = 0 (0 vs. 0)
Sergey, developer from Moscow region.
It's hot here today
https://docs.zoho.eu/file/40henad156481 ... 29fb3a8ebe
senya
Mentor
 
Posts: 54
Joined: Mon Sep 18, 2017 2:58 pm

Re: Proper use of the classes CefURLRequest, CefURLRequestCl

Postby senya » Fri Sep 20, 2019 9:36 am

I will try to describe how I use the above classes.

1) In a class derived from CefApp.

Code: Select all
void SerfiumCefApp::OnRegisterCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) {
    // Register the custom scheme as standard and secure.
    // Must be the same implementation in all processes.
    bool addSchemeResult {registrar->AddCustomScheme(CefString("http"),true,false,false,true,false,false)};
    addSchemeResult = registrar->AddCustomScheme(CefString("https"),true,false,false,true,false,false);
}

void SerfiumCefApp::OnContextInitialized() {
    CEF_REQUIRE_UI_THREAD();
    // SimpleHandler implements browser-level callbacks.
    bool registerResult {CefRegisterSchemeHandlerFactory(CefString("https"),CefString(""),new SerfiumCefSchemeHandlerFactory())};
    registerResult = CefRegisterSchemeHandlerFactory(CefString("http"),CefString(""),new SerfiumCefSchemeHandlerFactory());
}
//------------------


2) Custom class derived from CefSchemeHandlerFactory.

Code: Select all
// Implementation of the factory for creating scheme handlers.
class SerfiumCefSchemeHandlerFactory : public CefSchemeHandlerFactory {
public:
    SerfiumCefSchemeHandlerFactory() {}
    ~SerfiumCefSchemeHandlerFactory() OVERRIDE {}

protected:
    // Return a new scheme handler instance to handle the request.
    CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
                                         CefRefPtr<CefFrame> frame,
                                         const CefString& scheme_name,
                                         CefRefPtr<CefRequest> request) OVERRIDE;
private:
    IMPLEMENT_REFCOUNTING(SerfiumCefSchemeHandlerFactory);
    DISALLOW_COPY_AND_ASSIGN(SerfiumCefSchemeHandlerFactory);
};
//------------------

CefRefPtr<CefResourceHandler> SerfiumCefSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser,
                                                                     CefRefPtr<CefFrame> frame,
                                                                     const CefString& scheme_name,
                                                                     CefRefPtr<CefRequest> request) {
    CEF_REQUIRE_IO_THREAD();
    CefRefPtr<SerfiumSchemeHandler> result {nullptr};

    if ((nullptr != browser) && (nullptr != frame)) {
        result = new SerfiumSchemeHandler();
    }
   
    return result;
}
//------------------


3) Custom class derived from CefResourceHandler.

Code: Select all
// Implementation of the scheme handler for ... requests.
class SerfiumSchemeHandler : public CefResourceHandler {
public:
    SerfiumSchemeHandler();
    ~SerfiumSchemeHandler() OVERRIDE {}

protected:
    bool ProcessRequest(CefRefPtr<CefRequest> request,
                        CefRefPtr<CefCallback> callback) OVERRIDE;

    void Cancel() OVERRIDE { CEF_REQUIRE_IO_THREAD();}

    void GetResponseHeaders(CefRefPtr<CefResponse> response,
                            int64& response_length,
                            CefString& redirectUrl) OVERRIDE;

    bool ReadResponse(void* data_out,
                      int bytes_to_read,
                      int& bytes_read,
                      CefRefPtr<CefCallback> callback) OVERRIDE;

    virtual bool CanGetCookie(const CefCookie& cookie) OVERRIDE {}
    virtual bool CanSetCookie(const CefCookie& cookie) OVERRIDE {}

protected:
    CefRefPtr<SerfiumCefURLRequestClient> mUrlRequestClient = nullptr;
    CefRefPtr<CefURLRequest> mUrlRequest = nullptr;
    QSerfiumCefManager* mpSerfiumCefManager = nullptr; // Custom element for cef managment.

private:
    IMPLEMENT_REFCOUNTING(SerfiumSchemeHandler);
    DISALLOW_COPY_AND_ASSIGN(SerfiumSchemeHandler);
};
//------------------

SerfiumSchemeHandler::SerfiumSchemeHandler() {
    CEF_REQUIRE_IO_THREAD();
    mpSerfiumCefManager = QSerfiumCefManager::getInstance();
    if (nullptr == mpSerfiumCefManager) {
        qCritical() << SerfiumCefMisc::errors::pointerIsNull();
    }
}
//------------------

bool SerfiumSchemeHandler::ProcessRequest(CefRefPtr<CefRequest> request,
                                          CefRefPtr<CefCallback> callback) {
    CEF_REQUIRE_IO_THREAD();

    CefRequest::HeaderMap vHeaderMap;
    request->GetHeaderMap(vHeaderMap);
    CefRequest::HeaderMap::iterator i = vHeaderMap.begin();
    int c {0};
    while (i != vHeaderMap.end())
    {
        if (0 == SerfiumCefMisc::utils::cefStringToQString(i->first).compare("User-Agent",Qt::CaseInsensitive)) {
        }
        i++;
    }
    // cefStringToQString - get QString type becayse use Qt library here.
    if (0 == SerfiumCefMisc::utils::cefStringToQString(request->GetMethod()).compare("POST",Qt::CaseInsensitive)) {
        CefRefPtr<CefPostData> postData {request->GetPostData()};
        if (nullptr != postData) {
            int elementsCount {static_cast<int>(postData->GetElementCount())};
            std::vector<CefRefPtr<CefPostDataElement>> postElements;
            postData->GetElements(postElements);
            for (int i = 0; i < elementsCount; i++) {
            }
            if (0 == elementsCount) {
                CefRefPtr<CefPostDataElement> postDataElement {CefPostDataElement::Create()};
                postDataElement->SetToEmpty();
                postData->AddElement(postDataElement);
            }
        }
        else {
        }
    }
    else if (0 == SerfiumCefMisc::utils::cefStringToQString(request->GetMethod()).compare("GET",Qt::CaseInsensitive)) {
    }
   // Get global cef request context.
    CefRefPtr<CefRequestContext> requestContext {mpSerfiumCefManager->getSavedGlobalRequestContext()};
    mUrlRequestClient = new SerfiumCefURLRequestClient(callback);
    mUrlRequest = CefURLRequest::Create(request,mUrlRequestClient,requestContext);
    if (nullptr != mUrlRequest) {
    }
    else {
    }

    return true;
}
//------------------

void SerfiumSchemeHandler::GetResponseHeaders(CefRefPtr<CefResponse> response,
                                              int64& response_length,
                                              CefString& redirectUrl) {
    CEF_REQUIRE_IO_THREAD();

    if (CefURLRequest::Status::UR_SUCCESS != mUrlRequest->GetRequestStatus()) {
    }
    if (CefURLRequest::ErrorCode::ERR_NONE != mUrlRequest->GetRequestError()) {
    }
    response_length = mUrlRequestClient->getDownloadedDataSize();
}
//------------------

bool SerfiumSchemeHandler::ReadResponse(void* data_out,
                                        int bytes_to_read,
                                        int& bytes_read,
                                        CefRefPtr<CefCallback> callback) {
    CEF_REQUIRE_IO_THREAD();
    QByteArray amountOfData {mUrlRequestClient->cutDownloadedData(bytes_to_read)};
    std::memcpy(data_out,static_cast<void*>(amountOfData.data()),static_cast<std::size_t>(amountOfData.size()));
    bytes_read = amountOfData.size();

    callback->Continue();

    return true;
}
//------------------
Sergey, developer from Moscow region.
It's hot here today
https://docs.zoho.eu/file/40henad156481 ... 29fb3a8ebe
senya
Mentor
 
Posts: 54
Joined: Mon Sep 18, 2017 2:58 pm

Re: Proper use of the classes CefURLRequest, CefURLRequestCl

Postby senya » Fri Sep 20, 2019 9:49 am

When loading the Google homepage - https://google.com, I get an error stably
FATAL: url_fetcher_core.cc (587)] Check failed: is_chunked_upload_ || upload_content_set_.

I would be grateful if you tell me what I'm doing wrong.
Sergey, developer from Moscow region.
It's hot here today
https://docs.zoho.eu/file/40henad156481 ... 29fb3a8ebe
senya
Mentor
 
Posts: 54
Joined: Mon Sep 18, 2017 2:58 pm

Re: Proper use of the classes CefURLRequest, CefURLRequestCl

Postby Czarek » Fri Sep 20, 2019 10:05 am

Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Proper use of the classes CefURLRequest, CefURLRequestCl

Postby senya » Fri Sep 20, 2019 1:08 pm

Apparently I need to carefully read the documentation for the corresponding API again.
Sergey, developer from Moscow region.
It's hot here today
https://docs.zoho.eu/file/40henad156481 ... 29fb3a8ebe
senya
Mentor
 
Posts: 54
Joined: Mon Sep 18, 2017 2:58 pm


Return to Support Forum

Who is online

Users browsing this forum: finder2 and 87 guests