Continuing to deal with API of managed requests

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.

Continuing to deal with API of managed requests

Postby senya » Sun Nov 03, 2019 1:54 pm

Hello to forum users and admins.
Updated the version of chromium:
CEF Version: 77.1.14+g4fb61d2+chromium-77.0.3865.120
Chromium Version: 77.0.3865.120

I try to further deal with managed requests.
I see that CefResourceHandler class methods (Open,GetResponseHeaders,Read) are launched from an unknown thread.
i.e. from thread that is not of types: TID_UI,TID_IO,TID_RENDERER,TID_FILE,TID_FILE_USER_VISIBLE,TID_FILE_USER_BLOCKING,TID_PROCESS_LAUNCHER.

So it should be, or is something somewhere wrong?

Thank you.
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: Continuing to deal with API of managed requests

Postby senya » Mon Nov 04, 2019 10:28 am

// Class used to implement a custom request handler interface. The methods of
// this class will be called on the IO thread unless otherwise indicated.
///
/*--cef(source=client)--*/
class CefResourceHandler : public virtual CefBaseRefCounted

Comment on the class methods.
//This method will be called in
//sequence but not from a dedicated thread.

Methods of CefResourceHandler class execute in unknown thread. It seems that somehow I am not using class objects right or it should be so in the new version of the API.
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: Continuing to deal with API of managed requests

Postby senya » Mon Nov 04, 2019 10:38 am

Methods of other classes that I use to manage requests:
CefSchemeHandlerFactory and CefURLRequestClient executes in the IO thread (TID_IO).
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: Continuing to deal with API of managed requests

Postby magreenblatt » Mon Nov 04, 2019 10:53 am

What problem are you having?
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: Continuing to deal with API of managed requests

Postby senya » Mon Nov 04, 2019 12:18 pm

magreenblatt wrote:What problem are you having?


I am trying to make all standard requests (https,http) manageable with classes CefSchemeHandlerFactory,CefResourceHandler,CefURLRequestClient.
Got that class methods derived from CefResourceHandler run from an unknown thread. Although the methods of classes derived from the other two are launched from the IO thread (TID_IO).
In this case, I must make inter-thread messages for such circumstances.
UPD: inter-thread messages for data exchange.
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: Continuing to deal with API of managed requests

Postby senya » Thu Nov 07, 2019 7:25 am

My mistake was at the C ++ language level - misusing a variable reference.
Everything seems to be fine with the new API methods of managed requests.
CefResourceHandler::Open, CefResourceHandler::Read, CefResourceHandler::Skip.
Sorry.
I continue to solve the problem of managed requests in my application ...

P.S. I am writing so messy on the forum, because here in Russia where I work a really unhealthy environment. This state is returning to the terrorist dictatorship, here I work in alienation as a freelancer, I feel fear and stress. I don’t know what can await me here if I don’t cope - a concentration camp or a psycho-insulator.
Sotnik-TV Live - Welcome to PutLag Camp
https://youtu.be/j6lfxQaMMDg
(file of video: https://mega.nz/#!diYnBQBY!E2j5qeyjjKAy ... NlB5UGjz_8)

Sotnik-TV Live - PICK UP THE PACE, MAN-EATER!
https://youtu.be/eTpo0ovogcA
(file of video: https://mega.nz/#!43pXAYxJ!YQV9oJnseKyr ... 4g-TMP0CSw)

UPD: Evaluating the current situation
https://docs.zoho.eu/file/40henad156481 ... 29fb3a8ebe
Last edited by senya on Fri Nov 15, 2019 7:15 am, edited 1 time in total.
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: Continuing to deal with API of managed requests

Postby senya » Wed Nov 13, 2019 8:26 am

After the managed request is completed, for some reason the CefResourceHandler::Cancel method is called in my application.
I seem to do everything "according to the instructions", I took the code from the cefclient (cefclient/browser) example as an example.
When the data download is completed, I return the false in the method CefResourceHandler::Read(void* data_out,int bytes_to_read,int& bytes_read,CefRefPtr<CefResourceReadCallback> callback) and set bytes_read parameter value to 0. But instead of the web page being displayed in the browser tab, execution of request is canceled for some reason - CefResourceHandler::Cancel exec.
UPD: I checked the data of the downloaded web page on request - everything is fine this is a whole web page (I use the Google homepage for the test - https://google.com).
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: Continuing to deal with API of managed requests

Postby magreenblatt » Wed Nov 13, 2019 12:00 pm

Can you post example code that results in Cancel() being called?
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: Continuing to deal with API of managed requests

Postby senya » Wed Nov 13, 2019 2:36 pm

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;
}
}
//------------------
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: Continuing to deal with API of managed requests

Postby magreenblatt » Wed Nov 13, 2019 2:56 pm

I don't see anything obviously wrong in your code. Can you provide an example that runs in cefclient or cefsimple and reproduces the problem?
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 17 guests