magreenblatt wrote:Can you post example code that results in Cancel() being called?
Yes of course - i try to post my code.
(Use Qt programming library in project.)
First step.CefBrowserProcessHandler::OnContextInitialized() {
CefRegisterSchemeHandlerFactory(CefString("https"),CefString(""),new SerfiumCefSchemeHandlerFactory());
CefRegisterSchemeHandlerFactory(CefString("http"),CefString(""),new SerfiumCefSchemeHandlerFactory());}
//------------------
Second step.class SerfiumCefSchemeHandlerFactory : public CefSchemeHandlerFactory
...
CefRefPtr<CefResourceHandler> SerfiumCefSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& scheme_name,
CefRefPtr<CefRequest> request) {
// Return a new scheme handler instance to handle the request.
CEF_REQUIRE_IO_THREAD()
CefRefPtr<SerfiumSchemeHandler> result {nullptr}; if ((nullptr != browser) && (nullptr != frame)) {
result = new SerfiumSchemeHandler(request);
}
return result;}
//------------------
Third step.class SerfiumSchemeHandler : public CefResourceHandler {
...
virtual bool Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) OVERRIDE;
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl) OVERRIDE;
virtual void Cancel() OVERRIDE;
virtual bool Skip(int64 bytes_to_skip,
int64& bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback) OVERRIDE;
virtual bool Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) OVERRIDE;
protected:
CefRefPtr<CefRequest> mRequest;
CefRefPtr<SerfiumCefURLRequestClient> mUrlRequestClient = nullptr;
CefRefPtr<CefURLRequest> mUrlRequest = nullptr;
QSerfiumCefManager* mpSerfiumCefManager = nullptr;
int mRequestId;
QFile mOutputFile;
private:
IMPLEMENT_REFCOUNTING(SerfiumSchemeHandler);
DISALLOW_COPY_AND_ASSIGN(SerfiumSchemeHandler);
}
//------------------
bool SerfiumSchemeHandler::Open(CefRefPtr<CefRequest> request,
bool& handle_request,
CefRefPtr<CefCallback> callback) {
handle_request = true; 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++;
}
return true;}
//------------------
void SerfiumSchemeHandler::Cancel() {
CEF_REQUIRE_IO_THREAD()
}//------------------
bool SerfiumSchemeHandler::Skip(int64 bytes_to_skip,
int64 &bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback) {
CEF_REQUIRE_IO_THREAD()
bool result {true};
QByteArray amountOfData {mUrlRequestClient->cutDownloadedData(static_cast<int>(bytes_to_skip))};
bytes_skipped = amountOfData.count();
if (0 == bytes_skipped) {
mUrlRequestClient->delayDataSkipping(bytes_to_skip,bytes_skipped,callback);
}
return result;
}
//------------------
bool SerfiumSchemeHandler::Read(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefResourceReadCallback> callback) {
bool result {true}; QByteArray amountOfData {mUrlRequestClient->cutDownloadedData(bytes_to_read)};
if (amountOfData.count() > 0) {
std::memcpy(data_out,static_cast<void*>(amountOfData.data()),static_cast<std::size_t>(amountOfData.size()));
}
else if ((0 == amountOfData.count()) && (false == mUrlRequestClient->isRequestCompleted())) {
mUrlRequestClient->delayDataReceiving(data_out,bytes_to_read,bytes_read,callback);
}
else if ((0 == amountOfData.count()) && (true == mUrlRequestClient->isRequestCompleted())) {
result = false; }
bytes_read = amountOfData.count(); // 0 then request is completed.
return result;}
//------------------
void SerfiumSchemeHandler::GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl) {
CEF_REQUIRE_IO_THREAD()
response_length = -1;}
//------------------
Helper class for downloading data.
class SerfiumCefURLRequestClient : public CefURLRequestClient {
public:
SerfiumCefURLRequestClient();
~SerfiumCefURLRequestClient() OVERRIDE;
QByteArray getDownloadedData();
QByteArray cutDownloadedData(const int size);
int getDownloadedDataSize();
void delayDataReceiving(void *data_out,
int bytes_to_read,
int &bytes_read,
CefRefPtr<CefResourceReadCallback> callback);
void delayDataSkipping(int64 bytes_to_skip,
int64& bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback);
bool isRequestCompleted() const;
void setDebugFile(QFile *pDebugFile);
protected:
virtual void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE;
virtual void OnUploadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE;
void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE;
void OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) OVERRIDE;
bool GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) OVERRIDE;
protected:
QByteArray mData;
bool mbRequestComplete {false};
CefRefPtr<CefResourceReadCallback> mReceivingCallback;
bool mbDelayDataReceiving {false};
void *dataOut {nullptr};
int bytesToRead {0};
int bytesToSkip {0};
CefRefPtr<CefResourceSkipCallback> mSkippingCallback;
bool mbDelayDataSkipping {false};
QFile *mpDebugFile;
private:
IMPLEMENT_REFCOUNTING(SerfiumCefURLRequestClient);
};
//------------------
SerfiumCefURLRequestClient::SerfiumCefURLRequestClient() {
}
//------------------
SerfiumCefURLRequestClient::~SerfiumCefURLRequestClient() {
}
//------------------
QByteArray SerfiumCefURLRequestClient::getDownloadedData() {
return mData;
}
//------------------
QByteArray SerfiumCefURLRequestClient::cutDownloadedData(const int size) {
QByteArray result;
int lSize {size};
if (lSize > mData.size())
lSize = mData.size();
result = {mData.left(lSize)};
mData = mData.right(mData.size() - lSize);
return result;
}
//------------------
int SerfiumCefURLRequestClient::getDownloadedDataSize() {
return mData.size();
}
//------------------
void SerfiumCefURLRequestClient::delayDataReceiving(void *data_out,
int bytes_to_read,
int &bytes_read,
CefRefPtr<CefResourceReadCallback> callback) {
dataOut = data_out;
bytesToRead = bytes_to_read;
mReceivingCallback = callback;
mbDelayDataReceiving = true;
}
//------------------
void SerfiumCefURLRequestClient::delayDataSkipping(int64 bytes_to_skip,
int64& bytes_skipped,
CefRefPtr<CefResourceSkipCallback> callback) {
bytesToSkip = static_cast<int>(bytes_to_skip);
mbDelayDataSkipping = callback;
mbDelayDataSkipping = true;
}
//------------------
bool SerfiumCefURLRequestClient::isRequestCompleted() const {
return mbRequestComplete;
}
//------------------
void SerfiumCefURLRequestClient::setDebugFile(QFile *pDebugFile) {
mpDebugFile = pDebugFile;
}
//------------------
void SerfiumCefURLRequestClient::OnRequestComplete(CefRefPtr<CefURLRequest> request) {
CEF_REQUIRE_IO_THREAD()
mbRequestComplete = true;
}
//------------------
void SerfiumCefURLRequestClient::OnUploadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) {
CEF_REQUIRE_IO_THREAD()
}
//------------------
void SerfiumCefURLRequestClient::OnDownloadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) {
CEF_REQUIRE_IO_THREAD()
}
//------------------
void SerfiumCefURLRequestClient::OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) {
CEF_REQUIRE_IO_THREAD()
int ldata_length {static_cast<int>(data_length)}; // Копия переменной для удобства локального использования.
if (data_length > 0) {
mData.append(static_cast<const char*>(data),static_cast<int>(data_length));
}
if (true == mbDelayDataReceiving) {
if (mData.size() >= bytesToRead) {
std::memcpy(dataOut,mData.data(),static_cast<size_t>(bytesToRead));
mpDebugFile->write(static_cast<char*>(dataOut),bytesToRead);
mData.remove(0,bytesToRead);
mReceivingCallback->Continue(bytesToRead);
bytesToRead = 0;
mbDelayDataReceiving = false;
}
}
else if (true == mbDelayDataSkipping) {
if (mData.size() >= bytesToSkip) {
mData.remove(0,bytesToSkip);
mSkippingCallback->Continue(bytesToSkip);
bytesToSkip = 0;
mbDelayDataSkipping = false;
}
}
}
//------------------
bool SerfiumCefURLRequestClient::GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) {
CEF_REQUIRE_IO_THREAD()
if (true == isProxy) {
return true;
}
}
//------------------