CefSharp - заменить поток ответа - PullRequest
0 голосов
/ 05 мая 2020

Привет, сообщество StackOverflow

В настоящее время я работаю с CefSharp v79.1.36 (https://github.com/cefsharp/CefSharp) и пытаюсь заменить файл fla sh модифицированной версией этого.

Пока я использую ResponseFilter (как показано здесь https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/Handlers/ExampleResourceRequestHandler.cs), и он захватывает поток файла fla sh.


Проблема в том, что поток захватывается фрагментами, а не одним большим потоком. Я могу получить весь поток, переопределив метод OnResourceLoadComplete, но я не могу изменить ответ в этом методе. И мне нужен весь поток, прежде чем изменять его.

Кто-нибудь знает, есть ли способ изменить поток ответов после получения всего потока?


Вот мой код:

Установить обработчик пользовательских запросов браузера

RequestHandler requestHandler = new CustomBasicRequestHandler();
browser.RequestHandler = requestHandler;

CustomBasicRequestHandler

public class CustomBasicRequestHandler : RequestHandler
{
    protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
    {
        if (request.Url.Contains("MyFlashFile.swf"))
        {
            return new ExampleResourceRequestHandler();
        }

        //Default behaviour, url will be loaded normally.
        return null;
    }
}

ExampleResourceRequestHandler

public class ExampleResourceRequestHandler : ResourceRequestHandler
{
    private MemoryStream memoryStream;

    protected override bool OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
    {
        //NOTE: You cannot modify the response, only the request
        // You can now access the headers
        //var headers = response.Headers;

        return false;
    }

    protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
    {
        if (response.MimeType == "application/x-shockwave-flash")
        {
            return new StreamResponseFilter(memoryStream);
        }

        return null;
    }

    protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
    {
        var data = memoryStream.ToArray();
        var dataLength = data.Length;
        // Got the whole Stream here, but cannot modify the response!
    }
}

StreamResponseFilter

public class StreamResponseFilter : IResponseFilter
{
    private Stream responseStream;

    /// <summary>
    /// StreamResponseFilter constructor
    /// </summary>
    /// <param name="stream">a writable stream</param>
    public StreamResponseFilter(Stream stream)
    {
        responseStream = stream;
    }

    bool IResponseFilter.InitFilter()
    {
        return responseStream != null && responseStream.CanWrite;
    }

    FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
    {
        if (dataIn == null)
        {
            dataInRead = 0;
            dataOutWritten = 0;

            return FilterStatus.Done;
        }

        //Calculate how much data we can read, in some instances dataIn.Length is
        //greater than dataOut.Length
        dataInRead = Math.Min(dataIn.Length, dataOut.Length);
        dataOutWritten = dataInRead;

        var readBytes = new byte[dataInRead];
        dataIn.Read(readBytes, 0, readBytes.Length);
        dataOut.Write(readBytes, 0, readBytes.Length);

        //Write buffer to the memory stream
        responseStream.Write(readBytes, 0, readBytes.Length);

        //If we read less than the total amount avaliable then we need
        //return FilterStatus.NeedMoreData so we can then write the rest
        if (dataInRead < dataIn.Length)
        {
            return FilterStatus.NeedMoreData;
        }

        return FilterStatus.Done;
    }

    void IDisposable.Dispose()
    {
        responseStream = null;
    }
}

Большое спасибо за любую помощь :) 1034 *

...