Commit 8242536d authored by titanium007's avatar titanium007

Separate Request & Response

parent 27fc293a
......@@ -44,7 +44,7 @@ namespace Titanium.Web.Proxy.EventArguments
internal bool RequestBodyRead { get; set; }
public List<HttpHeader> RequestHeaders { get; internal set; }
internal bool RequestLocked { get; set; }
internal HttpWebClient ProxySession { get; set; }
internal HttpWebSession ProxySession { get; set; }
internal Encoding ResponseEncoding { get; set; }
internal Stream ResponseStream { get; set; }
......@@ -69,13 +69,13 @@ namespace Titanium.Web.Proxy.EventArguments
public string RequestMethod
{
get { return ProxySession.Method; }
get { return ProxySession.Request.Method; }
}
public string ResponseStatusCode
{
get { return ProxySession.ResponseStatusCode; }
get { return ProxySession.Response.ResponseStatusCode; }
}
public string ResponseContentType
......@@ -102,7 +102,7 @@ namespace Titanium.Web.Proxy.EventArguments
private void ReadRequestBody()
{
if ((ProxySession.Method.ToUpper() != "POST" && ProxySession.Method.ToUpper() != "PUT"))
if ((ProxySession.Request.Method.ToUpper() != "POST" && ProxySession.Request.Method.ToUpper() != "PUT"))
{
throw new BodyNotFoundException("Request don't have a body." +
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body.");
......@@ -189,7 +189,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
if (ResponseBody == null)
{
switch ( ProxySession.ResponseContentEncoding)
switch ( ProxySession.Response.ResponseContentEncoding)
{
case "gzip":
ResponseBody = CompressionHelper.DecompressGzip(ResponseStream);
......
......@@ -6,13 +6,13 @@ namespace Titanium.Web.Proxy.Extensions
{
public static class HttpWebRequestExtensions
{
public static Encoding GetEncoding(this HttpWebClient request)
public static Encoding GetEncoding(this HttpWebSession request)
{
try
{
if (request.RequestContentType == null) return Encoding.GetEncoding("ISO-8859-1");
if (request.Request.RequestContentType == null) return Encoding.GetEncoding("ISO-8859-1");
var contentTypes = request.RequestContentType.Split(';');
var contentTypes = request.Request.RequestContentType.Split(';');
foreach (var contentType in contentTypes)
{
var encodingSplit = contentType.Split('=');
......
......@@ -6,10 +6,10 @@ namespace Titanium.Web.Proxy.Extensions
{
public static class HttpWebResponseExtensions
{
public static Encoding GetResponseEncoding(this HttpWebClient response)
public static Encoding GetResponseEncoding(this HttpWebSession response)
{
if (string.IsNullOrEmpty(response.ResponseCharacterSet)) return Encoding.GetEncoding("ISO-8859-1");
return Encoding.GetEncoding(response.ResponseCharacterSet.Replace(@"""",string.Empty));
if (string.IsNullOrEmpty(response.Response.ResponseCharacterSet)) return Encoding.GetEncoding("ISO-8859-1");
return Encoding.GetEncoding(response.Response.ResponseCharacterSet.Replace(@"""", string.Empty));
}
}
}
\ No newline at end of file
......@@ -12,10 +12,8 @@ using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http
{
public class HttpWebClient
public class Request
{
private const string Space = " ";
public string Method { get; set; }
public Uri RequestUri { get; set; }
......@@ -24,30 +22,75 @@ namespace Titanium.Web.Proxy.Http
public List<HttpHeader> RequestHeaders { get; set; }
public bool IsSecure
public string RequestStatus { get; set; }
public int RequestContentLength { get; set; }
public bool RequestSendChunked { get; set; }
public string RequestContentType { get; set; }
public bool RequestKeepAlive { get; set; }
public string RequestHost { get; set; }
public Request()
{
get
{
return this.RequestUri.Scheme == Uri.UriSchemeHttps;
}
this.RequestHeaders = new List<HttpHeader>();
}
}
public TcpClient Client { get; set; }
public string RequestStatus { get; set; }
public class Response
{
public List<HttpHeader> ResponseHeaders { get; set; }
public int RequestContentLength { get; set; }
public string ResponseCharacterSet { get; set; }
public bool RequestSendChunked { get; set; }
public string ResponseContentEncoding { get; set; }
public System.Version ResponseProtocolVersion { get; set; }
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; }
public bool ResponseKeepAlive { get; set; }
public string ResponseContentType { get; set; }
public HttpWebClient()
public Response()
{
this.RequestHeaders = new List<HttpHeader>();
this.ResponseHeaders = new List<HttpHeader>();
}
public int ContentLength { get; set; }
}
public class HttpWebSession
{
private const string Space = " ";
public bool IsSecure
{
get
{
return this.Request.RequestUri.Scheme == Uri.UriSchemeHttps;
}
}
public Request Request { get; set; }
public Response Response { get; set; }
public TcpClient Client { get; set; }
public HttpWebSession()
{
this.Request = new Request();
this.Response = new Response();
}
public CustomBinaryReader ServerStreamReader { get; set; }
public async Task SendRequest()
......@@ -58,12 +101,12 @@ namespace Titanium.Web.Proxy.Http
requestLines.AppendLine(string.Join(" ", new string[3]
{
this.Method,
this.RequestUri.AbsolutePath,
this.Version
this.Request.Method,
this.Request.RequestUri.AbsolutePath,
this.Request.Version
}));
foreach (HttpHeader httpHeader in this.RequestHeaders)
foreach (HttpHeader httpHeader in this.Request.RequestHeaders)
{
requestLines.AppendLine(httpHeader.Name + ':' + httpHeader.Value);
......@@ -77,7 +120,7 @@ namespace Titanium.Web.Proxy.Http
await AsyncExtensions.FlushAsync((Stream)stream);
}
public void ReceiveResponse()
public void ReceiveResponse()
{
Stream stream = Client.GetStream();
ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII);
......@@ -95,46 +138,26 @@ namespace Titanium.Web.Proxy.Http
version = new Version(1, 0);
}
this.ResponseProtocolVersion = version;
this.ResponseStatusCode = httpResult[1];
this.Response.ResponseProtocolVersion = version;
this.Response.ResponseStatusCode = httpResult[1];
string status = httpResult[2];
for (int i = 3; i < httpResult.Length; i++)
{
status = status + Space + httpResult[i];
}
this.ResponseStatusDescription = status;
this.Response.ResponseStatusDescription = status;
List<string> responseLines = ServerStreamReader.ReadAllLines();
for (int index = 0; index < responseLines.Count; ++index)
{
string[] strArray = responseLines[index].Split(':');
this.ResponseHeaders.Add(new HttpHeader(strArray[0], strArray[1]));
this.Response.ResponseHeaders.Add(new HttpHeader(strArray[0], strArray[1]));
}
}
public string RequestContentType { get; set; }
public bool RequestKeepAlive { get; set; }
public string RequestHost { get; set; }
public string ResponseCharacterSet { get; set; }
public string ResponseContentEncoding { get; set; }
public System.Version ResponseProtocolVersion { get; set; }
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; }
public bool ResponseKeepAlive { get; set; }
public string ResponseContentType { get; set; }
}
......
......@@ -176,28 +176,28 @@ namespace Titanium.Web.Proxy
}
//construct the web request that we are going to issue on behalf of the client.
args.ProxySession = new Http.HttpWebClient();
args.ProxySession.RequestUri = httpRemoteUri;
args.ProxySession = new Http.HttpWebSession();
args.ProxySession.Request.RequestUri = httpRemoteUri;
//args.ProxyRequest.Proxy = null;
//args.ProxyRequest.UseDefaultCredentials = true;
args.ProxySession.Method = httpMethod;
args.ProxySession.Version = httpVersion;
args.ProxySession.Request.Method = httpMethod;
args.ProxySession.Request.Version = httpVersion;
// args.ProxyRequest.ProtocolVersion = version;
args.ClientStream = clientStream;
args.ClientStreamReader = clientStreamReader;
args.ClientStreamWriter = clientStreamWriter;
// args.ProxyRequest.AllowAutoRedirect = false;
// args.ProxyRequest.AutomaticDecompression = DecompressionMethods.None;
args.RequestHostname = args.ProxySession.RequestUri.Host;
args.RequestUrl = args.ProxySession.RequestUri.OriginalString;
args.RequestHostname = args.ProxySession.Request.RequestUri.Host;
args.RequestUrl = args.ProxySession.Request.RequestUri.OriginalString;
args.ClientPort = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
args.ClientIpAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
args.RequestHttpVersion = version;
//args.RequestIsAlive = args.ProxyRequest.KeepAlive;
//args.ProxyRequest.AllowWriteStreamBuffering = true;
args.Client = await TcpConnectionManager.GetClient(args.ProxySession.RequestUri.Host, args.ProxySession.RequestUri.Port, args.IsHttps);
args.Client = await TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps);
args.ProxySession.Client = args.Client;
//If requested interception
if (BeforeRequest != null)
......@@ -221,7 +221,7 @@ namespace Titanium.Web.Proxy
//If request was modified by user
if (args.RequestBodyRead)
{
args.ProxySession.RequestContentLength = args.RequestBody.Length;
args.ProxySession.Request.RequestContentLength = args.RequestBody.Length;
var newStream = args.ProxySession.ServerStreamReader.BaseStream;
newStream.Write(args.RequestBody, 0, args.RequestBody.Length);
}
......@@ -243,6 +243,7 @@ namespace Titanium.Web.Proxy
return;
}
//TcpConnectionManager.AddClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps, args.ProxySession.Client);
// read the next request
httpCmd = clientStreamReader.ReadLine();
......@@ -264,7 +265,7 @@ namespace Titanium.Web.Proxy
clientStreamWriter.Flush();
}
private static void SetRequestHeaders(List<HttpHeader> requestHeaders, HttpWebClient webRequest)
private static void SetRequestHeaders(List<HttpHeader> requestHeaders, HttpWebSession webRequest)
{
for (var i = 0; i < requestHeaders.Count; i++)
{
......@@ -281,16 +282,16 @@ namespace Titanium.Web.Proxy
break;
case "connection":
if (requestHeaders[i].Value.ToLower() == "keep-alive")
webRequest.RequestKeepAlive = true;
webRequest.Request.RequestKeepAlive = true;
break;
case "content-length":
int contentLen;
int.TryParse(requestHeaders[i].Value, out contentLen);
if (contentLen != 0)
webRequest.RequestContentLength = contentLen;
webRequest.Request.RequestContentLength = contentLen;
break;
case "content-type":
webRequest.RequestContentType = requestHeaders[i].Value;
webRequest.Request.RequestContentType = requestHeaders[i].Value;
break;
case "expect":
//if (requestHeaders[i].Value.ToLower() == "100-continue")
......@@ -299,7 +300,7 @@ namespace Titanium.Web.Proxy
// webRequest.Expect = requestHeaders[i].Value;
break;
case "host":
webRequest.RequestHost = requestHeaders[i].Value;
webRequest.Request.RequestHost = requestHeaders[i].Value;
break;
case "if-modified-since":
// var sb = requestHeaders[i].Value.Trim().Split(SemiSplit);
......@@ -309,9 +310,9 @@ namespace Titanium.Web.Proxy
break;
case "proxy-connection":
if (requestHeaders[i].Value.ToLower() == "keep-alive")
webRequest.RequestKeepAlive = true;
webRequest.Request.RequestKeepAlive = true;
else if (requestHeaders[i].Value.ToLower() == "close")
webRequest.RequestKeepAlive = false;
webRequest.Request.RequestKeepAlive = false;
break;
case "range":
// var startEnd = requestHeaders[i].Value.Replace(Environment.NewLine, "").Remove(0, 6).Split('-');
......@@ -335,9 +336,9 @@ namespace Titanium.Web.Proxy
//But how to identify if client is sending chunked body for PUT/POST?
case "transfer-encoding":
if (requestHeaders[i].Value.ToLower().Contains("chunked"))
webRequest.RequestSendChunked = true;
webRequest.Request.RequestSendChunked = true;
else
webRequest.RequestSendChunked = false;
webRequest.Request.RequestSendChunked = false;
break;
case "upgrade":
// if (requestHeaders[i].Value.ToLower() == "http/1.1")
......@@ -351,7 +352,7 @@ namespace Titanium.Web.Proxy
}
}
webRequest.RequestHeaders = requestHeaders;
webRequest.Request.RequestHeaders = requestHeaders;
}
//This is called when the request is PUT/POST to read the body
......@@ -361,7 +362,7 @@ namespace Titanium.Web.Proxy
var postStream = args.ProxySession.ServerStreamReader;
if (args.ProxySession.RequestContentLength > 0)
if (args.ProxySession.Request.RequestContentLength > 0)
{
//args.ProxyRequest.AllowWriteStreamBuffering = true;
try
......@@ -369,20 +370,20 @@ namespace Titanium.Web.Proxy
var totalbytesRead = 0;
int bytesToRead;
if (args.ProxySession.RequestContentLength < BUFFER_SIZE)
if (args.ProxySession.Request.RequestContentLength < BUFFER_SIZE)
{
bytesToRead = (int)args.ProxySession.RequestContentLength;
bytesToRead = (int)args.ProxySession.Request.RequestContentLength;
}
else
bytesToRead = BUFFER_SIZE;
while (totalbytesRead < (int)args.ProxySession.RequestContentLength)
while (totalbytesRead < (int)args.ProxySession.Request.RequestContentLength)
{
var buffer = args.ClientStreamReader.ReadBytes(bytesToRead);
totalbytesRead += buffer.Length;
var remainingBytes = (int)args.ProxySession.RequestContentLength - totalbytesRead;
var remainingBytes = (int)args.ProxySession.Request.RequestContentLength - totalbytesRead;
if (remainingBytes < bytesToRead)
{
bytesToRead = remainingBytes;
......@@ -400,7 +401,7 @@ namespace Titanium.Web.Proxy
}
}
//Need to revist, find any potential bugs
else if (args.ProxySession.RequestSendChunked)
else if (args.ProxySession.Request.RequestSendChunked)
{
//args.ProxyRequest.AllowWriteStreamBuffering = true;
......
......@@ -39,8 +39,8 @@ namespace Titanium.Web.Proxy
if (args.ResponseBodyRead)
{
var isChunked = args.ProxySession.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
var contentEncoding = args.ProxySession.ResponseContentEncoding;
var isChunked = args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
var contentEncoding = args.ProxySession.Response.ResponseContentEncoding;
switch (contentEncoding.ToLower())
{
......@@ -55,8 +55,8 @@ namespace Titanium.Web.Proxy
break;
}
WriteResponseStatus(args.ProxySession.ResponseProtocolVersion, args.ProxySession.ResponseStatusCode,
args.ProxySession.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders, args.ResponseBody.Length,
isChunked);
WriteResponseBody(args.ClientStream, args.ResponseBody, isChunked);
......@@ -65,10 +65,10 @@ namespace Titanium.Web.Proxy
{
// var isChunked = args.ProxySession.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
WriteResponseStatus(args.ProxySession.ResponseProtocolVersion, args.ProxySession.ResponseStatusCode,
args.ProxySession.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders);
WriteResponseBody(args.ResponseStream, args.ClientStream, false);
WriteResponseBody(args.ResponseStream, args.ClientStream, false, args.ProxySession.Response.ContentLength);
}
args.ClientStream.Flush();
......@@ -84,24 +84,24 @@ namespace Titanium.Web.Proxy
}
}
private static List<HttpHeader> ReadResponseHeaders(HttpWebClient response)
private static List<HttpHeader> ReadResponseHeaders(HttpWebSession response)
{
for (var i = 0; i < response.ResponseHeaders.Count; i++)
for (var i = 0; i < response.Response.ResponseHeaders.Count; i++)
{
switch (response.ResponseHeaders[i].Name.ToLower())
switch (response.Response.ResponseHeaders[i].Name.ToLower())
{
case "content-encoding":
response.ResponseContentEncoding = response.ResponseHeaders[i].Value;
response.Response.ResponseContentEncoding = response.Response.ResponseHeaders[i].Value;
break;
case "content-type":
if (response.ResponseHeaders[i].Value.Contains(";"))
if (response.Response.ResponseHeaders[i].Value.Contains(";"))
{
response.ResponseContentType = response.ResponseHeaders[i].Value.Split(';')[0].Trim();
response.ResponseCharacterSet = response.ResponseHeaders[i].Value.Split(';')[1].Replace("charset=", string.Empty).Trim();
response.Response.ResponseContentType = response.Response.ResponseHeaders[i].Value.Split(';')[0].Trim();
response.Response.ResponseCharacterSet = response.Response.ResponseHeaders[i].Value.Split(';')[1].Replace("charset=", string.Empty).Trim();
}
else
response.ResponseContentType = response.ResponseHeaders[i].Value.Trim();
response.Response.ResponseContentType = response.Response.ResponseHeaders[i].Value.Trim();
break;
......@@ -113,8 +113,8 @@ namespace Titanium.Web.Proxy
}
}
// response.ResponseHeaders.RemoveAll(x => x.Name.ToLower() == "connection");
return response.ResponseHeaders;
return response.Response.ResponseHeaders;
}
private static void WriteResponseStatus(Version version, string code, string description,
......@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy
WriteResponseBodyChunked(data, clientStream);
}
private static void WriteResponseBody(Stream inStream, Stream outStream, bool isChunked)
private static void WriteResponseBody(Stream inStream, Stream outStream, bool isChunked, int BodyLength)
{
if (!isChunked)
{
......
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