Как правильно декодировать поток ответов в ServiceStack ProxyFeature? - PullRequest
2 голосов
/ 29 апреля 2019

Я пытаюсь заменить URL в теле ответа в ProxyFeature, но получаю закодированное тело.

Вот код:

Plugins.Add(new ProxyFeature(
          matchingRequests: req =>
          {
            return req.PathInfo.StartsWith("/proxy");
          },
          resolveUrl: (req) =>
          {
            string var = req.RawUrl.Replace("/proxy/", "");
            return var;
          })
      {
        IgnoreResponseHeaders = {
                    "X-Frame-Options"
                },
        TransformResponse = async (res, responseStream) =>
        {          
          using (var reader = new StreamReader(responseStream,Encoding.UTF8))
          {
            var responseBody = await reader.ReadToEndAsync();
            Console.WriteLine(responseBody);
            var replacedBody = responseBody.Replace("http://","/proxy/http://");
            replacedBody = replacedBody.Replace("https://", "/proxy/https://");

            return MemoryStreamFactory.GetStream(replacedBody.ToUtf8Bytes());
          }
        }

Я не уверен, что делаю неправильно, поскольку это более или менее копия примера кода на веб-сайте с небольшими изменениями.

Результат должен быть любым, и все URL в теле должны начинаться с «/ proxy /», и это должно применяться к любому URL, на который пользователь переходит.

Хорошо бы отметить, что это работает достаточно хорошо, если я уберу часть «TransformResponse».

Любые идеи относительно того, что я здесь делаю неправильно.

Спасибо.

Обновление:

Часть возвращаемого содержимого. В этом случае указана ссылка "https://www.theverge.com".

?p?}^??d????i+s4?~?<???$?x]??????j??u?,?z?md?F6??G??{???g;?tU??q???????08;???vφ????N?? k???d8??l??GA?x???p?";?f??yk2?R?r2??
fA?z?7Q?Y}??2?v????p<|dù?s???q????t?M?^0_???o?/??V???z?S?5??r-s?N?U?j?:??1Bo?Z?>?-?
??u??{{*v????Q?g??s4??       ;?$;?Q???A0??YFo/{:;6??{?q/;?????????G????s??.??g?E?????w??'wL{?Lw0?-¬?????~????p?u??TC?X??J?j??lW??Z??(???z?u?u????a?W???~?R?t{?J?Q??f?^?6k?R?X????]^M?3??_g?????Y? *????l?xp?sT
~??9?L??4D{1q3V??r??;?'9He(??FeCTP[??/???T?{??j%??h?????@?f?e??k???p?R?&?VM????n<R?+???wR???      ????p?pyo#y??a??7L?????7VL??6n#0o,m?q????????J??#?+-Io??pr#n|????|qU?7?:??mVT?y?M??Mf ??"?=?B??u??F?X/4??f?^,?^?t????N???????fk??T!??y{?SG???a??'???#EWz?O???{???????po~?V]?Vo????Y?σ??@??2QTg??4??n????4?=???P5j!?j????}?7?M'??[??A?/[=?Q??O???     ~-^???,?/f??U?????p???A:??????M.`?.R??????8??]+???T??|o?0????????GD?_0???'{??~x?3?tM??Xe{???T0, f8!?w?j?m=??3??f?????[q?????}??a???r?????l??d[)?????p?w

1 Ответ

0 голосов
/ 30 апреля 2019

Искаженный вывод, потому что возвращаемый ответ ниже по потоку сжимается, но вы пытаетесь прочитать его непосредственно как строку.

Если прокси-ответ сжат, вам нужно его распаковать, выполнить любые преобразования строк, а затем сжать его обратно, например:

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/proxy"),
    resolveUrl: req => req.RawUrl.Replace("/proxy/", ""))
{
    IgnoreResponseHeaders = { "X-Frame-Options" },
    TransformResponse = async (res, responseStream) => {
        var enc = res.GetHeader(HttpHeaders.ContentEncoding);
        var useStream = responseStream;
        if (enc != null)
            useStream = responseStream.Decompress(enc);

        using (var reader = new StreamReader(useStream,Encoding.UTF8))
        {
            var responseBody = await reader.ReadToEndAsync();
            var replacedBody = responseBody.Replace("http://","/proxy/http://");
            replacedBody = replacedBody.Replace("https://", "/proxy/https://");

            var bytes = replacedBody.ToUtf8Bytes();
            return new MemoryStream(enc != null ? bytes.CompressBytes(enc) : bytes);
        }
    }
});
...