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

Commit 7fd744b

Browse files
committed
Fix issue #47
Allow developers to modify request/response headers
1 parent bcd0747 commit 7fd744b

File tree

4 files changed

+141
-91
lines changed

4 files changed

+141
-91
lines changed

Titanium.Web.Proxy.Test/ProxyTestController.cs

+33-33
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public void StartProxy()
2020
//Usefull for clients that use certificate pinning
2121
//for example dropbox.com
2222
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true){
23-
ExcludedHttpsHostNameRegex = new List<string>() { "dropbox.com" }
23+
// ExcludedHttpsHostNameRegex = new List<string>() { "google.com", "dropbox.com" }
2424
};
2525

2626
//An explicit endpoint is where the client knows about the existance of a proxy
@@ -68,49 +68,49 @@ public void OnRequest(object sender, SessionEventArgs e)
6868
{
6969
Console.WriteLine(e.ProxySession.Request.Url);
7070

71-
////read request headers
72-
//var requestHeaders = e.ProxySession.Request.RequestHeaders;
71+
//read request headers
72+
var requestHeaders = e.ProxySession.Request.RequestHeaders;
7373

74-
//if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT"))
75-
//{
76-
// //Get/Set request body bytes
77-
// byte[] bodyBytes = e.GetRequestBody();
78-
// e.SetRequestBody(bodyBytes);
74+
if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT"))
75+
{
76+
//Get/Set request body bytes
77+
byte[] bodyBytes = e.GetRequestBody();
78+
e.SetRequestBody(bodyBytes);
7979

80-
// //Get/Set request body as string
81-
// string bodyString = e.GetRequestBodyAsString();
82-
// e.SetRequestBodyString(bodyString);
80+
//Get/Set request body as string
81+
string bodyString = e.GetRequestBodyAsString();
82+
e.SetRequestBodyString(bodyString);
8383

84-
//}
84+
}
8585

86-
////To cancel a request with a custom HTML content
87-
////Filter URL
86+
//To cancel a request with a custom HTML content
87+
//Filter URL
8888

89-
//if (e.ProxySession.Request.RequestUrl.Contains("google.com"))
90-
//{
91-
// e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
92-
//}
89+
if (e.ProxySession.Request.RequestUri.AbsoluteUri.Contains("google.com"))
90+
{
91+
e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
92+
}
9393
}
9494

9595
//Test script injection
9696
//Insert script to read the Browser URL and send it back to proxy
9797
public void OnResponse(object sender, SessionEventArgs e)
9898
{
99-
100-
////read response headers
101-
// var responseHeaders = e.ProxySession.Response.ResponseHeaders;
102-
103-
//if (!e.ProxySession.Request.Hostname.Equals("medeczane.sgk.gov.tr")) return;
104-
//if (e.RequestMethod == "GET" || e.RequestMethod == "POST")
105-
//{
106-
// if (e.ProxySession.Response.ResponseStatusCode == "200")
107-
// {
108-
// if (e.ProxySession.Response.ContentType.Trim().ToLower().Contains("text/html"))
109-
// {
110-
// string body = e.GetResponseBodyAsString();
111-
// }
112-
// }
113-
//}
99+
100+
//read response headers
101+
var responseHeaders = e.ProxySession.Response.ResponseHeaders;
102+
103+
//if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
104+
if (e.RequestMethod == "GET" || e.RequestMethod == "POST")
105+
{
106+
if (e.ProxySession.Response.ResponseStatusCode == "200")
107+
{
108+
if (e.ProxySession.Response.ContentType.Trim().ToLower().Contains("text/html"))
109+
{
110+
string body = e.GetResponseBodyAsString();
111+
}
112+
}
113+
}
114114
}
115115
}
116116
}

