Commit 53163418 authored by Honfika's avatar Honfika

baseclass for request and response

parent 3ed0a2ef
using System;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Compression
{
......@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Compression
{
switch (type)
{
case "gzip":
case KnownHeaders.ContentEncodingGzip:
return gzip.Value;
case "deflate":
case KnownHeaders.ContentEncodingDeflate:
return deflate.Value;
default:
return def.Value;
......
using System;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Decompression
{
......@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Decompression
{
switch (type)
{
case "gzip":
case KnownHeaders.ContentEncodingGzip:
return gzip.Value;
case "deflate":
case KnownHeaders.ContentEncodingDeflate:
return deflate.Value;
default:
return def.Value;
......
......@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
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.");
}
......@@ -453,7 +453,7 @@ namespace Titanium.Web.Proxy.EventArguments
public async Task SetRequestBody(byte[] body)
{
var request = WebSession.Request;
if (request.RequestLocked)
if (request.Locked)
{
throw new Exception("You cannot call this function after request is made to server.");
}
......@@ -474,7 +474,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
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.");
}
......@@ -522,7 +522,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
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.");
}
......@@ -547,7 +547,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
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.");
}
......@@ -659,14 +659,14 @@ namespace Titanium.Web.Proxy.EventArguments
/// a generic responder method
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.");
}
WebSession.Request.RequestLocked = true;
WebSession.Request.Locked = true;
response.ResponseLocked = true;
response.Locked = true;
response.IsBodyRead = true;
WebSession.Response = response;
......
......@@ -40,6 +40,8 @@ namespace Titanium.Web.Proxy.Http
// Response headers
public const string ContentEncoding = "content-encoding";
public const string ContentEncodingDeflate = "deflate";
public const string ContentEncodingGzip = "gzip";
public const string Location = "Location";
......
......@@ -3,28 +3,17 @@ using System.ComponentModel;
using System.Text;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Http
{
/// <summary>
/// A HTTP(S) request object
/// Http(s) request object
/// </summary>
[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>
/// Request Method
/// </summary>
......@@ -45,16 +34,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
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>
/// Has request body?
/// </summary>
......@@ -97,80 +76,6 @@ namespace Titanium.Web.Proxy.Http
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>
/// Does this request has a 100-continue header?
/// </summary>
......@@ -190,17 +95,12 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public string Url => RequestUri.OriginalString;
/// <summary>
/// Encoding for this request
/// </summary>
public Encoding Encoding => HttpHelper.GetEncodingFromContentType(ContentType);
/// <summary>
/// Terminates the underlying Tcp Connection to client after current request
/// </summary>
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
if (!HasBody)
......@@ -211,7 +111,7 @@ namespace Titanium.Web.Proxy.Http
if (!IsBodyRead)
{
if (RequestLocked)
if (Locked)
{
throw new Exception("You cannot get the request body after request is made to server.");
}
......@@ -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>
/// Does this request has an upgrade to websocket header?
/// </summary>
......@@ -278,11 +143,6 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// Request header collection
/// </summary>
public HeaderCollection Headers { get; } = new HeaderCollection();
/// <summary>
/// Does server responsed positively for 100 continue request
/// </summary>
......@@ -296,7 +156,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Gets the header text.
/// </summary>
public string HeaderText
public override string HeaderText
{
get
{
......@@ -367,27 +227,5 @@ namespace Titanium.Web.Proxy.Http
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 @@
using System.ComponentModel;
using System.Text;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Shared;
......@@ -12,18 +11,8 @@ namespace Titanium.Web.Proxy.Http
/// Http(s) response object
/// </summary>
[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>
/// Response Status Code.
/// </summary>
......@@ -34,26 +23,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
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>
/// Has response body?
/// </summary>
......@@ -108,78 +77,9 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// 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
internal override void EnsureBodyAvailable(bool throwWhenNotReadYet = true)
{
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
{
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)
if (!IsBodyRead && throwWhenNotReadYet)
{
throw new Exception("Response body is not read yet. " +
"Use SessionEventArgs.GetResponseBody() or SessionEventArgs.GetResponseBodyAsString() " +
......@@ -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>
/// Is response 100-continue
/// </summary>
......@@ -240,7 +105,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Gets the header text.
/// </summary>
public string HeaderText
public override string HeaderText
{
get
{
......@@ -280,27 +145,5 @@ namespace Titanium.Web.Proxy.Http
statusCode = int.Parse(httpResult[1]);
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
}
//If user requested call back then do it
if (!args.WebSession.Response.ResponseLocked)
if (!args.WebSession.Response.Locked)
{
await InvokeBeforeResponse(args);
}
......@@ -490,7 +490,7 @@ namespace Titanium.Web.Proxy
try
{
var request = args.WebSession.Request;
request.RequestLocked = true;
request.Locked = true;
//if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue
......
......@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy
args.ReRequest = false;
//if user requested call back then do it
if (!response.ResponseLocked)
if (!response.Locked)
{
await InvokeBeforeResponse(args);
}
......@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy
return;
}
response.ResponseLocked = true;
response.Locked = true;
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