Page 1 of 2
Read response data. response.GetHeaderMap doesnt help.
Posted: Wed Jan 24, 2018 8:15 pm
by michal@dorfin.waw.pl
I know that this topic was reported some time ago. It ewas not solved. You suggested then to use response.GetHeaderMap.
I tried to read HeaderMap in two events : onResourceResponse and onResourceLoadComplete.
Unfortunatelly response.GetHeaderMap gives only the header data not the body.
Do we have any possibility to read actual response ?
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Wed Jan 24, 2018 8:35 pm
by salvadordf
Maybe this could be a solution but I've never used it.
I found this old CEF3 issue :
https://bitbucket.org/chromiumembedded/cef/issues/515
It seems that you can use a filter to get the raw response.
In CEF4Delphi you can set this filter in the TChromium.OnGetResourceResponseFilter event. There you set the "Result" parameter with a TCefResponseFilterOwn you created previously.
These are the original code comments for TCefResponseFilterOwn :
Code: Select all
///
// Initialize the response filter. Will only be called a single time. The
// filter will not be installed if this function returns false (0).
///
int(CEF_CALLBACK* init_filter)(struct _cef_response_filter_t* self);
///
// Called to filter a chunk of data. Expected usage is as follows:
//
// A. Read input data from |data_in| and set |data_in_read| to the number of
// bytes that were read up to a maximum of |data_in_size|. |data_in| will
// be NULL if |data_in_size| is zero.
// B. Write filtered output data to |data_out| and set |data_out_written| to
// the number of bytes that were written up to a maximum of
// |data_out_size|. If no output data was written then all data must be
// read from |data_in| (user must set |data_in_read| = |data_in_size|).
// C. Return RESPONSE_FILTER_DONE if all output data was written or
// RESPONSE_FILTER_NEED_MORE_DATA if output data is still pending.
//
// This function will be called repeatedly until the input buffer has been
// fully read (user sets |data_in_read| = |data_in_size|) and there is no more
// input data to filter (the resource response is complete). This function may
// then be called an additional time with an NULL input buffer if the user
// filled the output buffer (set |data_out_written| = |data_out_size|) and
// returned RESPONSE_FILTER_NEED_MORE_DATA to indicate that output data is
// still pending.
//
// Calls to this function will stop when one of the following conditions is
// met:
//
// A. There is no more input data to filter (the resource response is
// complete) and the user sets |data_out_written| = 0 or returns
// RESPONSE_FILTER_DONE to indicate that all data has been written, or;
// B. The user returns RESPONSE_FILTER_ERROR to indicate an error.
//
// Do not keep a reference to the buffers passed to this function.
///
cef_response_filter_status_t(CEF_CALLBACK* filter)(
struct _cef_response_filter_t* self,
void* data_in,
size_t data_in_size,
size_t* data_in_read,
void* data_out,
size_t data_out_size,
size_t* data_out_written);
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Wed Jan 24, 2018 9:54 pm
by michal@dorfin.waw.pl
Thank you for Your support. This is working perfect. I'm very grateful for Your help!
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Wed Jan 31, 2018 2:29 pm
by mike2k
michal@dorfin.waw.pl wrote: Wed Jan 24, 2018 9:54 pm
Thank you for Your support. This is working perfect. I'm very grateful for Your help!
Could you please share the solution you found to get the response data.
Thanks!
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Thu Feb 01, 2018 10:56 pm
by mike2k
Based on this sample in .NET:
https://github.com/cefsharp/CefSharp/bl ... eFilter.cs
I've tried to get first a passthru responder and after to get the response data from datain, but I'm stuck

Maybe, you guys can give a hand on this.
Thanks!
Code: Select all
type
TCefResponseFilter = class(TCefResponseFilterOwn)
protected
function InitFilter: Boolean; override;
function Filter(dataIn: Pointer; dataInSize, dataInRead: NativeUInt; dataOut: Pointer;
dataOutSize, dataOutWritten: NativeUInt): TCefResponseFilterStatus; override;
public
constructor Create;
end;
constructor TCefResponseFilter.Create;
begin
inherited Create;
end;
function TCefResponseFilter.InitFilter: Boolean;
begin
result:=true;
end;
function TCefResponseFilter.Filter(dataIn: Pointer; dataInSize, dataInRead: NativeUInt; dataOut: Pointer;
dataOutSize, dataOutWritten: NativeUInt): TCefResponseFilterStatus;
var test:ansistring;
begin
if(dataIn = nil)then
begin
dataInRead := 0;
dataOutWritten := 0;
result:=RESPONSE_FILTER_DONE;
exit;
end;
// I'm stuck here....
// dataInRead = dataIn.Length;
// dataOutWritten = Math.Min(dataInRead, dataOut.Length);
// dataIn.CopyTo(dataOut);
result:=RESPONSE_FILTER_DONE;
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure Form1.OnGetResourceResponseFilter(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame;
const request: ICefRequest; const response: ICefResponse; out Result: ICefResponseFilter);
begin
result:=TCefResponseFilter.Create;
end;
Here are more filter samples:
https://github.com/cefsharp/CefSharp/tr ... le/Filters
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Fri Feb 02, 2018 8:05 am
by salvadordf
Hi,
Be careful with the class names.
TCefResponseFilter is already used in uCEFTypes and it might be interpreted differently by the compiler depending on the uses clause of each unit.
I'll try to add a demo about TCefResponseFilterOwn as soon as I can.
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Fri Feb 02, 2018 8:39 am
by mike2k
salvadordf,
Thanks, looking forward for your demos

Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Sat Feb 03, 2018 5:04 pm
by salvadordf
Hi,
The latest update includes a new
TCustomResponseFilter class and a new demo called
ResponseFilterBrowser.
The demo only "filters" one JS file from the wikipedia website and it shows the contents in a TMemo.
I couldn't get the HTTP headers, just the resource contents.

Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Sun Feb 04, 2018 12:07 am
by mike2k
Thanks!
I'm still using DCEF3 for WinXP support. I made your changes with the
VARs and it's working with it too

I get the response data, although sometimes in chunks. Any idea how to fix this?
Also, something I've noticed with DCEF3, if you can test it with CEF4DELPHI:
If I send all traffic through the filter (just plain passthrough filter, without any memorystream in it) sites, like YouTube fail to load properly.
Can you check if it happens in CEF4DELPHI too?
Thanks again!
Re: Read response data. response.GetHeaderMap doesnt help.
Posted: Sun Feb 04, 2018 10:53 am
by salvadordf
mike2k wrote: Sun Feb 04, 2018 12:07 am
I'm still using DCEF3 for WinXP support. I made your changes with the
VARs and it's working with it too

I get the response data, although sometimes in chunks. Any idea how to fix this?
I uploaded a new version of that demo with support for multiple chunks.
You should store all the chunks and set Result to RESPONSE_FILTER_NEED_MORE_DATA.
When there's no more data then data_in will be nil and you should set result to RESPONSE_FILTER_DONE.
mike2k wrote: Sun Feb 04, 2018 12:07 am
Also, something I've noticed with DCEF3, if you can test it with CEF4DELPHI:
If I send all traffic through the filter (just plain passthrough filter, without any memorystream in it) sites, like YouTube fail to load properly.
Can you check if it happens in CEF4DELPHI too?
Youtube.com doesn't even load if I try to filter everything.