Commit 53163418 authored by Honfika's avatar Honfika

baseclass for request and response

parent 3ed0a2ef
using System; using System;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Compression namespace Titanium.Web.Proxy.Compression
{ {
...@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Compression ...@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Compression
{ {
switch (type) switch (type)
{ {
case "gzip": case KnownHeaders.ContentEncodingGzip:
return gzip.Value; return gzip.Value;
case "deflate": case KnownHeaders.ContentEncodingDeflate:
return deflate.Value; return deflate.Value;
default: default:
return def.Value; return def.Value;
......
using System; using System;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Decompression namespace Titanium.Web.Proxy.Decompression
{ {
...@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Decompression ...@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Decompression
{ {
switch (type) switch (type)
{ {
case "gzip": case KnownHeaders.ContentEncodingGzip:
return gzip.Value; return gzip.Value;
case "deflate": case KnownHeaders.ContentEncodingDeflate:
return deflate.Value; return deflate.Value;
default: default:
return def.Value; return def.Value;
......
...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
private async Task ReadResponseBodyAsync() private async Task ReadResponseBodyAsync()
{ {
if (!WebSession.Request.RequestLocked) if (!WebSession.Request.Locked)
{ {
throw new Exception("You cannot read the response body before request is made to server."); throw new Exception("You cannot read the response body before request is made to server.");
} }
...@@ -453,7 +453,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -453,7 +453,7 @@ namespace Titanium.Web.Proxy.EventArguments
public async Task SetRequestBody(byte[] body) public async Task SetRequestBody(byte[] body)
{ {
var request = WebSession.Request; var request = WebSession.Request;
if (request.RequestLocked) if (request.Locked)
{ {
throw new Exception("You cannot call this function after request is made to server."); throw new Exception("You cannot call this function after request is made to server.");
} }
...@@ -474,7 +474,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -474,7 +474,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param> /// <param name="body"></param>
public async Task SetRequestBodyString(string body) public async Task SetRequestBodyString(string body)
{ {
if (WebSession.Request.RequestLocked) if (WebSession.Request.Locked)
{ {
throw new Exception("You cannot call this function after request is made to server."); throw new Exception("You cannot call this function after request is made to server.");
} }
...@@ -522,7 +522,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -522,7 +522,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param> /// <param name="body"></param>
public async Task SetResponseBody(byte[] body) public async Task SetResponseBody(byte[] body)
{ {
if (!WebSession.Request.RequestLocked) if (!WebSession.Request.Locked)
{ {
throw new Exception("You cannot call this function before request is made to server."); throw new Exception("You cannot call this function before request is made to server.");
} }
...@@ -547,7 +547,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -547,7 +547,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param> /// <param name="body"></param>
public async Task SetResponseBodyString(string body) public async Task SetResponseBodyString(string body)
{ {
if (!WebSession.Request.RequestLocked) if (!WebSession.Request.Locked)
{ {
throw new Exception("You cannot call this function before request is made to server."); throw new Exception("You cannot call this function before request is made to server.");
} }
...@@ -659,14 +659,14 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -659,14 +659,14 @@ namespace Titanium.Web.Proxy.EventArguments
/// a generic responder method /// a generic responder method
public void Respond(Response response) public void Respond(Response response)
{ {
if (WebSession.Request.RequestLocked) if (WebSession.Request.Locked)
{ {
throw new Exception("You cannot call this function after request is made to server."); throw new Exception("You cannot call this function after request is made to server.");
} }
WebSession.Request.RequestLocked = true; WebSession.Request.Locked = true;
response.ResponseLocked = true; response.Locked = true;
response.IsBodyRead = true; response.IsBodyRead = true;
WebSession.Response = response; WebSession.Response = response;
......
...@@ -40,6 +40,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -40,6 +40,8 @@ namespace Titanium.Web.Proxy.Http
// Response headers // Response headers
public const string ContentEncoding = "content-encoding"; public const string ContentEncoding = "content-encoding";
public const string ContentEncodingDeflate = "deflate";
public const string ContentEncodingGzip = "gzip";
public const string Location = "Location"; public const string Location = "Location";
......
...@@ -3,28 +3,17 @@ using System.ComponentModel; ...@@ -3,28 +3,17 @@ using System.ComponentModel;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
{ {
/// <summary> /// <summary>
/// A HTTP(S) request object /// Http(s) request object
/// </summary> /// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))] [TypeConverter(typeof(ExpandableObjectConverter))]
public class Request public class Request : RequestResponseBase
{ {
/// <summary>
/// Cached request body as byte array
/// </summary>
private byte[] body;
/// <summary>
/// Cached request body as string
/// </summary>
private string bodyString;
/// <summary> /// <summary>
/// Request Method /// Request Method
/// </summary> /// </summary>
...@@ -45,16 +34,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -45,16 +34,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public string OriginalUrl { get; set; } public string OriginalUrl { get; set; }
/// <summary>
/// Request Http Version
/// </summary>
public Version HttpVersion { get; set; }
/// <summary>
/// Keeps the request body data after the session is finished
/// </summary>
public bool KeepBody { get; set; }
/// <summary> /// <summary>
/// Has request body? /// Has request body?
/// </summary> /// </summary>
...@@ -97,80 +76,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -97,80 +76,6 @@ namespace Titanium.Web.Proxy.Http
set => Headers.SetOrAddHeaderValue(KnownHeaders.Host, value); set => Headers.SetOrAddHeaderValue(KnownHeaders.Host, value);
} }
/// <summary>
/// Content encoding header value
/// </summary>
public string ContentEncoding => Headers.GetHeaderValueOrNull(KnownHeaders.ContentEncoding);
/// <summary>
/// Request content-length
/// </summary>
public long ContentLength
{
get
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.ContentLength);
if (headerValue == null)
{
return -1;
}
long.TryParse(headerValue, out long contentLen);
if (contentLen >= 0)
{
return contentLen;
}
return -1;
}
set
{
if (value >= 0)
{
Headers.SetOrAddHeaderValue(KnownHeaders.ContentLength, value.ToString());
IsChunked = false;
}
else
{
Headers.RemoveHeader(KnownHeaders.ContentLength);
}
}
}
/// <summary>
/// Request content-type
/// </summary>
public string ContentType
{
get => Headers.GetHeaderValueOrNull(KnownHeaders.ContentType);
set => Headers.SetOrAddHeaderValue(KnownHeaders.ContentType, value);
}
/// <summary>
/// Is request body send as chunked bytes
/// </summary>
public bool IsChunked
{
get
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.TransferEncoding);
return headerValue != null && headerValue.ContainsIgnoreCase(KnownHeaders.TransferEncodingChunked);
}
set
{
if (value)
{
Headers.SetOrAddHeaderValue(KnownHeaders.TransferEncoding, KnownHeaders.TransferEncodingChunked);
ContentLength = -1;
}
else
{
Headers.RemoveHeader(KnownHeaders.TransferEncoding);
}
}
}
/// <summary> /// <summary>
/// Does this request has a 100-continue header? /// Does this request has a 100-continue header?
/// </summary> /// </summary>
...@@ -190,17 +95,12 @@ namespace Titanium.Web.Proxy.Http ...@@ -190,17 +95,12 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public string Url => RequestUri.OriginalString; public string Url => RequestUri.OriginalString;
/// <summary>
/// Encoding for this request
/// </summary>
public Encoding Encoding => HttpHelper.GetEncodingFromContentType(ContentType);
/// <summary> /// <summary>
/// Terminates the underlying Tcp Connection to client after current request /// Terminates the underlying Tcp Connection to client after current request
/// </summary> /// </summary>
internal bool CancelRequest { get; set; } internal bool CancelRequest { get; set; }
internal void EnsureBodyAvailable(bool throwWhenNotReadYet = true) internal override void EnsureBodyAvailable(bool throwWhenNotReadYet = true)
{ {
//GET request don't have a request body to read //GET request don't have a request body to read
if (!HasBody) if (!HasBody)
...@@ -211,7 +111,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -211,7 +111,7 @@ namespace Titanium.Web.Proxy.Http
if (!IsBodyRead) if (!IsBodyRead)
{ {
if (RequestLocked) if (Locked)
{ {
throw new Exception("You cannot get the request body after request is made to server."); throw new Exception("You cannot get the request body after request is made to server.");
} }
...@@ -225,41 +125,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -225,41 +125,6 @@ namespace Titanium.Web.Proxy.Http
} }
} }
/// <summary>
/// Request body as byte array
/// </summary>
[Browsable(false)]
public byte[] Body
{
get
{
EnsureBodyAvailable();
return body;
}
internal set
{
body = value;
bodyString = null;
}
}
/// <summary>
/// Request body as string
/// Use the encoding specified in request to decode the byte[] data to string
/// </summary>
[Browsable(false)]
public string BodyString => bodyString ?? (bodyString = Encoding.GetString(Body));
/// <summary>
/// Request body was read by user?
/// </summary>
public bool IsBodyRead { get; internal set; }
/// <summary>
/// Request is ready to be sent (user callbacks are complete?)
/// </summary>
internal bool RequestLocked { get; set; }
/// <summary> /// <summary>
/// Does this request has an upgrade to websocket header? /// Does this request has an upgrade to websocket header?
/// </summary> /// </summary>
...@@ -278,11 +143,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -278,11 +143,6 @@ namespace Titanium.Web.Proxy.Http
} }
} }
/// <summary>
/// Request header collection
/// </summary>
public HeaderCollection Headers { get; } = new HeaderCollection();
/// <summary> /// <summary>
/// Does server responsed positively for 100 continue request /// Does server responsed positively for 100 continue request
/// </summary> /// </summary>
...@@ -296,7 +156,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -296,7 +156,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Gets the header text. /// Gets the header text.
/// </summary> /// </summary>
public string HeaderText public override string HeaderText
{ {
get get
{ {
...@@ -367,27 +227,5 @@ namespace Titanium.Web.Proxy.Http ...@@ -367,27 +227,5 @@ namespace Titanium.Web.Proxy.Http
return true; return true;
} }
internal void UpdateContentLength()
{
ContentLength = IsChunked ? -1 : body.Length;
}
/// <summary>
/// Finish the session
/// </summary>
public void FinishSession()
{
if (!KeepBody)
{
body = null;
bodyString = null;
}
}
public override string ToString()
{
return HeaderText;
}
} }
} }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http
{
public abstract class RequestResponseBase
{
/// <summary>
/// Cached body content as byte array
/// </summary>
private byte[] body;
/// <summary>
/// Cached body as string
/// </summary>
private string bodyString;
/// <summary>
/// Keeps the body data after the session is finished
/// </summary>
public bool KeepBody { get; set; }
/// <summary>
/// Http Version
/// </summary>
public Version HttpVersion { get; set; } = HttpHeader.VersionUnknown;
/// <summary>
/// Collection of all headers
/// </summary>
public HeaderCollection Headers { get; } = new HeaderCollection();
/// <summary>
/// Length of the body
/// </summary>
public long ContentLength
{
get
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.ContentLength);
if (headerValue == null)
{
return -1;
}
if (long.TryParse(headerValue, out long contentLen) && contentLen >= 0)
{
return contentLen;
}
return -1;
}
set
{
if (value >= 0)
{
Headers.SetOrAddHeaderValue(KnownHeaders.ContentLength, value.ToString());
IsChunked = false;
}
else
{
Headers.RemoveHeader(KnownHeaders.ContentLength);
}
}
}
/// <summary>
/// Content encoding for this request/response
/// </summary>
public string ContentEncoding => Headers.GetHeaderValueOrNull(KnownHeaders.ContentEncoding)?.Trim();
/// <summary>
/// Encoding for this request/response
/// </summary>
public Encoding Encoding => HttpHelper.GetEncodingFromContentType(ContentType);
/// <summary>
/// Content-type of the request/response
/// </summary>
public string ContentType
{
get => Headers.GetHeaderValueOrNull(KnownHeaders.ContentType);
set => Headers.SetOrAddHeaderValue(KnownHeaders.ContentType, value);
}
/// <summary>
/// Is body send as chunked bytes
/// </summary>
public bool IsChunked
{
get
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.TransferEncoding);
return headerValue != null && headerValue.ContainsIgnoreCase(KnownHeaders.TransferEncodingChunked);
}
set
{
if (value)
{
Headers.SetOrAddHeaderValue(KnownHeaders.TransferEncoding, KnownHeaders.TransferEncodingChunked);
ContentLength = -1;
}
else
{
Headers.RemoveHeader(KnownHeaders.TransferEncoding);
}
}
}
public abstract string HeaderText { get; }
/// <summary>
/// Body as byte array
/// </summary>
[Browsable(false)]
public byte[] Body
{
get
{
EnsureBodyAvailable();
return body;
}
internal set
{
body = value;
bodyString = null;
}
}
internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true);
/// <summary>
/// Body as string
/// Use the encoding specified to decode the byte[] data to string
/// </summary>
[Browsable(false)]
public string BodyString => bodyString ?? (bodyString = Encoding.GetString(Body));
/// <summary>
/// Was the body read by user?
/// </summary>
public bool IsBodyRead { get; internal set; }
/// <summary>
/// Is the request/response no more modifyable by user (user callbacks complete?)
/// </summary>
internal bool Locked { get; set; }
internal void UpdateContentLength()
{
ContentLength = IsChunked ? -1 : body.Length;
}
/// <summary>
/// Finish the session
/// </summary>
internal void FinishSession()
{
if (!KeepBody)
{
body = null;
bodyString = null;
}
}
public override string ToString()
{
return HeaderText;
}
}
}
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
using System.ComponentModel; using System.ComponentModel;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
...@@ -12,18 +11,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -12,18 +11,8 @@ namespace Titanium.Web.Proxy.Http
/// Http(s) response object /// Http(s) response object
/// </summary> /// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))] [TypeConverter(typeof(ExpandableObjectConverter))]
public class Response public class Response : RequestResponseBase
{ {
/// <summary>
/// Cached response body content as byte array
/// </summary>
private byte[] body;
/// <summary>
/// Cached response body as string
/// </summary>
private string bodyString;
/// <summary> /// <summary>
/// Response Status Code. /// Response Status Code.
/// </summary> /// </summary>
...@@ -34,26 +23,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -34,26 +23,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public string StatusDescription { get; set; } public string StatusDescription { get; set; }
/// <summary>
/// Encoding used in response
/// </summary>
public Encoding Encoding => HttpHelper.GetEncodingFromContentType(ContentType);
/// <summary>
/// Content encoding for this response
/// </summary>
public string ContentEncoding => Headers.GetHeaderValueOrNull(KnownHeaders.ContentEncoding)?.Trim();
/// <summary>
/// Http version
/// </summary>
public Version HttpVersion { get; set; } = HttpHeader.VersionUnknown;
/// <summary>
/// Keeps the response body data after the session is finished
/// </summary>
public bool KeepBody { get; set; }
/// <summary> /// <summary>
/// Has response body? /// Has response body?
/// </summary> /// </summary>
...@@ -108,78 +77,9 @@ namespace Titanium.Web.Proxy.Http ...@@ -108,78 +77,9 @@ namespace Titanium.Web.Proxy.Http
} }
} }
/// <summary> internal override void EnsureBodyAvailable(bool throwWhenNotReadYet = true)
/// Content type of this response
/// </summary>
public string ContentType => Headers.GetHeaderValueOrNull(KnownHeaders.ContentType);
/// <summary>
/// Length of response body
/// </summary>
public long ContentLength
{
get
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.ContentLength);
if (headerValue == null)
{
return -1;
}
if (long.TryParse(headerValue, out long contentLen))
{
return contentLen;
}
return -1;
}
set
{
if (value >= 0)
{
Headers.SetOrAddHeaderValue(KnownHeaders.ContentLength, value.ToString());
IsChunked = false;
}
else
{
Headers.RemoveHeader(KnownHeaders.ContentLength);
}
}
}
/// <summary>
/// Response transfer-encoding is chunked?
/// </summary>
public bool IsChunked
{ {
get if (!IsBodyRead && throwWhenNotReadYet)
{
string headerValue = Headers.GetHeaderValueOrNull(KnownHeaders.TransferEncoding);
return headerValue != null && headerValue.ContainsIgnoreCase(KnownHeaders.TransferEncodingChunked);
}
set
{
if (value)
{
Headers.SetOrAddHeaderValue(KnownHeaders.TransferEncoding, KnownHeaders.TransferEncodingChunked);
ContentLength = -1;
}
else
{
Headers.RemoveHeader(KnownHeaders.TransferEncoding);
}
}
}
/// <summary>
/// Collection of all response headers
/// </summary>
public HeaderCollection Headers { get; } = new HeaderCollection();
internal void EnsureBodyAvailable()
{
if (!IsBodyRead)
{ {
throw new Exception("Response body is not read yet. " + throw new Exception("Response body is not read yet. " +
"Use SessionEventArgs.GetResponseBody() or SessionEventArgs.GetResponseBodyAsString() " + "Use SessionEventArgs.GetResponseBody() or SessionEventArgs.GetResponseBodyAsString() " +
...@@ -187,41 +87,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -187,41 +87,6 @@ namespace Titanium.Web.Proxy.Http
} }
} }
/// <summary>
/// Response body as byte array
/// </summary>
[Browsable(false)]
public byte[] Body
{
get
{
EnsureBodyAvailable();
return body;
}
internal set
{
body = value;
bodyString = null;
}
}
/// <summary>
/// Response body as string
/// Use the encoding specified in response to decode the byte[] data to string
/// </summary>
[Browsable(false)]
public string BodyString => bodyString ?? (bodyString = Encoding.GetString(Body));
/// <summary>
/// Was response body read by user
/// </summary>
public bool IsBodyRead { get; internal set; }
/// <summary>
/// Is response is no more modifyable by user (user callbacks complete?)
/// </summary>
internal bool ResponseLocked { get; set; }
/// <summary> /// <summary>
/// Is response 100-continue /// Is response 100-continue
/// </summary> /// </summary>
...@@ -240,7 +105,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -240,7 +105,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Gets the header text. /// Gets the header text.
/// </summary> /// </summary>
public string HeaderText public override string HeaderText
{ {
get get
{ {
...@@ -280,27 +145,5 @@ namespace Titanium.Web.Proxy.Http ...@@ -280,27 +145,5 @@ namespace Titanium.Web.Proxy.Http
statusCode = int.Parse(httpResult[1]); statusCode = int.Parse(httpResult[1]);
statusDescription = httpResult[2]; statusDescription = httpResult[2];
} }
internal void UpdateContentLength()
{
ContentLength = IsChunked ? -1 : body.Length;
}
/// <summary>
/// Finish the session
/// </summary>
internal void FinishSession()
{
if (!KeepBody)
{
body = null;
bodyString = null;
}
}
public override string ToString()
{
return HeaderText;
}
} }
} }
...@@ -435,7 +435,7 @@ namespace Titanium.Web.Proxy ...@@ -435,7 +435,7 @@ namespace Titanium.Web.Proxy
} }
//If user requested call back then do it //If user requested call back then do it
if (!args.WebSession.Response.ResponseLocked) if (!args.WebSession.Response.Locked)
{ {
await InvokeBeforeResponse(args); await InvokeBeforeResponse(args);
} }
...@@ -490,7 +490,7 @@ namespace Titanium.Web.Proxy ...@@ -490,7 +490,7 @@ namespace Titanium.Web.Proxy
try try
{ {
var request = args.WebSession.Request; var request = args.WebSession.Request;
request.RequestLocked = true; request.Locked = true;
//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
......
...@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy ...@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy
args.ReRequest = false; args.ReRequest = false;
//if user requested call back then do it //if user requested call back then do it
if (!response.ResponseLocked) if (!response.Locked)
{ {
await InvokeBeforeResponse(args); await InvokeBeforeResponse(args);
} }
...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy ...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy
return; return;
} }
response.ResponseLocked = true; response.Locked = true;
var clientStreamWriter = args.ProxyClient.ClientStreamWriter; var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
......
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