I am trying to use CefSharp to visit a URL and capture specific resources retrieved during the loading of a given page. Presumably as a Stream or byte array per resource.
CefSharp provides the interface IRequestHandler. You can create a class which implements this interface to respond to Request/Response events, but it does not contain the response body in any way.
Take a look at GetResourceResponseFilter
in your implementation of IRequestHandler
. GetResourceResponseFilter
returns an IResponseFilter
, which provides you with an opportunity to capture all responses. You'll need to implement your own IResponseFilter
, thankfully there are ample examples.
Example IResponseFilter
implementation taken from the CefSharp
GitHub project.
public class MemoryStreamResponseFilter : IResponseFilter
{
private MemoryStream memoryStream;
bool IResponseFilter.InitFilter()
{
//NOTE: We could initialize this earlier, just one possible use of InitFilter
memoryStream = new MemoryStream();
return true;
}
FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
{
if (dataIn == null)
{
dataInRead = 0;
dataOutWritten = 0;
return FilterStatus.Done;
}
dataInRead = dataIn.Length;
dataOutWritten = Math.Min(dataInRead, dataOut.Length);
//Important we copy dataIn to dataOut
dataIn.CopyTo(dataOut);
//Copy data to stream
dataIn.Position = 0;
dataIn.CopyTo(memoryStream);
return FilterStatus.Done;
}
void IDisposable.Dispose()
{
memoryStream.Dispose();
memoryStream = null;
}
public byte[] Data
{
get { return memoryStream.ToArray(); }
}
}
Now in your GetResourceResponseFilter
method:
private Dictionary<ulong, MemoryStreamResponseFilter> responseDictionary = new Dictionary<ulong, MemoryStreamResponseFilter>();
public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
var dataFilter = new MemoryStreamResponseFilter();
responseDictionary.Add(request.Identifier, dataFilter);
return dataFilter;
}
Then in OnResourceLoadComplete
:
public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
{
MemoryStreamResponseFilter filter;
if (responseDictionary.TryGetValue(request.Identifier, out filter))
{
var data = filter.Data; //This returns a byte[]
//File.WriteAllBytes("c:/save/path", data);
}
}
You can use the properties within the IRequest
and IResponse
parameters to decide what you want to filter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With