Commit bcd0747a authored by titanium007's avatar titanium007

allow modifying request headers

parent 39bdfe5d
......@@ -22,14 +22,13 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
public class SessionEventArgs : EventArgs, IDisposable
{
readonly int _bufferSize;
/// <summary>
/// Constructor to initialize the proxy
/// </summary>
internal SessionEventArgs(int bufferSize)
internal SessionEventArgs()
{
_bufferSize = bufferSize;
Client = new ProxyClient();
ProxySession = new HttpWebSession();
}
......@@ -406,7 +405,7 @@ namespace Titanium.Web.Proxy.EventArguments
connectStreamWriter.WriteLine("Pragma: no-cache");
connectStreamWriter.WriteLine("Expires: 0");
connectStreamWriter.WriteLine(ProxySession.Request.IsAlive ? "Connection: Keep-Alive" : "Connection: close");
//connectStreamWriter.WriteLine(ProxySession.Request.IsAlive ? "Connection: Keep-Alive" : "Connection: close");
connectStreamWriter.WriteLine();
connectStreamWriter.Flush();
......
......@@ -10,15 +10,15 @@ namespace Titanium.Web.Proxy.Extensions
public static class HttpWebRequestExtensions
{
//Get encoding of the HTTP request
public static Encoding GetEncoding(this HttpWebSession request)
public static Encoding GetEncoding(this Request request)
{
try
{
//return default if not specified
if (request.Request.ContentType == null) return Encoding.GetEncoding("ISO-8859-1");
if (request.ContentType == null) return Encoding.GetEncoding("ISO-8859-1");
//extract the encoding by finding the charset
var contentTypes = request.Request.ContentType.Split(';');
var contentTypes = request.ContentType.Split(';');
foreach (var contentType in contentTypes)
{
var encodingSplit = contentType.Split('=');
......
......@@ -9,34 +9,124 @@ using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
using System.Linq;
using Titanium.Web.Proxy.Extensions;
namespace Titanium.Web.Proxy.Network
{
public class Request
{
public string Method { get; internal set; }
public Uri RequestUri { get; internal set; }
public string HttpVersion { get; internal set; }
public string Method { get; set; }
public Uri RequestUri { get; set; }
public string HttpVersion { get; set; }
public string Status { get; internal set; }
public int ContentLength { get; internal set; }
public bool SendChunked { get; internal set; }
public string ContentType { get; internal set; }
public bool KeepAlive { get; internal set; }
public string Hostname { get; internal set; }
public string Host
{
get
{
var host = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "host");
if (host != null)
return host.Value;
return null;
}
set
{
var host = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "host");
if (host != null)
host.Value = value;
else
RequestHeaders.Add(new HttpHeader("Host", value));
}
}
public string Url { get; internal set; }
public int ContentLength
{
get
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-length");
if (header == null)
return 0;
int contentLen;
int.TryParse(header.Value, out contentLen);
if (contentLen != 0)
return contentLen;
return 0;
}
set
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-length");
if (header != null)
header.Value = value.ToString();
else
RequestHeaders.Add(new HttpHeader("content-length", value.ToString()));
}
}
public string ContentType
{
get
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-type");
if (header != null)
return header.Value;
return null;
}
set
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-type");
if (header != null)
header.Value = value.ToString();
else
RequestHeaders.Add(new HttpHeader("content-type", value.ToString()));
}
}
public bool SendChunked
{
get
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "transfer-encoding");
if (header != null) return header.Value.ToLower().Contains("chunked");
return false;
}
}
public string Url { get { return RequestUri.OriginalString; } }
internal Encoding Encoding { get { return this.GetEncoding(); } }
internal Encoding Encoding { get; set; }
internal bool IsAlive { get; set; }
internal bool CancelRequest { get; set; }
internal byte[] RequestBody { get; set; }
internal string RequestBodyString { get; set; }
internal bool RequestBodyRead { get; set; }
internal bool UpgradeToWebSocket { get; set; }
public List<HttpHeader> RequestHeaders { get; internal set; }
internal bool RequestLocked { get; set; }
internal bool UpgradeToWebSocket
{
get
{
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "upgrade");
if (header == null)
return false;
if (header.Value.ToLower() == "websocket")
return true;
return false;
}
}
public List<HttpHeader> RequestHeaders { get; set; }
public Request()
{
this.RequestHeaders = new List<HttpHeader>();
......@@ -46,6 +136,8 @@ namespace Titanium.Web.Proxy.Network
public class Response
{
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; }
internal Encoding Encoding { get; set; }
internal Stream ResponseStream { get; set; }
......@@ -53,17 +145,18 @@ namespace Titanium.Web.Proxy.Network
internal string ResponseBodyString { get; set; }
internal bool ResponseBodyRead { get; set; }
internal bool ResponseLocked { get; set; }
public List<HttpHeader> ResponseHeaders { get; internal set; }
internal string CharacterSet { get; set; }
internal string ContentEncoding { get; set; }
internal string HttpVersion { get; set; }
public string ResponseStatusCode { get; internal set; }
public string ResponseStatusDescription { get; internal set; }
internal bool ResponseKeepAlive { get; set; }
public string ContentType { get; internal set; }
internal int ContentLength { get; set; }
internal bool IsChunked { get; set; }
public List<HttpHeader> ResponseHeaders { get; internal set; }
public Response()
{
this.ResponseHeaders = new List<HttpHeader>();
......@@ -129,7 +222,7 @@ namespace Titanium.Web.Proxy.Network
{
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
if(string.IsNullOrEmpty(httpResult[0]))
if (string.IsNullOrEmpty(httpResult[0]))
{
var s = ProxyClient.ServerStreamReader.ReadLine();
}
......
......@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy
break;
}
var args = new SessionEventArgs(BUFFER_SIZE);
var args = new SessionEventArgs();
args.Client.TcpClient = client;
try
......@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy
SetRequestHeaders(args.ProxySession.Request.RequestHeaders, args.ProxySession);
var httpRemoteUri = new Uri(!IsHttps ? httpCmdSplit[1] : (string.Concat("https://", args.ProxySession.Request.Hostname, httpCmdSplit[1])));
var httpRemoteUri = new Uri(!IsHttps ? httpCmdSplit[1] : (string.Concat("https://", args.ProxySession.Request.Host, httpCmdSplit[1])));
args.IsHttps = IsHttps;
if (args.ProxySession.Request.UpgradeToWebSocket)
......@@ -237,14 +237,11 @@ namespace Titanium.Web.Proxy
args.Client.ClientStream = clientStream;
args.Client.ClientStreamReader = clientStreamReader;
args.Client.ClientStreamWriter = clientStreamWriter;
args.ProxySession.Request.Hostname = args.ProxySession.Request.RequestUri.Host;
args.ProxySession.Request.Url = args.ProxySession.Request.RequestUri.OriginalString;
args.ProxySession.Request.Host = args.ProxySession.Request.RequestUri.Host;
//If requested interception
if (BeforeRequest != null)
{
args.ProxySession.Request.Encoding = args.ProxySession.GetEncoding();
BeforeRequest(null, args);
}
......@@ -260,10 +257,10 @@ namespace Titanium.Web.Proxy
//construct the web request that we are going to issue on behalf of the client.
connection = connection == null ?
TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
: lastRequestHostName != args.ProxySession.Request.Hostname ? TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
: lastRequestHostName != args.ProxySession.Request.Host ? TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
: connection;
lastRequestHostName = args.ProxySession.Request.Hostname;
lastRequestHostName = args.ProxySession.Request.Host;
args.ProxySession.SetConnection(connection);
args.ProxySession.SendRequest();
......@@ -327,42 +324,6 @@ namespace Titanium.Web.Proxy
case "accept-encoding":
requestHeaders[i].Value = "gzip,deflate,zlib";
break;
case "connection":
if (requestHeaders[i].Value.ToLower() == "keep-alive")
webRequest.Request.KeepAlive = true;
break;
case "content-length":
int contentLen;
int.TryParse(requestHeaders[i].Value, out contentLen);
if (contentLen != 0)
webRequest.Request.ContentLength = contentLen;
break;
case "content-type":
webRequest.Request.ContentType = requestHeaders[i].Value;
break;
case "host":
webRequest.Request.Hostname = requestHeaders[i].Value;
break;
case "proxy-connection":
if (requestHeaders[i].Value.ToLower() == "keep-alive")
webRequest.Request.KeepAlive = true;
else if (requestHeaders[i].Value.ToLower() == "close")
webRequest.Request.KeepAlive = false;
break;
case "upgrade":
if (requestHeaders[i].Value.ToLower() == "websocket")
webRequest.Request.UpgradeToWebSocket = true;
break;
//revisit this, transfer-encoding is not a request header according to spec
//But how to identify if client is sending chunked body for PUT/POST?
case "transfer-encoding":
if (requestHeaders[i].Value.ToLower().Contains("chunked"))
webRequest.Request.SendChunked = true;
else
webRequest.Request.SendChunked = false;
break;
default:
break;
......
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