Commit bb2d9b0e authored by Honfika's avatar Honfika

request body should be compressed earlier for expect 100-continue (to update...

request body should be compressed earlier for expect 100-continue (to update the content length in header)
parent dff59f07
...@@ -93,14 +93,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -93,14 +93,11 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="flush"></param> /// <param name="flush"></param>
/// <returns></returns> /// <returns></returns>
public async Task WriteHeadersAsync(HeaderCollection headers, bool flush = true) public async Task WriteHeadersAsync(HeaderCollection headers, bool flush = true)
{
if (headers != null)
{ {
foreach (var header in headers) foreach (var header in headers)
{ {
await header.WriteToStreamAsync(this); await header.WriteToStreamAsync(this);
} }
}
await WriteLineAsync(); await WriteLineAsync();
if (flush) if (flush)
...@@ -274,52 +271,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -274,52 +271,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
protected async Task WriteAsync(RequestResponseBase requestResponse, bool flush = true) protected async Task WriteAsync(RequestResponseBase requestResponse, bool flush = true)
{ {
if (requestResponse.HasBody) var body = requestResponse.CompressBodyAndUpdateContentLength();
{
bool isChunked = requestResponse.IsChunked;
string contentEncoding = requestResponse.ContentEncoding;
var body = requestResponse.Body;
if (contentEncoding != null && body != null)
{
body = GetCompressedBody(contentEncoding, body);
if (isChunked == false)
{
requestResponse.ContentLength = body.Length;
}
else
{
requestResponse.ContentLength = -1;
}
}
await WriteHeadersAsync(requestResponse.Headers, flush);
await WriteBodyAsync(body, isChunked);
}
else
{
await WriteHeadersAsync(requestResponse.Headers, flush); await WriteHeadersAsync(requestResponse.Headers, flush);
}
}
/// <summary> if (body != null)
/// get the compressed body from given bytes
/// </summary>
/// <param name="encodingType"></param>
/// <param name="body"></param>
/// <returns></returns>
internal byte[] GetCompressedBody(string encodingType, byte[] body)
{
var compressor = CompressionFactory.GetCompression(encodingType);
using (var ms = new MemoryStream())
{ {
using (var zip = compressor.GetStream(ms)) await WriteBodyAsync(body, requestResponse.IsChunked);
{
zip.Write(body, 0, body.Length);
}
return ms.ToArray();
} }
} }
} }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using Titanium.Web.Proxy.Compression;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
...@@ -150,6 +151,55 @@ namespace Titanium.Web.Proxy.Http ...@@ -150,6 +151,55 @@ namespace Titanium.Web.Proxy.Http
internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true); internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true);
/// <summary>
/// get the compressed body from given bytes
/// </summary>
/// <param name="encodingType"></param>
/// <param name="body"></param>
/// <returns></returns>
internal byte[] GetCompressedBody(string encodingType, byte[] body)
{
var compressor = CompressionFactory.GetCompression(encodingType);
using (var ms = new MemoryStream())
{
using (var zip = compressor.GetStream(ms))
{
zip.Write(body, 0, body.Length);
}
return ms.ToArray();
}
}
internal byte[] CompressBodyAndUpdateContentLength()
{
bool isChunked = IsChunked;
string contentEncoding = ContentEncoding;
if (HasBody)
{
var body = Body;
if (contentEncoding != null && body != null)
{
body = GetCompressedBody(contentEncoding, body);
if (isChunked == false)
{
ContentLength = body.Length;
}
else
{
ContentLength = -1;
}
}
return body;
}
ContentLength = 0;
return null;
}
/// <summary> /// <summary>
/// Body as string /// Body as string
/// Use the encoding specified to decode the byte[] data to string /// Use the encoding specified to decode the byte[] data to string
......
...@@ -422,9 +422,8 @@ namespace Titanium.Web.Proxy ...@@ -422,9 +422,8 @@ namespace Titanium.Web.Proxy
if (request.UpgradeToWebSocket) if (request.UpgradeToWebSocket)
{ {
//prepare the prefix content //prepare the prefix content
var requestHeaders = request.Headers;
await connection.StreamWriter.WriteLineAsync(httpCmd); await connection.StreamWriter.WriteLineAsync(httpCmd);
await connection.StreamWriter.WriteHeadersAsync(requestHeaders); await connection.StreamWriter.WriteHeadersAsync(request.Headers);
string httpStatus = await connection.StreamReader.ReadLineAsync(); string httpStatus = await connection.StreamReader.ReadLineAsync();
Response.ParseResponseLine(httpStatus, out var responseVersion, out int responseStatusCode, Response.ParseResponseLine(httpStatus, out var responseVersion, out int responseStatusCode,
...@@ -499,6 +498,8 @@ namespace Titanium.Web.Proxy ...@@ -499,6 +498,8 @@ namespace Titanium.Web.Proxy
var request = args.WebSession.Request; var request = args.WebSession.Request;
request.Locked = true; request.Locked = true;
var body = request.CompressBodyAndUpdateContentLength();
//if expect continue is enabled then send the headers first //if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue //and see if server would return 100 conitinue
if (request.ExpectContinue) if (request.ExpectContinue)
...@@ -538,25 +539,7 @@ namespace Titanium.Web.Proxy ...@@ -538,25 +539,7 @@ namespace Titanium.Web.Proxy
if (request.IsBodyRead) if (request.IsBodyRead)
{ {
var writer = args.WebSession.ServerConnection.StreamWriter; var writer = args.WebSession.ServerConnection.StreamWriter;
bool isChunked = request.IsChunked; await writer.WriteBodyAsync(body, request.IsChunked);
string contentEncoding = request.ContentEncoding;
var body = request.Body;
if (contentEncoding != null && body != null)
{
body = writer.GetCompressedBody(contentEncoding, body);
if (isChunked == false)
{
request.ContentLength = body.Length;
}
else
{
request.ContentLength = -1;
}
}
await writer.WriteBodyAsync(body, isChunked);
} }
else else
{ {
......
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