Titanium.Web.Proxy/Extensions/HttpWebResponseExtensions.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ namespace Titanium.Web.Proxy.Extensions
66
{
77
public static class HttpWebResponseExtensions
88
{
9-
public static Encoding GetResponseEncoding(this HttpWebSession response)
9+
public static Encoding GetResponseEncoding(this Response response)
1010
{
11-
if (string.IsNullOrEmpty(response.Response.CharacterSet))
11+
if (string.IsNullOrEmpty(response.CharacterSet))
1212
return Encoding.GetEncoding("ISO-8859-1");
1313

1414
try
1515
{
16-
return Encoding.GetEncoding(response.Response.CharacterSet.Replace(@"""", string.Empty));
16+
return Encoding.GetEncoding(response.CharacterSet.Replace(@"""", string.Empty));
1717
}
1818
catch { return Encoding.GetEncoding("ISO-8859-1"); }
1919
}

Titanium.Web.Proxy/Network/HttpWebClient.cs

+104-12
Original file line numberDiff line numberDiff line change
@@ -139,28 +139,120 @@ public class Response
139139
public string ResponseStatusCode { get; set; }
140140
public string ResponseStatusDescription { get; set; }
141141

142-
internal Encoding Encoding { get; set; }
142+
internal Encoding Encoding { get { return this.GetResponseEncoding(); } }
143+
144+
internal string CharacterSet
145+
{
146+
get
147+
{
148+
149+
if (this.ContentType.Contains(";"))
150+
{
151+
152+
return this.ContentType.Split(';')[1].Substring(9).Trim();
153+
}
154+
return null;
155+
156+
}
157+
}
158+
internal string ContentEncoding
159+
{
160+
get
161+
{
162+
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-encoding"));
163+
164+
if (header != null)
165+
{
166+
return header.Value.Trim().ToLower();
167+
}
168+
169+
return null;
170+
}
171+
}
172+
173+
internal string HttpVersion { get; set; }
174+
internal bool ResponseKeepAlive
175+
{
176+
get
177+
{
178+
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("connection"));
179+
180+
if (header != null && header.Value.ToLower().Contains("close"))
181+
{
182+
return false;
183+
}
184+
185+
return true;
186+
187+
}
188+
}
189+
190+
public string ContentType
191+
{
192+
get
193+
{
194+
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-type"));
195+
196+
if (header != null)
197+
{
198+
if (header.Value.Contains(";"))
199+
{
200+
201+
return header.Value.Split(';')[0].Trim();
202+
}
203+
else
204+
return header.Value.ToLower().Trim();
205+
}
206+
207+
return null;
208+
209+
}
210+
}
211+
212+
internal int ContentLength
213+
{
214+
get
215+
{
216+
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-length"));
217+
218+
if (header != null)
219+
{
220+
return int.Parse(header.Value.Trim());
221+
}
222+
223+
return -1;
224+
225+
}
226+
}
227+
228+
internal bool IsChunked
229+
{
230+
get
231+
{
232+
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("transfer-encoding"));
233+
234+
if (header != null && header.Value.ToLower().Contains("chunked"))
235+
{
236+
return true;
237+
}
238+
239+
return false;
240+
241+
}
242+
}
243+
244+
public List<HttpHeader> ResponseHeaders { get; set; }
245+
143246
internal Stream ResponseStream { get; set; }
144247
internal byte[] ResponseBody { get; set; }
145248
internal string ResponseBodyString { get; set; }
146249
internal bool ResponseBodyRead { get; set; }
147250
internal bool ResponseLocked { get; set; }
148-
internal string CharacterSet { get; set; }
149-
internal string ContentEncoding { get; set; }
150-
internal string HttpVersion { get; set; }
151-
internal bool ResponseKeepAlive { get; set; }
152-
153-
public string ContentType { get; internal set; }
154-
155-
internal int ContentLength { get; set; }
156-
internal bool IsChunked { get; set; }
157251

158-
public List<HttpHeader> ResponseHeaders { get; internal set; }
159252

160253
public Response()
161254
{
162255
this.ResponseHeaders = new List<HttpHeader>();
163-
this.ResponseKeepAlive = true;
164256
}
165257
}
166258

Titanium.Web.Proxy/ResponseHandler.cs

+1-43
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ private static void HandleHttpSessionResponse(SessionEventArgs args)
2525
try
2626
{
2727

28-
args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
2928
args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
3029

3130

3231
if (BeforeResponse != null)
33-
{
34-
args.ProxySession.Response.Encoding = args.ProxySession.GetResponseEncoding();
32+
{
3533
BeforeResponse(null, args);
3634
}
3735

@@ -85,47 +83,7 @@ private static void HandleHttpSessionResponse(SessionEventArgs args)
8583
}
8684
}
8785

88-
private static List<HttpHeader> ReadResponseHeaders(HttpWebSession response)
89-
{
90-
for (var i = 0; i < response.Response.ResponseHeaders.Count; i++)
91-
{
92-
switch (response.Response.ResponseHeaders[i].Name.ToLower())
93-
{
94-
case "content-length":
95-
response.Response.ContentLength = int.Parse(response.Response.ResponseHeaders[i].Value.Trim());
96-
break;
97-
98-
case "content-encoding":
99-
response.Response.ContentEncoding = response.Response.ResponseHeaders[i].Value.Trim().ToLower();
100-
break;
101-
102-
case "content-type":
103-
if (response.Response.ResponseHeaders[i].Value.Contains(";"))
104-
{
105-
response.Response.ContentType = response.Response.ResponseHeaders[i].Value.Split(';')[0].Trim();
106-
response.Response.CharacterSet = response.Response.ResponseHeaders[i].Value.Split(';')[1].Substring(9).Trim();
107-
}
108-
else
109-
response.Response.ContentType = response.Response.ResponseHeaders[i].Value.ToLower().Trim();
110-
break;
111-
112-
case "transfer-encoding":
113-
if (response.Response.ResponseHeaders[i].Value.ToLower().Contains("chunked"))
114-
response.Response.IsChunked = true;
115-
break;
11686

117-
case "connection":
118-
if (response.Response.ResponseHeaders[i].Value.ToLower().Contains("close"))
119-
response.Response.ResponseKeepAlive = false;
120-
break;
121-
122-
default:
123-
break;
124-
}
125-
}
126-
127-
return response.Response.ResponseHeaders;
128-
}
12987

13088

13189
private static void WriteResponseStatus(string version, string code, string description,

0 commit comments

Comments
 (0)