Commit 4c68f687 authored by Hakan Arıcı's avatar Hakan Arıcı

Various code refactorings.

parent c1d0e60e
......@@ -29,27 +29,20 @@ namespace Titanium.Web.Proxy.Extensions
await input.CopyToAsync(output);
}
/// <summary>
/// copies the specified bytes to the stream from the input stream
/// </summary>
/// <param name="streamReader"></param>
/// <param name="stream"></param>
/// <param name="totalBytesToRead"></param>
/// <returns></returns>
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, int bufferSize, Stream stream, long totalBytesToRead)
/// <summary>
/// copies the specified bytes to the stream from the input stream
/// </summary>
/// <param name="streamReader"></param>
/// <param name="bufferSize"></param>
/// <param name="stream"></param>
/// <param name="totalBytesToRead"></param>
/// <returns></returns>
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, int bufferSize, Stream stream, long totalBytesToRead)
{
var totalbytesRead = 0;
long bytesToRead;
if (totalBytesToRead < bufferSize)
{
bytesToRead = totalBytesToRead;
}
else
{
bytesToRead = bufferSize;
}
long bytesToRead = totalBytesToRead < bufferSize ? totalBytesToRead : bufferSize;
while (totalbytesRead < totalBytesToRead)
{
......@@ -72,13 +65,14 @@ namespace Titanium.Web.Proxy.Extensions
}
}
/// <summary>
/// Copies the stream chunked
/// </summary>
/// <param name="clientStreamReader"></param>
/// <param name="stream"></param>
/// <returns></returns>
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, int bufferSize, Stream stream)
/// <summary>
/// Copies the stream chunked
/// </summary>
/// <param name="clientStreamReader"></param>
/// <param name="bufferSize"></param>
/// <param name="stream"></param>
/// <returns></returns>
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, int bufferSize, Stream stream)
{
while (true)
{
......@@ -117,30 +111,32 @@ namespace Titanium.Web.Proxy.Extensions
await WriteResponseBodyChunked(data, clientStream);
}
}
/// <summary>
/// Copies the specified content length number of bytes to the output stream from the given inputs stream
/// optionally chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="outStream"></param>
/// <param name="isChunked"></param>
/// <param name="ContentLength"></param>
/// <returns></returns>
internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream, bool isChunked, long ContentLength)
/// <summary>
/// Copies the specified content length number of bytes to the output stream from the given inputs stream
/// optionally chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="bufferSize"></param>
/// <param name="outStream"></param>
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <returns></returns>
internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream, bool isChunked, long contentLength)
{
if (!isChunked)
{
//http 1.0
if (ContentLength == -1)
if (contentLength == -1)
{
ContentLength = long.MaxValue;
contentLength = long.MaxValue;
}
int bytesToRead = bufferSize;
if (ContentLength < bufferSize)
if (contentLength < bufferSize)
{
bytesToRead = (int)ContentLength;
bytesToRead = (int)contentLength;
}
var buffer = new byte[bufferSize];
......@@ -153,11 +149,11 @@ namespace Titanium.Web.Proxy.Extensions
await outStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
if (totalBytesRead == ContentLength)
if (totalBytesRead == contentLength)
break;
bytesRead = 0;
var remainingBytes = (ContentLength - totalBytesRead);
var remainingBytes = (contentLength - totalBytesRead);
bytesToRead = remainingBytes > (long)bufferSize ? bufferSize : (int)remainingBytes;
}
}
......@@ -167,13 +163,14 @@ namespace Titanium.Web.Proxy.Extensions
}
}
/// <summary>
/// Copies the streams chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="outStream"></param>
/// <returns></returns>
internal static async Task WriteResponseBodyChunked(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream)
/// <summary>
/// Copies the streams chunked
/// </summary>
/// <param name="inStreamReader"></param>
/// <param name="bufferSize"></param>
/// <param name="outStream"></param>
/// <returns></returns>
internal static async Task WriteResponseBodyChunked(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream)
{
while (true)
{
......
......@@ -37,37 +37,30 @@ namespace Titanium.Web.Proxy.Helpers
{
using (var readBuffer = new MemoryStream())
{
try
{
var lastChar = default(char);
var buffer = new byte[1];
while ((await this.stream.ReadAsync(buffer, 0, 1)) > 0)
{
//if new line
if (lastChar == '\r' && buffer[0] == '\n')
{
var result = readBuffer.ToArray();
return encoding.GetString(result.SubArray(0, result.Length - 1));
}
//end of stream
if (buffer[0] == '\0')
{
return encoding.GetString(readBuffer.ToArray());
}
await readBuffer.WriteAsync(buffer,0,1);
//store last char for new line comparison
lastChar = (char)buffer[0];
}
return encoding.GetString(readBuffer.ToArray());
}
catch (IOException)
{
throw;
}
var lastChar = default(char);
var buffer = new byte[1];
while ((await this.stream.ReadAsync(buffer, 0, 1)) > 0)
{
//if new line
if (lastChar == '\r' && buffer[0] == '\n')
{
var result = readBuffer.ToArray();
return encoding.GetString(result.SubArray(0, result.Length - 1));
}
//end of stream
if (buffer[0] == '\0')
{
return encoding.GetString(readBuffer.ToArray());
}
await readBuffer.WriteAsync(buffer,0,1);
//store last char for new line comparison
lastChar = (char)buffer[0];
}
return encoding.GetString(readBuffer.ToArray());
}
}
......
......@@ -4,13 +4,19 @@ using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
/// <summary>
/// Helper classes for setting system proxy settings
/// </summary>
namespace Titanium.Web.Proxy.Helpers
{
internal enum ProxyProtocolType
{
Http,
Https,
}
internal partial class NativeMethods
{
[DllImport("wininet.dll")]
......@@ -26,16 +32,10 @@ namespace Titanium.Web.Proxy.Helpers
public override string ToString()
{
if (!IsHttps)
{
return "http=" + HostName + ":" + Port;
}
else
{
return "https=" + HostName + ":" + Port;
}
return $"{(IsHttps ? "https" : "http")}={HostName}:{Port}";
}
}
/// <summary>
/// Manage system proxy settings
/// </summary>
......@@ -44,62 +44,17 @@ namespace Titanium.Web.Proxy.Helpers
internal const int InternetOptionSettingsChanged = 39;
internal const int InternetOptionRefresh = 37;
internal void SetHttpProxy(string hostname, int port)
internal void SetHttpProxy(string hostname, int port)
{
var reg = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (reg != null)
{
prepareRegistry(reg);
var exisitingContent = reg.GetValue("ProxyServer") as string;
var existingSystemProxyValues = GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => !x.IsHttps);
existingSystemProxyValues.Add(new HttpSystemProxyValue()
{
HostName = hostname,
IsHttps = false,
Port = port
});
reg.SetValue("ProxyEnable", 1);
reg.SetValue("ProxyServer", String.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
}
Refresh();
SetProxy(hostname, port, ProxyProtocolType.Http);
}
/// <summary>
/// Remove the http proxy setting from current machine
/// </summary>
internal void RemoveHttpProxy()
internal void RemoveHttpProxy()
{
var reg = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (reg != null)
{
if (reg.GetValue("ProxyServer") != null)
{
var exisitingContent = reg.GetValue("ProxyServer") as string;
var existingSystemProxyValues = GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => !x.IsHttps);
if (!(existingSystemProxyValues.Count() == 0))
{
reg.SetValue("ProxyEnable", 1);
reg.SetValue("ProxyServer", String.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
}
else
{
reg.SetValue("ProxyEnable", 0);
reg.SetValue("ProxyServer", string.Empty);
}
}
}
Refresh();
RemoveProxy(ProxyProtocolType.Http);
}
/// <summary>
......@@ -107,60 +62,65 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="hostname"></param>
/// <param name="port"></param>
internal void SetHttpsProxy(string hostname, int port)
internal void SetHttpsProxy(string hostname, int port)
{
SetProxy(hostname, port, ProxyProtocolType.Https);
}
/// <summary>
/// Removes the https proxy setting to nothing
/// </summary>
internal void RemoveHttpsProxy()
{
RemoveProxy(ProxyProtocolType.Https);
}
private void SetProxy(string hostname, int port, ProxyProtocolType protocolType)
{
var reg = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (reg != null)
{
prepareRegistry(reg);
PrepareRegistry(reg);
var exisitingContent = reg.GetValue("ProxyServer") as string;
var existingSystemProxyValues = GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => x.IsHttps);
existingSystemProxyValues.RemoveAll(x => protocolType == ProxyProtocolType.Https ? x.IsHttps : !x.IsHttps);
existingSystemProxyValues.Add(new HttpSystemProxyValue()
{
HostName = hostname,
IsHttps = true,
IsHttps = protocolType == ProxyProtocolType.Https,
Port = port
});
reg.SetValue("ProxyEnable", 1);
reg.SetValue("ProxyServer", String.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
reg.SetValue("ProxyServer", string.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
}
Refresh();
}
/// <summary>
/// Removes the https proxy setting to nothing
/// </summary>
internal void RemoveHttpsProxy()
private void RemoveProxy(ProxyProtocolType protocolType)
{
var reg = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (reg != null)
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (reg?.GetValue("ProxyServer") != null)
{
if (reg.GetValue("ProxyServer") != null)
{
var exisitingContent = reg.GetValue("ProxyServer") as string;
var existingSystemProxyValues = GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => x.IsHttps);
if (!(existingSystemProxyValues.Count() == 0))
{
reg.SetValue("ProxyEnable", 1);
reg.SetValue("ProxyServer", String.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
}
else
{
reg.SetValue("ProxyEnable", 0);
reg.SetValue("ProxyServer", string.Empty);
}
var exisitingContent = reg.GetValue("ProxyServer") as string;
var existingSystemProxyValues = GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => protocolType == ProxyProtocolType.Https ? x.IsHttps : !x.IsHttps);
if (existingSystemProxyValues.Count != 0)
{
reg.SetValue("ProxyEnable", 1);
reg.SetValue("ProxyServer", string.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
}
else
{
reg.SetValue("ProxyEnable", 0);
reg.SetValue("ProxyServer", string.Empty);
}
}
......@@ -170,7 +130,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// Removes all types of proxy settings (both http & https)
/// </summary>
internal void DisableAllProxy()
internal void DisableAllProxy()
{
var reg = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
......@@ -189,7 +149,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="prevServerValue"></param>
/// <returns></returns>
private List<HttpSystemProxyValue> GetSystemProxyValues(string prevServerValue)
private List<HttpSystemProxyValue> GetSystemProxyValues(string prevServerValue)
{
var result = new List<HttpSystemProxyValue>();
......@@ -200,16 +160,11 @@ namespace Titanium.Web.Proxy.Helpers
if (proxyValues.Length > 0)
{
foreach (var value in proxyValues)
{
var parsedValue = parseProxyValue(value);
if (parsedValue != null)
result.Add(parsedValue);
}
result.AddRange(proxyValues.Select(ParseProxyValue).Where(parsedValue => parsedValue != null));
}
else
{
var parsedValue = parseProxyValue(prevServerValue);
var parsedValue = ParseProxyValue(prevServerValue);
if (parsedValue != null)
result.Add(parsedValue);
}
......@@ -222,29 +177,21 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private HttpSystemProxyValue parseProxyValue(string value)
private HttpSystemProxyValue ParseProxyValue(string value)
{
var tmp = Regex.Replace(value, @"\s+", " ").Trim().ToLower();
if (tmp.StartsWith("http="))
{
var endPoint = tmp.Substring(5);
return new HttpSystemProxyValue()
{
HostName = endPoint.Split(':')[0],
Port = int.Parse(endPoint.Split(':')[1]),
IsHttps = false
};
}
else if (tmp.StartsWith("https="))
if (tmp.StartsWith("http=") || tmp.StartsWith("https="))
{
var endPoint = tmp.Substring(5);
return new HttpSystemProxyValue()
{
HostName = endPoint.Split(':')[0],
Port = int.Parse(endPoint.Split(':')[1]),
IsHttps = true
};
IsHttps = tmp.StartsWith("https=")
};
}
return null;
}
......@@ -252,7 +199,7 @@ namespace Titanium.Web.Proxy.Helpers
/// Prepares the proxy server registry (create empty values if they don't exist)
/// </summary>
/// <param name="reg"></param>
private void prepareRegistry(RegistryKey reg)
private static void PrepareRegistry(RegistryKey reg)
{
if (reg.GetValue("ProxyEnable") == null)
{
......@@ -269,7 +216,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// Refresh the settings so that the system know about a change in proxy setting
/// </summary>
private void Refresh()
private void Refresh()
{
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionSettingsChanged, IntPtr.Zero, 0);
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionRefresh, IntPtr.Zero, 0);
......
......@@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Text;
......@@ -169,31 +168,18 @@ namespace Titanium.Web.Proxy.Helpers
try
{
TcpClient tunnelClient = tcpConnection.TcpClient;
Stream tunnelStream = tcpConnection.Stream;
Task sendRelay;
//Now async relay all server=>client & client=>server data
if (sb != null)
{
sendRelay = clientStream.CopyToAsync(sb.ToString(), tunnelStream);
}
else
{
sendRelay = clientStream.CopyToAsync(string.Empty, tunnelStream);
}
sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream);
var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream);
var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream);
await Task.WhenAll(sendRelay, receiveRelay);
}
catch
{
throw;
}
finally
{
tcpConnection.Dispose();
......
......@@ -50,22 +50,16 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Is Https?
/// </summary>
public bool IsHttps
{
get
{
return this.Request.RequestUri.Scheme == Uri.UriSchemeHttps;
}
}
public bool IsHttps => this.Request.RequestUri.Scheme == Uri.UriSchemeHttps;
/// <summary>
/// <summary>
/// Set the tcp connection to server used by this webclient
/// </summary>
/// <param name="Connection"></param>
internal void SetConnection(TcpConnection Connection)
/// <param name="connection">Instance of <see cref="TcpConnection"/></param>
internal void SetConnection(TcpConnection connection)
{
Connection.LastAccess = DateTime.Now;
ServerConnection = Connection;
connection.LastAccess = DateTime.Now;
ServerConnection = connection;
}
internal HttpWebClient()
......@@ -87,28 +81,18 @@ namespace Titanium.Web.Proxy.Http
//prepare the request & headers
if ((ServerConnection.UpStreamHttpProxy != null && ServerConnection.IsHttps == false) || (ServerConnection.UpStreamHttpsProxy != null && ServerConnection.IsHttps == true))
{
requestLines.AppendLine(string.Join(" ", new string[3]
{
this.Request.Method,
this.Request.RequestUri.AbsoluteUri,
string.Format("HTTP/{0}.{1}",this.Request.HttpVersion.Major, this.Request.HttpVersion.Minor)
}));
requestLines.AppendLine(string.Join(" ", this.Request.Method, this.Request.RequestUri.AbsoluteUri, $"HTTP/{this.Request.HttpVersion.Major}.{this.Request.HttpVersion.Minor}"));
}
else
{
requestLines.AppendLine(string.Join(" ", new string[3]
{
this.Request.Method,
this.Request.RequestUri.PathAndQuery,
string.Format("HTTP/{0}.{1}",this.Request.HttpVersion.Major, this.Request.HttpVersion.Minor)
}));
requestLines.AppendLine(string.Join(" ", this.Request.Method, this.Request.RequestUri.PathAndQuery, $"HTTP/{this.Request.HttpVersion.Major}.{this.Request.HttpVersion.Minor}"));
}
//Send Authentication to Upstream proxy if needed
if (ServerConnection.UpStreamHttpProxy != null && ServerConnection.IsHttps == false && ServerConnection.UpStreamHttpProxy.UserName != null && ServerConnection.UpStreamHttpProxy.UserName != "" && ServerConnection.UpStreamHttpProxy.Password != null)
if (ServerConnection.UpStreamHttpProxy != null && ServerConnection.IsHttps == false && !string.IsNullOrEmpty(ServerConnection.UpStreamHttpProxy.UserName) && ServerConnection.UpStreamHttpProxy.Password != null)
{
requestLines.AppendLine("Proxy-Connection: keep-alive");
requestLines.AppendLine("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ServerConnection.UpStreamHttpProxy.UserName + ":" + ServerConnection.UpStreamHttpProxy.Password)));
requestLines.AppendLine("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ServerConnection.UpStreamHttpProxy.UserName + ":" + ServerConnection.UpStreamHttpProxy.Password)));
}
//write request headers
foreach (var headerItem in this.Request.RequestHeaders)
......@@ -138,8 +122,6 @@ namespace Titanium.Web.Proxy.Http
string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request);
var test = Encoding.UTF8.GetString(requestBytes);
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
await stream.FlushAsync();
......@@ -240,12 +222,9 @@ namespace Titanium.Web.Proxy.Http
{
var existing = Response.ResponseHeaders[newHeader.Name];
var nonUniqueHeaders = new List<HttpHeader>();
var nonUniqueHeaders = new List<HttpHeader> {existing, newHeader};
nonUniqueHeaders.Add(existing);
nonUniqueHeaders.Add(newHeader);
Response.NonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders);
Response.NonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders);
Response.ResponseHeaders.Remove(newHeader.Name);
}
//add to unique header collection
......@@ -256,5 +235,4 @@ namespace Titanium.Web.Proxy.Http
}
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Extensions;
......@@ -234,13 +233,14 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Request Url
/// </summary>
public string Url { get { return RequestUri.OriginalString; } }
public string Url => RequestUri.OriginalString;
/// <summary>
/// <summary>
/// Encoding for this request
/// </summary>
internal Encoding Encoding { get { return this.GetEncoding(); } }
/// <summary>
internal Encoding Encoding => this.GetEncoding();
/// <summary>
/// Terminates the underlying Tcp Connection to client after current request
/// </summary>
internal bool CancelRequest { get; set; }
......
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Extensions;
......@@ -16,9 +15,9 @@ namespace Titanium.Web.Proxy.Http
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; }
internal Encoding Encoding { get { return this.GetResponseCharacterEncoding(); } }
internal Encoding Encoding => this.GetResponseCharacterEncoding();
/// <summary>
/// <summary>
/// Content encoding for this response
/// </summary>
internal string ContentEncoding
......
......@@ -3,7 +3,7 @@
/// <summary>
/// 200 Ok response
/// </summary>
public class OkResponse : Response
public sealed class OkResponse : Response
{
public OkResponse()
{
......
using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy.Http.Responses
namespace Titanium.Web.Proxy.Http.Responses
{
/// <summary>
/// Redirect response
/// </summary>
public class RedirectResponse : Response
public sealed class RedirectResponse : Response
{
public RedirectResponse()
{
......
......@@ -2,11 +2,9 @@
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Threading;
using System.Linq;
using System.Collections.Concurrent;
using System.IO;
using System.Diagnostics;
namespace Titanium.Web.Proxy.Network
{
......
......@@ -56,11 +56,11 @@ namespace Titanium.Web.Proxy.Network
using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize, true))
{
await writer.WriteLineAsync(string.Format("CONNECT {0}:{1} HTTP/{2}", remoteHostName, remotePort,httpVersion));
await writer.WriteLineAsync(string.Format("Host: {0}:{1}", remoteHostName, remotePort));
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync("Connection: Keep-Alive");
if (externalHttpsProxy.UserName != null && externalHttpsProxy.UserName != "" && externalHttpsProxy.Password != null)
if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null)
{
await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(externalHttpsProxy.UserName + ":" + externalHttpsProxy.Password)));
......
......@@ -17,22 +17,13 @@ namespace Titanium.Web.Proxy
/// </summary>
public partial class ProxyServer : IDisposable
{
private static Action<Exception> _exceptionFunc=null;
private static readonly Lazy<Action<Exception>> _defaultExceptionFunc = new Lazy<Action<Exception>>(() => (e => { }));
private static Action<Exception> _exceptionFunc;
public static Action<Exception> ExceptionFunc
{
get
{
if(_exceptionFunc!=null)
{
return _exceptionFunc;
}
else
{
return (e)=>
{
};
}
return _exceptionFunc ?? _defaultExceptionFunc.Value;
}
set
{
......
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