Commit 4d5ed370 authored by justcoding121's avatar justcoding121

Merge pull request #53 from justcoding121/release

Release
parents aabea620 ca5e25df
...@@ -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,49 +68,49 @@ namespace Titanium.Web.Proxy.Test ...@@ -68,49 +68,49 @@ 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
//Insert script to read the Browser URL and send it back to proxy //Insert script to read the Browser URL and send it back to proxy
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
...@@ -22,14 +22,13 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -22,14 +22,13 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public class SessionEventArgs : EventArgs, IDisposable public class SessionEventArgs : EventArgs, IDisposable
{ {
readonly int _bufferSize;
/// <summary> /// <summary>
/// Constructor to initialize the proxy /// Constructor to initialize the proxy
/// </summary> /// </summary>
internal SessionEventArgs(int bufferSize) internal SessionEventArgs()
{ {
_bufferSize = bufferSize;
Client = new ProxyClient(); Client = new ProxyClient();
ProxySession = new HttpWebSession(); ProxySession = new HttpWebSession();
} }
...@@ -385,10 +384,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -385,10 +384,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// Before request is made to server /// Before request is made to server
/// Respond with the specified HTML string to client /// Respond with the specified HTML string to client
/// and ignore the request /// and ignore the request
/// Marking as obsolete, need to comeup with a generic responder method in future
/// </summary> /// </summary>
/// <param name="html"></param> /// <param name="html"></param>
// [Obsolete]
public void Ok(string html) public void Ok(string html)
{ {
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server."); if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
...@@ -398,22 +395,47 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -398,22 +395,47 @@ namespace Titanium.Web.Proxy.EventArguments
var result = Encoding.Default.GetBytes(html); var result = Encoding.Default.GetBytes(html);
var connectStreamWriter = new StreamWriter(this.Client.ClientStream); Ok(result);
connectStreamWriter.WriteLine(string.Format("{0} {1} {2}", ProxySession.Request.HttpVersion, 200, "Ok")); }
connectStreamWriter.WriteLine("Timestamp: {0}", DateTime.Now);
connectStreamWriter.WriteLine("content-length: " + result.Length); /// <summary>
connectStreamWriter.WriteLine("Cache-Control: no-cache, no-store, must-revalidate"); /// Before request is made to server
connectStreamWriter.WriteLine("Pragma: no-cache"); /// Respond with the specified byte[] to client
connectStreamWriter.WriteLine("Expires: 0"); /// and ignore the request
/// </summary>
/// <param name="body"></param>
public void Ok(byte[] result)
{
var response = new Response();
response.HttpVersion = ProxySession.Request.HttpVersion;
response.ResponseStatusCode = "200";
response.ResponseStatusDescription = "Ok";
connectStreamWriter.WriteLine(ProxySession.Request.IsAlive ? "Connection: Keep-Alive" : "Connection: close"); response.ResponseHeaders.Add(new HttpHeader("Timestamp", DateTime.Now.ToString()));
connectStreamWriter.WriteLine(); response.ResponseHeaders.Add(new HttpHeader("content-length", DateTime.Now.ToString()));
connectStreamWriter.Flush(); response.ResponseHeaders.Add(new HttpHeader("Cache-Control", "no-cache, no-store, must-revalidate"));
response.ResponseHeaders.Add(new HttpHeader("Pragma", "no-cache"));
response.ResponseHeaders.Add(new HttpHeader("Expires", "0"));
this.Client.ClientStream.Write(result, 0, result.Length); response.ResponseBody = result;
Respond(response);
ProxySession.Request.CancelRequest = true; ProxySession.Request.CancelRequest = true;
} }
/// a generic responder method
public void Respond(Response response)
{
ProxySession.Request.RequestLocked = true;
response.ResponseLocked = true;
response.ResponseBodyRead = true;
ProxySession.Response = response;
ProxyServer.HandleHttpSessionResponse(this);
}
} }
} }
\ No newline at end of file
...@@ -10,15 +10,15 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -10,15 +10,15 @@ namespace Titanium.Web.Proxy.Extensions
public static class HttpWebRequestExtensions public static class HttpWebRequestExtensions
{ {
//Get encoding of the HTTP request //Get encoding of the HTTP request
public static Encoding GetEncoding(this HttpWebSession request) public static Encoding GetEncoding(this Request request)
{ {
try try
{ {
//return default if not specified //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 //extract the encoding by finding the charset
var contentTypes = request.Request.ContentType.Split(';'); var contentTypes = request.ContentType.Split(';');
foreach (var contentType in contentTypes) foreach (var contentType in contentTypes)
{ {
var encodingSplit = contentType.Split('='); var encodingSplit = contentType.Split('=');
......
...@@ -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"); }
} }
......
...@@ -9,34 +9,124 @@ using System.Text; ...@@ -9,34 +9,124 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using System.Linq;
using Titanium.Web.Proxy.Extensions;
namespace Titanium.Web.Proxy.Network namespace Titanium.Web.Proxy.Network
{ {
public class Request public class Request
{ {
public string Method { get; internal set; } public string Method { get; set; }
public Uri RequestUri { get; internal set; } public Uri RequestUri { get; set; }
public string HttpVersion { get; internal set; } public string HttpVersion { get; set; }
public string Status { get; internal set; } public string Host
public int ContentLength { get; internal set; } {
public bool SendChunked { get; internal set; } get
public string ContentType { get; internal set; } {
public bool KeepAlive { get; internal set; } var host = RequestHeaders.FirstOrDefault(x => x.Name.ToLower() == "host");
public string Hostname { get; internal set; } 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 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 string Url { get; internal set; } }
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 bool CancelRequest { get; set; }
internal byte[] RequestBody { get; set; } internal byte[] RequestBody { get; set; }
internal string RequestBodyString { get; set; } internal string RequestBodyString { get; set; }
internal bool RequestBodyRead { 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 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() public Request()
{ {
this.RequestHeaders = new List<HttpHeader>(); this.RequestHeaders = new List<HttpHeader>();
...@@ -46,29 +136,124 @@ namespace Titanium.Web.Proxy.Network ...@@ -46,29 +136,124 @@ namespace Titanium.Web.Proxy.Network
public class Response public class Response
{ {
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { 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 Encoding Encoding { 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; }
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 Response() public Response()
{ {
this.ResponseHeaders = new List<HttpHeader>(); this.ResponseHeaders = new List<HttpHeader>();
this.ResponseKeepAlive = true; }
}
} }
public class HttpWebSession public class HttpWebSession
...@@ -127,9 +312,12 @@ namespace Titanium.Web.Proxy.Network ...@@ -127,9 +312,12 @@ namespace Titanium.Web.Proxy.Network
public void ReceiveResponse() public void ReceiveResponse()
{ {
//return if this is already read
if (this.Response.ResponseStatusCode != null) return;
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3); var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
if(string.IsNullOrEmpty(httpResult[0])) if (string.IsNullOrEmpty(httpResult[0]))
{ {
var s = ProxyClient.ServerStreamReader.ReadLine(); var s = ProxyClient.ServerStreamReader.ReadLine();
} }
......
...@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy ...@@ -184,7 +184,7 @@ namespace Titanium.Web.Proxy
break; break;
} }
var args = new SessionEventArgs(BUFFER_SIZE); var args = new SessionEventArgs();
args.Client.TcpClient = client; args.Client.TcpClient = client;
try try
...@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy ...@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy
SetRequestHeaders(args.ProxySession.Request.RequestHeaders, args.ProxySession); 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; args.IsHttps = IsHttps;
if (args.ProxySession.Request.UpgradeToWebSocket) if (args.ProxySession.Request.UpgradeToWebSocket)
...@@ -237,14 +237,11 @@ namespace Titanium.Web.Proxy ...@@ -237,14 +237,11 @@ namespace Titanium.Web.Proxy
args.Client.ClientStream = clientStream; args.Client.ClientStream = clientStream;
args.Client.ClientStreamReader = clientStreamReader; args.Client.ClientStreamReader = clientStreamReader;
args.Client.ClientStreamWriter = clientStreamWriter; args.Client.ClientStreamWriter = clientStreamWriter;
args.ProxySession.Request.Hostname = args.ProxySession.Request.RequestUri.Host; args.ProxySession.Request.Host = args.ProxySession.Request.RequestUri.Host;
args.ProxySession.Request.Url = args.ProxySession.Request.RequestUri.OriginalString;
//If requested interception //If requested interception
if (BeforeRequest != null) if (BeforeRequest != null)
{ {
args.ProxySession.Request.Encoding = args.ProxySession.GetEncoding();
BeforeRequest(null, args); BeforeRequest(null, args);
} }
...@@ -260,10 +257,10 @@ namespace Titanium.Web.Proxy ...@@ -260,10 +257,10 @@ namespace Titanium.Web.Proxy
//construct the web request that we are going to issue on behalf of the client. //construct the web request that we are going to issue on behalf of the client.
connection = connection == null ? connection = connection == null ?
TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps) 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; : connection;
lastRequestHostName = args.ProxySession.Request.Hostname; lastRequestHostName = args.ProxySession.Request.Host;
args.ProxySession.SetConnection(connection); args.ProxySession.SetConnection(connection);
args.ProxySession.SendRequest(); args.ProxySession.SendRequest();
...@@ -326,44 +323,8 @@ namespace Titanium.Web.Proxy ...@@ -326,44 +323,8 @@ namespace Titanium.Web.Proxy
{ {
case "accept-encoding": case "accept-encoding":
requestHeaders[i].Value = "gzip,deflate,zlib"; requestHeaders[i].Value = "gzip,deflate,zlib";
break; 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: default:
break; break;
} }
......
...@@ -18,20 +18,18 @@ namespace Titanium.Web.Proxy ...@@ -18,20 +18,18 @@ namespace Titanium.Web.Proxy
partial class ProxyServer partial class ProxyServer
{ {
//Called asynchronously when a request was successfully and we received the response //Called asynchronously when a request was successfully and we received the response
private static void HandleHttpSessionResponse(SessionEventArgs args) public static void HandleHttpSessionResponse(SessionEventArgs args)
{ {
args.ProxySession.ReceiveResponse(); args.ProxySession.ReceiveResponse();
try try
{ {
if (!args.ProxySession.Response.ResponseBodyRead)
args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
if (BeforeResponse != null && !args.ProxySession.Response.ResponseLocked)
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