Commit db2b48a6 authored by Honfika's avatar Honfika

simplify compressionfactory, usre stream reader interface when only the read...

simplify compressionfactory, usre stream reader interface when only the read methods are used, stream dispose in getbody
parent a991c2bc
using System; using System;
using System.IO;
using System.IO.Compression;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Compression namespace Titanium.Web.Proxy.Compression
...@@ -8,18 +10,14 @@ namespace Titanium.Web.Proxy.Compression ...@@ -8,18 +10,14 @@ namespace Titanium.Web.Proxy.Compression
/// </summary> /// </summary>
internal static class CompressionFactory internal static class CompressionFactory
{ {
//cache internal static Stream Create(string type, Stream stream, bool leaveOpen = true)
private static readonly ICompression gzip = new GZipCompression();
private static readonly ICompression deflate = new DeflateCompression();
internal static ICompression GetCompression(string type)
{ {
switch (type) switch (type)
{ {
case KnownHeaders.ContentEncodingGzip: case KnownHeaders.ContentEncodingGzip:
return gzip; return new GZipStream(stream, CompressionMode.Compress, leaveOpen);
case KnownHeaders.ContentEncodingDeflate: case KnownHeaders.ContentEncodingDeflate:
return deflate; return new DeflateStream(stream, CompressionMode.Compress, leaveOpen);
default: default:
throw new Exception($"Unsupported compression mode: {type}"); throw new Exception($"Unsupported compression mode: {type}");
} }
......
using System; using System;
using System.IO;
using System.IO.Compression;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Decompression namespace Titanium.Web.Proxy.Compression
{ {
/// <summary> /// <summary>
/// A factory to generate the de-compression methods based on the type of compression /// A factory to generate the de-compression methods based on the type of compression
/// </summary> /// </summary>
internal class DecompressionFactory internal class DecompressionFactory
{ {
//cache internal static Stream Create(string type, Stream stream, bool leaveOpen = true)
private static readonly IDecompression gzip = new GZipDecompression();
private static readonly IDecompression deflate = new DeflateDecompression();
internal static IDecompression Create(string type)
{ {
switch (type) switch (type)
{ {
case KnownHeaders.ContentEncodingGzip: case KnownHeaders.ContentEncodingGzip:
return gzip; return new GZipStream(stream, CompressionMode.Decompress, leaveOpen);
case KnownHeaders.ContentEncodingDeflate: case KnownHeaders.ContentEncodingDeflate:
return deflate; return new DeflateStream(stream, CompressionMode.Decompress, leaveOpen);
default: default:
throw new Exception($"Unsupported decompression mode: {type}"); throw new Exception($"Unsupported decompression mode: {type}");
} }
......
using System.IO;
using System.IO.Compression;
namespace Titanium.Web.Proxy.Compression
{
/// <summary>
/// Concrete implementation of deflate compression
/// </summary>
internal class DeflateCompression : ICompression
{
public Stream GetStream(Stream stream)
{
return new DeflateStream(stream, CompressionMode.Compress, true);
}
}
}
using System.IO;
using System.IO.Compression;
namespace Titanium.Web.Proxy.Compression
{
/// <summary>
/// concreate implementation of gzip compression
/// </summary>
internal class GZipCompression : ICompression
{
public Stream GetStream(Stream stream)
{
return new GZipStream(stream, CompressionMode.Compress, true);
}
}
}
using System.IO;
namespace Titanium.Web.Proxy.Compression
{
/// <summary>
/// An inteface for http compression
/// </summary>
internal interface ICompression
{
Stream GetStream(Stream stream);
}
}
using System.IO;
using System.IO.Compression;
namespace Titanium.Web.Proxy.Decompression
{
/// <summary>
/// concrete implementation of deflate de-compression
/// </summary>
internal class DeflateDecompression : IDecompression
{
public Stream GetStream(Stream stream)
{
return new DeflateStream(stream, CompressionMode.Decompress, true);
}
}
}
using System.IO;
using System.IO.Compression;
namespace Titanium.Web.Proxy.Decompression
{
/// <summary>
/// concrete implementation of gzip de-compression
/// </summary>
internal class GZipDecompression : IDecompression
{
public Stream GetStream(Stream stream)
{
return new GZipStream(stream, CompressionMode.Decompress, true);
}
}
}
using System.IO;
namespace Titanium.Web.Proxy.Decompression
{
/// <summary>
/// An interface for decompression
/// </summary>
internal interface IDecompression
{
Stream GetStream(Stream stream);
}
}
...@@ -6,7 +6,7 @@ using System.Threading; ...@@ -6,7 +6,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using StreamExtended.Helpers; using StreamExtended.Helpers;
using StreamExtended.Network; using StreamExtended.Network;
using Titanium.Web.Proxy.Decompression; using Titanium.Web.Proxy.Compression;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http.Responses; using Titanium.Web.Proxy.Http.Responses;
...@@ -256,13 +256,15 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -256,13 +256,15 @@ namespace Titanium.Web.Proxy.EventArguments
if (transformation == TransformationMode.Uncompress && contentEncoding != null) if (transformation == TransformationMode.Uncompress && contentEncoding != null)
{ {
s = decompressStream = DecompressionFactory.Create(contentEncoding).GetStream(s); s = decompressStream = DecompressionFactory.Create(contentEncoding, s);
} }
try try
{ {
var bufStream = new CustomBufferedStream(s, BufferSize, true); using (var bufStream = new CustomBufferedStream(s, BufferSize, true))
await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken); {
await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken);
}
} }
finally finally
{ {
......
...@@ -118,38 +118,38 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -118,38 +118,38 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// Determines whether is connect method. /// Determines whether is connect method.
/// </summary> /// </summary>
/// <param name="clientStream">The client stream.</param> /// <param name="clientStreamReader">The client stream reader.</param>
/// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsConnectMethod(CustomBufferedStream clientStream) internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader)
{ {
return StartsWith(clientStream, "CONNECT"); return StartsWith(clientStreamReader, "CONNECT");
} }
/// <summary> /// <summary>
/// Determines whether is pri method (HTTP/2). /// Determines whether is pri method (HTTP/2).
/// </summary> /// </summary>
/// <param name="clientStream">The client stream.</param> /// <param name="clientStreamReader">The client stream reader.</param>
/// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsPriMethod(CustomBufferedStream clientStream) internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader)
{ {
return StartsWith(clientStream, "PRI"); return StartsWith(clientStreamReader, "PRI");
} }
/// <summary> /// <summary>
/// Determines whether the stream starts with the given string. /// Determines whether the stream starts with the given string.
/// </summary> /// </summary>
/// <param name="clientStream">The client stream.</param> /// <param name="clientStreamReader">The client stream reader.</param>
/// <param name="expectedStart">The expected start.</param> /// <param name="expectedStart">The expected start.</param>
/// <returns> /// <returns>
/// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise /// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise
/// </returns> /// </returns>
private static async Task<int> StartsWith(CustomBufferedStream clientStream, string expectedStart) private static async Task<int> StartsWith(ICustomStreamReader clientStreamReader, string expectedStart)
{ {
bool isExpected = true; bool isExpected = true;
int legthToCheck = 10; int legthToCheck = 10;
for (int i = 0; i < legthToCheck; i++) for (int i = 0; i < legthToCheck; i++)
{ {
int b = await clientStream.PeekByteAsync(i); int b = await clientStreamReader.PeekByteAsync(i);
if (b == -1) if (b == -1)
{ {
return -1; return -1;
......
...@@ -177,10 +177,9 @@ namespace Titanium.Web.Proxy.Http ...@@ -177,10 +177,9 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns> /// <returns></returns>
internal byte[] GetCompressedBody(string encodingType, byte[] body) internal byte[] GetCompressedBody(string encodingType, byte[] body)
{ {
var compressor = CompressionFactory.GetCompression(encodingType);
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
using (var zip = compressor.GetStream(ms)) using (var zip = CompressionFactory.Create(encodingType, ms))
{ {
zip.Write(body, 0, body.Length); zip.Write(body, 0, body.Length);
} }
......
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