Commit 973c6219 authored by Honfika's avatar Honfika

remove chunk encoding and compress as a stream (inside readbodyasync), so...

remove chunk encoding and compress as a stream (inside readbodyasync), so later it can be made public
parent 6e209022
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
...@@ -102,6 +103,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -102,6 +103,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
proxyServer.BeforeRequest += ProxyServer_BeforeRequest; proxyServer.BeforeRequest += ProxyServer_BeforeRequest;
proxyServer.BeforeResponse += ProxyServer_BeforeResponse; proxyServer.BeforeResponse += ProxyServer_BeforeResponse;
proxyServer.AfterResponse += ProxyServer_AfterResponse;
explicitEndPoint.BeforeTunnelConnectRequest += ProxyServer_BeforeTunnelConnectRequest; explicitEndPoint.BeforeTunnelConnectRequest += ProxyServer_BeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse += ProxyServer_BeforeTunnelConnectResponse; explicitEndPoint.BeforeTunnelConnectResponse += ProxyServer_BeforeTunnelConnectResponse;
proxyServer.ClientConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ClientConnectionCount = proxyServer.ClientConnectionCount; }); }; proxyServer.ClientConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ClientConnectionCount = proxyServer.ClientConnectionCount; }); };
...@@ -179,6 +181,17 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -179,6 +181,17 @@ namespace Titanium.Web.Proxy.Examples.Wpf
} }
} }
private async Task ProxyServer_AfterResponse(object sender, SessionEventArgs e)
{
await Dispatcher.InvokeAsync(() =>
{
if (sessionDictionary.TryGetValue(e.WebSession, out var item))
{
item.Exception = e.Exception;
}
});
}
private SessionListItem AddSession(SessionEventArgs e) private SessionListItem AddSession(SessionEventArgs e)
{ {
var item = CreateSessionListItem(e); var item = CreateSessionListItem(e);
...@@ -255,9 +268,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -255,9 +268,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
} }
//string hexStr = string.Join(" ", data.Select(x => x.ToString("X2"))); //string hexStr = string.Join(" ", data.Select(x => x.ToString("X2")));
TextBoxRequest.Text = request.HeaderText + request.Encoding.GetString(data) + var sb = new StringBuilder();
(truncated ? Environment.NewLine + $"Data is truncated after {truncateLimit} bytes" : null) + sb.Append(request.HeaderText);
(request as ConnectRequest)?.ClientHelloInfo; sb.Append(request.Encoding.GetString(data));
sb.Append(truncated ? Environment.NewLine + $"Data is truncated after {truncateLimit} bytes" : null);
sb.Append((request as ConnectRequest)?.ClientHelloInfo);
TextBoxRequest.Text = sb.ToString();
var response = session.Response; var response = session.Response;
data = (response.IsBodyRead ? response.Body : null) ?? new byte[0]; data = (response.IsBodyRead ? response.Body : null) ?? new byte[0];
...@@ -268,9 +284,18 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -268,9 +284,18 @@ namespace Titanium.Web.Proxy.Examples.Wpf
} }
//hexStr = string.Join(" ", data.Select(x => x.ToString("X2"))); //hexStr = string.Join(" ", data.Select(x => x.ToString("X2")));
TextBoxResponse.Text = session.Response.HeaderText + session.Response.Encoding.GetString(data) + sb = new StringBuilder();
(truncated ? Environment.NewLine + $"Data is truncated after {truncateLimit} bytes" : null) + sb.Append(response.HeaderText);
(session.Response as ConnectResponse)?.ServerHelloInfo; sb.Append(response.Encoding.GetString(data));
sb.Append(truncated ? Environment.NewLine + $"Data is truncated after {truncateLimit} bytes" : null);
sb.Append((response as ConnectResponse)?.ServerHelloInfo);
if (SelectedSession.Exception != null)
{
sb.Append(Environment.NewLine);
sb.Append(SelectedSession.Exception);
}
TextBoxResponse.Text = sb.ToString();
} }
} }
} }
...@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private string process; private string process;
private long receivedDataCount; private long receivedDataCount;
private long sentDataCount; private long sentDataCount;
private Exception exception;
public int Number { get; set; } public int Number { get; set; }
...@@ -72,6 +73,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -72,6 +73,12 @@ namespace Titanium.Web.Proxy.Examples.Wpf
set => SetField(ref sentDataCount, value); set => SetField(ref sentDataCount, value);
} }
public Exception Exception
{
get => exception;
set => SetField(ref exception, value);
}
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T>(ref T field, T value,[CallerMemberName] string propertyName = null) protected void SetField<T>(ref T field, T value,[CallerMemberName] string propertyName = null)
......
...@@ -8,8 +8,8 @@ namespace Titanium.Web.Proxy.Compression ...@@ -8,8 +8,8 @@ namespace Titanium.Web.Proxy.Compression
internal class CompressionFactory internal class CompressionFactory
{ {
//cache //cache
private static Lazy<ICompression> gzip = new Lazy<ICompression>(() => new GZipCompression()); private static readonly Lazy<ICompression> gzip = new Lazy<ICompression>(() => new GZipCompression());
private static Lazy<ICompression> deflate = new Lazy<ICompression>(() => new DeflateCompression()); private static readonly Lazy<ICompression> deflate = new Lazy<ICompression>(() => new DeflateCompression());
public static ICompression GetCompression(string type) public static ICompression GetCompression(string type)
{ {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
/// </summary> /// </summary>
internal class DecompressionFactory internal class DecompressionFactory
{ {
public static DecompressionFactory Instance = new DecompressionFactory();
internal IDecompression Create(string type) internal IDecompression Create(string type)
{ {
switch (type) switch (type)
......
using System.Threading.Tasks; using System.IO;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Decompression namespace Titanium.Web.Proxy.Decompression
{ {
/// <summary> /// <summary>
/// When no compression is specified just return the byte array /// When no compression is specified just return the stream
/// </summary> /// </summary>
internal class DefaultDecompression : IDecompression internal class DefaultDecompression : IDecompression
{ {
public Task<byte[]> Decompress(byte[] compressedArray, int bufferSize) public Stream GetStream(Stream stream)
{ {
return Task.FromResult(compressedArray); return stream;
} }
} }
} }
...@@ -10,30 +10,9 @@ namespace Titanium.Web.Proxy.Decompression ...@@ -10,30 +10,9 @@ namespace Titanium.Web.Proxy.Decompression
/// </summary> /// </summary>
internal class DeflateDecompression : IDecompression internal class DeflateDecompression : IDecompression
{ {
public async Task<byte[]> Decompress(byte[] compressedArray, int bufferSize) public Stream GetStream(Stream stream)
{ {
using (var stream = new MemoryStream(compressedArray)) return new DeflateStream(stream, CompressionMode.Decompress);
using (var decompressor = new DeflateStream(stream, CompressionMode.Decompress))
{
var buffer = BufferPool.GetBuffer(bufferSize);
try
{
using (var output = new MemoryStream())
{
int read;
while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return output.ToArray();
}
}
finally
{
BufferPool.ReturnBuffer(buffer);
}
}
} }
} }
} }
...@@ -10,29 +10,9 @@ namespace Titanium.Web.Proxy.Decompression ...@@ -10,29 +10,9 @@ namespace Titanium.Web.Proxy.Decompression
/// </summary> /// </summary>
internal class GZipDecompression : IDecompression internal class GZipDecompression : IDecompression
{ {
public async Task<byte[]> Decompress(byte[] compressedArray, int bufferSize) public Stream GetStream(Stream stream)
{ {
using (var decompressor = new GZipStream(new MemoryStream(compressedArray), CompressionMode.Decompress)) return new GZipStream(stream, CompressionMode.Decompress);
{
var buffer = BufferPool.GetBuffer(bufferSize);
try
{
using (var output = new MemoryStream())
{
int read;
while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
return output.ToArray();
}
}
finally
{
BufferPool.ReturnBuffer(buffer);
}
}
} }
} }
} }
using System.Threading.Tasks; using System.IO;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Decompression namespace Titanium.Web.Proxy.Decompression
{ {
...@@ -7,6 +8,6 @@ namespace Titanium.Web.Proxy.Decompression ...@@ -7,6 +8,6 @@ namespace Titanium.Web.Proxy.Decompression
/// </summary> /// </summary>
internal interface IDecompression internal interface IDecompression
{ {
Task<byte[]> Decompress(byte[] compressedArray, int bufferSize); Stream GetStream(Stream stream);
} }
} }
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
using StreamExtended.Helpers;
using StreamExtended.Network;
namespace Titanium.Web.Proxy.EventArguments
{
internal class ChunkedStream : Stream
{
private readonly CustomBufferedStream baseStream;
private readonly CustomBinaryReader baseReader;
private bool readChunkTrail;
private int chunkBytesRemaining;
public ChunkedStream(CustomBufferedStream baseStream, CustomBinaryReader baseReader)
{
this.baseStream = baseStream;
this.baseReader = baseReader;
}
private void GetNextChunk()
{
if (readChunkTrail)
{
// read the chunk trail of the previous chunk
string s = baseReader.ReadLineAsync().Result;
}
readChunkTrail = true;
string chunkHead = baseReader.ReadLineAsync().Result;
int idx = chunkHead.IndexOf(";");
if (idx >= 0)
{
// remove chunk extension
chunkHead = chunkHead.Substring(0, idx);
}
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
chunkBytesRemaining = chunkSize;
if (chunkSize == 0)
{
chunkBytesRemaining = -1;
//chunk trail
string s = baseReader.ReadLineAsync().Result;
}
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (chunkBytesRemaining == -1)
{
return 0;
}
if (chunkBytesRemaining == 0)
{
GetNextChunk();
}
if (chunkBytesRemaining == -1)
{
return 0;
}
int toRead = Math.Min(count, chunkBytesRemaining);
int res = baseStream.Read(buffer, offset, toRead);
chunkBytesRemaining -= res;
return res;
}
public async Task Finish()
{
var buffer = BufferPool.GetBuffer(baseReader.Buffer.Length);
try
{
while (chunkBytesRemaining != -1)
{
await ReadAsync(buffer, 0, buffer.Length);
}
}
finally
{
BufferPool.ReturnBuffer(buffer);
}
}
protected override void Dispose(bool disposing)
{
if (chunkBytesRemaining != -1)
{
;
}
base.Dispose(disposing);
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => throw new NotSupportedException();
public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
}
}
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -100,6 +101,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -100,6 +101,8 @@ namespace Titanium.Web.Proxy.EventArguments
public bool IsTransparent => LocalEndPoint is TransparentProxyEndPoint; public bool IsTransparent => LocalEndPoint is TransparentProxyEndPoint;
public Exception Exception { get; internal set; }
/// <summary> /// <summary>
/// Constructor to initialize the proxy /// Constructor to initialize the proxy
/// </summary> /// </summary>
...@@ -146,7 +149,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -146,7 +149,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet) //If not already read (not cached yet)
if (!request.IsBodyRead) if (!request.IsBodyRead)
{ {
var body = await ReadBodyAsync(ProxyClient.ClientStreamReader, request.IsChunked, request.ContentLength, request.ContentEncoding, true); var body = await ReadBodyAsync(ProxyClient.ClientStreamReader, true);
request.Body = body; request.Body = body;
//Now set the flag to true //Now set the flag to true
...@@ -221,7 +224,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -221,7 +224,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet) //If not already read (not cached yet)
if (!response.IsBodyRead) if (!response.IsBodyRead)
{ {
var body = await ReadBodyAsync(WebSession.ServerConnection.StreamReader, response.IsChunked, response.ContentLength, response.ContentEncoding, false); var body = await ReadBodyAsync(WebSession.ServerConnection.StreamReader, false);
response.Body = body; response.Body = body;
//Now set the flag to true //Now set the flag to true
...@@ -231,21 +234,21 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -231,21 +234,21 @@ namespace Titanium.Web.Proxy.EventArguments
} }
} }
private async Task<byte[]> ReadBodyAsync(CustomBinaryReader reader, bool isChunked, long contentLength, string contentEncoding, bool isRequest) private async Task<byte[]> ReadBodyAsync(CustomBinaryReader reader, bool isRequest)
{ {
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, bufferSize); var writer = new HttpWriter(bodyStream, bufferSize);
if (isRequest) if (isRequest)
{ {
await CopyRequestBodyAsync(writer, true); await CopyRequestBodyAsync(writer, TransformationMode.Uncompress);
} }
else else
{ {
await CopyResponseBodyAsync(writer, true); await CopyResponseBodyAsync(writer, TransformationMode.Uncompress);
} }
return await GetDecompressedBodyAsync(contentEncoding, bodyStream.ToArray()); return bodyStream.ToArray();
} }
} }
...@@ -253,7 +256,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -253,7 +256,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// This is called when the request is PUT/POST/PATCH to read the body /// This is called when the request is PUT/POST/PATCH to read the body
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal async Task CopyRequestBodyAsync(HttpWriter writer, bool removeChunkedEncoding) internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation)
{ {
// End the operation // End the operation
var request = WebSession.Request; var request = WebSession.Request;
...@@ -290,16 +293,67 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -290,16 +293,67 @@ namespace Titanium.Web.Proxy.EventArguments
} }
else else
{ {
await writer.CopyBodyAsync(reader, request.IsChunked, contentLength, removeChunkedEncoding, OnDataSent); await CopyBodyAsync(ProxyClient.ClientStream, reader, writer,
request.IsChunked, transformation, request.ContentEncoding, contentLength, OnDataSent);
} }
} }
internal async Task CopyResponseBodyAsync(HttpWriter writer, bool removeChunkedEncoding) private async Task CopyBodyAsync(CustomBufferedStream stream, CustomBinaryReader reader, HttpWriter writer,
bool isChunked, TransformationMode transformation, string contentEncoding, long contentLength,
Action<byte[], int, int> onCopy)
{
bool newReader = false;
Stream s = stream;
ChunkedStream chunkedStream = null;
Stream decompressStream = null;
if (isChunked && transformation != TransformationMode.None)
{
s = chunkedStream = new ChunkedStream(stream, reader);
isChunked = false;
newReader = true;
}
if (transformation == TransformationMode.Uncompress)
{
s = decompressStream = DecompressionFactory.Instance.Create(contentEncoding).GetStream(s);
newReader = true;
}
try
{
if (newReader)
{
var bufStream = new CustomBufferedStream(s, bufferSize);
s = bufStream;
reader = new CustomBinaryReader(bufStream, bufferSize);
}
await writer.CopyBodyAsync(reader, isChunked, contentLength, onCopy);
}
finally
{
if (newReader)
{
reader?.Dispose();
decompressStream?.Dispose();
if (chunkedStream != null)
{
await chunkedStream.Finish();
chunkedStream.Dispose();
}
}
}
}
internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation)
{ {
var response = WebSession.Response; var response = WebSession.Response;
var reader = WebSession.ServerConnection.StreamReader; var reader = WebSession.ServerConnection.StreamReader;
await writer.CopyBodyAsync(reader, response.IsChunked, response.ContentLength, removeChunkedEncoding, OnDataReceived); await CopyBodyAsync(WebSession.ServerConnection.Stream, reader, writer,
response.IsChunked, transformation, response.ContentEncoding, response.ContentLength, OnDataReceived);
} }
/// <summary> /// <summary>
...@@ -513,14 +567,6 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -513,14 +567,6 @@ namespace Titanium.Web.Proxy.EventArguments
await SetResponseBody(bodyBytes); await SetResponseBody(bodyBytes);
} }
private async Task<byte[]> GetDecompressedBodyAsync(string encodingType, byte[] bodyStream)
{
var decompressionFactory = new DecompressionFactory();
var decompressor = decompressionFactory.Create(encodingType);
return await decompressor.Decompress(bodyStream, bufferSize);
}
/// <summary> /// <summary>
/// Before request is made to server /// Before request is made to server
/// Respond with the specified HTML string to client /// Respond with the specified HTML string to client
...@@ -642,6 +688,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -642,6 +688,7 @@ namespace Titanium.Web.Proxy.EventArguments
DataSent = null; DataSent = null;
DataReceived = null; DataReceived = null;
MultipartRequestPartSent = null; MultipartRequestPartSent = null;
Exception = null;
WebSession.FinishSession(); WebSession.FinishSession();
} }
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.EventArguments
{
internal enum TransformationMode
{
None,
/// <summary>
/// Removes the chunked encoding
/// </summary>
RemoveChunked,
/// <summary>
/// Uncompress the body (this also removes the chunked encoding if exists)
/// </summary>
Uncompress,
}
}
...@@ -5,6 +5,7 @@ using System.Text; ...@@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using StreamExtended.Helpers; using StreamExtended.Helpers;
using StreamExtended.Network; using StreamExtended.Network;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
...@@ -152,17 +153,16 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -152,17 +153,16 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="streamReader"></param> /// <param name="streamReader"></param>
/// <param name="isChunked"></param> /// <param name="isChunked"></param>
/// <param name="contentLength"></param> /// <param name="contentLength"></param>
/// <param name="removeChunkedEncoding"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <returns></returns> /// <returns></returns>
internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength, bool removeChunkedEncoding, Action<byte[], int, int> onCopy) internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength, Action<byte[], int, int> onCopy)
{ {
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol //For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (isChunked) if (isChunked)
{ {
//Need to revist, find any potential bugs //Need to revist, find any potential bugs
//send the body bytes to server in chunks //send the body bytes to server in chunks
return CopyBodyChunkedAsync(streamReader, removeChunkedEncoding, onCopy); return CopyBodyChunkedAsync(streamReader, onCopy);
} }
//http 1.0 //http 1.0
...@@ -197,30 +197,30 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -197,30 +197,30 @@ namespace Titanium.Web.Proxy.Helpers
/// Copies the streams chunked /// Copies the streams chunked
/// </summary> /// </summary>
/// <param name="reader"></param> /// <param name="reader"></param>
/// <param name="removeChunkedEncoding"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <returns></returns> /// <returns></returns>
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, bool removeChunkedEncoding, Action<byte[], int, int> onCopy) private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, Action<byte[], int, int> onCopy)
{ {
while (true) while (true)
{ {
string chunkHead = await reader.ReadLineAsync(); string chunkHead = await reader.ReadLineAsync();
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber); int idx = chunkHead.IndexOf(";");
if (idx >= 0)
if (!removeChunkedEncoding)
{ {
await WriteLineAsync(chunkHead); // remove chunk extension
chunkHead = chunkHead.Substring(0, idx);
} }
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
await WriteLineAsync(chunkHead);
if (chunkSize != 0) if (chunkSize != 0)
{ {
await CopyBytesFromStream(reader, chunkSize, onCopy); await CopyBytesFromStream(reader, chunkSize, onCopy);
} }
if (!removeChunkedEncoding) await WriteLineAsync();
{
await WriteLineAsync();
}
//chunk trail //chunk trail
await reader.ReadLineAsync(); await reader.ReadLineAsync();
......
...@@ -189,6 +189,11 @@ namespace Titanium.Web.Proxy ...@@ -189,6 +189,11 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
public event AsyncEventHandler<SessionEventArgs> BeforeResponse; public event AsyncEventHandler<SessionEventArgs> BeforeResponse;
/// <summary>
/// Intercept after response from server
/// </summary>
public event AsyncEventHandler<SessionEventArgs> AfterResponse;
/// <summary> /// <summary>
/// Callback for error events in proxy /// Callback for error events in proxy
/// </summary> /// </summary>
......
This diff is collapsed.
...@@ -80,22 +80,23 @@ namespace Titanium.Web.Proxy ...@@ -80,22 +80,23 @@ namespace Titanium.Web.Proxy
bool isChunked = response.IsChunked; bool isChunked = response.IsChunked;
string contentEncoding = response.ContentEncoding; string contentEncoding = response.ContentEncoding;
var body = response.Body;
if (contentEncoding != null) if (contentEncoding != null)
{ {
response.Body = await GetCompressedResponseBody(contentEncoding, response.Body); body = await GetCompressedResponseBody(contentEncoding, body);
if (isChunked == false) if (isChunked == false)
{ {
response.ContentLength = response.Body.Length; response.ContentLength = body.Length;
} }
else else
{ {
response.ContentLength = -1; response.ContentLength = -1;
} }
} }
await clientStreamWriter.WriteHeadersAsync(response.Headers); await clientStreamWriter.WriteHeadersAsync(response.Headers);
await clientStreamWriter.WriteBodyAsync(response.Body, isChunked); await clientStreamWriter.WriteBodyAsync(body, isChunked);
} }
else else
{ {
...@@ -104,7 +105,7 @@ namespace Titanium.Web.Proxy ...@@ -104,7 +105,7 @@ namespace Titanium.Web.Proxy
//Write body if exists //Write body if exists
if (response.HasBody) if (response.HasBody)
{ {
await args.CopyResponseBodyAsync(clientStreamWriter, false); await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None);
} }
} }
} }
...@@ -134,5 +135,13 @@ namespace Titanium.Web.Proxy ...@@ -134,5 +135,13 @@ namespace Titanium.Web.Proxy
await BeforeResponse.InvokeAsync(this, args, ExceptionFunc); await BeforeResponse.InvokeAsync(this, args, ExceptionFunc);
} }
} }
private async Task InvokeAfterResponse(SessionEventArgs args)
{
if (AfterResponse != null)
{
await AfterResponse.InvokeAsync(this, args, ExceptionFunc);
}
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment