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;
}
//------------------