Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit bcd0747

Browse files
committed
allow modifying request headers
1 parent 39bdfe5 commit bcd0747

File tree

4 files changed

+125
-72
lines changed

4 files changed

+125
-72
lines changed

Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ namespace Titanium.Web.Proxy.EventArguments
2222
/// </summary>
2323
public class SessionEventArgs : EventArgs, IDisposable
2424
{
25-
readonly int _bufferSize;
2625

2726
/// <summary>
2827
/// Constructor to initialize the proxy
2928
/// </summary>
30-
internal SessionEventArgs(int bufferSize)
29+
internal SessionEventArgs()
3130
{
32-
_bufferSize = bufferSize;
31+
3332
Client = new ProxyClient();
3433
ProxySession = new HttpWebSession();
3534
}
@@ -406,7 +405,7 @@ public void Ok(string html)
406405
connectStreamWriter.WriteLine("Pragma: no-cache");
407406
connectStreamWriter.WriteLine("Expires: 0");
408407

409-
connectStreamWriter.WriteLine(ProxySession.Request.IsAlive ? "Connection: Keep-Alive" : "Connection: close");
408+
//connectStreamWriter.WriteLine(ProxySession.Request.IsAlive ? "Connection: Keep-Alive" : "Connection: close");
410409

411410
connectStreamWriter.WriteLine();
412411
connectStreamWriter.Flush();

Titanium.Web.Proxy/Extensions/HttpWebRequestExtensions.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ namespace Titanium.Web.Proxy.Extensions
1010
public static class HttpWebRequestExtensions
1111
{
1212
//Get encoding of the HTTP request
13-
public static Encoding GetEncoding(this HttpWebSession request)
13+
public static Encoding GetEncoding(this Request request)
1414
{
1515
try
1616
{
1717
//return default if not specified
18-
if (request.Request.ContentType == null) return Encoding.GetEncoding("ISO-8859-1");
18+
if (request.ContentType == null) return Encoding.GetEncoding("ISO-8859-1");
1919

2020
//extract the encoding by finding the charset
21-
var contentTypes = request.Request.ContentType.Split(';');
21+
var contentTypes = request.ContentType.Split(';');
2222
foreach (var contentType in contentTypes)
2323
{
2424
var encodingSplit = contentType.Split('=');

Titanium.Web.Proxy/Network/HttpWebClient.cs

+112-19
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,124 @@
99
using System.Threading.Tasks;
1010
using Titanium.Web.Proxy.Helpers;
1111
using Titanium.Web.Proxy.Models;
12+
using System.Linq;
13+
using Titanium.Web.Proxy.Extensions;
1214

1315
namespace Titanium.Web.Proxy.Network
1416
{
1517
public class Request
1618
{
17-
public string Method { get; internal set; }
18-
public Uri RequestUri { get; internal set; }
19-
public string HttpVersion { get; internal set; }
19+
public string Method { get; set; }
20+
public Uri RequestUri { get; set; }
21+
public string HttpVersion { get; set; }
2022

21-
public string Status { get; internal set; }
22-
public int ContentLength { get; internal set; }
23-
public bool SendChunked { get; internal set; }
24-
public string ContentType { get; internal set; }
25-
public bool KeepAlive { get; internal set; }
26-
public string Hostname { get; internal set; }
23+
public string Host
24+
{
25+
get
26+
{
27+
var host = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "host");
28+
if (host != null)
29+
return host.Value;
30+
return null;
31+
}
32+
set
33+
{
34+
var host = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "host");
35+
if (host != null)
36+
host.Value = value;
37+
else
38+
RequestHeaders.Add(new HttpHeader("Host", value));
39+
}
40+
}
2741

28-
public string Url { get; internal set; }
42+
public int ContentLength
43+
{
44+
get
45+
{
46+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-length");
47+
48+
if (header == null)
49+
return 0;
50+
51+
int contentLen;
52+
int.TryParse(header.Value, out contentLen);
53+
if (contentLen != 0)
54+
return contentLen;
55+
56+
return 0;
57+
}
58+
set
59+
{
60+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-length");
61+
62+
if (header != null)
63+
header.Value = value.ToString();
64+
else
65+
RequestHeaders.Add(new HttpHeader("content-length", value.ToString()));
66+
}
67+
}
68+
69+
public string ContentType
70+
{
71+
get
72+
{
73+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-type");
74+
if (header != null)
75+
return header.Value;
76+
return null;
77+
}
78+
set
79+
{
80+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "content-type");
81+
82+
if (header != null)
83+
header.Value = value.ToString();
84+
else
85+
RequestHeaders.Add(new HttpHeader("content-type", value.ToString()));
86+
}
87+
88+
}
89+
90+
public bool SendChunked
91+
{
92+
get
93+
{
94+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "transfer-encoding");
95+
if (header != null) return header.Value.ToLower().Contains("chunked");
96+
return false;
97+
}
98+
}
99+
100+
public string Url { get { return RequestUri.OriginalString; } }
101+
102+
internal Encoding Encoding { get { return this.GetEncoding(); } }
29103

30-
internal Encoding Encoding { get; set; }
31-
internal bool IsAlive { get; set; }
32104
internal bool CancelRequest { get; set; }
105+
33106
internal byte[] RequestBody { get; set; }
34107
internal string RequestBodyString { get; set; }
35108
internal bool RequestBodyRead { get; set; }
36-
internal bool UpgradeToWebSocket { get; set; }
37-
public List<HttpHeader> RequestHeaders { get; internal set; }
38109
internal bool RequestLocked { get; set; }
39110

111+
internal bool UpgradeToWebSocket
112+
{
113+
get
114+
{
115+
var header = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "upgrade");
116+
if (header == null)
117+
return false;
118+
119+
if (header.Value.ToLower() == "websocket")
120+
return true;
121+
122+
return false;
123+
124+
}
125+
}
126+
127+
public List<HttpHeader> RequestHeaders { get; set; }
128+
129+
40130
public Request()
41131
{
42132
this.RequestHeaders = new List<HttpHeader>();
@@ -46,29 +136,32 @@ public Request()
46136

47137
public class Response
48138
{
139+
public string ResponseStatusCode { get; set; }
140+
public string ResponseStatusDescription { get; set; }
49141

50142
internal Encoding Encoding { get; set; }
51143
internal Stream ResponseStream { get; set; }
52144
internal byte[] ResponseBody { get; set; }
53145
internal string ResponseBodyString { get; set; }
54146
internal bool ResponseBodyRead { get; set; }
55147
internal bool ResponseLocked { get; set; }
56-
public List<HttpHeader> ResponseHeaders { get; internal set; }
57148
internal string CharacterSet { get; set; }
58149
internal string ContentEncoding { get; set; }
59150
internal string HttpVersion { get; set; }
60-
public string ResponseStatusCode { get; internal set; }
61-
public string ResponseStatusDescription { get; internal set; }
62151
internal bool ResponseKeepAlive { get; set; }
152+
63153
public string ContentType { get; internal set; }
154+
64155
internal int ContentLength { get; set; }
65156
internal bool IsChunked { get; set; }
66157

158+
public List<HttpHeader> ResponseHeaders { get; internal set; }
159+
67160
public Response()
68161
{
69162
this.ResponseHeaders = new List<HttpHeader>();
70163
this.ResponseKeepAlive = true;
71-
}
164+
}
72165
}
73166

74167
public class HttpWebSession
@@ -129,7 +222,7 @@ public void ReceiveResponse()
129222
{
130223
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
131224

132-
if(string.IsNullOrEmpty(httpResult[0]))
225+
if (string.IsNullOrEmpty(httpResult[0]))
133226
{
134227
var s = ProxyClient.ServerStreamReader.ReadLine();
135228
}

Titanium.Web.Proxy/RequestHandler.cs

+7-46
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, S
184184
break;
185185
}
186186

187-
var args = new SessionEventArgs(BUFFER_SIZE);
187+
var args = new SessionEventArgs();
188188
args.Client.TcpClient = client;
189189

190190
try
@@ -219,7 +219,7 @@ private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, S
219219

220220
SetRequestHeaders(args.ProxySession.Request.RequestHeaders, args.ProxySession);
221221

222-
var httpRemoteUri = new Uri(!IsHttps ? httpCmdSplit[1] : (string.Concat("https://", args.ProxySession.Request.Hostname, httpCmdSplit[1])));
222+
var httpRemoteUri = new Uri(!IsHttps ? httpCmdSplit[1] : (string.Concat("https://", args.ProxySession.Request.Host, httpCmdSplit[1])));
223223
args.IsHttps = IsHttps;
224224

225225
if (args.ProxySession.Request.UpgradeToWebSocket)
@@ -237,14 +237,11 @@ private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, S
237237
args.Client.ClientStream = clientStream;
238238
args.Client.ClientStreamReader = clientStreamReader;
239239
args.Client.ClientStreamWriter = clientStreamWriter;
240-
args.ProxySession.Request.Hostname = args.ProxySession.Request.RequestUri.Host;
241-
args.ProxySession.Request.Url = args.ProxySession.Request.RequestUri.OriginalString;
242-
240+
args.ProxySession.Request.Host = args.ProxySession.Request.RequestUri.Host;
243241

244242
//If requested interception
245243
if (BeforeRequest != null)
246244
{
247-
args.ProxySession.Request.Encoding = args.ProxySession.GetEncoding();
248245
BeforeRequest(null, args);
249246
}
250247

@@ -260,10 +257,10 @@ private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, S
260257
//construct the web request that we are going to issue on behalf of the client.
261258
connection = connection == null ?
262259
TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
263-
: lastRequestHostName != args.ProxySession.Request.Hostname ? TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
260+
: lastRequestHostName != args.ProxySession.Request.Host ? TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
264261
: connection;
265262

266-
lastRequestHostName = args.ProxySession.Request.Hostname;
263+
lastRequestHostName = args.ProxySession.Request.Host;
267264

268265
args.ProxySession.SetConnection(connection);
269266
args.ProxySession.SendRequest();
@@ -326,44 +323,8 @@ private static void SetRequestHeaders(List<HttpHeader> requestHeaders, HttpWebSe
326323
{
327324
case "accept-encoding":
328325
requestHeaders[i].Value = "gzip,deflate,zlib";
329-
break;
330-
case "connection":
331-
if (requestHeaders[i].Value.ToLower() == "keep-alive")
332-
webRequest.Request.KeepAlive = true;
333-
break;
334-
case "content-length":
335-
int contentLen;
336-
int.TryParse(requestHeaders[i].Value, out contentLen);
337-
if (contentLen != 0)
338-
webRequest.Request.ContentLength = contentLen;
339-
break;
340-
case "content-type":
341-
webRequest.Request.ContentType = requestHeaders[i].Value;
342-
break;
343-
case "host":
344-
webRequest.Request.Hostname = requestHeaders[i].Value;
345-
break;
346-
case "proxy-connection":
347-
if (requestHeaders[i].Value.ToLower() == "keep-alive")
348-
webRequest.Request.KeepAlive = true;
349-
else if (requestHeaders[i].Value.ToLower() == "close")
350-
webRequest.Request.KeepAlive = false;
351-
break;
352-
353-
case "upgrade":
354-
if (requestHeaders[i].Value.ToLower() == "websocket")
355-
webRequest.Request.UpgradeToWebSocket = true;
356-
break;
357-
358-
//revisit this, transfer-encoding is not a request header according to spec
359-
//But how to identify if client is sending chunked body for PUT/POST?
360-
case "transfer-encoding":
361-
if (requestHeaders[i].Value.ToLower().Contains("chunked"))
362-
webRequest.Request.SendChunked = true;
363-
else
364-
webRequest.Request.SendChunked = false;
365-
break;
366-
326+
break;
327+
367328
default:
368329
break;
369330
}

0 commit comments

Comments
 (0)