Commit 7fd744bb authored by titanium007's avatar titanium007

Fix issue #47

Allow developers to modify request/response headers
parent bcd0747a
...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Test ...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Test
//Usefull for clients that use certificate pinning //Usefull for clients that use certificate pinning
//for example dropbox.com //for example dropbox.com
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true){ var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true){
ExcludedHttpsHostNameRegex = new List<string>() { "dropbox.com" } // ExcludedHttpsHostNameRegex = new List<string>() { "google.com", "dropbox.com" }
}; };
//An explicit endpoint is where the client knows about the existance of a proxy //An explicit endpoint is where the client knows about the existance of a proxy
...@@ -68,28 +68,28 @@ namespace Titanium.Web.Proxy.Test ...@@ -68,28 +68,28 @@ namespace Titanium.Web.Proxy.Test
{ {
Console.WriteLine(e.ProxySession.Request.Url); Console.WriteLine(e.ProxySession.Request.Url);
////read request headers //read request headers
//var requestHeaders = e.ProxySession.Request.RequestHeaders; var requestHeaders = e.ProxySession.Request.RequestHeaders;
//if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT")) if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT"))
//{ {
// //Get/Set request body bytes //Get/Set request body bytes
// byte[] bodyBytes = e.GetRequestBody(); byte[] bodyBytes = e.GetRequestBody();
// e.SetRequestBody(bodyBytes); e.SetRequestBody(bodyBytes);
// //Get/Set request body as string //Get/Set request body as string
// string bodyString = e.GetRequestBodyAsString(); string bodyString = e.GetRequestBodyAsString();
// e.SetRequestBodyString(bodyString); e.SetRequestBodyString(bodyString);
//} }
////To cancel a request with a custom HTML content //To cancel a request with a custom HTML content
////Filter URL //Filter URL
//if (e.ProxySession.Request.RequestUrl.Contains("google.com")) if (e.ProxySession.Request.RequestUri.AbsoluteUri.Contains("google.com"))
//{ {
// e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>"); e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
//} }
} }
//Test script injection //Test script injection
...@@ -97,20 +97,20 @@ namespace Titanium.Web.Proxy.Test ...@@ -97,20 +97,20 @@ namespace Titanium.Web.Proxy.Test
public void OnResponse(object sender, SessionEventArgs e) public void OnResponse(object sender, SessionEventArgs e)
{ {
////read response headers //read response headers
// var responseHeaders = e.ProxySession.Response.ResponseHeaders; var responseHeaders = e.ProxySession.Response.ResponseHeaders;
//if (!e.ProxySession.Request.Hostname.Equals("medeczane.sgk.gov.tr")) return; //if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
//if (e.RequestMethod == "GET" || e.RequestMethod == "POST") if (e.RequestMethod == "GET" || e.RequestMethod == "POST")
//{ {
// if (e.ProxySession.Response.ResponseStatusCode == "200") if (e.ProxySession.Response.ResponseStatusCode == "200")
// { {
// if (e.ProxySession.Response.ContentType.Trim().ToLower().Contains("text/html")) if (e.ProxySession.Response.ContentType.Trim().ToLower().Contains("text/html"))
// { {
// string body = e.GetResponseBodyAsString(); string body = e.GetResponseBodyAsString();
// } }
// } }
//} }
} }
} }
} }
\ No newline at end of file
...@@ -6,14 +6,14 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -6,14 +6,14 @@ namespace Titanium.Web.Proxy.Extensions
{ {
public static class HttpWebResponseExtensions public static class HttpWebResponseExtensions
{ {
public static Encoding GetResponseEncoding(this HttpWebSession response) public static Encoding GetResponseEncoding(this Response response)
{ {
if (string.IsNullOrEmpty(response.Response.CharacterSet)) if (string.IsNullOrEmpty(response.CharacterSet))
return Encoding.GetEncoding("ISO-8859-1"); return Encoding.GetEncoding("ISO-8859-1");
try try
{ {
return Encoding.GetEncoding(response.Response.CharacterSet.Replace(@"""", string.Empty)); return Encoding.GetEncoding(response.CharacterSet.Replace(@"""", string.Empty));
} }
catch { return Encoding.GetEncoding("ISO-8859-1"); } catch { return Encoding.GetEncoding("ISO-8859-1"); }
} }
......
...@@ -139,28 +139,120 @@ namespace Titanium.Web.Proxy.Network ...@@ -139,28 +139,120 @@ namespace Titanium.Web.Proxy.Network
public string ResponseStatusCode { get; set; } public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; } public string ResponseStatusDescription { get; set; }
internal Encoding Encoding { get; set; } internal Encoding Encoding { get { return this.GetResponseEncoding(); } }
internal string CharacterSet
{
get
{
if (this.ContentType.Contains(";"))
{
return this.ContentType.Split(';')[1].Substring(9).Trim();
}
return null;
}
}
internal string ContentEncoding
{
get
{
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-encoding"));
if (header != null)
{
return header.Value.Trim().ToLower();
}
return null;
}
}
internal string HttpVersion { get; set; }
internal bool ResponseKeepAlive
{
get
{
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("connection"));
if (header != null && header.Value.ToLower().Contains("close"))
{
return false;
}
return true;
}
}
public string ContentType
{
get
{
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-type"));
if (header != null)
{
if (header.Value.Contains(";"))
{
return header.Value.Split(';')[0].Trim();
}
else
return header.Value.ToLower().Trim();
}
return null;
}
}
internal int ContentLength
{
get
{
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("content-length"));
if (header != null)
{
return int.Parse(header.Value.Trim());
}
return -1;
}
}
internal bool IsChunked
{
get
{
var header = this.ResponseHeaders.FirstOrDefault(x => x.Name.ToLower().Equals("transfer-encoding"));
if (header != null && header.Value.ToLower().Contains("chunked"))
{
return true;
}
return false;
}
}
public List<HttpHeader> ResponseHeaders { get; set; }
internal Stream ResponseStream { get; set; } internal Stream ResponseStream { get; set; }
internal byte[] ResponseBody { get; set; } internal byte[] ResponseBody { get; set; }
internal string ResponseBodyString { get; set; } internal string ResponseBodyString { get; set; }
internal bool ResponseBodyRead { get; set; } internal bool ResponseBodyRead { get; set; }
internal bool ResponseLocked { get; set; } internal bool ResponseLocked { get; set; }
internal string CharacterSet { get; set; }
internal string ContentEncoding { get; set; }
internal string HttpVersion { get; 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() public Response()
{ {
this.ResponseHeaders = new List<HttpHeader>(); this.ResponseHeaders = new List<HttpHeader>();
this.ResponseKeepAlive = true;
} }
} }
......
...@@ -25,13 +25,11 @@ namespace Titanium.Web.Proxy ...@@ -25,13 +25,11 @@ namespace Titanium.Web.Proxy
try try
{ {
args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream; args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
if (BeforeResponse != null) if (BeforeResponse != null)
{ {
args.ProxySession.Response.Encoding = args.ProxySession.GetResponseEncoding();
BeforeResponse(null, args); BeforeResponse(null, args);
} }
...@@ -85,47 +83,7 @@ namespace Titanium.Web.Proxy ...@@ -85,47 +83,7 @@ namespace Titanium.Web.Proxy
} }
} }
private static List<HttpHeader> ReadResponseHeaders(HttpWebSession response)
{
for (var i = 0; i < response.Response.ResponseHeaders.Count; i++)
{
switch (response.Response.ResponseHeaders[i].Name.ToLower())
{
case "content-length":
response.Response.ContentLength = int.Parse(response.Response.ResponseHeaders[i].Value.Trim());
break;
case "content-encoding":
response.Response.ContentEncoding = response.Response.ResponseHeaders[i].Value.Trim().ToLower();
break;
case "content-type":
if (response.Response.ResponseHeaders[i].Value.Contains(";"))
{
response.Response.ContentType = response.Response.ResponseHeaders[i].Value.Split(';')[0].Trim();
response.Response.CharacterSet = response.Response.ResponseHeaders[i].Value.Split(';')[1].Substring(9).Trim();
}
else
response.Response.ContentType = response.Response.ResponseHeaders[i].Value.ToLower().Trim();
break;
case "transfer-encoding":
if (response.Response.ResponseHeaders[i].Value.ToLower().Contains("chunked"))
response.Response.IsChunked = true;
break;
case "connection":
if (response.Response.ResponseHeaders[i].Value.ToLower().Contains("close"))
response.Response.ResponseKeepAlive = false;
break;
default:
break;
}
}
return response.Response.ResponseHeaders;
}
private static void WriteResponseStatus(string version, string code, string description, private static void WriteResponseStatus(string version, string code, string description,
......
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