Commit 9019ee91 authored by Stéphane Graziano's avatar Stéphane Graziano
parents 453feabf 6a186156
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
</span> </span>
<a id="Titanium_Web_Proxy_EventArguments_CertificateSelectionEventArgs_AcceptableIssuers_" data-uid="Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.AcceptableIssuers*"></a> <a id="Titanium_Web_Proxy_EventArguments_CertificateSelectionEventArgs_AcceptableIssuers_" data-uid="Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.AcceptableIssuers*"></a>
<h4 id="Titanium_Web_Proxy_EventArguments_CertificateSelectionEventArgs_AcceptableIssuers" data-uid="Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.AcceptableIssuers">AcceptableIssuers</h4> <h4 id="Titanium_Web_Proxy_EventArguments_CertificateSelectionEventArgs_AcceptableIssuers" data-uid="Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.AcceptableIssuers">AcceptableIssuers</h4>
<div class="markdown level1 summary"><p>Acceptable issuers as listed by remoted server.</p> <div class="markdown level1 summary"><p>Acceptable issuers as listed by remote server.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
......
...@@ -103,13 +103,13 @@ or when server terminates connection from proxy.</p> ...@@ -103,13 +103,13 @@ or when server terminates connection from proxy.</p>
<div class="inheritedMembers"> <div class="inheritedMembers">
<h5>Inherited Members</h5> <h5>Inherited Members</h5>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferSize">SessionEventArgsBase.bufferSize</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferSize">SessionEventArgsBase.BufferSize</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferPool">SessionEventArgsBase.bufferPool</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferPool">SessionEventArgsBase.BufferPool</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_exceptionFunc">SessionEventArgsBase.exceptionFunc</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ExceptionFunc">SessionEventArgsBase.ExceptionFunc</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_TimeLine">SessionEventArgsBase.TimeLine</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_TimeLine">SessionEventArgsBase.TimeLine</a>
......
...@@ -187,17 +187,17 @@ or when server terminates connection from proxy.</p> ...@@ -187,17 +187,17 @@ or when server terminates connection from proxy.</p>
</h3> </h3>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<span class="divider">|</span> <span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L28">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L28">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferPool" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferPool">bufferPool</h4> <h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferPool" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferPool">BufferPool</h4>
<div class="markdown level1 summary"></div> <div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">protected readonly IBufferPool bufferPool</code></pre> <pre><code class="lang-csharp hljs">protected readonly IBufferPool BufferPool</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -209,24 +209,24 @@ or when server terminates connection from proxy.</p> ...@@ -209,24 +209,24 @@ or when server terminates connection from proxy.</p>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><span class="xref">StreamExtended.IBufferPool</span></td> <td><span class="xref">IBufferPool</span></td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<span class="divider">|</span> <span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferSize.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferSize%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferSize.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferSize%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L27">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L27">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferSize" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferSize">bufferSize</h4> <h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferSize" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferSize">BufferSize</h4>
<div class="markdown level1 summary"></div> <div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">protected readonly int bufferSize</code></pre> <pre><code class="lang-csharp hljs">protected readonly int BufferSize</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -245,17 +245,17 @@ or when server terminates connection from proxy.</p> ...@@ -245,17 +245,17 @@ or when server terminates connection from proxy.</p>
</table> </table>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<span class="divider">|</span> <span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_exceptionFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.exceptionFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ExceptionFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ExceptionFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L29">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs/#L29">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_exceptionFunc" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.exceptionFunc">exceptionFunc</h4> <h4 id="Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ExceptionFunc" data-uid="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ExceptionFunc">ExceptionFunc</h4>
<div class="markdown level1 summary"></div> <div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">protected readonly ExceptionHandler exceptionFunc</code></pre> <pre><code class="lang-csharp hljs">protected readonly ExceptionHandler ExceptionFunc</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -505,7 +505,7 @@ or when server terminates connection from proxy.</p> ...@@ -505,7 +505,7 @@ or when server terminates connection from proxy.</p>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public Dictionary&lt;string, DateTime&gt; TimeLine { get; set; }</code></pre> <pre><code class="lang-csharp hljs">public Dictionary&lt;string, DateTime&gt; TimeLine { get; }</code></pre>
</div> </div>
<h5 class="propertyValue">Property Value</h5> <h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -646,7 +646,7 @@ public HttpWebClient WebSession { get; }</code></pre> ...@@ -646,7 +646,7 @@ public HttpWebClient WebSession { get; }</code></pre>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.eventhandler-1">EventHandler</a>&lt;<span class="xref">StreamExtended.Network.DataEventArgs</span>&gt;</td> <td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.eventhandler-1">EventHandler</a>&lt;<span class="xref">DataEventArgs</span>&gt;</td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
...@@ -676,7 +676,7 @@ public HttpWebClient WebSession { get; }</code></pre> ...@@ -676,7 +676,7 @@ public HttpWebClient WebSession { get; }</code></pre>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.eventhandler-1">EventHandler</a>&lt;<span class="xref">StreamExtended.Network.DataEventArgs</span>&gt;</td> <td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.eventhandler-1">EventHandler</a>&lt;<span class="xref">DataEventArgs</span>&gt;</td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
......
...@@ -100,13 +100,13 @@ ...@@ -100,13 +100,13 @@
<div class="inheritedMembers"> <div class="inheritedMembers">
<h5>Inherited Members</h5> <h5>Inherited Members</h5>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferSize">SessionEventArgsBase.bufferSize</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferSize">SessionEventArgsBase.BufferSize</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferPool">SessionEventArgsBase.bufferPool</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferPool">SessionEventArgsBase.BufferPool</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_exceptionFunc">SessionEventArgsBase.exceptionFunc</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ExceptionFunc">SessionEventArgsBase.ExceptionFunc</a>
</div> </div>
<div> <div>
<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_TimeLine">SessionEventArgsBase.TimeLine</a> <a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_TimeLine">SessionEventArgsBase.TimeLine</a>
...@@ -255,7 +255,7 @@ Default is true.</p> ...@@ -255,7 +255,7 @@ Default is true.</p>
</span> </span>
<a id="Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_IsHttpsConnect_" data-uid="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.IsHttpsConnect*"></a> <a id="Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_IsHttpsConnect_" data-uid="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.IsHttpsConnect*"></a>
<h4 id="Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_IsHttpsConnect" data-uid="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.IsHttpsConnect">IsHttpsConnect</h4> <h4 id="Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_IsHttpsConnect" data-uid="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.IsHttpsConnect">IsHttpsConnect</h4>
<div class="markdown level1 summary"><p>Is this a connect request to secure HTTP server? Or is it to someother protocol.</p> <div class="markdown level1 summary"><p>Is this a connect request to secure HTTP server? Or is it to some other protocol.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
<tr> <tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td> <td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td>
<td><span class="parametername">message</span></td> <td><span class="parametername">message</span></td>
<td><p>Excception message</p> <td><p>Exception message</p>
</td> </td>
</tr> </tr>
<tr> <tr>
......
...@@ -222,7 +222,7 @@ ...@@ -222,7 +222,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Http/ConnectRequest.cs/#L15">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Http/ConnectRequest.cs/#L17">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo_" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo*"></a> <a id="Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo_" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo*"></a>
<h4 id="Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo">ClientHelloInfo</h4> <h4 id="Titanium_Web_Proxy_Http_ConnectRequest_ClientHelloInfo" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo">ClientHelloInfo</h4>
...@@ -242,7 +242,37 @@ ...@@ -242,7 +242,37 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><span class="xref">StreamExtended.ClientHelloInfo</span></td> <td><span class="xref">ClientHelloInfo</span></td>
<td></td>
</tr>
</tbody>
</table>
<span class="small pull-right mobile-hide">
<span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Http_ConnectRequest_TunnelType.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Http.ConnectRequest.TunnelType%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Http/ConnectRequest.cs/#L15">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Http_ConnectRequest_TunnelType_" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.TunnelType*"></a>
<h4 id="Titanium_Web_Proxy_Http_ConnectRequest_TunnelType" data-uid="Titanium.Web.Proxy.Http.ConnectRequest.TunnelType">TunnelType</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public TunnelType TunnelType { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">TunnelType</span></td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
......
...@@ -201,7 +201,7 @@ ...@@ -201,7 +201,7 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><span class="xref">StreamExtended.ServerHelloInfo</span></td> <td><span class="xref">ServerHelloInfo</span></td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
......
...@@ -517,7 +517,7 @@ public class HeaderCollection : IEnumerable&lt;HttpHeader&gt;, IEnumerable</code ...@@ -517,7 +517,7 @@ public class HeaderCollection : IEnumerable&lt;HttpHeader&gt;, IEnumerable</code
<a id="Titanium_Web_Proxy_Http_HeaderCollection_GetHeaders_" data-uid="Titanium.Web.Proxy.Http.HeaderCollection.GetHeaders*"></a> <a id="Titanium_Web_Proxy_Http_HeaderCollection_GetHeaders_" data-uid="Titanium.Web.Proxy.Http.HeaderCollection.GetHeaders*"></a>
<h4 id="Titanium_Web_Proxy_Http_HeaderCollection_GetHeaders_System_String_" data-uid="Titanium.Web.Proxy.Http.HeaderCollection.GetHeaders(System.String)">GetHeaders(String)</h4> <h4 id="Titanium_Web_Proxy_Http_HeaderCollection_GetHeaders_System_String_" data-uid="Titanium.Web.Proxy.Http.HeaderCollection.GetHeaders(System.String)">GetHeaders(String)</h4>
<div class="markdown level1 summary"><p>Returns all headers with given name if exists <div class="markdown level1 summary"><p>Returns all headers with given name if exists
Returns null if does&apos;nt exist</p> Returns null if doesn&apos;t exist</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
......
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string AcceptEncoding = &quot;accept-encoding&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string AcceptEncoding = &quot;Accept-Encoding&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string Connection = &quot;connection&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string Connection = &quot;Connection&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -280,7 +280,7 @@ ...@@ -280,7 +280,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string ContentEncoding = &quot;content-encoding&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string ContentEncoding = &quot;Content-Encoding&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -396,7 +396,7 @@ ...@@ -396,7 +396,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string ContentLength = &quot;content-length&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string ContentLength = &quot;Content-Length&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -425,7 +425,7 @@ ...@@ -425,7 +425,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string ContentType = &quot;content-type&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string ContentType = &quot;Content-Type&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -512,7 +512,7 @@ ...@@ -512,7 +512,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string Expect = &quot;expect&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string Expect = &quot;Expect&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -570,7 +570,7 @@ ...@@ -570,7 +570,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string Host = &quot;host&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string Host = &quot;Host&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -773,7 +773,7 @@ ...@@ -773,7 +773,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string TransferEncoding = &quot;transfer-encoding&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string TransferEncoding = &quot;Transfer-Encoding&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
...@@ -831,7 +831,7 @@ ...@@ -831,7 +831,7 @@
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string Upgrade = &quot;upgrade&quot;</code></pre> <pre><code class="lang-csharp hljs">public const string Upgrade = &quot;Upgrade&quot;</code></pre>
</div> </div>
<h5 class="fieldValue">Field Value</h5> <h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
......
...@@ -199,7 +199,7 @@ So client application know that it is communicating with a proxy server.</p> ...@@ -199,7 +199,7 @@ So client application know that it is communicating with a proxy server.</p>
<div class="markdown level1 summary"><p>Intercept tunnel connect request. <div class="markdown level1 summary"><p>Intercept tunnel connect request.
Valid only for explicit endpoints. Valid only for explicit endpoints.
Set the <a class="xref" href="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html#Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_DecryptSsl">DecryptSsl</a> property to false if this HTTP connect request Set the <a class="xref" href="Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html#Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_DecryptSsl">DecryptSsl</a> property to false if this HTTP connect request
should&apos;nt be decrypted and instead be relayed.</p> shouldn&apos;t be decrypted and instead be relayed.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
......
...@@ -210,7 +210,7 @@ The additional 32 octets account for an estimated overhead associated with an en ...@@ -210,7 +210,7 @@ The additional 32 octets account for an estimated overhead associated with an en
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
<div class="codewrapper"> <div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Name { get; set; }</code></pre> <pre><code class="lang-csharp hljs">public string Name { get; }</code></pre>
</div> </div>
<h5 class="propertyValue">Property Value</h5> <h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed"> <table class="table table-bordered table-striped table-condensed">
......
...@@ -243,7 +243,7 @@ prompting for UAC if required?</p> ...@@ -243,7 +243,7 @@ prompting for UAC if required?</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BufferPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BufferPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BufferPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BufferPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L244">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L253">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_BufferPool_" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool*"></a> <a id="Titanium_Web_Proxy_ProxyServer_BufferPool_" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_BufferPool" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool">BufferPool</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_BufferPool" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool">BufferPool</h4>
...@@ -266,7 +266,7 @@ By default this uses DefaultBufferPool implementation available in StreamExtende ...@@ -266,7 +266,7 @@ By default this uses DefaultBufferPool implementation available in StreamExtende
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><span class="xref">StreamExtended.IBufferPool</span></td> <td><span class="xref">IBufferPool</span></td>
<td></td> <td></td>
</tr> </tr>
</tbody> </tbody>
...@@ -276,7 +276,7 @@ By default this uses DefaultBufferPool implementation available in StreamExtende ...@@ -276,7 +276,7 @@ By default this uses DefaultBufferPool implementation available in StreamExtende
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BufferSize.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BufferSize%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BufferSize.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BufferSize%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L187">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L196">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_BufferSize_" data-uid="Titanium.Web.Proxy.ProxyServer.BufferSize*"></a> <a id="Titanium_Web_Proxy_ProxyServer_BufferSize_" data-uid="Titanium.Web.Proxy.ProxyServer.BufferSize*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_BufferSize" data-uid="Titanium.Web.Proxy.ProxyServer.BufferSize">BufferSize</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_BufferSize" data-uid="Titanium.Web.Proxy.ProxyServer.BufferSize">BufferSize</h4>
...@@ -308,7 +308,7 @@ Default value is 8192 bytes.</p> ...@@ -308,7 +308,7 @@ Default value is 8192 bytes.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_CertificateManager.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.CertificateManager%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_CertificateManager.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.CertificateManager%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L249">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L258">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_CertificateManager_" data-uid="Titanium.Web.Proxy.ProxyServer.CertificateManager*"></a> <a id="Titanium_Web_Proxy_ProxyServer_CertificateManager_" data-uid="Titanium.Web.Proxy.ProxyServer.CertificateManager*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_CertificateManager" data-uid="Titanium.Web.Proxy.ProxyServer.CertificateManager">CertificateManager</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_CertificateManager" data-uid="Titanium.Web.Proxy.ProxyServer.CertificateManager">CertificateManager</h4>
...@@ -339,11 +339,11 @@ Default value is 8192 bytes.</p> ...@@ -339,11 +339,11 @@ Default value is 8192 bytes.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L152">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L161">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation_" data-uid="Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation*"></a> <a id="Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation_" data-uid="Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation" data-uid="Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation">CheckCertificateRevocation</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_CheckCertificateRevocation" data-uid="Titanium.Web.Proxy.ProxyServer.CheckCertificateRevocation">CheckCertificateRevocation</h4>
<div class="markdown level1 summary"><p>Should we check for certificare revocation during SSL authentication to servers <div class="markdown level1 summary"><p>Should we check for certificate revocation during SSL authentication to servers
Note: If enabled can reduce performance. Defaults to false.</p> Note: If enabled can reduce performance. Defaults to false.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
...@@ -371,7 +371,7 @@ Note: If enabled can reduce performance. Defaults to false.</p> ...@@ -371,7 +371,7 @@ Note: If enabled can reduce performance. Defaults to false.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientConnectionCount.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientConnectionCount%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientConnectionCount.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientConnectionCount%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L218">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L227">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCount_" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCount*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCount_" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCount*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCount" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCount">ClientConnectionCount</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCount" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCount">ClientConnectionCount</h4>
...@@ -402,7 +402,7 @@ Note: If enabled can reduce performance. Defaults to false.</p> ...@@ -402,7 +402,7 @@ Note: If enabled can reduce performance. Defaults to false.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L194">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L203">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds_" data-uid="Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds_" data-uid="Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds" data-uid="Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds">ConnectionTimeOutSeconds</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ConnectionTimeOutSeconds" data-uid="Titanium.Web.Proxy.ProxyServer.ConnectionTimeOutSeconds">ConnectionTimeOutSeconds</h4>
...@@ -435,7 +435,7 @@ Default value is 60 seconds.</p> ...@@ -435,7 +435,7 @@ Default value is 60 seconds.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L159">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L168">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour_" data-uid="Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour*"></a> <a id="Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour_" data-uid="Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour" data-uid="Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour">Enable100ContinueBehaviour</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_Enable100ContinueBehaviour" data-uid="Titanium.Web.Proxy.ProxyServer.Enable100ContinueBehaviour">Enable100ContinueBehaviour</h4>
...@@ -468,7 +468,7 @@ Defaults to false.</p> ...@@ -468,7 +468,7 @@ Defaults to false.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_EnableConnectionPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.EnableConnectionPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_EnableConnectionPool.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.EnableConnectionPool%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L165">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L174">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_EnableConnectionPool_" data-uid="Titanium.Web.Proxy.ProxyServer.EnableConnectionPool*"></a> <a id="Titanium_Web_Proxy_ProxyServer_EnableConnectionPool_" data-uid="Titanium.Web.Proxy.ProxyServer.EnableConnectionPool*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_EnableConnectionPool" data-uid="Titanium.Web.Proxy.ProxyServer.EnableConnectionPool">EnableConnectionPool</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_EnableConnectionPool" data-uid="Titanium.Web.Proxy.ProxyServer.EnableConnectionPool">EnableConnectionPool</h4>
...@@ -495,12 +495,49 @@ Defaults to true.</p> ...@@ -495,12 +495,49 @@ Defaults to true.</p>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<span class="small pull-right mobile-hide">
<span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_EnableHttp2.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.EnableHttp2%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L155">View Source</a>
</span>
<a id="Titanium_Web_Proxy_ProxyServer_EnableHttp2_" data-uid="Titanium.Web.Proxy.ProxyServer.EnableHttp2*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_EnableHttp2" data-uid="Titanium.Web.Proxy.ProxyServer.EnableHttp2">EnableHttp2</h4>
<div class="markdown level1 summary"><p>Enable disable HTTP/2 support.
Warning: HTTP/2 support is very limited</p>
<ul>
<li>only enabled when both client and server supports it (no protocol changing in proxy)</li>
<li>GetRequest/ResponseBody(AsString) methods are not supported</li>
<li>cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored)</li>
</ul>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool EnableHttp2 { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.boolean">Boolean</a></td>
<td></td>
</tr>
</tbody>
</table>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<span class="divider">|</span> <span class="divider">|</span>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L175">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L184">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch_" data-uid="Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch*"></a> <a id="Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch_" data-uid="Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch" data-uid="Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch">EnableTcpServerConnectionPrefetch</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch" data-uid="Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch">EnableTcpServerConnectionPrefetch</h4>
...@@ -508,7 +545,7 @@ Defaults to true.</p> ...@@ -508,7 +545,7 @@ Defaults to true.</p>
When enabled, as soon as we receive a client connection we concurrently initiate When enabled, as soon as we receive a client connection we concurrently initiate
corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request
we will have the server connection immediately ready or in the process of getting ready. we will have the server connection immediately ready or in the process of getting ready.
If a server connection is available in cache then this prefetch task will immediatly return with the available connection from cache. If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache.
Defaults to true.</p> Defaults to true.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
...@@ -571,7 +608,7 @@ Defaults to false.</p> ...@@ -571,7 +608,7 @@ Defaults to false.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ExceptionFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ExceptionFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ExceptionFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ExceptionFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L281">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L290">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ExceptionFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ExceptionFunc*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ExceptionFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ExceptionFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ExceptionFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ExceptionFunc">ExceptionFunc</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ExceptionFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ExceptionFunc">ExceptionFunc</h4>
...@@ -634,7 +671,7 @@ Defaults to false.</p> ...@@ -634,7 +671,7 @@ Defaults to false.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L276">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L285">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc*"></a> <a id="Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc" data-uid="Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc">GetCustomUpStreamProxyFunc</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_GetCustomUpStreamProxyFunc" data-uid="Titanium.Web.Proxy.ProxyServer.GetCustomUpStreamProxyFunc">GetCustomUpStreamProxyFunc</h4>
...@@ -666,7 +703,7 @@ User should return the ExternalProxy object with valid credentials.</p> ...@@ -666,7 +703,7 @@ User should return the ExternalProxy object with valid credentials.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_MaxCachedConnections.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.MaxCachedConnections%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_MaxCachedConnections.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.MaxCachedConnections%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L201">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L210">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_MaxCachedConnections_" data-uid="Titanium.Web.Proxy.ProxyServer.MaxCachedConnections*"></a> <a id="Titanium_Web_Proxy_ProxyServer_MaxCachedConnections_" data-uid="Titanium.Web.Proxy.ProxyServer.MaxCachedConnections*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_MaxCachedConnections" data-uid="Titanium.Web.Proxy.ProxyServer.MaxCachedConnections">MaxCachedConnections</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_MaxCachedConnections" data-uid="Titanium.Web.Proxy.ProxyServer.MaxCachedConnections">MaxCachedConnections</h4>
...@@ -699,7 +736,7 @@ Default value is 2.</p> ...@@ -699,7 +736,7 @@ Default value is 2.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_NoDelay.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.NoDelay%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_NoDelay.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.NoDelay%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L181">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L190">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_NoDelay_" data-uid="Titanium.Web.Proxy.ProxyServer.NoDelay*"></a> <a id="Titanium_Web_Proxy_ProxyServer_NoDelay_" data-uid="Titanium.Web.Proxy.ProxyServer.NoDelay*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_NoDelay" data-uid="Titanium.Web.Proxy.ProxyServer.NoDelay">NoDelay</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_NoDelay" data-uid="Titanium.Web.Proxy.ProxyServer.NoDelay">NoDelay</h4>
...@@ -731,7 +768,7 @@ Defaults to true, no nagle algorithm is used.</p> ...@@ -731,7 +768,7 @@ Defaults to true, no nagle algorithm is used.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L228">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L237">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm">ProxyAuthenticationRealm</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm">ProxyAuthenticationRealm</h4>
...@@ -762,7 +799,7 @@ Defaults to true, no nagle algorithm is used.</p> ...@@ -762,7 +799,7 @@ Defaults to true, no nagle algorithm is used.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L309">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L318">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes">ProxyAuthenticationSchemes</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes">ProxyAuthenticationSchemes</h4>
...@@ -794,7 +831,7 @@ Works in relation with ProxySchemeAuthenticateFunc.</p> ...@@ -794,7 +831,7 @@ Works in relation with ProxySchemeAuthenticateFunc.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L296">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L305">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc">ProxyBasicAuthenticateFunc</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc">ProxyBasicAuthenticateFunc</h4>
...@@ -827,7 +864,7 @@ Should return true for successful authentication.</p> ...@@ -827,7 +864,7 @@ Should return true for successful authentication.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyEndPoints.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyEndPoints%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxyEndPoints.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxyEndPoints%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L270">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L279">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints">ProxyEndPoints</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints">ProxyEndPoints</h4>
...@@ -889,7 +926,7 @@ Should return true for successful authentication.</p> ...@@ -889,7 +926,7 @@ Should return true for successful authentication.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L303">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L312">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc">ProxySchemeAuthenticateFunc</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc">ProxySchemeAuthenticateFunc</h4>
...@@ -922,7 +959,7 @@ Should return success for successful authentication, continuation if the package ...@@ -922,7 +959,7 @@ Should return success for successful authentication, continuation if the package
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ReuseSocket.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ReuseSocket%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ReuseSocket.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ReuseSocket%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L213">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L222">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ReuseSocket_" data-uid="Titanium.Web.Proxy.ProxyServer.ReuseSocket*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ReuseSocket_" data-uid="Titanium.Web.Proxy.ProxyServer.ReuseSocket*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ReuseSocket" data-uid="Titanium.Web.Proxy.ProxyServer.ReuseSocket">ReuseSocket</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ReuseSocket" data-uid="Titanium.Web.Proxy.ProxyServer.ReuseSocket">ReuseSocket</h4>
...@@ -954,7 +991,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p> ...@@ -954,7 +991,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerConnectionCount.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerConnectionCount%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerConnectionCount.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerConnectionCount%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L223">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L232">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount_" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount_" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount">ServerConnectionCount</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount">ServerConnectionCount</h4>
...@@ -985,7 +1022,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p> ...@@ -985,7 +1022,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L233">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L242">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols_" data-uid="Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols*"></a> <a id="Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols_" data-uid="Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols" data-uid="Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols">SupportedSslProtocols</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_SupportedSslProtocols" data-uid="Titanium.Web.Proxy.ProxyServer.SupportedSslProtocols">SupportedSslProtocols</h4>
...@@ -1016,7 +1053,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p> ...@@ -1016,7 +1053,7 @@ Default is true (disabled for linux/macOS due to bug in .Net core).</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L207">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L216">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds_" data-uid="Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds*"></a> <a id="Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds_" data-uid="Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds" data-uid="Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds">TcpTimeWaitSeconds</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_TcpTimeWaitSeconds" data-uid="Titanium.Web.Proxy.ProxyServer.TcpTimeWaitSeconds">TcpTimeWaitSeconds</h4>
...@@ -1048,7 +1085,7 @@ Default value is 30.</p> ...@@ -1048,7 +1085,7 @@ Default value is 30.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L359">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L368">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread_" data-uid="Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread*"></a> <a id="Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread_" data-uid="Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread" data-uid="Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread">ThreadPoolWorkerThread</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ThreadPoolWorkerThread" data-uid="Titanium.Web.Proxy.ProxyServer.ThreadPoolWorkerThread">ThreadPoolWorkerThread</h4>
...@@ -1079,7 +1116,7 @@ Default value is 30.</p> ...@@ -1079,7 +1116,7 @@ Default value is 30.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L265">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L274">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint*"></a> <a id="Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint">UpStreamEndPoint</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamEndPoint" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamEndPoint">UpStreamEndPoint</h4>
...@@ -1111,7 +1148,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1111,7 +1148,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L254">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L263">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy">UpStreamHttpProxy</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpProxy" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpProxy">UpStreamHttpProxy</h4>
...@@ -1142,7 +1179,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1142,7 +1179,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L259">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L268">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy">UpStreamHttpsProxy</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_UpStreamHttpsProxy" data-uid="Titanium.Web.Proxy.ProxyServer.UpStreamHttpsProxy">UpStreamHttpsProxy</h4>
...@@ -1175,7 +1212,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1175,7 +1212,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_AddEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.AddEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_AddEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.AddEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L365">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L374">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_AddEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.AddEndPoint*"></a> <a id="Titanium_Web_Proxy_ProxyServer_AddEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.AddEndPoint*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_AddEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.AddEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)">AddEndPoint(ProxyEndPoint)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_AddEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.AddEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)">AddEndPoint(ProxyEndPoint)</h4>
...@@ -1209,7 +1246,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1209,7 +1246,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L532">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L541">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies*"></a> <a id="Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies" data-uid="Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies">DisableAllSystemProxies()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_DisableAllSystemProxies" data-uid="Titanium.Web.Proxy.ProxyServer.DisableAllSystemProxies">DisableAllSystemProxies()</h4>
...@@ -1225,7 +1262,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1225,7 +1262,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L502">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L511">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy">DisableSystemHttpProxy()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpProxy" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpProxy">DisableSystemHttpProxy()</h4>
...@@ -1241,7 +1278,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1241,7 +1278,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L510">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L519">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy">DisableSystemHttpsProxy()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemHttpsProxy" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemHttpsProxy">DisableSystemHttpsProxy()</h4>
...@@ -1257,7 +1294,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1257,7 +1294,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_Titanium_Web_Proxy_Models_ProxyProtocolType_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemProxy(Titanium.Web.Proxy.Models.ProxyProtocolType)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_Titanium_Web_Proxy_Models_ProxyProtocolType_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.DisableSystemProxy(Titanium.Web.Proxy.Models.ProxyProtocolType)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L518">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L527">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_Titanium_Web_Proxy_Models_ProxyProtocolType_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemProxy(Titanium.Web.Proxy.Models.ProxyProtocolType)">DisableSystemProxy(ProxyProtocolType)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_DisableSystemProxy_Titanium_Web_Proxy_Models_ProxyProtocolType_" data-uid="Titanium.Web.Proxy.ProxyServer.DisableSystemProxy(Titanium.Web.Proxy.Models.ProxyProtocolType)">DisableSystemProxy(ProxyProtocolType)</h4>
...@@ -1290,7 +1327,7 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1290,7 +1327,7 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Dispose.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Dispose%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Dispose.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Dispose%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L882">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L889">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_Dispose_" data-uid="Titanium.Web.Proxy.ProxyServer.Dispose*"></a> <a id="Titanium_Web_Proxy_ProxyServer_Dispose_" data-uid="Titanium.Web.Proxy.ProxyServer.Dispose*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_Dispose" data-uid="Titanium.Web.Proxy.ProxyServer.Dispose">Dispose()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_Dispose" data-uid="Titanium.Web.Proxy.ProxyServer.Dispose">Dispose()</h4>
...@@ -1306,12 +1343,12 @@ Defaults via any IP addresses of this machine.</p> ...@@ -1306,12 +1343,12 @@ Defaults via any IP addresses of this machine.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.RemoveEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.RemoveEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L386">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L395">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.RemoveEndPoint*"></a> <a id="Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.RemoveEndPoint*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.RemoveEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)">RemoveEndPoint(ProxyEndPoint)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.RemoveEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)">RemoveEndPoint(ProxyEndPoint)</h4>
<div class="markdown level1 summary"><p>Remove a proxy end point. <div class="markdown level1 summary"><p>Remove a proxy end point.
Will throw error if the end point does&apos;nt exist.</p> Will throw error if the end point doesn&apos;t exist.</p>
</div> </div>
<div class="markdown level1 conceptual"></div> <div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5> <h5 class="decalaration">Declaration</h5>
...@@ -1341,7 +1378,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1341,7 +1378,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L405">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L414">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)">SetAsSystemHttpProxy(ExplicitProxyEndPoint)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)">SetAsSystemHttpProxy(ExplicitProxyEndPoint)</h4>
...@@ -1375,7 +1412,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1375,7 +1412,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L414">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L423">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)">SetAsSystemHttpsProxy(ExplicitProxyEndPoint)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemHttpsProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemHttpsProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint)">SetAsSystemHttpsProxy(ExplicitProxyEndPoint)</h4>
...@@ -1409,7 +1446,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1409,7 +1446,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_Titanium_Web_Proxy_Models_ProxyProtocolType_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint%2CTitanium.Web.Proxy.Models.ProxyProtocolType)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_Titanium_Web_Proxy_Models_ProxyProtocolType_.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint%2CTitanium.Web.Proxy.Models.ProxyProtocolType)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L424">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L433">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy*"></a> <a id="Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_Titanium_Web_Proxy_Models_ProxyProtocolType_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint,Titanium.Web.Proxy.Models.ProxyProtocolType)">SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType)</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_SetAsSystemProxy_Titanium_Web_Proxy_Models_ExplicitProxyEndPoint_Titanium_Web_Proxy_Models_ProxyProtocolType_" data-uid="Titanium.Web.Proxy.ProxyServer.SetAsSystemProxy(Titanium.Web.Proxy.Models.ExplicitProxyEndPoint,Titanium.Web.Proxy.Models.ProxyProtocolType)">SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType)</h4>
...@@ -1449,7 +1486,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1449,7 +1486,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Start.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Start%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Start.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Start%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L546">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L555">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_Start_" data-uid="Titanium.Web.Proxy.ProxyServer.Start*"></a> <a id="Titanium_Web_Proxy_ProxyServer_Start_" data-uid="Titanium.Web.Proxy.ProxyServer.Start*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_Start" data-uid="Titanium.Web.Proxy.ProxyServer.Start">Start()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_Start" data-uid="Titanium.Web.Proxy.ProxyServer.Start">Start()</h4>
...@@ -1465,7 +1502,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1465,7 +1502,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Stop.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Stop%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_Stop.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.Stop%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L606">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L615">View Source</a>
</span> </span>
<a id="Titanium_Web_Proxy_ProxyServer_Stop_" data-uid="Titanium.Web.Proxy.ProxyServer.Stop*"></a> <a id="Titanium_Web_Proxy_ProxyServer_Stop_" data-uid="Titanium.Web.Proxy.ProxyServer.Stop*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_Stop" data-uid="Titanium.Web.Proxy.ProxyServer.Stop">Stop()</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_Stop" data-uid="Titanium.Web.Proxy.ProxyServer.Stop">Stop()</h4>
...@@ -1483,7 +1520,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1483,7 +1520,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_AfterResponse.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.AfterResponse%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_AfterResponse.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.AfterResponse%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L344">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L353">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_AfterResponse" data-uid="Titanium.Web.Proxy.ProxyServer.AfterResponse">AfterResponse</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_AfterResponse" data-uid="Titanium.Web.Proxy.ProxyServer.AfterResponse">AfterResponse</h4>
<div class="markdown level1 summary"><p>Intercept after response event from server.</p> <div class="markdown level1 summary"><p>Intercept after response event from server.</p>
...@@ -1513,7 +1550,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1513,7 +1550,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BeforeRequest.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BeforeRequest%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BeforeRequest.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BeforeRequest%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L334">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L343">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_BeforeRequest" data-uid="Titanium.Web.Proxy.ProxyServer.BeforeRequest">BeforeRequest</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_BeforeRequest" data-uid="Titanium.Web.Proxy.ProxyServer.BeforeRequest">BeforeRequest</h4>
<div class="markdown level1 summary"><p>Intercept request event to server.</p> <div class="markdown level1 summary"><p>Intercept request event to server.</p>
...@@ -1543,7 +1580,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1543,7 +1580,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BeforeResponse.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BeforeResponse%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_BeforeResponse.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.BeforeResponse%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L339">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L348">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_BeforeResponse" data-uid="Titanium.Web.Proxy.ProxyServer.BeforeResponse">BeforeResponse</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_BeforeResponse" data-uid="Titanium.Web.Proxy.ProxyServer.BeforeResponse">BeforeResponse</h4>
<div class="markdown level1 summary"><p>Intercept response event from server.</p> <div class="markdown level1 summary"><p>Intercept response event from server.</p>
...@@ -1573,7 +1610,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1573,7 +1610,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientCertificateSelectionCallback.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientCertificateSelectionCallback%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientCertificateSelectionCallback.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientCertificateSelectionCallback%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L329">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L338">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_ClientCertificateSelectionCallback" data-uid="Titanium.Web.Proxy.ProxyServer.ClientCertificateSelectionCallback">ClientCertificateSelectionCallback</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ClientCertificateSelectionCallback" data-uid="Titanium.Web.Proxy.ProxyServer.ClientCertificateSelectionCallback">ClientCertificateSelectionCallback</h4>
<div class="markdown level1 summary"><p>Event to override client certificate selection during mutual SSL authentication.</p> <div class="markdown level1 summary"><p>Event to override client certificate selection during mutual SSL authentication.</p>
...@@ -1603,7 +1640,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1603,7 +1640,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientConnectionCountChanged.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientConnectionCountChanged%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ClientConnectionCountChanged.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ClientConnectionCountChanged%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L314">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L323">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCountChanged" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCountChanged">ClientConnectionCountChanged</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ClientConnectionCountChanged" data-uid="Titanium.Web.Proxy.ProxyServer.ClientConnectionCountChanged">ClientConnectionCountChanged</h4>
<div class="markdown level1 summary"><p>Event occurs when client connection count changed.</p> <div class="markdown level1 summary"><p>Event occurs when client connection count changed.</p>
...@@ -1633,7 +1670,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1633,7 +1670,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_OnClientConnectionCreate.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.OnClientConnectionCreate%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_OnClientConnectionCreate.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.OnClientConnectionCreate%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L349">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L358">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_OnClientConnectionCreate" data-uid="Titanium.Web.Proxy.ProxyServer.OnClientConnectionCreate">OnClientConnectionCreate</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_OnClientConnectionCreate" data-uid="Titanium.Web.Proxy.ProxyServer.OnClientConnectionCreate">OnClientConnectionCreate</h4>
<div class="markdown level1 summary"><p>Customize TcpClient used for client connection upon create.</p> <div class="markdown level1 summary"><p>Customize TcpClient used for client connection upon create.</p>
...@@ -1663,7 +1700,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1663,7 +1700,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_OnServerConnectionCreate.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_OnServerConnectionCreate.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L354">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L363">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_OnServerConnectionCreate" data-uid="Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate">OnServerConnectionCreate</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_OnServerConnectionCreate" data-uid="Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate">OnServerConnectionCreate</h4>
<div class="markdown level1 summary"><p>Customize TcpClient used for server connection upon create.</p> <div class="markdown level1 summary"><p>Customize TcpClient used for server connection upon create.</p>
...@@ -1693,7 +1730,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1693,7 +1730,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerCertificateValidationCallback.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerCertificateValidationCallback%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerCertificateValidationCallback.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerCertificateValidationCallback%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L324">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L333">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_ServerCertificateValidationCallback" data-uid="Titanium.Web.Proxy.ProxyServer.ServerCertificateValidationCallback">ServerCertificateValidationCallback</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ServerCertificateValidationCallback" data-uid="Titanium.Web.Proxy.ProxyServer.ServerCertificateValidationCallback">ServerCertificateValidationCallback</h4>
<div class="markdown level1 summary"><p>Event to override the default verification logic of remote SSL certificate received during authentication.</p> <div class="markdown level1 summary"><p>Event to override the default verification logic of remote SSL certificate received during authentication.</p>
...@@ -1723,7 +1760,7 @@ Will throw error if the end point does&apos;nt exist.</p> ...@@ -1723,7 +1760,7 @@ Will throw error if the end point does&apos;nt exist.</p>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerConnectionCountChanged.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerConnectionCountChanged%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_ProxyServer_ServerConnectionCountChanged.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.ProxyServer.ServerConnectionCountChanged%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span> </span>
<span class="small pull-right mobile-hide"> <span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L319">View Source</a> <a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/ProxyServer.cs/#L328">View Source</a>
</span> </span>
<h4 id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCountChanged" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCountChanged">ServerConnectionCountChanged</h4> <h4 id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCountChanged" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCountChanged">ServerConnectionCountChanged</h4>
<div class="markdown level1 summary"><p>Event occurs when server connection count changed.</p> <div class="markdown level1 summary"><p>Event occurs when server connection count changed.</p>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
"api/Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.html": { "api/Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.html": {
"href": "api/Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.html", "href": "api/Titanium.Web.Proxy.EventArguments.CertificateSelectionEventArgs.html",
"title": "Class CertificateSelectionEventArgs | Titanium Web Proxy", "title": "Class CertificateSelectionEventArgs | Titanium Web Proxy",
"keywords": "Class CertificateSelectionEventArgs An argument passed on to user for client certificate selection during mutual SSL authentication. Inheritance Object EventArgs CertificateSelectionEventArgs Inherited Members EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class CertificateSelectionEventArgs : EventArgs Properties | Improve this Doc View Source AcceptableIssuers Acceptable issuers as listed by remoted server. Declaration public string[] AcceptableIssuers { get; } Property Value Type Description String [] | Improve this Doc View Source ClientCertificate Client Certificate we selected. Set this value to override. Declaration public X509Certificate ClientCertificate { get; set; } Property Value Type Description X509Certificate | Improve this Doc View Source LocalCertificates Local certificates in store with matching issuers requested by TargetHost website. Declaration public X509CertificateCollection LocalCertificates { get; } Property Value Type Description X509CertificateCollection | Improve this Doc View Source RemoteCertificate Certificate of the remote server. Declaration public X509Certificate RemoteCertificate { get; } Property Value Type Description X509Certificate | Improve this Doc View Source Sender The proxy server instance. Declaration public object Sender { get; } Property Value Type Description Object | Improve this Doc View Source TargetHost The remote hostname to which we are authenticating against. Declaration public string TargetHost { get; } Property Value Type Description String" "keywords": "Class CertificateSelectionEventArgs An argument passed on to user for client certificate selection during mutual SSL authentication. Inheritance Object EventArgs CertificateSelectionEventArgs Inherited Members EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class CertificateSelectionEventArgs : EventArgs Properties | Improve this Doc View Source AcceptableIssuers Acceptable issuers as listed by remote server. Declaration public string[] AcceptableIssuers { get; } Property Value Type Description String [] | Improve this Doc View Source ClientCertificate Client Certificate we selected. Set this value to override. Declaration public X509Certificate ClientCertificate { get; set; } Property Value Type Description X509Certificate | Improve this Doc View Source LocalCertificates Local certificates in store with matching issuers requested by TargetHost website. Declaration public X509CertificateCollection LocalCertificates { get; } Property Value Type Description X509CertificateCollection | Improve this Doc View Source RemoteCertificate Certificate of the remote server. Declaration public X509Certificate RemoteCertificate { get; } Property Value Type Description X509Certificate | Improve this Doc View Source Sender The proxy server instance. Declaration public object Sender { get; } Property Value Type Description Object | Improve this Doc View Source TargetHost The remote hostname to which we are authenticating against. Declaration public string TargetHost { get; } Property Value Type Description String"
}, },
"api/Titanium.Web.Proxy.EventArguments.CertificateValidationEventArgs.html": { "api/Titanium.Web.Proxy.EventArguments.CertificateValidationEventArgs.html": {
"href": "api/Titanium.Web.Proxy.EventArguments.CertificateValidationEventArgs.html", "href": "api/Titanium.Web.Proxy.EventArguments.CertificateValidationEventArgs.html",
...@@ -32,17 +32,17 @@ ...@@ -32,17 +32,17 @@
"api/Titanium.Web.Proxy.EventArguments.SessionEventArgs.html": { "api/Titanium.Web.Proxy.EventArguments.SessionEventArgs.html": {
"href": "api/Titanium.Web.Proxy.EventArguments.SessionEventArgs.html", "href": "api/Titanium.Web.Proxy.EventArguments.SessionEventArgs.html",
"title": "Class SessionEventArgs | Titanium Web Proxy", "title": "Class SessionEventArgs | Titanium Web Proxy",
"keywords": "Class SessionEventArgs Holds info related to a single proxy session (single request/response sequence). A proxy session is bounded to a single connection from client. A proxy session ends when client terminates connection to proxy or when server terminates connection from proxy. Inheritance Object EventArgs SessionEventArgsBase SessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.bufferSize SessionEventArgsBase.bufferPool SessionEventArgsBase.exceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class SessionEventArgs : SessionEventArgsBase, IDisposable Constructors | Improve this Doc View Source SessionEventArgs(ProxyServer, ProxyEndPoint, Request, CancellationTokenSource) Declaration protected SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, Request request, CancellationTokenSource cancellationTokenSource) Parameters Type Name Description ProxyServer server ProxyEndPoint endPoint Request request CancellationTokenSource cancellationTokenSource Properties | Improve this Doc View Source ReRequest Should we send the request again ? Declaration public bool ReRequest { get; set; } Property Value Type Description Boolean Methods | Improve this Doc View Source Dispose() Implement any cleanup here Declaration public override void Dispose() Overrides SessionEventArgsBase.Dispose() | Improve this Doc View Source GenericResponse(Byte[], HttpStatusCode, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified byte[], the specified status to client. And then ignore the request. Declaration public void GenericResponse(byte[] result, HttpStatusCode status, Dictionary<string, HttpHeader> headers, bool closeServerConnection = false) Parameters Type Name Description Byte [] result The bytes to sent. HttpStatusCode status The HTTP status code. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source GenericResponse(String, HttpStatusCode, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified HTML string and the specified status to client. And then ignore the request. Declaration public void GenericResponse(string html, HttpStatusCode status, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description String html The html content. HttpStatusCode status The HTTP status code. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source GetRequestBody(CancellationToken) Gets the request body as bytes. Declaration public Task<byte[]> GetRequestBody(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < Byte []> The body as bytes. | Improve this Doc View Source GetRequestBodyAsString(CancellationToken) Gets the request body as string. Declaration public Task<string> GetRequestBodyAsString(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < String > The body as string. | Improve this Doc View Source GetResponseBody(CancellationToken) Gets the response body as bytes. Declaration public Task<byte[]> GetResponseBody(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < Byte []> The resulting bytes. | Improve this Doc View Source GetResponseBodyAsString(CancellationToken) Gets the response body as string. Declaration public Task<string> GetResponseBodyAsString(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < String > The string body. | Improve this Doc View Source Ok(Byte[], Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified byte[] to client and ignore the request. Declaration public void Ok(byte[] result, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description Byte [] result The html content bytes. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Ok(String, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified HTML string to client and ignore the request. Declaration public void Ok(string html, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description String html HTML content to sent. Dictionary < String , HttpHeader > headers HTTP response headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Redirect(String, Boolean) Redirect to provided URL. Declaration public void Redirect(string url, bool closeServerConnection = false) Parameters Type Name Description String url The URL to redirect. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Respond(Response, Boolean) Respond with given response object to client. Declaration public void Respond(Response response, bool closeServerConnection = false) Parameters Type Name Description Response response The response object. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source SetRequestBody(Byte[]) Sets the request body. Declaration public void SetRequestBody(byte[] body) Parameters Type Name Description Byte [] body The request body bytes. | Improve this Doc View Source SetRequestBodyString(String) Sets the body with the specified string. Declaration public void SetRequestBodyString(string body) Parameters Type Name Description String body The request body string to set. | Improve this Doc View Source SetResponseBody(Byte[]) Set the response body bytes. Declaration public void SetResponseBody(byte[] body) Parameters Type Name Description Byte [] body The body bytes to set. | Improve this Doc View Source SetResponseBodyString(String) Replace the response body with the specified string. Declaration public void SetResponseBodyString(string body) Parameters Type Name Description String body The body string to set. | Improve this Doc View Source TerminateServerConnection() Terminate the connection to server at the end of this HTTP request/response session. Declaration public void TerminateServerConnection() Events | Improve this Doc View Source MultipartRequestPartSent Occurs when multipart request part sent. Declaration public event EventHandler<MultipartRequestPartSentEventArgs> MultipartRequestPartSent Event Type Type Description EventHandler < MultipartRequestPartSentEventArgs > Implements System.IDisposable" "keywords": "Class SessionEventArgs Holds info related to a single proxy session (single request/response sequence). A proxy session is bounded to a single connection from client. A proxy session ends when client terminates connection to proxy or when server terminates connection from proxy. Inheritance Object EventArgs SessionEventArgsBase SessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.BufferSize SessionEventArgsBase.BufferPool SessionEventArgsBase.ExceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class SessionEventArgs : SessionEventArgsBase, IDisposable Constructors | Improve this Doc View Source SessionEventArgs(ProxyServer, ProxyEndPoint, Request, CancellationTokenSource) Declaration protected SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, Request request, CancellationTokenSource cancellationTokenSource) Parameters Type Name Description ProxyServer server ProxyEndPoint endPoint Request request CancellationTokenSource cancellationTokenSource Properties | Improve this Doc View Source ReRequest Should we send the request again ? Declaration public bool ReRequest { get; set; } Property Value Type Description Boolean Methods | Improve this Doc View Source Dispose() Implement any cleanup here Declaration public override void Dispose() Overrides SessionEventArgsBase.Dispose() | Improve this Doc View Source GenericResponse(Byte[], HttpStatusCode, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified byte[], the specified status to client. And then ignore the request. Declaration public void GenericResponse(byte[] result, HttpStatusCode status, Dictionary<string, HttpHeader> headers, bool closeServerConnection = false) Parameters Type Name Description Byte [] result The bytes to sent. HttpStatusCode status The HTTP status code. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source GenericResponse(String, HttpStatusCode, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified HTML string and the specified status to client. And then ignore the request. Declaration public void GenericResponse(string html, HttpStatusCode status, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description String html The html content. HttpStatusCode status The HTTP status code. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source GetRequestBody(CancellationToken) Gets the request body as bytes. Declaration public Task<byte[]> GetRequestBody(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < Byte []> The body as bytes. | Improve this Doc View Source GetRequestBodyAsString(CancellationToken) Gets the request body as string. Declaration public Task<string> GetRequestBodyAsString(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < String > The body as string. | Improve this Doc View Source GetResponseBody(CancellationToken) Gets the response body as bytes. Declaration public Task<byte[]> GetResponseBody(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < Byte []> The resulting bytes. | Improve this Doc View Source GetResponseBodyAsString(CancellationToken) Gets the response body as string. Declaration public Task<string> GetResponseBodyAsString(CancellationToken cancellationToken = default(CancellationToken)) Parameters Type Name Description CancellationToken cancellationToken Optional cancellation token for this async task. Returns Type Description Task < String > The string body. | Improve this Doc View Source Ok(Byte[], Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified byte[] to client and ignore the request. Declaration public void Ok(byte[] result, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description Byte [] result The html content bytes. Dictionary < String , HttpHeader > headers The HTTP headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Ok(String, Dictionary<String, HttpHeader>, Boolean) Before request is made to server respond with the specified HTML string to client and ignore the request. Declaration public void Ok(string html, Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Parameters Type Name Description String html HTML content to sent. Dictionary < String , HttpHeader > headers HTTP response headers. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Redirect(String, Boolean) Redirect to provided URL. Declaration public void Redirect(string url, bool closeServerConnection = false) Parameters Type Name Description String url The URL to redirect. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source Respond(Response, Boolean) Respond with given response object to client. Declaration public void Respond(Response response, bool closeServerConnection = false) Parameters Type Name Description Response response The response object. Boolean closeServerConnection Close the server connection used by request if any? | Improve this Doc View Source SetRequestBody(Byte[]) Sets the request body. Declaration public void SetRequestBody(byte[] body) Parameters Type Name Description Byte [] body The request body bytes. | Improve this Doc View Source SetRequestBodyString(String) Sets the body with the specified string. Declaration public void SetRequestBodyString(string body) Parameters Type Name Description String body The request body string to set. | Improve this Doc View Source SetResponseBody(Byte[]) Set the response body bytes. Declaration public void SetResponseBody(byte[] body) Parameters Type Name Description Byte [] body The body bytes to set. | Improve this Doc View Source SetResponseBodyString(String) Replace the response body with the specified string. Declaration public void SetResponseBodyString(string body) Parameters Type Name Description String body The body string to set. | Improve this Doc View Source TerminateServerConnection() Terminate the connection to server at the end of this HTTP request/response session. Declaration public void TerminateServerConnection() Events | Improve this Doc View Source MultipartRequestPartSent Occurs when multipart request part sent. Declaration public event EventHandler<MultipartRequestPartSentEventArgs> MultipartRequestPartSent Event Type Type Description EventHandler < MultipartRequestPartSentEventArgs > Implements System.IDisposable"
}, },
"api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html": { "api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html": {
"href": "api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html", "href": "api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html",
"title": "Class SessionEventArgsBase | Titanium Web Proxy", "title": "Class SessionEventArgsBase | Titanium Web Proxy",
"keywords": "Class SessionEventArgsBase Holds info related to a single proxy session (single request/response sequence). A proxy session is bounded to a single connection from client. A proxy session ends when client terminates connection to proxy or when server terminates connection from proxy. Inheritance Object EventArgs SessionEventArgsBase SessionEventArgs TunnelConnectSessionEventArgs Implements IDisposable Inherited Members EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public abstract class SessionEventArgsBase : EventArgs, IDisposable Constructors | Improve this Doc View Source SessionEventArgsBase(ProxyServer, ProxyEndPoint, CancellationTokenSource, Request) Declaration protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, CancellationTokenSource cancellationTokenSource, Request request) Parameters Type Name Description ProxyServer server ProxyEndPoint endPoint CancellationTokenSource cancellationTokenSource Request request Fields | Improve this Doc View Source bufferPool Declaration protected readonly IBufferPool bufferPool Field Value Type Description StreamExtended.IBufferPool | Improve this Doc View Source bufferSize Declaration protected readonly int bufferSize Field Value Type Description Int32 | Improve this Doc View Source exceptionFunc Declaration protected readonly ExceptionHandler exceptionFunc Field Value Type Description ExceptionHandler Properties | Improve this Doc View Source ClientEndPoint Client End Point. Declaration public IPEndPoint ClientEndPoint { get; } Property Value Type Description IPEndPoint | Improve this Doc View Source CustomUpStreamProxyUsed Are we using a custom upstream HTTP(S) proxy? Declaration public ExternalProxy CustomUpStreamProxyUsed { get; } Property Value Type Description ExternalProxy | Improve this Doc View Source Exception The last exception that happened. Declaration public Exception Exception { get; } Property Value Type Description Exception | Improve this Doc View Source HttpClient The web client used to communicate with server for this session. Declaration public HttpWebClient HttpClient { get; } Property Value Type Description HttpWebClient | Improve this Doc View Source IsHttps Does this session uses SSL? Declaration public bool IsHttps { get; } Property Value Type Description Boolean | Improve this Doc View Source IsTransparent Is this a transparent endpoint? Declaration public bool IsTransparent { get; } Property Value Type Description Boolean | Improve this Doc View Source LocalEndPoint Local endpoint via which we make the request. Declaration public ProxyEndPoint LocalEndPoint { get; } Property Value Type Description ProxyEndPoint | Improve this Doc View Source TimeLine Relative milliseconds for various events. Declaration public Dictionary<string, DateTime> TimeLine { get; set; } Property Value Type Description Dictionary < String , DateTime > | Improve this Doc View Source UserData Returns a user data for this request/response session which is same as the user data of HttpClient. Declaration public object UserData { get; set; } Property Value Type Description Object | Improve this Doc View Source WebSession Declaration [Obsolete(\"Use HttpClient instead.\")] public HttpWebClient WebSession { get; } Property Value Type Description HttpWebClient Methods | Improve this Doc View Source Dispose() Implements cleanup here. Declaration public virtual void Dispose() | Improve this Doc View Source TerminateSession() Terminates the session abruptly by terminating client/server connections. Declaration public void TerminateSession() Events | Improve this Doc View Source DataReceived Fired when data is received within this session from client/server. Declaration public event EventHandler<DataEventArgs> DataReceived Event Type Type Description EventHandler < StreamExtended.Network.DataEventArgs > | Improve this Doc View Source DataSent Fired when data is sent within this session to server/client. Declaration public event EventHandler<DataEventArgs> DataSent Event Type Type Description EventHandler < StreamExtended.Network.DataEventArgs > Implements System.IDisposable" "keywords": "Class SessionEventArgsBase Holds info related to a single proxy session (single request/response sequence). A proxy session is bounded to a single connection from client. A proxy session ends when client terminates connection to proxy or when server terminates connection from proxy. Inheritance Object EventArgs SessionEventArgsBase SessionEventArgs TunnelConnectSessionEventArgs Implements IDisposable Inherited Members EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public abstract class SessionEventArgsBase : EventArgs, IDisposable Constructors | Improve this Doc View Source SessionEventArgsBase(ProxyServer, ProxyEndPoint, CancellationTokenSource, Request) Declaration protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, CancellationTokenSource cancellationTokenSource, Request request) Parameters Type Name Description ProxyServer server ProxyEndPoint endPoint CancellationTokenSource cancellationTokenSource Request request Fields | Improve this Doc View Source BufferPool Declaration protected readonly IBufferPool BufferPool Field Value Type Description IBufferPool | Improve this Doc View Source BufferSize Declaration protected readonly int BufferSize Field Value Type Description Int32 | Improve this Doc View Source ExceptionFunc Declaration protected readonly ExceptionHandler ExceptionFunc Field Value Type Description ExceptionHandler Properties | Improve this Doc View Source ClientEndPoint Client End Point. Declaration public IPEndPoint ClientEndPoint { get; } Property Value Type Description IPEndPoint | Improve this Doc View Source CustomUpStreamProxyUsed Are we using a custom upstream HTTP(S) proxy? Declaration public ExternalProxy CustomUpStreamProxyUsed { get; } Property Value Type Description ExternalProxy | Improve this Doc View Source Exception The last exception that happened. Declaration public Exception Exception { get; } Property Value Type Description Exception | Improve this Doc View Source HttpClient The web client used to communicate with server for this session. Declaration public HttpWebClient HttpClient { get; } Property Value Type Description HttpWebClient | Improve this Doc View Source IsHttps Does this session uses SSL? Declaration public bool IsHttps { get; } Property Value Type Description Boolean | Improve this Doc View Source IsTransparent Is this a transparent endpoint? Declaration public bool IsTransparent { get; } Property Value Type Description Boolean | Improve this Doc View Source LocalEndPoint Local endpoint via which we make the request. Declaration public ProxyEndPoint LocalEndPoint { get; } Property Value Type Description ProxyEndPoint | Improve this Doc View Source TimeLine Relative milliseconds for various events. Declaration public Dictionary<string, DateTime> TimeLine { get; } Property Value Type Description Dictionary < String , DateTime > | Improve this Doc View Source UserData Returns a user data for this request/response session which is same as the user data of HttpClient. Declaration public object UserData { get; set; } Property Value Type Description Object | Improve this Doc View Source WebSession Declaration [Obsolete(\"Use HttpClient instead.\")] public HttpWebClient WebSession { get; } Property Value Type Description HttpWebClient Methods | Improve this Doc View Source Dispose() Implements cleanup here. Declaration public virtual void Dispose() | Improve this Doc View Source TerminateSession() Terminates the session abruptly by terminating client/server connections. Declaration public void TerminateSession() Events | Improve this Doc View Source DataReceived Fired when data is received within this session from client/server. Declaration public event EventHandler<DataEventArgs> DataReceived Event Type Type Description EventHandler < DataEventArgs > | Improve this Doc View Source DataSent Fired when data is sent within this session to server/client. Declaration public event EventHandler<DataEventArgs> DataSent Event Type Type Description EventHandler < DataEventArgs > Implements System.IDisposable"
}, },
"api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html": { "api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html": {
"href": "api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html", "href": "api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html",
"title": "Class TunnelConnectSessionEventArgs | Titanium Web Proxy", "title": "Class TunnelConnectSessionEventArgs | Titanium Web Proxy",
"keywords": "Class TunnelConnectSessionEventArgs A class that wraps the state when a tunnel connect event happen for Explicit endpoints. Inheritance Object EventArgs SessionEventArgsBase TunnelConnectSessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.bufferSize SessionEventArgsBase.bufferPool SessionEventArgsBase.exceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.Dispose() SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class TunnelConnectSessionEventArgs : SessionEventArgsBase, IDisposable Properties | Improve this Doc View Source DecryptSsl Should we decrypt the Ssl or relay it to server? Default is true. Declaration public bool DecryptSsl { get; set; } Property Value Type Description Boolean | Improve this Doc View Source DenyConnect When set to true it denies the connect request with a Forbidden status. Declaration public bool DenyConnect { get; set; } Property Value Type Description Boolean | Improve this Doc View Source IsHttpsConnect Is this a connect request to secure HTTP server? Or is it to someother protocol. Declaration public bool IsHttpsConnect { get; } Property Value Type Description Boolean Implements System.IDisposable" "keywords": "Class TunnelConnectSessionEventArgs A class that wraps the state when a tunnel connect event happen for Explicit endpoints. Inheritance Object EventArgs SessionEventArgsBase TunnelConnectSessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.BufferSize SessionEventArgsBase.BufferPool SessionEventArgsBase.ExceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.Dispose() SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class TunnelConnectSessionEventArgs : SessionEventArgsBase, IDisposable Properties | Improve this Doc View Source DecryptSsl Should we decrypt the Ssl or relay it to server? Default is true. Declaration public bool DecryptSsl { get; set; } Property Value Type Description Boolean | Improve this Doc View Source DenyConnect When set to true it denies the connect request with a Forbidden status. Declaration public bool DenyConnect { get; set; } Property Value Type Description Boolean | Improve this Doc View Source IsHttpsConnect Is this a connect request to secure HTTP server? Or is it to some other protocol. Declaration public bool IsHttpsConnect { get; } Property Value Type Description Boolean Implements System.IDisposable"
}, },
"api/Titanium.Web.Proxy.ExceptionHandler.html": { "api/Titanium.Web.Proxy.ExceptionHandler.html": {
"href": "api/Titanium.Web.Proxy.ExceptionHandler.html", "href": "api/Titanium.Web.Proxy.ExceptionHandler.html",
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
"api/Titanium.Web.Proxy.Exceptions.ProxyException.html": { "api/Titanium.Web.Proxy.Exceptions.ProxyException.html": {
"href": "api/Titanium.Web.Proxy.Exceptions.ProxyException.html", "href": "api/Titanium.Web.Proxy.Exceptions.ProxyException.html",
"title": "Class ProxyException | Titanium Web Proxy", "title": "Class ProxyException | Titanium Web Proxy",
"keywords": "Class ProxyException Base class exception associated with this proxy server. Inheritance Object Exception ProxyException BodyNotFoundException ProxyAuthorizationException ProxyConnectException ProxyHttpException ServerConnectionException Implements ISerializable _Exception Inherited Members Exception.GetBaseException() Exception.ToString() Exception.GetObjectData(SerializationInfo, StreamingContext) Exception.GetType() Exception.Message Exception.Data Exception.InnerException Exception.TargetSite Exception.StackTrace Exception.HelpLink Exception.Source Exception.HResult Exception.SerializeObjectState Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Exceptions Assembly : Titanium.Web.Proxy.dll Syntax public abstract class ProxyException : Exception, ISerializable, _Exception Constructors | Improve this Doc View Source ProxyException(String) Initializes a new instance of the ProxyException class. must be invoked by derived classes' constructors Declaration protected ProxyException(string message) Parameters Type Name Description String message Exception message | Improve this Doc View Source ProxyException(String, Exception) Initializes a new instance of the ProxyException class. must be invoked by derived classes' constructors Declaration protected ProxyException(string message, Exception innerException) Parameters Type Name Description String message Excception message Exception innerException Inner exception associated Implements System.Runtime.Serialization.ISerializable System.Runtime.InteropServices._Exception" "keywords": "Class ProxyException Base class exception associated with this proxy server. Inheritance Object Exception ProxyException BodyNotFoundException ProxyAuthorizationException ProxyConnectException ProxyHttpException ServerConnectionException Implements ISerializable _Exception Inherited Members Exception.GetBaseException() Exception.ToString() Exception.GetObjectData(SerializationInfo, StreamingContext) Exception.GetType() Exception.Message Exception.Data Exception.InnerException Exception.TargetSite Exception.StackTrace Exception.HelpLink Exception.Source Exception.HResult Exception.SerializeObjectState Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Exceptions Assembly : Titanium.Web.Proxy.dll Syntax public abstract class ProxyException : Exception, ISerializable, _Exception Constructors | Improve this Doc View Source ProxyException(String) Initializes a new instance of the ProxyException class. must be invoked by derived classes' constructors Declaration protected ProxyException(string message) Parameters Type Name Description String message Exception message | Improve this Doc View Source ProxyException(String, Exception) Initializes a new instance of the ProxyException class. must be invoked by derived classes' constructors Declaration protected ProxyException(string message, Exception innerException) Parameters Type Name Description String message Exception message Exception innerException Inner exception associated Implements System.Runtime.Serialization.ISerializable System.Runtime.InteropServices._Exception"
}, },
"api/Titanium.Web.Proxy.Exceptions.ProxyHttpException.html": { "api/Titanium.Web.Proxy.Exceptions.ProxyHttpException.html": {
"href": "api/Titanium.Web.Proxy.Exceptions.ProxyHttpException.html", "href": "api/Titanium.Web.Proxy.Exceptions.ProxyHttpException.html",
...@@ -102,17 +102,17 @@ ...@@ -102,17 +102,17 @@
"api/Titanium.Web.Proxy.Http.ConnectRequest.html": { "api/Titanium.Web.Proxy.Http.ConnectRequest.html": {
"href": "api/Titanium.Web.Proxy.Http.ConnectRequest.html", "href": "api/Titanium.Web.Proxy.Http.ConnectRequest.html",
"title": "Class ConnectRequest | Titanium Web Proxy", "title": "Class ConnectRequest | Titanium Web Proxy",
"keywords": "Class ConnectRequest The tcp tunnel Connect request. Inheritance Object RequestResponseBase Request ConnectRequest Inherited Members Request.Method Request.RequestUri Request.IsHttps Request.OriginalUrl Request.HasBody Request.Host Request.ExpectContinue Request.IsMultipartFormData Request.Url Request.UpgradeToWebSocket Request.ExpectationSucceeded Request.ExpectationFailed Request.HeaderText RequestResponseBase.BodyInternal RequestResponseBase.KeepBody RequestResponseBase.HttpVersion RequestResponseBase.Headers RequestResponseBase.ContentLength RequestResponseBase.ContentEncoding RequestResponseBase.Encoding RequestResponseBase.ContentType RequestResponseBase.IsChunked RequestResponseBase.Body RequestResponseBase.BodyString RequestResponseBase.IsBodyRead RequestResponseBase.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public class ConnectRequest : Request Constructors | Improve this Doc View Source ConnectRequest() Declaration public ConnectRequest() Properties | Improve this Doc View Source ClientHelloInfo Declaration public ClientHelloInfo ClientHelloInfo { get; set; } Property Value Type Description StreamExtended.ClientHelloInfo" "keywords": "Class ConnectRequest The tcp tunnel Connect request. Inheritance Object RequestResponseBase Request ConnectRequest Inherited Members Request.Method Request.RequestUri Request.IsHttps Request.OriginalUrl Request.HasBody Request.Host Request.ExpectContinue Request.IsMultipartFormData Request.Url Request.UpgradeToWebSocket Request.ExpectationSucceeded Request.ExpectationFailed Request.HeaderText RequestResponseBase.BodyInternal RequestResponseBase.KeepBody RequestResponseBase.HttpVersion RequestResponseBase.Headers RequestResponseBase.ContentLength RequestResponseBase.ContentEncoding RequestResponseBase.Encoding RequestResponseBase.ContentType RequestResponseBase.IsChunked RequestResponseBase.Body RequestResponseBase.BodyString RequestResponseBase.IsBodyRead RequestResponseBase.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public class ConnectRequest : Request Constructors | Improve this Doc View Source ConnectRequest() Declaration public ConnectRequest() Properties | Improve this Doc View Source ClientHelloInfo Declaration public ClientHelloInfo ClientHelloInfo { get; set; } Property Value Type Description ClientHelloInfo | Improve this Doc View Source TunnelType Declaration public TunnelType TunnelType { get; } Property Value Type Description TunnelType"
}, },
"api/Titanium.Web.Proxy.Http.ConnectResponse.html": { "api/Titanium.Web.Proxy.Http.ConnectResponse.html": {
"href": "api/Titanium.Web.Proxy.Http.ConnectResponse.html", "href": "api/Titanium.Web.Proxy.Http.ConnectResponse.html",
"title": "Class ConnectResponse | Titanium Web Proxy", "title": "Class ConnectResponse | Titanium Web Proxy",
"keywords": "Class ConnectResponse The tcp tunnel connect response object. Inheritance Object RequestResponseBase Response ConnectResponse Inherited Members Response.StatusCode Response.StatusDescription Response.HasBody Response.KeepAlive Response.HeaderText RequestResponseBase.BodyInternal RequestResponseBase.KeepBody RequestResponseBase.HttpVersion RequestResponseBase.Headers RequestResponseBase.ContentLength RequestResponseBase.ContentEncoding RequestResponseBase.Encoding RequestResponseBase.ContentType RequestResponseBase.IsChunked RequestResponseBase.Body RequestResponseBase.BodyString RequestResponseBase.IsBodyRead RequestResponseBase.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public class ConnectResponse : Response Properties | Improve this Doc View Source ServerHelloInfo Declaration public ServerHelloInfo ServerHelloInfo { get; set; } Property Value Type Description StreamExtended.ServerHelloInfo" "keywords": "Class ConnectResponse The tcp tunnel connect response object. Inheritance Object RequestResponseBase Response ConnectResponse Inherited Members Response.StatusCode Response.StatusDescription Response.HasBody Response.KeepAlive Response.HeaderText RequestResponseBase.BodyInternal RequestResponseBase.KeepBody RequestResponseBase.HttpVersion RequestResponseBase.Headers RequestResponseBase.ContentLength RequestResponseBase.ContentEncoding RequestResponseBase.Encoding RequestResponseBase.ContentType RequestResponseBase.IsChunked RequestResponseBase.Body RequestResponseBase.BodyString RequestResponseBase.IsBodyRead RequestResponseBase.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public class ConnectResponse : Response Properties | Improve this Doc View Source ServerHelloInfo Declaration public ServerHelloInfo ServerHelloInfo { get; set; } Property Value Type Description ServerHelloInfo"
}, },
"api/Titanium.Web.Proxy.Http.HeaderCollection.html": { "api/Titanium.Web.Proxy.Http.HeaderCollection.html": {
"href": "api/Titanium.Web.Proxy.Http.HeaderCollection.html", "href": "api/Titanium.Web.Proxy.Http.HeaderCollection.html",
"title": "Class HeaderCollection | Titanium Web Proxy", "title": "Class HeaderCollection | Titanium Web Proxy",
"keywords": "Class HeaderCollection The http header collection. Inheritance Object HeaderCollection Implements IEnumerable < HttpHeader > IEnumerable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax [TypeConverter(typeof(ExpandableObjectConverter))] public class HeaderCollection : IEnumerable<HttpHeader>, IEnumerable Constructors | Improve this Doc View Source HeaderCollection() Initializes a new instance of the HeaderCollection class. Declaration public HeaderCollection() Properties | Improve this Doc View Source Headers Unique Request header collection. Declaration public ReadOnlyDictionary<string, HttpHeader> Headers { get; } Property Value Type Description ReadOnlyDictionary < String , HttpHeader > | Improve this Doc View Source NonUniqueHeaders Non Unique headers. Declaration public ReadOnlyDictionary<string, List<HttpHeader>> NonUniqueHeaders { get; } Property Value Type Description ReadOnlyDictionary < String , List < HttpHeader >> Methods | Improve this Doc View Source AddHeader(String, String) Add a new header with given name and value Declaration public void AddHeader(string name, string value) Parameters Type Name Description String name String value | Improve this Doc View Source AddHeader(HttpHeader) Adds the given header object to Request Declaration public void AddHeader(HttpHeader newHeader) Parameters Type Name Description HttpHeader newHeader | Improve this Doc View Source AddHeaders(IEnumerable<KeyValuePair<String, String>>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<KeyValuePair<string, string>> newHeaders) Parameters Type Name Description IEnumerable < KeyValuePair < String , String >> newHeaders | Improve this Doc View Source AddHeaders(IEnumerable<KeyValuePair<String, HttpHeader>>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<KeyValuePair<string, HttpHeader>> newHeaders) Parameters Type Name Description IEnumerable < KeyValuePair < String , HttpHeader >> newHeaders | Improve this Doc View Source AddHeaders(IEnumerable<HttpHeader>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<HttpHeader> newHeaders) Parameters Type Name Description IEnumerable < HttpHeader > newHeaders | Improve this Doc View Source Clear() Removes all the headers. Declaration public void Clear() | Improve this Doc View Source GetAllHeaders() Returns all headers Declaration public List<HttpHeader> GetAllHeaders() Returns Type Description List < HttpHeader > | Improve this Doc View Source GetEnumerator() Returns an enumerator that iterates through the collection. Declaration public IEnumerator<HttpHeader> GetEnumerator() Returns Type Description IEnumerator < HttpHeader > An enumerator that can be used to iterate through the collection. | Improve this Doc View Source GetFirstHeader(String) Declaration public HttpHeader GetFirstHeader(string name) Parameters Type Name Description String name Returns Type Description HttpHeader | Improve this Doc View Source GetHeaders(String) Returns all headers with given name if exists Returns null if does'nt exist Declaration public List<HttpHeader> GetHeaders(string name) Parameters Type Name Description String name Returns Type Description List < HttpHeader > | Improve this Doc View Source HeaderExists(String) True if header exists Declaration public bool HeaderExists(string name) Parameters Type Name Description String name Returns Type Description Boolean | Improve this Doc View Source RemoveHeader(String) removes all headers with given name Declaration public bool RemoveHeader(string headerName) Parameters Type Name Description String headerName Returns Type Description Boolean True if header was removed False if no header exists with given name | Improve this Doc View Source RemoveHeader(HttpHeader) Removes given header object if it exist Declaration public bool RemoveHeader(HttpHeader header) Parameters Type Name Description HttpHeader header Returns true if header exists and was removed Returns Type Description Boolean Explicit Interface Implementations | Improve this Doc View Source IEnumerable.GetEnumerator() Declaration IEnumerator IEnumerable.GetEnumerator() Returns Type Description IEnumerator Implements System.Collections.Generic.IEnumerable<T> System.Collections.IEnumerable" "keywords": "Class HeaderCollection The http header collection. Inheritance Object HeaderCollection Implements IEnumerable < HttpHeader > IEnumerable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax [TypeConverter(typeof(ExpandableObjectConverter))] public class HeaderCollection : IEnumerable<HttpHeader>, IEnumerable Constructors | Improve this Doc View Source HeaderCollection() Initializes a new instance of the HeaderCollection class. Declaration public HeaderCollection() Properties | Improve this Doc View Source Headers Unique Request header collection. Declaration public ReadOnlyDictionary<string, HttpHeader> Headers { get; } Property Value Type Description ReadOnlyDictionary < String , HttpHeader > | Improve this Doc View Source NonUniqueHeaders Non Unique headers. Declaration public ReadOnlyDictionary<string, List<HttpHeader>> NonUniqueHeaders { get; } Property Value Type Description ReadOnlyDictionary < String , List < HttpHeader >> Methods | Improve this Doc View Source AddHeader(String, String) Add a new header with given name and value Declaration public void AddHeader(string name, string value) Parameters Type Name Description String name String value | Improve this Doc View Source AddHeader(HttpHeader) Adds the given header object to Request Declaration public void AddHeader(HttpHeader newHeader) Parameters Type Name Description HttpHeader newHeader | Improve this Doc View Source AddHeaders(IEnumerable<KeyValuePair<String, String>>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<KeyValuePair<string, string>> newHeaders) Parameters Type Name Description IEnumerable < KeyValuePair < String , String >> newHeaders | Improve this Doc View Source AddHeaders(IEnumerable<KeyValuePair<String, HttpHeader>>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<KeyValuePair<string, HttpHeader>> newHeaders) Parameters Type Name Description IEnumerable < KeyValuePair < String , HttpHeader >> newHeaders | Improve this Doc View Source AddHeaders(IEnumerable<HttpHeader>) Adds the given header objects to Request Declaration public void AddHeaders(IEnumerable<HttpHeader> newHeaders) Parameters Type Name Description IEnumerable < HttpHeader > newHeaders | Improve this Doc View Source Clear() Removes all the headers. Declaration public void Clear() | Improve this Doc View Source GetAllHeaders() Returns all headers Declaration public List<HttpHeader> GetAllHeaders() Returns Type Description List < HttpHeader > | Improve this Doc View Source GetEnumerator() Returns an enumerator that iterates through the collection. Declaration public IEnumerator<HttpHeader> GetEnumerator() Returns Type Description IEnumerator < HttpHeader > An enumerator that can be used to iterate through the collection. | Improve this Doc View Source GetFirstHeader(String) Declaration public HttpHeader GetFirstHeader(string name) Parameters Type Name Description String name Returns Type Description HttpHeader | Improve this Doc View Source GetHeaders(String) Returns all headers with given name if exists Returns null if doesn't exist Declaration public List<HttpHeader> GetHeaders(string name) Parameters Type Name Description String name Returns Type Description List < HttpHeader > | Improve this Doc View Source HeaderExists(String) True if header exists Declaration public bool HeaderExists(string name) Parameters Type Name Description String name Returns Type Description Boolean | Improve this Doc View Source RemoveHeader(String) removes all headers with given name Declaration public bool RemoveHeader(string headerName) Parameters Type Name Description String headerName Returns Type Description Boolean True if header was removed False if no header exists with given name | Improve this Doc View Source RemoveHeader(HttpHeader) Removes given header object if it exist Declaration public bool RemoveHeader(HttpHeader header) Parameters Type Name Description HttpHeader header Returns true if header exists and was removed Returns Type Description Boolean Explicit Interface Implementations | Improve this Doc View Source IEnumerable.GetEnumerator() Declaration IEnumerator IEnumerable.GetEnumerator() Returns Type Description IEnumerator Implements System.Collections.Generic.IEnumerable<T> System.Collections.IEnumerable"
}, },
"api/Titanium.Web.Proxy.Http.html": { "api/Titanium.Web.Proxy.Http.html": {
"href": "api/Titanium.Web.Proxy.Http.html", "href": "api/Titanium.Web.Proxy.Http.html",
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
"api/Titanium.Web.Proxy.Http.KnownHeaders.html": { "api/Titanium.Web.Proxy.Http.KnownHeaders.html": {
"href": "api/Titanium.Web.Proxy.Http.KnownHeaders.html", "href": "api/Titanium.Web.Proxy.Http.KnownHeaders.html",
"title": "Class KnownHeaders | Titanium Web Proxy", "title": "Class KnownHeaders | Titanium Web Proxy",
"keywords": "Class KnownHeaders Well known http headers. Inheritance Object KnownHeaders Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public static class KnownHeaders Fields | Improve this Doc View Source AcceptEncoding Declaration public const string AcceptEncoding = \"accept-encoding\" Field Value Type Description String | Improve this Doc View Source Authorization Declaration public const string Authorization = \"Authorization\" Field Value Type Description String | Improve this Doc View Source Connection Declaration public const string Connection = \"connection\" Field Value Type Description String | Improve this Doc View Source ConnectionClose Declaration public const string ConnectionClose = \"close\" Field Value Type Description String | Improve this Doc View Source ConnectionKeepAlive Declaration public const string ConnectionKeepAlive = \"keep-alive\" Field Value Type Description String | Improve this Doc View Source ContentEncoding Declaration public const string ContentEncoding = \"content-encoding\" Field Value Type Description String | Improve this Doc View Source ContentEncodingBrotli Declaration public const string ContentEncodingBrotli = \"br\" Field Value Type Description String | Improve this Doc View Source ContentEncodingDeflate Declaration public const string ContentEncodingDeflate = \"deflate\" Field Value Type Description String | Improve this Doc View Source ContentEncodingGzip Declaration public const string ContentEncodingGzip = \"gzip\" Field Value Type Description String | Improve this Doc View Source ContentLength Declaration public const string ContentLength = \"content-length\" Field Value Type Description String | Improve this Doc View Source ContentType Declaration public const string ContentType = \"content-type\" Field Value Type Description String | Improve this Doc View Source ContentTypeBoundary Declaration public const string ContentTypeBoundary = \"boundary\" Field Value Type Description String | Improve this Doc View Source ContentTypeCharset Declaration public const string ContentTypeCharset = \"charset\" Field Value Type Description String | Improve this Doc View Source Expect Declaration public const string Expect = \"expect\" Field Value Type Description String | Improve this Doc View Source Expect100Continue Declaration public const string Expect100Continue = \"100-continue\" Field Value Type Description String | Improve this Doc View Source Host Declaration public const string Host = \"host\" Field Value Type Description String | Improve this Doc View Source Location Declaration public const string Location = \"Location\" Field Value Type Description String | Improve this Doc View Source ProxyAuthenticate Declaration public const string ProxyAuthenticate = \"Proxy-Authenticate\" Field Value Type Description String | Improve this Doc View Source ProxyAuthorization Declaration public const string ProxyAuthorization = \"Proxy-Authorization\" Field Value Type Description String | Improve this Doc View Source ProxyAuthorizationBasic Declaration public const string ProxyAuthorizationBasic = \"basic\" Field Value Type Description String | Improve this Doc View Source ProxyConnection Declaration public const string ProxyConnection = \"Proxy-Connection\" Field Value Type Description String | Improve this Doc View Source ProxyConnectionClose Declaration public const string ProxyConnectionClose = \"close\" Field Value Type Description String | Improve this Doc View Source TransferEncoding Declaration public const string TransferEncoding = \"transfer-encoding\" Field Value Type Description String | Improve this Doc View Source TransferEncodingChunked Declaration public const string TransferEncodingChunked = \"chunked\" Field Value Type Description String | Improve this Doc View Source Upgrade Declaration public const string Upgrade = \"upgrade\" Field Value Type Description String | Improve this Doc View Source UpgradeWebsocket Declaration public const string UpgradeWebsocket = \"websocket\" Field Value Type Description String" "keywords": "Class KnownHeaders Well known http headers. Inheritance Object KnownHeaders Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Http Assembly : Titanium.Web.Proxy.dll Syntax public static class KnownHeaders Fields | Improve this Doc View Source AcceptEncoding Declaration public const string AcceptEncoding = \"Accept-Encoding\" Field Value Type Description String | Improve this Doc View Source Authorization Declaration public const string Authorization = \"Authorization\" Field Value Type Description String | Improve this Doc View Source Connection Declaration public const string Connection = \"Connection\" Field Value Type Description String | Improve this Doc View Source ConnectionClose Declaration public const string ConnectionClose = \"close\" Field Value Type Description String | Improve this Doc View Source ConnectionKeepAlive Declaration public const string ConnectionKeepAlive = \"keep-alive\" Field Value Type Description String | Improve this Doc View Source ContentEncoding Declaration public const string ContentEncoding = \"Content-Encoding\" Field Value Type Description String | Improve this Doc View Source ContentEncodingBrotli Declaration public const string ContentEncodingBrotli = \"br\" Field Value Type Description String | Improve this Doc View Source ContentEncodingDeflate Declaration public const string ContentEncodingDeflate = \"deflate\" Field Value Type Description String | Improve this Doc View Source ContentEncodingGzip Declaration public const string ContentEncodingGzip = \"gzip\" Field Value Type Description String | Improve this Doc View Source ContentLength Declaration public const string ContentLength = \"Content-Length\" Field Value Type Description String | Improve this Doc View Source ContentType Declaration public const string ContentType = \"Content-Type\" Field Value Type Description String | Improve this Doc View Source ContentTypeBoundary Declaration public const string ContentTypeBoundary = \"boundary\" Field Value Type Description String | Improve this Doc View Source ContentTypeCharset Declaration public const string ContentTypeCharset = \"charset\" Field Value Type Description String | Improve this Doc View Source Expect Declaration public const string Expect = \"Expect\" Field Value Type Description String | Improve this Doc View Source Expect100Continue Declaration public const string Expect100Continue = \"100-continue\" Field Value Type Description String | Improve this Doc View Source Host Declaration public const string Host = \"Host\" Field Value Type Description String | Improve this Doc View Source Location Declaration public const string Location = \"Location\" Field Value Type Description String | Improve this Doc View Source ProxyAuthenticate Declaration public const string ProxyAuthenticate = \"Proxy-Authenticate\" Field Value Type Description String | Improve this Doc View Source ProxyAuthorization Declaration public const string ProxyAuthorization = \"Proxy-Authorization\" Field Value Type Description String | Improve this Doc View Source ProxyAuthorizationBasic Declaration public const string ProxyAuthorizationBasic = \"basic\" Field Value Type Description String | Improve this Doc View Source ProxyConnection Declaration public const string ProxyConnection = \"Proxy-Connection\" Field Value Type Description String | Improve this Doc View Source ProxyConnectionClose Declaration public const string ProxyConnectionClose = \"close\" Field Value Type Description String | Improve this Doc View Source TransferEncoding Declaration public const string TransferEncoding = \"Transfer-Encoding\" Field Value Type Description String | Improve this Doc View Source TransferEncodingChunked Declaration public const string TransferEncodingChunked = \"chunked\" Field Value Type Description String | Improve this Doc View Source Upgrade Declaration public const string Upgrade = \"Upgrade\" Field Value Type Description String | Improve this Doc View Source UpgradeWebsocket Declaration public const string UpgradeWebsocket = \"websocket\" Field Value Type Description String"
}, },
"api/Titanium.Web.Proxy.Http.Request.html": { "api/Titanium.Web.Proxy.Http.Request.html": {
"href": "api/Titanium.Web.Proxy.Http.Request.html", "href": "api/Titanium.Web.Proxy.Http.Request.html",
...@@ -217,7 +217,7 @@ ...@@ -217,7 +217,7 @@
"api/Titanium.Web.Proxy.Models.ExplicitProxyEndPoint.html": { "api/Titanium.Web.Proxy.Models.ExplicitProxyEndPoint.html": {
"href": "api/Titanium.Web.Proxy.Models.ExplicitProxyEndPoint.html", "href": "api/Titanium.Web.Proxy.Models.ExplicitProxyEndPoint.html",
"title": "Class ExplicitProxyEndPoint | Titanium Web Proxy", "title": "Class ExplicitProxyEndPoint | Titanium Web Proxy",
"keywords": "Class ExplicitProxyEndPoint A proxy endpoint that the client is aware of. So client application know that it is communicating with a proxy server. Inheritance Object ProxyEndPoint ExplicitProxyEndPoint Inherited Members ProxyEndPoint.IpAddress ProxyEndPoint.Port ProxyEndPoint.DecryptSsl ProxyEndPoint.IpV6Enabled ProxyEndPoint.GenericCertificate Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Models Assembly : Titanium.Web.Proxy.dll Syntax public class ExplicitProxyEndPoint : ProxyEndPoint Constructors | Improve this Doc View Source ExplicitProxyEndPoint(IPAddress, Int32, Boolean) Constructor. Declaration public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool decryptSsl = true) Parameters Type Name Description IPAddress ipAddress Listening IP address. Int32 port Listening port. Boolean decryptSsl Should we decrypt ssl? Events | Improve this Doc View Source BeforeTunnelConnectRequest Intercept tunnel connect request. Valid only for explicit endpoints. Set the DecryptSsl property to false if this HTTP connect request should'nt be decrypted and instead be relayed. Declaration public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectRequest Event Type Type Description AsyncEventHandler < TunnelConnectSessionEventArgs > | Improve this Doc View Source BeforeTunnelConnectResponse Intercept tunnel connect response. Valid only for explicit endpoints. Declaration public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectResponse Event Type Type Description AsyncEventHandler < TunnelConnectSessionEventArgs >" "keywords": "Class ExplicitProxyEndPoint A proxy endpoint that the client is aware of. So client application know that it is communicating with a proxy server. Inheritance Object ProxyEndPoint ExplicitProxyEndPoint Inherited Members ProxyEndPoint.IpAddress ProxyEndPoint.Port ProxyEndPoint.DecryptSsl ProxyEndPoint.IpV6Enabled ProxyEndPoint.GenericCertificate Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Models Assembly : Titanium.Web.Proxy.dll Syntax public class ExplicitProxyEndPoint : ProxyEndPoint Constructors | Improve this Doc View Source ExplicitProxyEndPoint(IPAddress, Int32, Boolean) Constructor. Declaration public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool decryptSsl = true) Parameters Type Name Description IPAddress ipAddress Listening IP address. Int32 port Listening port. Boolean decryptSsl Should we decrypt ssl? Events | Improve this Doc View Source BeforeTunnelConnectRequest Intercept tunnel connect request. Valid only for explicit endpoints. Set the DecryptSsl property to false if this HTTP connect request shouldn't be decrypted and instead be relayed. Declaration public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectRequest Event Type Type Description AsyncEventHandler < TunnelConnectSessionEventArgs > | Improve this Doc View Source BeforeTunnelConnectResponse Intercept tunnel connect response. Valid only for explicit endpoints. Declaration public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectResponse Event Type Type Description AsyncEventHandler < TunnelConnectSessionEventArgs >"
}, },
"api/Titanium.Web.Proxy.Models.ExternalProxy.html": { "api/Titanium.Web.Proxy.Models.ExternalProxy.html": {
"href": "api/Titanium.Web.Proxy.Models.ExternalProxy.html", "href": "api/Titanium.Web.Proxy.Models.ExternalProxy.html",
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
"api/Titanium.Web.Proxy.Models.HttpHeader.html": { "api/Titanium.Web.Proxy.Models.HttpHeader.html": {
"href": "api/Titanium.Web.Proxy.Models.HttpHeader.html", "href": "api/Titanium.Web.Proxy.Models.HttpHeader.html",
"title": "Class HttpHeader | Titanium Web Proxy", "title": "Class HttpHeader | Titanium Web Proxy",
"keywords": "Class HttpHeader Http Header object used by proxy Inheritance Object HttpHeader Inherited Members Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Models Assembly : Titanium.Web.Proxy.dll Syntax public class HttpHeader Constructors | Improve this Doc View Source HttpHeader(String, String) Initialize a new instance. Declaration public HttpHeader(string name, string value) Parameters Type Name Description String name Header name. String value Header value. Fields | Improve this Doc View Source HttpHeaderOverhead HPACK: Header Compression for HTTP/2 Section 4.1. Calculating Table Size The additional 32 octets account for an estimated overhead associated with an entry. Declaration public const int HttpHeaderOverhead = 32 Field Value Type Description Int32 Properties | Improve this Doc View Source Name Header Name. Declaration public string Name { get; set; } Property Value Type Description String | Improve this Doc View Source Size Declaration public int Size { get; } Property Value Type Description Int32 | Improve this Doc View Source Value Header Value. Declaration public string Value { get; set; } Property Value Type Description String Methods | Improve this Doc View Source SizeOf(String, String) Declaration public static int SizeOf(string name, string value) Parameters Type Name Description String name String value Returns Type Description Int32 | Improve this Doc View Source ToString() Returns header as a valid header string. Declaration public override string ToString() Returns Type Description String Overrides Object.ToString()" "keywords": "Class HttpHeader Http Header object used by proxy Inheritance Object HttpHeader Inherited Members Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy.Models Assembly : Titanium.Web.Proxy.dll Syntax public class HttpHeader Constructors | Improve this Doc View Source HttpHeader(String, String) Initialize a new instance. Declaration public HttpHeader(string name, string value) Parameters Type Name Description String name Header name. String value Header value. Fields | Improve this Doc View Source HttpHeaderOverhead HPACK: Header Compression for HTTP/2 Section 4.1. Calculating Table Size The additional 32 octets account for an estimated overhead associated with an entry. Declaration public const int HttpHeaderOverhead = 32 Field Value Type Description Int32 Properties | Improve this Doc View Source Name Header Name. Declaration public string Name { get; } Property Value Type Description String | Improve this Doc View Source Size Declaration public int Size { get; } Property Value Type Description Int32 | Improve this Doc View Source Value Header Value. Declaration public string Value { get; set; } Property Value Type Description String Methods | Improve this Doc View Source SizeOf(String, String) Declaration public static int SizeOf(string name, string value) Parameters Type Name Description String name String value Returns Type Description Int32 | Improve this Doc View Source ToString() Returns header as a valid header string. Declaration public override string ToString() Returns Type Description String Overrides Object.ToString()"
}, },
"api/Titanium.Web.Proxy.Models.ProxyAuthenticationContext.html": { "api/Titanium.Web.Proxy.Models.ProxyAuthenticationContext.html": {
"href": "api/Titanium.Web.Proxy.Models.ProxyAuthenticationContext.html", "href": "api/Titanium.Web.Proxy.Models.ProxyAuthenticationContext.html",
...@@ -277,6 +277,6 @@ ...@@ -277,6 +277,6 @@
"api/Titanium.Web.Proxy.ProxyServer.html": { "api/Titanium.Web.Proxy.ProxyServer.html": {
"href": "api/Titanium.Web.Proxy.ProxyServer.html", "href": "api/Titanium.Web.Proxy.ProxyServer.html",
"title": "Class ProxyServer | Titanium Web Proxy", "title": "Class ProxyServer | Titanium Web Proxy",
"keywords": "Class ProxyServer This class is the backbone of proxy. One can create as many instances as needed. However care should be taken to avoid using the same listening ports across multiple instances. Inheritance Object ProxyServer Implements IDisposable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors | Improve this Doc View Source ProxyServer(Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? | Improve this Doc View Source ProxyServer(String, String, Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description String rootCertificateName Name of the root certificate. String rootCertificateIssuerName Name of the root certificate issuer. Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? Properties | Improve this Doc View Source BufferPool The buffer pool used throughout this proxy instance. Set custom implementations by implementing this interface. By default this uses DefaultBufferPool implementation available in StreamExtended library package. Declaration public IBufferPool BufferPool { get; set; } Property Value Type Description StreamExtended.IBufferPool | Improve this Doc View Source BufferSize Buffer size in bytes used throughout this proxy. Default value is 8192 bytes. Declaration public int BufferSize { get; set; } Property Value Type Description Int32 | Improve this Doc View Source CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager | Improve this Doc View Source CheckCertificateRevocation Should we check for certificare revocation during SSL authentication to servers Note: If enabled can reduce performance. Defaults to false. Declaration public X509RevocationMode CheckCertificateRevocation { get; set; } Property Value Type Description X509RevocationMode | Improve this Doc View Source ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source ConnectionTimeOutSeconds Seconds client/server connection are to be kept alive when waiting for read/write to complete. This will also determine the pool eviction time when connection pool is enabled. Default value is 60 seconds. Declaration public int ConnectionTimeOutSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 continue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableConnectionPool Should we enable experimental server connection pool? Defaults to true. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableTcpServerConnectionPrefetch Should we enable tcp server connection prefetching? When enabled, as soon as we receive a client connection we concurrently initiate corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request we will have the server connection immediately ready or in the process of getting ready. If a server connection is available in cache then this prefetch task will immediatly return with the available connection from cache. Defaults to true. Declaration public bool EnableTcpServerConnectionPrefetch { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableWinAuth Enable disable Windows Authentication (NTLM/Kerberos). Note: NTLM/Kerberos will always send local credentials of current user running the proxy process. This is because a man in middle attack with Windows domain authentication is not currently supported. Defaults to false. Declaration public bool EnableWinAuth { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler | Improve this Doc View Source ForwardToUpstreamGateway Gets or sets a value indicating whether requests will be chained to upstream gateway. Defaults to false. Declaration public bool ForwardToUpstreamGateway { get; set; } Property Value Type Description Boolean | Improve this Doc View Source GetCustomUpStreamProxyFunc A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP(S) requests. User should return the ExternalProxy object with valid credentials. Declaration public Func<SessionEventArgsBase, Task<ExternalProxy>> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> | Improve this Doc View Source MaxCachedConnections Maximum number of concurrent connections per remote host in cache. Only valid when connection pooling is enabled. Default value is 2. Declaration public int MaxCachedConnections { get; set; } Property Value Type Description Int32 | Improve this Doc View Source NoDelay Gets or sets a Boolean value that specifies whether server and client stream Sockets are using the Nagle algorithm. Defaults to true, no nagle algorithm is used. Declaration public bool NoDelay { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ProxyAuthenticationRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyAuthenticationRealm { get; set; } Property Value Type Description String | Improve this Doc View Source ProxyAuthenticationSchemes A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required. Works in relation with ProxySchemeAuthenticateFunc. Declaration public IEnumerable<string> ProxyAuthenticationSchemes { get; set; } Property Value Type Description IEnumerable < String > | Improve this Doc View Source ProxyBasicAuthenticateFunc A callback to authenticate proxy clients via basic authentication. Parameters are username and password as provided by client. Should return true for successful authentication. Declaration public Func<SessionEventArgsBase, string, string, Task<bool>> ProxyBasicAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < Boolean >> | Improve this Doc View Source ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List<ProxyEndPoint> ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > | Improve this Doc View Source ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean | Improve this Doc View Source ProxySchemeAuthenticateFunc A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc. Parameters are current working session, schemeType, and token as provided by a calling client. Should return success for successful authentication, continuation if the package requests, or failure. Declaration public Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>> ProxySchemeAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < ProxyAuthenticationContext >> | Improve this Doc View Source ReuseSocket Should we reuse client/server tcp sockets. Default is true (disabled for linux/macOS due to bug in .Net core). Declaration public bool ReuseSocket { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols | Improve this Doc View Source TcpTimeWaitSeconds Number of seconds to linger when Tcp connection is in TIME_WAIT state. Default value is 30. Declaration public int TcpTimeWaitSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source ThreadPoolWorkerThread Customize the minimum ThreadPool size (increase it on a server) Declaration public int ThreadPoolWorkerThread { get; set; } Property Value Type Description Int32 | Improve this Doc View Source UpStreamEndPoint Local adapter/NIC endpoint where proxy makes request via. Defaults via any IP addresses of this machine. Declaration public IPEndPoint UpStreamEndPoint { get; set; } Property Value Type Description IPEndPoint | Improve this Doc View Source UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy | Improve this Doc View Source UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods | Improve this Doc View Source AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. | Improve this Doc View Source DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() | Improve this Doc View Source DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() | Improve this Doc View Source DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() | Improve this Doc View Source DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType | Improve this Doc View Source Dispose() Dispose the Proxy instance. Declaration public void Dispose() | Improve this Doc View Source RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point does'nt exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. | Improve this Doc View Source SetAsSystemHttpProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. | Improve this Doc View Source SetAsSystemHttpsProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. | Improve this Doc View Source SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. ProxyProtocolType protocolType The proxy protocol type. | Improve this Doc View Source Start() Start this proxy server instance. Declaration public void Start() | Improve this Doc View Source Stop() Stop this proxy server instance. Declaration public void Stop() Events | Improve this Doc View Source AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler<CertificateSelectionEventArgs> ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > | Improve this Doc View Source ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler | Improve this Doc View Source OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnClientConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnServerConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler<CertificateValidationEventArgs> ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > | Improve this Doc View Source ServerConnectionCountChanged Event occurs when server connection count changed. Declaration public event EventHandler ServerConnectionCountChanged Event Type Type Description EventHandler Implements System.IDisposable" "keywords": "Class ProxyServer This class is the backbone of proxy. One can create as many instances as needed. However care should be taken to avoid using the same listening ports across multiple instances. Inheritance Object ProxyServer Implements IDisposable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors | Improve this Doc View Source ProxyServer(Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? | Improve this Doc View Source ProxyServer(String, String, Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description String rootCertificateName Name of the root certificate. String rootCertificateIssuerName Name of the root certificate issuer. Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? Properties | Improve this Doc View Source BufferPool The buffer pool used throughout this proxy instance. Set custom implementations by implementing this interface. By default this uses DefaultBufferPool implementation available in StreamExtended library package. Declaration public IBufferPool BufferPool { get; set; } Property Value Type Description IBufferPool | Improve this Doc View Source BufferSize Buffer size in bytes used throughout this proxy. Default value is 8192 bytes. Declaration public int BufferSize { get; set; } Property Value Type Description Int32 | Improve this Doc View Source CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager | Improve this Doc View Source CheckCertificateRevocation Should we check for certificate revocation during SSL authentication to servers Note: If enabled can reduce performance. Defaults to false. Declaration public X509RevocationMode CheckCertificateRevocation { get; set; } Property Value Type Description X509RevocationMode | Improve this Doc View Source ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source ConnectionTimeOutSeconds Seconds client/server connection are to be kept alive when waiting for read/write to complete. This will also determine the pool eviction time when connection pool is enabled. Default value is 60 seconds. Declaration public int ConnectionTimeOutSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 continue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableConnectionPool Should we enable experimental server connection pool? Defaults to true. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableHttp2 Enable disable HTTP/2 support. Warning: HTTP/2 support is very limited only enabled when both client and server supports it (no protocol changing in proxy) GetRequest/ResponseBody(AsString) methods are not supported cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored) Declaration public bool EnableHttp2 { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableTcpServerConnectionPrefetch Should we enable tcp server connection prefetching? When enabled, as soon as we receive a client connection we concurrently initiate corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request we will have the server connection immediately ready or in the process of getting ready. If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache. Defaults to true. Declaration public bool EnableTcpServerConnectionPrefetch { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableWinAuth Enable disable Windows Authentication (NTLM/Kerberos). Note: NTLM/Kerberos will always send local credentials of current user running the proxy process. This is because a man in middle attack with Windows domain authentication is not currently supported. Defaults to false. Declaration public bool EnableWinAuth { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler | Improve this Doc View Source ForwardToUpstreamGateway Gets or sets a value indicating whether requests will be chained to upstream gateway. Defaults to false. Declaration public bool ForwardToUpstreamGateway { get; set; } Property Value Type Description Boolean | Improve this Doc View Source GetCustomUpStreamProxyFunc A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP(S) requests. User should return the ExternalProxy object with valid credentials. Declaration public Func<SessionEventArgsBase, Task<ExternalProxy>> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> | Improve this Doc View Source MaxCachedConnections Maximum number of concurrent connections per remote host in cache. Only valid when connection pooling is enabled. Default value is 2. Declaration public int MaxCachedConnections { get; set; } Property Value Type Description Int32 | Improve this Doc View Source NoDelay Gets or sets a Boolean value that specifies whether server and client stream Sockets are using the Nagle algorithm. Defaults to true, no nagle algorithm is used. Declaration public bool NoDelay { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ProxyAuthenticationRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyAuthenticationRealm { get; set; } Property Value Type Description String | Improve this Doc View Source ProxyAuthenticationSchemes A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required. Works in relation with ProxySchemeAuthenticateFunc. Declaration public IEnumerable<string> ProxyAuthenticationSchemes { get; set; } Property Value Type Description IEnumerable < String > | Improve this Doc View Source ProxyBasicAuthenticateFunc A callback to authenticate proxy clients via basic authentication. Parameters are username and password as provided by client. Should return true for successful authentication. Declaration public Func<SessionEventArgsBase, string, string, Task<bool>> ProxyBasicAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < Boolean >> | Improve this Doc View Source ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List<ProxyEndPoint> ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > | Improve this Doc View Source ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean | Improve this Doc View Source ProxySchemeAuthenticateFunc A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc. Parameters are current working session, schemeType, and token as provided by a calling client. Should return success for successful authentication, continuation if the package requests, or failure. Declaration public Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>> ProxySchemeAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < ProxyAuthenticationContext >> | Improve this Doc View Source ReuseSocket Should we reuse client/server tcp sockets. Default is true (disabled for linux/macOS due to bug in .Net core). Declaration public bool ReuseSocket { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols | Improve this Doc View Source TcpTimeWaitSeconds Number of seconds to linger when Tcp connection is in TIME_WAIT state. Default value is 30. Declaration public int TcpTimeWaitSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source ThreadPoolWorkerThread Customize the minimum ThreadPool size (increase it on a server) Declaration public int ThreadPoolWorkerThread { get; set; } Property Value Type Description Int32 | Improve this Doc View Source UpStreamEndPoint Local adapter/NIC endpoint where proxy makes request via. Defaults via any IP addresses of this machine. Declaration public IPEndPoint UpStreamEndPoint { get; set; } Property Value Type Description IPEndPoint | Improve this Doc View Source UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy | Improve this Doc View Source UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods | Improve this Doc View Source AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. | Improve this Doc View Source DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() | Improve this Doc View Source DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() | Improve this Doc View Source DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() | Improve this Doc View Source DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType | Improve this Doc View Source Dispose() Dispose the Proxy instance. Declaration public void Dispose() | Improve this Doc View Source RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point doesn't exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. | Improve this Doc View Source SetAsSystemHttpProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. | Improve this Doc View Source SetAsSystemHttpsProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. | Improve this Doc View Source SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. ProxyProtocolType protocolType The proxy protocol type. | Improve this Doc View Source Start() Start this proxy server instance. Declaration public void Start() | Improve this Doc View Source Stop() Stop this proxy server instance. Declaration public void Stop() Events | Improve this Doc View Source AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler<CertificateSelectionEventArgs> ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > | Improve this Doc View Source ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler | Improve this Doc View Source OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnClientConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnServerConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler<CertificateValidationEventArgs> ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > | Improve this Doc View Source ServerConnectionCountChanged Event occurs when server connection count changed. Declaration public event EventHandler ServerConnectionCountChanged Event Type Type Description EventHandler Implements System.IDisposable"
} }
} }
...@@ -510,18 +510,18 @@ references: ...@@ -510,18 +510,18 @@ references:
isSpec: "True" isSpec: "True"
fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.SessionEventArgsBase fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.SessionEventArgsBase
nameWithType: SessionEventArgsBase.SessionEventArgsBase nameWithType: SessionEventArgsBase.SessionEventArgsBase
- uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferPool - uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferPool
name: bufferPool name: BufferPool
href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferPool href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferPool
commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferPool commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferPool
fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferPool fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferPool
nameWithType: SessionEventArgsBase.bufferPool nameWithType: SessionEventArgsBase.BufferPool
- uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferSize - uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferSize
name: bufferSize name: BufferSize
href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_bufferSize href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_BufferSize
commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferSize commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferSize
fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.bufferSize fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.BufferSize
nameWithType: SessionEventArgsBase.bufferSize nameWithType: SessionEventArgsBase.BufferSize
- uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ClientEndPoint - uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ClientEndPoint
name: ClientEndPoint name: ClientEndPoint
href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ClientEndPoint href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ClientEndPoint
...@@ -586,12 +586,12 @@ references: ...@@ -586,12 +586,12 @@ references:
isSpec: "True" isSpec: "True"
fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.Exception fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.Exception
nameWithType: SessionEventArgsBase.Exception nameWithType: SessionEventArgsBase.Exception
- uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.exceptionFunc - uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ExceptionFunc
name: exceptionFunc name: ExceptionFunc
href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_exceptionFunc href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_ExceptionFunc
commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.exceptionFunc commentId: F:Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ExceptionFunc
fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.exceptionFunc fullName: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.ExceptionFunc
nameWithType: SessionEventArgsBase.exceptionFunc nameWithType: SessionEventArgsBase.ExceptionFunc
- uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.HttpClient - uid: Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.HttpClient
name: HttpClient name: HttpClient
href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_HttpClient href: api/Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html#Titanium_Web_Proxy_EventArguments_SessionEventArgsBase_HttpClient
...@@ -962,6 +962,19 @@ references: ...@@ -962,6 +962,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo fullName: Titanium.Web.Proxy.Http.ConnectRequest.ClientHelloInfo
nameWithType: ConnectRequest.ClientHelloInfo nameWithType: ConnectRequest.ClientHelloInfo
- uid: Titanium.Web.Proxy.Http.ConnectRequest.TunnelType
name: TunnelType
href: api/Titanium.Web.Proxy.Http.ConnectRequest.html#Titanium_Web_Proxy_Http_ConnectRequest_TunnelType
commentId: P:Titanium.Web.Proxy.Http.ConnectRequest.TunnelType
fullName: Titanium.Web.Proxy.Http.ConnectRequest.TunnelType
nameWithType: ConnectRequest.TunnelType
- uid: Titanium.Web.Proxy.Http.ConnectRequest.TunnelType*
name: TunnelType
href: api/Titanium.Web.Proxy.Http.ConnectRequest.html#Titanium_Web_Proxy_Http_ConnectRequest_TunnelType_
commentId: Overload:Titanium.Web.Proxy.Http.ConnectRequest.TunnelType
isSpec: "True"
fullName: Titanium.Web.Proxy.Http.ConnectRequest.TunnelType
nameWithType: ConnectRequest.TunnelType
- uid: Titanium.Web.Proxy.Http.ConnectResponse - uid: Titanium.Web.Proxy.Http.ConnectResponse
name: ConnectResponse name: ConnectResponse
href: api/Titanium.Web.Proxy.Http.ConnectResponse.html href: api/Titanium.Web.Proxy.Http.ConnectResponse.html
...@@ -3492,6 +3505,19 @@ references: ...@@ -3492,6 +3505,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.EnableConnectionPool fullName: Titanium.Web.Proxy.ProxyServer.EnableConnectionPool
nameWithType: ProxyServer.EnableConnectionPool nameWithType: ProxyServer.EnableConnectionPool
- uid: Titanium.Web.Proxy.ProxyServer.EnableHttp2
name: EnableHttp2
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_EnableHttp2
commentId: P:Titanium.Web.Proxy.ProxyServer.EnableHttp2
fullName: Titanium.Web.Proxy.ProxyServer.EnableHttp2
nameWithType: ProxyServer.EnableHttp2
- uid: Titanium.Web.Proxy.ProxyServer.EnableHttp2*
name: EnableHttp2
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_EnableHttp2_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.EnableHttp2
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.EnableHttp2
nameWithType: ProxyServer.EnableHttp2
- uid: Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch - uid: Titanium.Web.Proxy.ProxyServer.EnableTcpServerConnectionPrefetch
name: EnableTcpServerConnectionPrefetch name: EnableTcpServerConnectionPrefetch
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_EnableTcpServerConnectionPrefetch
......
...@@ -4,7 +4,7 @@ using System.Runtime.InteropServices; ...@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Titanium.Web.Proxy.Examples.Basic.Helpers namespace Titanium.Web.Proxy.Examples.Basic.Helpers
{ {
/// <summary> /// <summary>
/// Adapated from /// Adapted from
/// http://stackoverflow.com/questions/13656846/how-to-programmatic-disable-c-sharp-console-applications-quick-edit-mode /// http://stackoverflow.com/questions/13656846/how-to-programmatic-disable-c-sharp-console-applications-quick-edit-mode
/// </summary> /// </summary>
internal static class ConsoleHelper internal static class ConsoleHelper
......
...@@ -32,11 +32,11 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -32,11 +32,11 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
if (exception is ProxyHttpException phex) if (exception is ProxyHttpException phex)
{ {
await WriteToConsole(exception.Message + ": " + phex.InnerException?.Message, true); await writeToConsole(exception.Message + ": " + phex.InnerException?.Message, true);
} }
else else
{ {
await WriteToConsole(exception.Message, true); await writeToConsole(exception.Message, true);
} }
}; };
proxyServer.ForwardToUpstreamGateway = true; proxyServer.ForwardToUpstreamGateway = true;
...@@ -52,8 +52,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -52,8 +52,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
public void StartProxy() public void StartProxy()
{ {
proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeRequest += onRequest;
proxyServer.BeforeResponse += OnResponse; proxyServer.BeforeResponse += onResponse;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
...@@ -63,8 +63,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -63,8 +63,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000); explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000);
// Fired when a CONNECT request is received // Fired when a CONNECT request is received
explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; explicitEndPoint.BeforeTunnelConnectRequest += onBeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse += OnBeforeTunnelConnectResponse; explicitEndPoint.BeforeTunnelConnectResponse += onBeforeTunnelConnectResponse;
// An explicit endpoint is where the client knows about the existence of a proxy // An explicit endpoint is where the client knows about the existence of a proxy
// So client sends request in a proxy friendly manner // So client sends request in a proxy friendly manner
...@@ -102,11 +102,11 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -102,11 +102,11 @@ namespace Titanium.Web.Proxy.Examples.Basic
public void Stop() public void Stop()
{ {
explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest; explicitEndPoint.BeforeTunnelConnectRequest -= onBeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse -= OnBeforeTunnelConnectResponse; explicitEndPoint.BeforeTunnelConnectResponse -= onBeforeTunnelConnectResponse;
proxyServer.BeforeRequest -= OnRequest; proxyServer.BeforeRequest -= onRequest;
proxyServer.BeforeResponse -= OnResponse; proxyServer.BeforeResponse -= onResponse;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection; proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
...@@ -116,10 +116,10 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -116,10 +116,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.CertificateManager.RemoveTrustedRootCertificates(); //proxyServer.CertificateManager.RemoveTrustedRootCertificates();
} }
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
string hostname = e.HttpClient.Request.RequestUri.Host; string hostname = e.HttpClient.Request.RequestUri.Host;
await WriteToConsole("Tunnel to: " + hostname); await writeToConsole("Tunnel to: " + hostname);
if (hostname.Contains("dropbox.com")) if (hostname.Contains("dropbox.com"))
{ {
...@@ -130,16 +130,16 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -130,16 +130,16 @@ namespace Titanium.Web.Proxy.Examples.Basic
} }
} }
private Task OnBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e) private Task onBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
{ {
return Task.FromResult(false); return Task.FromResult(false);
} }
// intecept & cancel redirect or update requests // intecept & cancel redirect or update requests
private async Task OnRequest(object sender, SessionEventArgs e) private async Task onRequest(object sender, SessionEventArgs e)
{ {
await WriteToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
await WriteToConsole(e.HttpClient.Request.Url); await writeToConsole(e.HttpClient.Request.Url);
// store it in the UserData property // store it in the UserData property
// It can be a simple integer, Guid, or any type // It can be a simple integer, Guid, or any type
...@@ -177,19 +177,19 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -177,19 +177,19 @@ namespace Titanium.Web.Proxy.Examples.Basic
} }
// Modify response // Modify response
private async Task MultipartRequestPartSent(object sender, MultipartRequestPartSentEventArgs e) private async Task multipartRequestPartSent(object sender, MultipartRequestPartSentEventArgs e)
{ {
var session = (SessionEventArgs)sender; var session = (SessionEventArgs)sender;
await WriteToConsole("Multipart form data headers:"); await writeToConsole("Multipart form data headers:");
foreach (var header in e.Headers) foreach (var header in e.Headers)
{ {
await WriteToConsole(header.ToString()); await writeToConsole(header.ToString());
} }
} }
private async Task OnResponse(object sender, SessionEventArgs e) private async Task onResponse(object sender, SessionEventArgs e)
{ {
await WriteToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount); await writeToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount);
string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath); string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath);
...@@ -261,7 +261,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -261,7 +261,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
return Task.FromResult(0); return Task.FromResult(0);
} }
private async Task WriteToConsole(string message, bool useRedColor = false) private async Task writeToConsole(string message, bool useRedColor = false)
{ {
await @lock.WaitAsync(); await @lock.WaitAsync();
......
...@@ -36,13 +36,20 @@ ...@@ -36,13 +36,20 @@
</ListView> </ListView>
<TabControl Grid.Column="2" Grid.Row="0"> <TabControl Grid.Column="2" Grid.Row="0">
<TabItem Header="Session"> <TabItem Header="Session">
<Grid Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBox x:Name="TextBoxRequest" Grid.Row="0" /> <TextBox x:Name="TextBoxRequest" Grid.Row="0" />
<TextBox x:Name="TextBoxResponse" Grid.Row="1" /> <TabControl Grid.Row="1">
<TabItem Header="Text">
<TextBox x:Name="TextBoxResponse" />
</TabItem>
<TabItem Header="Image">
<Image x:Name="ImageResponse" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None" />
</TabItem>
</TabControl>
</Grid> </Grid>
</TabItem> </TabItem>
</TabControl> </TabControl>
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
...@@ -8,6 +9,7 @@ using System.Threading.Tasks; ...@@ -8,6 +9,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media.Imaging;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
...@@ -36,6 +38,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -36,6 +38,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public MainWindow() public MainWindow()
{ {
proxyServer = new ProxyServer(); proxyServer = new ProxyServer();
proxyServer.EnableHttp2 = true;
//proxyServer.CertificateManager.CertificateEngine = CertificateEngine.DefaultWindows; //proxyServer.CertificateManager.CertificateEngine = CertificateEngine.DefaultWindows;
////Set a password for the .pfx file ////Set a password for the .pfx file
...@@ -96,7 +101,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -96,7 +101,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
InitializeComponent(); InitializeComponent();
} }
public ObservableCollection<SessionListItem> Sessions { get; } = new ObservableCollection<SessionListItem>(); public ObservableCollectionEx<SessionListItem> Sessions { get; } = new ObservableCollectionEx<SessionListItem>();
public SessionListItem SelectedSession public SessionListItem SelectedSession
{ {
...@@ -106,7 +111,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -106,7 +111,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
if (value != selectedSession) if (value != selectedSession)
{ {
selectedSession = value; selectedSession = value;
SelectedSessionChanged(); selectedSessionChanged();
} }
} }
} }
...@@ -131,7 +136,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -131,7 +136,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
e.DecryptSsl = false; e.DecryptSsl = false;
} }
await Dispatcher.InvokeAsync(() => { AddSession(e); }); await Dispatcher.InvokeAsync(() => { addSession(e); });
} }
private async Task ProxyServer_BeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e) private async Task ProxyServer_BeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
...@@ -147,8 +152,20 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -147,8 +152,20 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private async Task ProxyServer_BeforeRequest(object sender, SessionEventArgs e) private async Task ProxyServer_BeforeRequest(object sender, SessionEventArgs e)
{ {
if (e.HttpClient.ConnectRequest?.TunnelType != TunnelType.Http2)
{
return;
}
SessionListItem item = null; SessionListItem item = null;
await Dispatcher.InvokeAsync(() => { item = AddSession(e); }); await Dispatcher.InvokeAsync(() => { item = addSession(e); });
//if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Http2)
//{
//}
//if (!e.HttpClient.Request.RequestUri.ToString().Contains("/mail/u/"))
// return;
if (e.HttpClient.Request.HasBody) if (e.HttpClient.Request.HasBody)
{ {
...@@ -159,6 +176,11 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -159,6 +176,11 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e) private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e)
{ {
if (e.HttpClient.ConnectRequest?.TunnelType != TunnelType.Http2)
{
return;
}
SessionListItem item = null; SessionListItem item = null;
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
...@@ -168,6 +190,10 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -168,6 +190,10 @@ namespace Titanium.Web.Proxy.Examples.Wpf
} }
}); });
//e.HttpClient.Response.Headers.AddHeader("X-Titanium-Header", "HTTP/2 works");
//e.SetResponseBody(Encoding.ASCII.GetBytes("TITANIUMMMM!!!!"));
if (item != null) if (item != null)
{ {
if (e.HttpClient.Response.HasBody) if (e.HttpClient.Response.HasBody)
...@@ -191,15 +217,15 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -191,15 +217,15 @@ namespace Titanium.Web.Proxy.Examples.Wpf
}); });
} }
private SessionListItem AddSession(SessionEventArgsBase e) private SessionListItem addSession(SessionEventArgsBase e)
{ {
var item = CreateSessionListItem(e); var item = createSessionListItem(e);
Sessions.Add(item); Sessions.Add(item);
sessionDictionary.Add(e.HttpClient, item); sessionDictionary.Add(e.HttpClient, item);
return item; return item;
} }
private SessionListItem CreateSessionListItem(SessionEventArgsBase e) private SessionListItem createSessionListItem(SessionEventArgsBase e)
{ {
lastSessionNumber++; lastSessionNumber++;
bool isTunnelConnect = e is TunnelConnectSessionEventArgs; bool isTunnelConnect = e is TunnelConnectSessionEventArgs;
...@@ -214,18 +240,30 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -214,18 +240,30 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
e.DataReceived += (sender, args) => e.DataReceived += (sender, args) =>
{ {
var session = (SessionEventArgs)sender; var session = (SessionEventArgsBase)sender;
if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) if (sessionDictionary.TryGetValue(session.HttpClient, out var li))
{ {
var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown;
if (tunnelType != TunnelType.Unknown)
{
li.Protocol = TunnelTypeToString(tunnelType);
}
li.ReceivedDataCount += args.Count; li.ReceivedDataCount += args.Count;
} }
}; };
e.DataSent += (sender, args) => e.DataSent += (sender, args) =>
{ {
var session = (SessionEventArgs)sender; var session = (SessionEventArgsBase)sender;
if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) if (sessionDictionary.TryGetValue(session.HttpClient, out var li))
{ {
var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown;
if (tunnelType != TunnelType.Unknown)
{
li.Protocol = TunnelTypeToString(tunnelType);
}
li.SentDataCount += args.Count; li.SentDataCount += args.Count;
} }
}; };
...@@ -235,20 +273,38 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -235,20 +273,38 @@ namespace Titanium.Web.Proxy.Examples.Wpf
return item; return item;
} }
private string TunnelTypeToString(TunnelType tunnelType)
{
switch (tunnelType)
{
case TunnelType.Https:
return "https";
case TunnelType.Websocket:
return "websocket";
case TunnelType.Http2:
return "http2";
}
return null;
}
private void ListViewSessions_OnKeyDown(object sender, KeyEventArgs e) private void ListViewSessions_OnKeyDown(object sender, KeyEventArgs e)
{ {
if (e.Key == Key.Delete) if (e.Key == Key.Delete)
{ {
var selectedItems = ((ListView)sender).SelectedItems; var selectedItems = ((ListView)sender).SelectedItems;
Sessions.SuppressNotification = true;
foreach (var item in selectedItems.Cast<SessionListItem>().ToArray()) foreach (var item in selectedItems.Cast<SessionListItem>().ToArray())
{ {
Sessions.Remove(item); Sessions.Remove(item);
sessionDictionary.Remove(item.HttpClient); sessionDictionary.Remove(item.HttpClient);
} }
Sessions.SuppressNotification = false;
} }
} }
private void SelectedSessionChanged() private void selectedSessionChanged()
{ {
if (SelectedSession == null) if (SelectedSession == null)
{ {
...@@ -259,7 +315,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -259,7 +315,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
var session = SelectedSession.HttpClient; var session = SelectedSession.HttpClient;
var request = session.Request; var request = session.Request;
var data = (request.IsBodyRead ? request.Body : null) ?? new byte[0]; var fullData = (request.IsBodyRead ? request.Body : null) ?? new byte[0];
var data = fullData;
bool truncated = data.Length > truncateLimit; bool truncated = data.Length > truncateLimit;
if (truncated) if (truncated)
{ {
...@@ -275,7 +332,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -275,7 +332,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
TextBoxRequest.Text = sb.ToString(); TextBoxRequest.Text = sb.ToString();
var response = session.Response; var response = session.Response;
data = (response.IsBodyRead ? response.Body : null) ?? new byte[0]; fullData = (response.IsBodyRead ? response.Body : null) ?? new byte[0];
data = fullData;
truncated = data.Length > truncateLimit; truncated = data.Length > truncateLimit;
if (truncated) if (truncated)
{ {
...@@ -295,6 +353,19 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -295,6 +353,19 @@ namespace Titanium.Web.Proxy.Examples.Wpf
} }
TextBoxResponse.Text = sb.ToString(); TextBoxResponse.Text = sb.ToString();
try
{
using (MemoryStream stream = new MemoryStream(fullData))
{
ImageResponse.Source =
BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
catch
{
ImageResponse.Source = null;
}
} }
} }
} }
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Titanium.Web.Proxy.Examples.Wpf
{
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
private bool notificationSuppressed;
private bool suppressNotification;
public bool SuppressNotification
{
get => suppressNotification;
set
{
suppressNotification = value;
if (suppressNotification == false && notificationSuppressed)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
notificationSuppressed = false;
}
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (SuppressNotification)
{
notificationSuppressed = true;
return;
}
base.OnCollectionChanged(e);
}
}
}
\ No newline at end of file
...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations ...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations
} }
/// <summary> /// <summary>
/// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task
/// and Lazy classes to indicate that the value of a collection item, of the Task.Result property /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property
/// or of the Lazy.Value property can never be null. /// or of the Lazy.Value property can never be null.
/// </summary> /// </summary>
...@@ -85,7 +85,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations ...@@ -85,7 +85,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations
} }
/// <summary> /// <summary>
/// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task
/// and Lazy classes to indicate that the value of a collection item, of the Task.Result property /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property
/// or of the Lazy.Value property can be null. /// or of the Lazy.Value property can be null.
/// </summary> /// </summary>
...@@ -251,7 +251,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations ...@@ -251,7 +251,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf.Annotations
/// </list> /// </list>
/// If method has single input parameter, it's name could be omitted.<br /> /// If method has single input parameter, it's name could be omitted.<br />
/// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for method output /// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for method output
/// means that the methos doesn't return normally (throws or terminates the process).<br /> /// means that the method doesn't return normally (throws or terminates the process).<br />
/// Value <c>canbenull</c> is only applicable for output parameters.<br /> /// Value <c>canbenull</c> is only applicable for output parameters.<br />
/// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute /// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute
/// with rows separated by semicolon. There is no notion of order rows, all rows are checked /// with rows separated by semicolon. There is no notion of order rows, all rows are checked
......
...@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private long? bodySize; private long? bodySize;
private Exception exception; private Exception exception;
private string host; private string host;
private string process; private int processId;
private string protocol; private string protocol;
private long receivedDataCount; private long receivedDataCount;
private long sentDataCount; private long sentDataCount;
...@@ -54,10 +54,32 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -54,10 +54,32 @@ namespace Titanium.Web.Proxy.Examples.Wpf
set => SetField(ref bodySize, value); set => SetField(ref bodySize, value);
} }
public int ProcessId
{
get => processId;
set
{
if (SetField(ref processId, value))
{
OnPropertyChanged(nameof(Process));
}
}
}
public string Process public string Process
{ {
get => process; get
set => SetField(ref process, value); {
try
{
var process = System.Diagnostics.Process.GetProcessById(processId);
return process.ProcessName + ":" + processId;
}
catch (Exception)
{
return string.Empty;
}
}
} }
public long ReceivedDataCount public long ReceivedDataCount
...@@ -80,13 +102,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -80,13 +102,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{ {
if (!Equals(field, value)) if (!Equals(field, value))
{ {
field = value; field = value;
OnPropertyChanged(propertyName); OnPropertyChanged(propertyName);
return true;
} }
return false;
} }
[NotifyPropertyChangedInvocator] [NotifyPropertyChangedInvocator]
...@@ -132,20 +157,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -132,20 +157,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
BodySize = responseSize; BodySize = responseSize;
} }
Process = GetProcessDescription(HttpClient.ProcessId.Value); ProcessId = HttpClient.ProcessId.Value;
}
private string GetProcessDescription(int processId)
{
try
{
var process = System.Diagnostics.Process.GetProcessById(processId);
return process.ProcessName + ":" + processId;
}
catch (Exception)
{
return string.Empty;
}
} }
} }
} }
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj" />
</ItemGroup>
</Project>
\ No newline at end of file
...@@ -72,9 +72,6 @@ ...@@ -72,9 +72,6 @@
<Prefer32Bit>true</Prefer32Bit> <Prefer32Bit>true</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="StreamExtended, Version=1.0.201.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
<HintPath>..\..\src\packages\StreamExtended.1.0.201\lib\net45\StreamExtended.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
...@@ -95,6 +92,7 @@ ...@@ -95,6 +92,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="ObservableCollectionEx.cs" />
<Compile Include="Properties\Annotations.cs" /> <Compile Include="Properties\Annotations.cs" />
<Compile Include="SessionListItem.cs" /> <Compile Include="SessionListItem.cs" />
<Page Include="MainWindow.xaml"> <Page Include="MainWindow.xaml">
...@@ -128,7 +126,6 @@ ...@@ -128,7 +126,6 @@
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput> <LastGenOutput>Settings.Designer.cs</LastGenOutput>
...@@ -145,6 +142,10 @@ ...@@ -145,6 +142,10 @@
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\StreamExtended\StreamExtended.csproj">
<Project>{61539dc1-ce80-41e6-a696-8f455ace8d15}</Project>
<Name>StreamExtended</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj"> <ProjectReference Include="..\..\src\Titanium.Web.Proxy\Titanium.Web.Proxy.csproj">
<Project>{91018b6d-a7a9-45be-9cb3-79cbb8b169a6}</Project> <Project>{91018b6d-a7a9-45be-9cb3-79cbb8b169a6}</Project>
<Name>Titanium.Web.Proxy</Name> <Name>Titanium.Web.Proxy</Name>
......
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StreamExtended" version="1.0.201" targetFramework="net45" />
</packages>
\ No newline at end of file
using System.Collections.Concurrent;
namespace StreamExtended
{
/// <summary>
/// A concrete IBufferPool implementation using a thread-safe stack.
/// Works well when all consumers ask for buffers with the same size.
/// If your application would use variable size buffers consider implementing IBufferPool using System.Buffers library from Microsoft.
/// </summary>
public class DefaultBufferPool : IBufferPool
{
private readonly ConcurrentStack<byte[]> buffers = new ConcurrentStack<byte[]>();
/// <summary>
/// Gets a buffer.
/// </summary>
/// <param name="bufferSize">Size of the buffer.</param>
/// <returns></returns>
public byte[] GetBuffer(int bufferSize)
{
if (!buffers.TryPop(out var buffer) || buffer.Length != bufferSize)
{
buffer = new byte[bufferSize];
}
return buffer;
}
/// <summary>
/// Returns the buffer.
/// </summary>
/// <param name="buffer">The buffer.</param>
public void ReturnBuffer(byte[] buffer)
{
if (buffer != null)
{
buffers.Push(buffer);
}
}
public void Dispose()
{
buffers.Clear();
}
}
}
using System;
namespace StreamExtended
{
/// <summary>
/// Use this interface to implement custom buffer pool.
/// To use the default buffer pool implementation use DefaultBufferPool class.
/// </summary>
public interface IBufferPool : IDisposable
{
byte[] GetBuffer(int bufferSize);
void ReturnBuffer(byte[] buffer);
}
}
using StreamExtended.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StreamExtended
{
/// <summary>
/// Wraps up the client SSL hello information.
/// </summary>
public class ClientHelloInfo
{
private static readonly string[] compressions = {
"null",
"DEFLATE"
};
public int HandshakeVersion { get; set; }
public int MajorVersion { get; set; }
public int MinorVersion { get; set; }
public byte[] Random { get; set; }
public DateTime Time
{
get
{
DateTime time = DateTime.MinValue;
if (Random.Length > 3)
{
time = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
.AddSeconds(((uint)Random[3] << 24) + ((uint)Random[2] << 16) + ((uint)Random[1] << 8) + (uint)Random[0]).ToLocalTime();
}
return time;
}
}
public byte[] SessionId { get; set; }
public int[] Ciphers { get; set; }
public byte[] CompressionData { get; set; }
internal int ClientHelloLength { get; set; }
internal int EntensionsStartPosition { get; set; }
public Dictionary<string, SslExtension> Extensions { get; set; }
private static string SslVersionToString(int major, int minor)
{
string str = "Unknown";
if (major == 3 && minor == 3)
str = "TLS/1.2";
else if (major == 3 && minor == 2)
str = "TLS/1.1";
else if (major == 3 && minor == 1)
str = "TLS/1.0";
else if (major == 3 && minor == 0)
str = "SSL/3.0";
else if (major == 2 && minor == 0)
str = "SSL/2.0";
return $"{major}.{minor} ({str})";
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine($"A SSLv{HandshakeVersion}-compatible ClientHello handshake was found. Titanium extracted the parameters below.");
sb.AppendLine();
sb.AppendLine($"Version: {SslVersionToString(MajorVersion, MinorVersion)}");
sb.AppendLine($"Random: {string.Join(" ", Random.Select(x => x.ToString("X2")))}");
sb.AppendLine($"\"Time\": {Time}");
sb.AppendLine($"SessionID: {string.Join(" ", SessionId.Select(x => x.ToString("X2")))}");
if (Extensions != null)
{
sb.AppendLine("Extensions:");
foreach (var extension in Extensions.Values.OrderBy(x => x.Position))
{
sb.AppendLine($"{extension.Name}: {extension.Data}");
}
}
if (CompressionData != null && CompressionData.Length > 0)
{
int compressionMethod = CompressionData[0];
string compression = compressions.Length > compressionMethod
? compressions[compressionMethod]
: $"unknown [0x{compressionMethod:X2}]";
sb.AppendLine($"Compression: {compression}");
}
if (Ciphers.Length > 0)
{
sb.AppendLine("Ciphers:");
foreach (int cipherSuite in Ciphers)
{
if (!SslCiphers.Ciphers.TryGetValue(cipherSuite, out string cipherStr))
{
cipherStr = "unknown";
}
sb.AppendLine($"[0x{cipherSuite:X4}] {cipherStr}");
}
}
return sb.ToString();
}
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace StreamExtended.Models
{
internal static class SslCiphers
{
internal static readonly Dictionary<int, string> Ciphers = new Dictionary<int, string>
{
{ 0x0000, "TLS_NULL_WITH_NULL_NULL" },
{ 0x0001, "TLS_RSA_WITH_NULL_MD5" },
{ 0x0002, "TLS_RSA_WITH_NULL_SHA" },
{ 0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5" },
{ 0x0004, "TLS_RSA_WITH_RC4_128_MD5" },
{ 0x0005, "TLS_RSA_WITH_RC4_128_SHA" },
{ 0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5" },
{ 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA" },
{ 0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x0009, "TLS_RSA_WITH_DES_CBC_SHA" },
{ 0x000A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0x000B, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x000C, "TLS_DH_DSS_WITH_DES_CBC_SHA" },
{ 0x000D, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA" },
{ 0x000E, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x000F, "TLS_DH_RSA_WITH_DES_CBC_SHA" },
{ 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA" },
{ 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA" },
{ 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA" },
{ 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5" },
{ 0x0018, "TLS_DH_anon_WITH_RC4_128_MD5" },
{ 0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA" },
{ 0x001A, "TLS_DH_anon_WITH_DES_CBC_SHA" },
{ 0x001B, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA" },
{ 0x001C, "SSL_FORTEZZA_KEA_WITH_NULL_SHA" },
{ 0x001D, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA" },
//{ 0x001E, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA" },
// RFC 2712
{ 0x001E, "TLS_KRB5_WITH_DES_CBC_SHA" },
{ 0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA" },
{ 0x0020, "TLS_KRB5_WITH_RC4_128_SHA" },
{ 0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA" },
{ 0x0022, "TLS_KRB5_WITH_DES_CBC_MD5" },
{ 0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5" },
{ 0x0024, "TLS_KRB5_WITH_RC4_128_MD5" },
{ 0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5" },
{ 0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA" },
{ 0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA" },
{ 0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA" },
{ 0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5" },
{ 0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5" },
{ 0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5" },
// RFC 4785
{ 0x002C, "TLS_PSK_WITH_NULL_SHA" },
{ 0x002D, "TLS_DHE_PSK_WITH_NULL_SHA" },
{ 0x002E, "TLS_RSA_PSK_WITH_NULL_SHA" },
// RFC 5246
{ 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA" },
{ 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA" },
{ 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA" },
{ 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" },
{ 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" },
{ 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA" },
{ 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA" },
{ 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA" },
{ 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA" },
{ 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" },
{ 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
{ 0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA" },
{ 0x003B, "TLS_RSA_WITH_NULL_SHA256" },
{ 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256" },
{ 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256" },
{ 0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256" },
{ 0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256" },
{ 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" },
{ 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA" },
{ 0x0047, "TLS_ECDH_ECDSA_WITH_NULL_SHA" },
{ 0x0048, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA" },
{ 0x0049, "TLS_ECDH_ECDSA_WITH_DES_CBC_SHA" },
{ 0x004A, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA" },
{ 0x004B, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA" },
{ 0x004C, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA" },
{ 0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5" },
{ 0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5" },
{ 0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA" },
{ 0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA" },
{ 0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA" },
{ 0x0065, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA" },
{ 0x0066, "TLS_DHE_DSS_WITH_RC4_128_SHA" },
{ 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" },
{ 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256" },
{ 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256" },
{ 0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256" },
{ 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
{ 0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256" },
{ 0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256" },
{ 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA" },
{ 0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA" },
{ 0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA" },
{ 0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" },
{ 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" },
{ 0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA" },
// RFC 4279
{ 0x008A, "TLS_PSK_WITH_RC4_128_SHA" },
{ 0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA" },
{ 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA" },
{ 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA" },
{ 0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA" },
{ 0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" },
{ 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" },
{ 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" },
{ 0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA" },
{ 0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA" },
{ 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA" },
{ 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA" },
// RFC 4162
{ 0x0096, "TLS_RSA_WITH_SEED_CBC_SHA" },
{ 0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA" },
{ 0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA" },
{ 0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA" },
{ 0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA" },
{ 0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA" },
// RFC 5288
{ 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256" },
{ 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384" },
{ 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" },
{ 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" },
{ 0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256" },
{ 0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384" },
{ 0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" },
{ 0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" },
{ 0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256" },
{ 0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384" },
{ 0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256" },
{ 0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384" },
// RFC 5487
{ 0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256" },
{ 0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384" },
{ 0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" },
{ 0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" },
{ 0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256" },
{ 0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" },
{ 0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256" },
{ 0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384" },
{ 0x00B0, "TLS_PSK_WITH_NULL_SHA256" },
{ 0x00B1, "TLS_PSK_WITH_NULL_SHA384" },
{ 0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" },
{ 0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384" },
{ 0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256" },
{ 0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384" },
{ 0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256" },
{ 0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384" },
{ 0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256" },
{ 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384" },
// RFC 5932
{ 0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" },
{ 0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" },
{ 0x5600, "TLS_FALLBACK_SCSV" },
// RFC 4492
{ 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA" },
{ 0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA" },
{ 0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA" },
{ 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA" },
{ 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA" },
{ 0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" },
{ 0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" },
{ 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" },
{ 0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA" },
{ 0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA" },
{ 0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA" },
{ 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA" },
{ 0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA" },
{ 0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA" },
{ 0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" },
{ 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" },
{ 0xC015, "TLS_ECDH_anon_WITH_NULL_SHA" },
{ 0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA" },
{ 0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA" },
{ 0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA" },
{ 0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA" },
// RFC 5054
{ 0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA" },
{ 0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA" },
{ 0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA" },
{ 0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA" },
{ 0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA" },
{ 0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" },
{ 0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA" },
{ 0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA" },
// RFC 5589
{ 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" },
{ 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" },
{ 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256" },
{ 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384" },
{ 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
{ 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
{ 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256" },
{ 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384" },
{ 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
{ 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
{ 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256" },
{ 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384" },
{ 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
{ 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" },
{ 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" },
{ 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384" },
// RFC 5489
{ 0xC033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA" },
{ 0xC034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA" },
{ 0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
{ 0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA" },
{ 0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" },
{ 0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384" },
{ 0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA" },
{ 0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256" },
{ 0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384" },
{ 0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC03E, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256" },
{ 0xC03F, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384" },
{ 0xC040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256" },
{ 0xC043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384" },
{ 0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256" },
{ 0xC047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384" },
{ 0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256" },
{ 0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384" },
{ 0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" },
{ 0xC057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" },
{ 0xC058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256" },
{ 0xC059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384" },
{ 0xC05A, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256" },
{ 0xC05B, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384" },
{ 0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256" },
{ 0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384" },
{ 0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256" },
{ 0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384" },
{ 0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256" },
{ 0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384" },
{ 0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256" },
{ 0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384" },
{ 0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256" },
{ 0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384" },
{ 0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" },
{ 0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" },
{ 0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" },
{ 0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" },
{ 0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256" },
{ 0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384" },
{ 0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC07E, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC07F, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256" },
{ 0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384" },
{ 0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" },
{ 0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" },
{ 0xC09C, "TLS_RSA_WITH_AES_128_CCM" },
{ 0xC09D, "TLS_RSA_WITH_AES_256_CCM" },
{ 0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM" },
{ 0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM" },
{ 0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8" },
{ 0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8" },
{ 0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8" },
{ 0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8" },
{ 0xC0A4, "TLS_PSK_WITH_AES_128_CCM" },
{ 0xC0A5, "TLS_PSK_WITH_AES_256_CCM" },
{ 0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM" },
{ 0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM" },
{ 0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8" },
{ 0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8" },
{ 0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8" },
{ 0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8" },
{ 0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM" },
{ 0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM" },
{ 0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" },
{ 0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8" },
// old numbers used in the beginning http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305
{ 0xCC13, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCC14, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCC15, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
// http://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305
{ 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" },
{ 0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256" },
// http://tools.ietf.org/html/draft-josefsson-salsa20-tls
{ 0xE410, "TLS_RSA_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE411, "TLS_RSA_WITH_SALSA20_SHA1" },
{ 0xE412, "TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE413, "TLS_ECDHE_RSA_WITH_SALSA20_SHA1" },
{ 0xE414, "TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE415, "TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1" },
{ 0xE416, "TLS_PSK_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE417, "TLS_PSK_WITH_SALSA20_SHA1" },
{ 0xE418, "TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE419, "TLS_ECDHE_PSK_WITH_SALSA20_SHA1" },
{ 0xE41A, "TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE41B, "TLS_RSA_PSK_WITH_SALSA20_SHA1" },
{ 0xE41C, "TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE41D, "TLS_DHE_PSK_WITH_SALSA20_SHA1" },
{ 0xE41E, "TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1" },
{ 0xE41F, "TLS_DHE_RSA_WITH_SALSA20_SHA1" },
// these from http://www.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html
{ 0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"},
{ 0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA" },
{ 0xFFE0, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA" },
{ 0xFFE1, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"},
// note that ciphersuites of {0x00????} are TLS cipher suites in
// a sslv2 client hello message; the ???? above is the two-byte
// tls cipher suite id
{ 0x010080, "SSL2_RC4_128_WITH_MD5" },
{ 0x020080, "SSL2_RC4_128_EXPORT40_WITH_MD5" },
{ 0x030080, "SSL2_RC2_128_CBC_WITH_MD5" },
{ 0x040080, "SSL2_RC2_128_CBC_EXPORT40_WITH_MD5" },
{ 0x050080, "SSL2_IDEA_128_CBC_WITH_MD5" },
{ 0x060040, "SSL2_DES_64_CBC_WITH_MD5" },
{ 0x0700C0, "SSL2_DES_192_EDE3_CBC_WITH_MD5" },
{ 0x080080, "SSL2_RC4_64_WITH_MD5" },
// Microsoft's old PCT protocol. These are from Eric Rescorla's book "SSL and TLS"
{ 0x800001, "PCT_SSL_CERT_TYPE | PCT1_CERT_X509" },
{ 0x800003, "PCT_SSL_CERT_TYPE | PCT1_CERT_X509_CHAIN" },
{ 0x810001, "PCT_SSL_HASH_TYPE | PCT1_HASH_MD5" },
{ 0x810003, "PCT_SSL_HASH_TYPE | PCT1_HASH_SHA" },
{ 0x820001, "PCT_SSL_EXCH_TYPE | PCT1_EXCH_RSA_PKCS1" },
{ 0x830004, "PCT_SSL_CIPHER_TYPE_1ST_HALF | PCT1_CIPHER_RC4" },
{ 0x842840, "PCT_SSL_CIPHER_TYPE_2ND_HALF | PCT1_ENC_BITS_40 | PCT1_MAC_BITS_128" },
{ 0x848040, "PCT_SSL_CIPHER_TYPE_2ND_HALF | PCT1_ENC_BITS_128 | PCT1_MAC_BITS_128" },
{ 0x8F8001, "PCT_SSL_COMPAT | PCT_VERSION_1" },
};
}
}
namespace StreamExtended.Models
{
/// <summary>
/// The SSL extension information.
/// </summary>
public class SslExtension
{
/// <summary>
/// Gets the value.
/// </summary>
/// <value>
/// The value.
/// </value>
public int Value { get; }
/// <summary>
/// Gets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; }
/// <summary>
/// Gets the data.
/// </summary>
/// <value>
/// The data.
/// </value>
public string Data { get; }
/// <summary>
/// Gets the position.
/// </summary>
/// <value>
/// The position.
/// </value>
public int Position { get; }
/// <summary>
/// Initializes a new instance of the <see cref="SslExtension"/> class.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="name">The name.</param>
/// <param name="data">The data.</param>
/// <param name="position">The position.</param>
public SslExtension(int value, string name, string data, int position)
{
Value = value;
Name = name;
Data = data;
Position = position;
}
}
}
\ No newline at end of file
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace StreamExtended.Network
{
public class ClientHelloAlpnAdderStream : Stream
{
private readonly CustomBufferedStream stream;
private readonly IBufferPool bufferPool;
private bool called;
public ClientHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
{
this.stream = stream;
}
public override void Flush()
{
stream.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
stream.SetLength(value);
}
[DebuggerStepThrough]
public override int Read(byte[] buffer, int offset, int count)
{
return stream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
if (called)
{
stream.Write(buffer, offset, count);
return;
}
called = true;
var ms = new MemoryStream(buffer, offset, count);
//this can be non async, because reads from a memory stream
var cts = new CancellationTokenSource();
var clientHello = SslTools.PeekClientHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
if (clientHello != null)
{
// 0x00 0x10: ALPN identifier
// 0x00 0x0e: length of ALPN data
// 0x00 0x0c: length of ALPN data again:)
var dataToAdd = new byte[]
{
0x0, 0x10, 0x0, 0xE, 0x0, 0xC,
2, (byte)'h', (byte)'2',
8, (byte)'h', (byte)'t', (byte)'t', (byte)'p', (byte)'/', (byte)'1', (byte)'.', (byte)'1'
};
int newByteCount = clientHello.Extensions == null ? dataToAdd.Length + 2 : dataToAdd.Length;
var buffer2 = new byte[buffer.Length + newByteCount];
for (int i = 0; i < buffer.Length; i++)
{
buffer2[i] = buffer[i];
}
//this is a hacky solution, but works
int length = (buffer[offset + 3] << 8) + buffer[offset + 4];
length += newByteCount;
buffer2[offset + 3] = (byte)(length >> 8);
buffer2[offset + 4] = (byte)length;
length = (buffer[offset + 6] << 16) + (buffer[offset + 7] << 8) + buffer[offset + 8];
length += newByteCount;
buffer2[offset + 6] = (byte)(length >> 16);
buffer2[offset + 7] = (byte)(length >> 8);
buffer2[offset + 8] = (byte)length;
int pos = offset + clientHello.EntensionsStartPosition;
int endPos = offset + clientHello.ClientHelloLength;
if (clientHello.Extensions != null)
{
// update ALPN length
length = (buffer[pos] << 8) + buffer[pos + 1];
length += newByteCount;
buffer2[pos] = (byte)(length >> 8);
buffer2[pos + 1] = (byte)length;
}
else
{
// add ALPN length
length = dataToAdd.Length;
buffer2[pos] = (byte)(length >> 8);
buffer2[pos + 1] = (byte)length;
endPos += 2;
}
for (int i = 0; i < dataToAdd.Length; i++)
{
buffer2[endPos + i] = dataToAdd[i];
}
// copy the reamining data if any
for (int i = clientHello.ClientHelloLength; i < count; i++)
{
buffer2[offset + newByteCount + i] = buffer[offset + i];
}
buffer = buffer2;
count += newByteCount;
}
stream.Write(buffer, offset, count);
}
public override bool CanRead => stream.CanRead;
public override bool CanSeek => stream.CanSeek;
public override bool CanWrite => stream.CanWrite;
public override long Length => stream.Length;
public override long Position
{
get => stream.Position;
set => stream.Position = value;
}
}
}
\ No newline at end of file
using System;
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended.Network
{
/// <summary>
/// Copies the source stream to destination stream.
/// But this let users to peek and read the copying process.
/// </summary>
public class CopyStream : ICustomStreamReader, IDisposable
{
private readonly ICustomStreamReader reader;
private readonly ICustomStreamWriter writer;
private readonly IBufferPool bufferPool;
public int BufferSize { get; }
private int bufferLength;
private byte[] buffer;
private bool disposed;
public int Available => reader.Available;
public bool DataAvailable => reader.DataAvailable;
public long ReadBytes { get; private set; }
public CopyStream(ICustomStreamReader reader, ICustomStreamWriter writer, IBufferPool bufferPool, int bufferSize)
{
this.reader = reader;
this.writer = writer;
BufferSize = bufferSize;
buffer = bufferPool.GetBuffer(bufferSize);
this.bufferPool = bufferPool;
}
public async Task<bool> FillBufferAsync(CancellationToken cancellationToken = default(CancellationToken))
{
await FlushAsync(cancellationToken);
return await reader.FillBufferAsync(cancellationToken);
}
public byte PeekByteFromBuffer(int index)
{
return reader.PeekByteFromBuffer(index);
}
public Task<int> PeekByteAsync(int index, CancellationToken cancellationToken = default(CancellationToken))
{
return reader.PeekByteAsync(index, cancellationToken);
}
public Task<byte[]> PeekBytesAsync(int index, int size, CancellationToken cancellationToken = default(CancellationToken))
{
return reader.PeekBytesAsync(index, size, cancellationToken);
}
public void Flush()
{
//send out the current data from from the buffer
if (bufferLength > 0)
{
writer.Write(buffer, 0, bufferLength);
bufferLength = 0;
}
}
public async Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
//send out the current data from from the buffer
if (bufferLength > 0)
{
await writer.WriteAsync(buffer, 0, bufferLength, cancellationToken);
bufferLength = 0;
}
}
public byte ReadByteFromBuffer()
{
byte b = reader.ReadByteFromBuffer();
buffer[bufferLength++] = b;
ReadBytes++;
return b;
}
public int Read(byte[] buffer, int offset, int count)
{
int result = reader.Read(buffer, offset, count);
if (result > 0)
{
if (bufferLength + result > BufferSize)
{
Flush();
}
Buffer.BlockCopy(buffer, offset, this.buffer, bufferLength, result);
bufferLength += result;
ReadBytes += result;
Flush();
}
return result;
}
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default(CancellationToken))
{
int result = await reader.ReadAsync(buffer, offset, count, cancellationToken);
if (result > 0)
{
if (bufferLength + result > BufferSize)
{
await FlushAsync(cancellationToken);
}
Buffer.BlockCopy(buffer, offset, this.buffer, bufferLength, result);
bufferLength += result;
ReadBytes += result;
await FlushAsync(cancellationToken);
}
return result;
}
public Task<string> ReadLineAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return CustomBufferedStream.ReadLineInternalAsync(this, bufferPool, cancellationToken);
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
var b = buffer;
buffer = null;
bufferPool.ReturnBuffer(b);
}
}
}
}
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended.Network
{
internal class CustomBufferedPeekStream : ICustomStreamReader
{
private readonly IBufferPool bufferPool;
private readonly ICustomStreamReader baseStream;
internal int Position { get; private set; }
internal CustomBufferedPeekStream(ICustomStreamReader baseStream, IBufferPool bufferPool, int startPosition = 0)
{
this.bufferPool = bufferPool;
this.baseStream = baseStream;
Position = startPosition;
}
int ICustomStreamReader.BufferSize => baseStream.BufferSize;
/// <summary>
/// Gets a value indicating whether data is available.
/// </summary>
bool ICustomStreamReader.DataAvailable => Available > 0;
/// <summary>
/// Gets the available data size.
/// </summary>
public int Available => baseStream.Available - Position;
internal async Task<bool> EnsureBufferLength(int length, CancellationToken cancellationToken)
{
var val = await baseStream.PeekByteAsync(Position + length - 1, cancellationToken);
return val != -1;
}
internal byte ReadByte()
{
return baseStream.PeekByteFromBuffer(Position++);
}
internal int ReadInt16()
{
int i1 = ReadByte();
int i2 = ReadByte();
return (i1 << 8) + i2;
}
internal int ReadInt24()
{
int i1 = ReadByte();
int i2 = ReadByte();
int i3 = ReadByte();
return (i1 << 16) + (i2 << 8) + i3;
}
internal byte[] ReadBytes(int length)
{
var buffer = new byte[length];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = ReadByte();
}
return buffer;
}
/// <summary>
/// Fills the buffer asynchronous.
/// </summary>
/// <returns></returns>
Task<bool> ICustomStreamReader.FillBufferAsync(CancellationToken cancellationToken)
{
return baseStream.FillBufferAsync(cancellationToken);
}
/// <summary>
/// Peeks a byte from buffer.
/// </summary>
/// <param name="index">The index.</param>
/// <returns></returns>
byte ICustomStreamReader.PeekByteFromBuffer(int index)
{
return baseStream.PeekByteFromBuffer(index);
}
/// <summary>
/// Peeks bytes asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<byte[]> ICustomStreamReader.PeekBytesAsync(int index, int size, CancellationToken cancellationToken)
{
return baseStream.PeekBytesAsync(index, size, cancellationToken);
}
/// <summary>
/// Peeks a byte asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<int> ICustomStreamReader.PeekByteAsync(int index, CancellationToken cancellationToken)
{
return baseStream.PeekByteAsync(index, cancellationToken);
}
/// <summary>
/// Reads a byte from buffer.
/// </summary>
/// <returns></returns>
/// <exception cref="Exception">Buffer is empty</exception>
byte ICustomStreamReader.ReadByteFromBuffer()
{
return ReadByte();
}
int ICustomStreamReader.Read(byte[] buffer, int offset, int count)
{
return baseStream.Read(buffer, offset, count);
}
/// <summary>
/// Reads the asynchronous.
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset.</param>
/// <param name="count">The count.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<int> ICustomStreamReader.ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return baseStream.ReadAsync(buffer, offset, count, cancellationToken);
}
/// <summary>
/// Read a line from the byte stream
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<string> ICustomStreamReader.ReadLineAsync(CancellationToken cancellationToken)
{
return CustomBufferedStream.ReadLineInternalAsync(this, bufferPool, cancellationToken);
}
}
}
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended.Network
{
/// <summary>
/// A custom network stream inherited from stream
/// with an underlying read buffer supporting both read/write
/// of UTF-8 encoded string or raw bytes asynchronously from last read position.
/// </summary>
/// <seealso cref="System.IO.Stream" />
public class CustomBufferedStream : Stream, ICustomStreamReader
{
private readonly Stream baseStream;
private readonly bool leaveOpen;
private byte[] streamBuffer;
// default to UTF-8
private static readonly Encoding encoding = Encoding.UTF8;
private int bufferLength;
private int bufferPos;
private bool disposed;
private bool closed;
private readonly IBufferPool bufferPool;
public int BufferSize { get; }
public event EventHandler<DataEventArgs> DataRead;
public event EventHandler<DataEventArgs> DataWrite;
public bool IsClosed => closed;
/// <summary>
/// Initializes a new instance of the <see cref="CustomBufferedStream"/> class.
/// </summary>
/// <param name="baseStream">The base stream.</param>
/// <param name="bufferPool">Bufferpool.</param>
/// <param name="bufferSize">Size of the buffer.</param>
/// <param name="leaveOpen"><see langword="true" /> to leave the stream open after disposing the <see cref="T:CustomBufferedStream" /> object; otherwise, <see langword="false" />.</param>
public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, int bufferSize, bool leaveOpen = false)
{
this.baseStream = baseStream;
BufferSize = bufferSize;
this.leaveOpen = leaveOpen;
streamBuffer = bufferPool.GetBuffer(bufferSize);
this.bufferPool = bufferPool;
}
/// <summary>
/// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device.
/// </summary>
public override void Flush()
{
baseStream.Flush();
}
/// <summary>
/// When overridden in a derived class, sets the position within the current stream.
/// </summary>
/// <param name="offset">A byte offset relative to the <paramref name="origin" /> parameter.</param>
/// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin" /> indicating the reference point used to obtain the new position.</param>
/// <returns>
/// The new position within the current stream.
/// </returns>
public override long Seek(long offset, SeekOrigin origin)
{
bufferLength = 0;
bufferPos = 0;
return baseStream.Seek(offset, origin);
}
/// <summary>
/// When overridden in a derived class, sets the length of the current stream.
/// </summary>
/// <param name="value">The desired length of the current stream in bytes.</param>
public override void SetLength(long value)
{
baseStream.SetLength(value);
}
/// <summary>
/// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced by the bytes read from the current source.</param>
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read from the current stream.</param>
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
/// <returns>
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
/// </returns>
public override int Read(byte[] buffer, int offset, int count)
{
if (bufferLength == 0)
{
FillBuffer();
}
int available = Math.Min(bufferLength, count);
if (available > 0)
{
Buffer.BlockCopy(streamBuffer, bufferPos, buffer, offset, available);
bufferPos += available;
bufferLength -= available;
}
return available;
}
/// <summary>
/// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">An array of bytes. This method copies <paramref name="count" /> bytes from <paramref name="buffer" /> to the current stream.</param>
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the current stream.</param>
/// <param name="count">The number of bytes to be written to the current stream.</param>
[DebuggerStepThrough]
public override void Write(byte[] buffer, int offset, int count)
{
OnDataWrite(buffer, offset, count);
baseStream.Write(buffer, offset, count);
}
/// <summary>
/// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified buffer size and cancellation token.
/// </summary>
/// <param name="destination">The stream to which the contents of the current stream will be copied.</param>
/// <param name="bufferSize">The size, in bytes, of the buffer. This value must be greater than zero. The default size is 81920.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
/// <returns>
/// A task that represents the asynchronous copy operation.
/// </returns>
public override async Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken = default(CancellationToken))
{
if (bufferLength > 0)
{
await destination.WriteAsync(streamBuffer, bufferPos, bufferLength, cancellationToken);
bufferLength = 0;
}
await base.CopyToAsync(destination, bufferSize, cancellationToken);
}
/// <summary>
/// Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying device, and monitors cancellation requests.
/// </summary>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
/// <returns>
/// A task that represents the asynchronous flush operation.
/// </returns>
public override Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return baseStream.FlushAsync(cancellationToken);
}
/// <summary>
/// Asynchronously reads a sequence of bytes from the current stream,
/// advances the position within the stream by the number of bytes read,
/// and monitors cancellation requests.
/// </summary>
/// <param name="buffer">The buffer to write the data into.</param>
/// <param name="offset">The byte offset in <paramref name="buffer" /> at which
/// to begin writing data from the stream.</param>
/// <param name="count">The maximum number of bytes to read.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.
/// The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
/// <returns>
/// A task that represents the asynchronous read operation.
/// The value of the parameter contains the total
/// number of bytes read into the buffer.
/// The result value can be less than the number of bytes
/// requested if the number of bytes currently available is
/// less than the requested number, or it can be 0 (zero)
/// if the end of the stream has been reached.
/// </returns>
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default(CancellationToken))
{
if (bufferLength == 0)
{
await FillBufferAsync(cancellationToken);
}
int available = Math.Min(bufferLength, count);
if (available > 0)
{
Buffer.BlockCopy(streamBuffer, bufferPos, buffer, offset, available);
bufferPos += available;
bufferLength -= available;
}
return available;
}
/// <summary>
/// Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream.
/// </summary>
/// <returns>
/// The unsigned byte cast to an Int32, or -1 if at the end of the stream.
/// </returns>
public override int ReadByte()
{
if (bufferLength == 0)
{
FillBuffer();
}
if (bufferLength == 0)
{
return -1;
}
bufferLength--;
return streamBuffer[bufferPos++];
}
/// <summary>
/// Peeks a byte asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
public async Task<int> PeekByteAsync(int index, CancellationToken cancellationToken = default(CancellationToken))
{
if (Available <= index)
{
await FillBufferAsync(cancellationToken);
}
//When index is greater than the buffer size
if (streamBuffer.Length <= index)
{
throw new Exception("Requested Peek index exceeds the buffer size. Consider increasing the buffer size.");
}
//When index is greater than the buffer size
if (Available <= index)
{
return -1;
}
return streamBuffer[bufferPos + index];
}
/// <summary>
/// Peeks bytes asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
public async Task<byte[]> PeekBytesAsync(int index, int size, CancellationToken cancellationToken = default(CancellationToken))
{
if (Available <= index)
{
await FillBufferAsync(cancellationToken);
}
//When index is greater than the buffer size
if (streamBuffer.Length <= (index + size))
{
throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size.");
}
if (Available <= (index + size))
{
return null;
}
var vRet = new byte[size];
Array.Copy(streamBuffer, index, vRet, 0, size);
return vRet;
}
/// <summary>
/// Peeks a byte from buffer.
/// </summary>
/// <param name="index">The index.</param>
/// <returns></returns>
/// <exception cref="Exception">Index is out of buffer size</exception>
public byte PeekByteFromBuffer(int index)
{
if (bufferLength <= index)
{
throw new Exception("Index is out of buffer size");
}
return streamBuffer[bufferPos + index];
}
/// <summary>
/// Reads a byte from buffer.
/// </summary>
/// <returns></returns>
/// <exception cref="Exception">Buffer is empty</exception>
public byte ReadByteFromBuffer()
{
if (bufferLength == 0)
{
throw new Exception("Buffer is empty");
}
bufferLength--;
return streamBuffer[bufferPos++];
}
/// <summary>
/// Asynchronously writes a sequence of bytes to the current stream, advances the current position within this stream by the number of bytes written, and monitors cancellation requests.
/// </summary>
/// <param name="buffer">The buffer to write data from.</param>
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> from which to begin copying bytes to the stream.</param>
/// <param name="count">The maximum number of bytes to write.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
/// <returns>
/// A task that represents the asynchronous write operation.
/// </returns>
[DebuggerStepThrough]
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default(CancellationToken))
{
OnDataWrite(buffer, offset, count);
await baseStream.WriteAsync(buffer, offset, count, cancellationToken);
}
/// <summary>
/// Writes a byte to the current position in the stream and advances the position within the stream by one byte.
/// </summary>
/// <param name="value">The byte to write to the stream.</param>
public override void WriteByte(byte value)
{
var buffer = bufferPool.GetBuffer(BufferSize);
try
{
buffer[0] = value;
OnDataWrite(buffer, 0, 1);
baseStream.Write(buffer, 0, 1);
}
finally
{
bufferPool.ReturnBuffer(buffer);
}
}
protected virtual void OnDataWrite(byte[] buffer, int offset, int count)
{
DataWrite?.Invoke(this, new DataEventArgs(buffer, offset, count));
}
protected virtual void OnDataRead(byte[] buffer, int offset, int count)
{
DataRead?.Invoke(this, new DataEventArgs(buffer, offset, count));
}
/// <summary>
/// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream" /> and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
protected override void Dispose(bool disposing)
{
if (!disposed)
{
disposed = true;
closed = true;
if (!leaveOpen)
{
baseStream.Dispose();
}
var buffer = streamBuffer;
streamBuffer = null;
bufferPool.ReturnBuffer(buffer);
}
}
/// <summary>
/// When overridden in a derived class, gets a value indicating whether the current stream supports reading.
/// </summary>
public override bool CanRead => baseStream.CanRead;
/// <summary>
/// When overridden in a derived class, gets a value indicating whether the current stream supports seeking.
/// </summary>
public override bool CanSeek => baseStream.CanSeek;
/// <summary>
/// When overridden in a derived class, gets a value indicating whether the current stream supports writing.
/// </summary>
public override bool CanWrite => baseStream.CanWrite;
/// <summary>
/// Gets a value that determines whether the current stream can time out.
/// </summary>
public override bool CanTimeout => baseStream.CanTimeout;
/// <summary>
/// When overridden in a derived class, gets the length in bytes of the stream.
/// </summary>
public override long Length => baseStream.Length;
/// <summary>
/// Gets a value indicating whether data is available.
/// </summary>
public bool DataAvailable => bufferLength > 0;
/// <summary>
/// Gets the available data size.
/// </summary>
public int Available => bufferLength;
/// <summary>
/// When overridden in a derived class, gets or sets the position within the current stream.
/// </summary>
public override long Position
{
get => baseStream.Position;
set => baseStream.Position = value;
}
/// <summary>
/// Gets or sets a value, in miliseconds, that determines how long the stream will attempt to read before timing out.
/// </summary>
public override int ReadTimeout
{
get => baseStream.ReadTimeout;
set => baseStream.ReadTimeout = value;
}
/// <summary>
/// Gets or sets a value, in miliseconds, that determines how long the stream will attempt to write before timing out.
/// </summary>
public override int WriteTimeout
{
get => baseStream.WriteTimeout;
set => baseStream.WriteTimeout = value;
}
/// <summary>
/// Fills the buffer.
/// </summary>
public bool FillBuffer()
{
if (closed)
{
return false;
}
if (bufferLength > 0)
{
//normally we fill the buffer only when it is empty, but sometimes we need more data
//move the remanining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
}
bufferPos = 0;
int readBytes = baseStream.Read(streamBuffer, bufferLength, streamBuffer.Length - bufferLength);
bool result = readBytes > 0;
if (result)
{
OnDataRead(streamBuffer, bufferLength, readBytes);
bufferLength += readBytes;
}
else
{
closed = true;
}
return result;
}
/// <summary>
/// Fills the buffer asynchronous.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
public async Task<bool> FillBufferAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (closed)
{
return false;
}
if (bufferLength > 0)
{
//normally we fill the buffer only when it is empty, but sometimes we need more data
//move the remaining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
}
int bytesToRead = streamBuffer.Length - bufferLength;
if (bytesToRead == 0)
{
return false;
}
bufferPos = 0;
int readBytes = await baseStream.ReadAsync(streamBuffer, bufferLength, bytesToRead, cancellationToken);
bool result = readBytes > 0;
if (result)
{
OnDataRead(streamBuffer, bufferLength, readBytes);
bufferLength += readBytes;
}
else
{
closed = true;
}
return result;
}
/// <summary>
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
public Task<string> ReadLineAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return ReadLineInternalAsync(this, bufferPool, cancellationToken);
}
/// <summary>
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
internal static async Task<string> ReadLineInternalAsync(ICustomStreamReader reader, IBufferPool bufferPool, CancellationToken cancellationToken = default(CancellationToken))
{
byte lastChar = default(byte);
int bufferDataLength = 0;
// try to use buffer from the buffer pool, usually it is enough
var bufferPoolBuffer = bufferPool.GetBuffer(reader.BufferSize);
var buffer = bufferPoolBuffer;
try
{
while (reader.DataAvailable || await reader.FillBufferAsync(cancellationToken))
{
byte newChar = reader.ReadByteFromBuffer();
buffer[bufferDataLength] = newChar;
//if new line
if (newChar == '\n')
{
if (lastChar == '\r')
{
return encoding.GetString(buffer, 0, bufferDataLength - 1);
}
return encoding.GetString(buffer, 0, bufferDataLength);
}
bufferDataLength++;
//store last char for new line comparison
lastChar = newChar;
if (bufferDataLength == buffer.Length)
{
ResizeBuffer(ref buffer, bufferDataLength * 2);
}
}
}
finally
{
bufferPool.ReturnBuffer(bufferPoolBuffer);
}
if (bufferDataLength == 0)
{
return null;
}
return encoding.GetString(buffer, 0, bufferDataLength);
}
/// <summary>
/// Read until the last new line, ignores the result
/// </summary>
/// <returns></returns>
public async Task ReadAndIgnoreAllLinesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
while (!string.IsNullOrEmpty(await ReadLineAsync(cancellationToken)))
{
}
}
/// <summary>
/// Increase size of buffer and copy existing content to new buffer
/// </summary>
/// <param name="buffer"></param>
/// <param name="size"></param>
private static void ResizeBuffer(ref byte[] buffer, long size)
{
var newBuffer = new byte[size];
Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
buffer = newBuffer;
}
#if NET45
/// <summary>
/// Base Stream.BeginRead will call this.Read and block thread (we don't want this, Network stream handles async)
/// In order to really async Reading Launch this.ReadAsync as Task will fire NetworkStream.ReadAsync
/// See Threads here :
/// https://github.com/justcoding121/Stream-Extended/pull/43
/// https://github.com/justcoding121/Titanium-Web-Proxy/issues/575
/// </summary>
/// <returns></returns>
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
var vAsyncResult = this.ReadAsync(buffer, offset, count);
vAsyncResult.ContinueWith(pAsyncResult =>
{
//use TaskExtended to pass State as AsyncObject
//callback will call EndRead (otherwise, it will block)
callback(new TaskResult<int>(pAsyncResult, state));
});
return vAsyncResult;
}
/// <summary>
/// override EndRead to handle async Reading (see BeginRead comment)
/// </summary>
/// <returns></returns>
public override int EndRead(IAsyncResult asyncResult)
{
return ((TaskResult<int>)asyncResult).Result;
}
/// <summary>
/// Fix the .net bug with SslStream slow WriteAsync
/// https://github.com/justcoding121/Titanium-Web-Proxy/issues/495
/// Stream.BeginWrite + Stream.BeginRead uses the same SemaphoreSlim(1)
/// That's why we need to call NetworkStream.BeginWrite only (while read is waiting SemaphoreSlim)
/// </summary>
/// <returns></returns>
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return baseStream.BeginWrite(buffer, offset, count, callback, state);
}
public override void EndWrite(IAsyncResult asyncResult)
{
baseStream.EndWrite(asyncResult);
}
#endif
}
}
using System;
namespace StreamExtended.Network
{
/// <summary>
/// Wraps the data sent/received event argument.
/// </summary>
public class DataEventArgs : EventArgs
{
public DataEventArgs(byte[] buffer, int offset, int count)
{
Buffer = buffer;
Offset = offset;
Count = count;
}
/// <summary>
/// The buffer with data.
/// </summary>
public byte[] Buffer { get; }
/// <summary>
/// Offset in buffer from which valid data begins.
/// </summary>
public int Offset { get; }
/// <summary>
/// Length from offset in buffer with valid data.
/// </summary>
public int Count { get; }
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended.Network
{
/// <summary>
/// This concrete implemetation of interface acts as the source stream for CopyStream class.
/// </summary>
public interface ICustomStreamReader
{
int BufferSize { get; }
int Available { get; }
bool DataAvailable { get; }
/// <summary>
/// Fills the buffer asynchronous.
/// </summary>
/// <returns></returns>
Task<bool> FillBufferAsync(CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Peeks a byte from buffer.
/// </summary>
/// <param name="index">The index.</param>
/// <returns></returns>
/// <exception cref="Exception">Index is out of buffer size</exception>
byte PeekByteFromBuffer(int index);
/// <summary>
/// Peeks a byte asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<int> PeekByteAsync(int index, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Peeks bytes asynchronous.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<byte[]> PeekBytesAsync(int index, int size, CancellationToken cancellationToken = default(CancellationToken));
byte ReadByteFromBuffer();
/// <summary>
/// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced by the bytes read from the current source.</param>
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read from the current stream.</param>
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
/// <returns>
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
/// </returns>
int Read(byte[] buffer, int offset, int count);
/// <summary>
/// Read the specified number (or less) of raw bytes from the base stream to the given buffer to the specified offset
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="bytesToRead"></param>
/// <param name="cancellationToken"></param>
/// <returns>The number of bytes read</returns>
Task<int> ReadAsync(byte[] buffer, int offset, int bytesToRead,
CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
Task<string> ReadLineAsync(CancellationToken cancellationToken = default(CancellationToken));
}
}
\ No newline at end of file
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended.Network
{
/// <summary>
/// A concrete implementation of this interface is required when calling CopyStream.
/// </summary>
public interface ICustomStreamWriter
{
void Write(byte[] buffer, int i, int bufferLength);
Task WriteAsync(byte[] buffer, int i, int bufferLength, CancellationToken cancellationToken);
}
}
\ No newline at end of file
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace StreamExtended.Network
{
public class ServerHelloAlpnAdderStream : Stream
{
private readonly IBufferPool bufferPool;
private readonly CustomBufferedStream stream;
private bool called;
public ServerHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
{
this.bufferPool = bufferPool;
this.stream = stream;
}
public override void Flush()
{
stream.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
stream.SetLength(value);
}
[DebuggerStepThrough]
public override int Read(byte[] buffer, int offset, int count)
{
return stream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
if (called)
{
stream.Write(buffer, offset, count);
return;
}
called = true;
var ms = new MemoryStream(buffer, offset, count);
//this can be non async, because reads from a memory stream
var cts = new CancellationTokenSource();
var serverHello = SslTools.PeekServerHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
if (serverHello != null)
{
// 0x00 0x10: ALPN identifier
// 0x00 0x0e: length of ALPN data
// 0x00 0x0c: length of ALPN data again:)
var dataToAdd = new byte[]
{
0x0, 0x10, 0x0, 0x5, 0x0, 0x3,
2, (byte)'h', (byte)'2'
};
int newByteCount = serverHello.Extensions == null ? dataToAdd.Length + 2 : dataToAdd.Length;
var buffer2 = new byte[buffer.Length + newByteCount];
for (int i = 0; i < buffer.Length; i++)
{
buffer2[i] = buffer[i];
}
//this is a hacky solution, but works
int length = (buffer[offset + 3] << 8) + buffer[offset + 4];
length += newByteCount;
buffer2[offset + 3] = (byte)(length >> 8);
buffer2[offset + 4] = (byte)length;
length = (buffer[offset + 6] << 16) + (buffer[offset + 7] << 8) + buffer[offset + 8];
length += newByteCount;
buffer2[offset + 6] = (byte)(length >> 16);
buffer2[offset + 7] = (byte)(length >> 8);
buffer2[offset + 8] = (byte)length;
int pos = offset + serverHello.EntensionsStartPosition;
int endPos = offset + serverHello.ServerHelloLength;
if (serverHello.Extensions != null)
{
// update ALPN length
length = (buffer[pos] << 8) + buffer[pos + 1];
length += newByteCount;
buffer2[pos] = (byte)(length >> 8);
buffer2[pos + 1] = (byte)length;
}
else
{
// add ALPN length
length = dataToAdd.Length;
buffer2[pos] = (byte)(length >> 8);
buffer2[pos + 1] = (byte)length;
endPos += 2;
}
for (int i = 0; i < dataToAdd.Length; i++)
{
buffer2[endPos + i] = dataToAdd[i];
}
// copy the reamining data if any
for (int i = serverHello.ServerHelloLength; i < count; i++)
{
buffer2[offset + newByteCount + i] = buffer[offset + i];
}
buffer = buffer2;
count += newByteCount;
}
stream.Write(buffer, offset, count);
}
public override bool CanRead => stream.CanRead;
public override bool CanSeek => stream.CanSeek;
public override bool CanWrite => stream.CanWrite;
public override long Length => stream.Length;
public override long Position
{
get => stream.Position;
set => stream.Position = value;
}
}
}
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("StreamExtended.Properties")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("StreamExtended.Properties")]
[assembly: AssemblyCopyright("Copyright © Titanium 2015-2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5036e0b7-a0d0-4070-8eb0-72c129dee9a3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.1")]
[assembly: AssemblyFileVersion("1.0.1")]
using StreamExtended.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StreamExtended
{
/// <summary>
/// Wraps up the server SSL hello information.
/// </summary>
public class ServerHelloInfo
{
private static readonly string[] compressions = {
"null",
"DEFLATE"
};
public int HandshakeVersion { get; set; }
public int MajorVersion { get; set; }
public int MinorVersion { get; set; }
public byte[] Random { get; set; }
public DateTime Time
{
get
{
DateTime time = DateTime.MinValue;
if (Random.Length > 3)
{
time = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
.AddSeconds(((uint)Random[3] << 24) + ((uint)Random[2] << 16) + ((uint)Random[1] << 8) + (uint)Random[0]).ToLocalTime();
}
return time;
}
}
public byte[] SessionId { get; set; }
public int CipherSuite { get; set; }
public byte CompressionMethod { get; set; }
internal int ServerHelloLength { get; set; }
internal int EntensionsStartPosition { get; set; }
public Dictionary<string, SslExtension> Extensions { get; set; }
private static string SslVersionToString(int major, int minor)
{
string str = "Unknown";
if (major == 3 && minor == 3)
str = "TLS/1.2";
else if (major == 3 && minor == 2)
str = "TLS/1.1";
else if (major == 3 && minor == 1)
str = "TLS/1.0";
else if (major == 3 && minor == 0)
str = "SSL/3.0";
else if (major == 2 && minor == 0)
str = "SSL/2.0";
return $"{major}.{minor} ({str})";
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine($"A SSLv{HandshakeVersion}-compatible ServerHello handshake was found. Titanium extracted the parameters below.");
sb.AppendLine();
sb.AppendLine($"Version: {SslVersionToString(MajorVersion, MinorVersion)}");
sb.AppendLine($"Random: {string.Join(" ", Random.Select(x => x.ToString("X2")))}");
sb.AppendLine($"\"Time\": {Time}");
sb.AppendLine($"SessionID: {string.Join(" ", SessionId.Select(x => x.ToString("X2")))}");
if (Extensions != null)
{
sb.AppendLine("Extensions:");
foreach (var extension in Extensions.Values.OrderBy(x => x.Position))
{
sb.AppendLine($"{extension.Name}: {extension.Data}");
}
}
string compression = compressions.Length > CompressionMethod
? compressions[CompressionMethod]
: $"unknown [0x{CompressionMethod:X2}]";
sb.AppendLine($"Compression: {compression}");
sb.Append("Cipher:");
if (!SslCiphers.Ciphers.TryGetValue(CipherSuite, out string cipherStr))
{
cipherStr = "unknown";
}
sb.AppendLine($"[0x{CipherSuite:X4}] {cipherStr}");
return sb.ToString();
}
}
}
\ No newline at end of file
using StreamExtended.Models;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StreamExtended
{
internal class SslExtensions
{
internal static SslExtension GetExtension(int value, byte[] data, int position)
{
string name = GetExtensionName(value);
string dataStr = GetExtensionData(value, data);
return new SslExtension(value, name, dataStr, position);
}
private static string GetExtensionData(int value, byte[] data)
{
//https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch (value)
{
case 0:
var stringBuilder = new StringBuilder();
int index = 2;
while (index < data.Length)
{
int nameType = data[index];
int count = (data[index + 1] << 8) + data[index + 2];
string str = Encoding.ASCII.GetString(data, index + 3, count);
if (nameType == 0)
{
stringBuilder.AppendFormat("{0}{1}", stringBuilder.Length > 1 ? "; " : string.Empty, str);
}
index += 3 + count;
}
return stringBuilder.ToString();
case 5:
if (data.Length == 5 && data[0] == 1 && data[1] == 0 && data[2] == 0 && data[3] == 0 && data[4] == 0)
{
return "OCSP - Implicit Responder";
}
return ByteArrayToString(data);
case 10:
return GetSupportedGroup(data);
case 11:
return GetEcPointFormats(data);
case 13:
return GetSignatureAlgorithms(data);
case 16:
return GetApplicationLayerProtocolNegotiation(data);
case 35655:
return $"{data.Length} bytes";
default:
return ByteArrayToString(data);
}
}
private static string GetSupportedGroup(byte[] data)
{
//https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1
List<string> list = new List<string>();
if (data.Length < 2)
{
return string.Empty;
}
int i = 2;
while (i < data.Length - 1)
{
int namedCurve = (data[i] << 8) + data[i + 1];
switch (namedCurve)
{
case 1:
list.Add("sect163k1 [0x1]"); //deprecated
break;
case 2:
list.Add("sect163r1 [0x2]"); //deprecated
break;
case 3:
list.Add("sect163r2 [0x3]"); //deprecated
break;
case 4:
list.Add("sect193r1 [0x4]"); //deprecated
break;
case 5:
list.Add("sect193r2 [0x5]"); //deprecated
break;
case 6:
list.Add("sect233k1 [0x6]"); //deprecated
break;
case 7:
list.Add("sect233r1 [0x7]"); //deprecated
break;
case 8:
list.Add("sect239k1 [0x8]"); //deprecated
break;
case 9:
list.Add("sect283k1 [0x9]"); //deprecated
break;
case 10:
list.Add("sect283r1 [0xA]"); //deprecated
break;
case 11:
list.Add("sect409k1 [0xB]"); //deprecated
break;
case 12:
list.Add("sect409r1 [0xC]"); //deprecated
break;
case 13:
list.Add("sect571k1 [0xD]"); //deprecated
break;
case 14:
list.Add("sect571r1 [0xE]"); //deprecated
break;
case 15:
list.Add("secp160k1 [0xF]"); //deprecated
break;
case 16:
list.Add("secp160r1 [0x10]"); //deprecated
break;
case 17:
list.Add("secp160r2 [0x11]"); //deprecated
break;
case 18:
list.Add("secp192k1 [0x12]"); //deprecated
break;
case 19:
list.Add("secp192r1 [0x13]"); //deprecated
break;
case 20:
list.Add("secp224k1 [0x14]"); //deprecated
break;
case 21:
list.Add("secp224r1 [0x15]"); //deprecated
break;
case 22:
list.Add("secp256k1 [0x16]"); //deprecated
break;
case 23:
list.Add("secp256r1 [0x17]");
break;
case 24:
list.Add("secp384r1 [0x18]");
break;
case 25:
list.Add("secp521r1 [0x19]");
break;
case 26:
list.Add("brainpoolP256r1 [0x1A]");
break;
case 27:
list.Add("brainpoolP384r1 [0x1B]");
break;
case 28:
list.Add("brainpoolP512r1 [0x1C]");
break;
case 29:
list.Add("x25519 [0x1D]");
break;
case 30:
list.Add("x448 [0x1E]");
break;
case 256:
list.Add("ffdhe2048 [0x0100]");
break;
case 257:
list.Add("ffdhe3072 [0x0101]");
break;
case 258:
list.Add("ffdhe4096 [0x0102]");
break;
case 259:
list.Add("ffdhe6144 [0x0103]");
break;
case 260:
list.Add("ffdhe8192 [0x0104]");
break;
case 65281:
list.Add("arbitrary_explicit_prime_curves [0xFF01]"); //deprecated
break;
case 65282:
list.Add("arbitrary_explicit_char2_curves [0xFF02]"); //deprecated
break;
default:
list.Add($"unknown [0x{namedCurve:X4}]");
break;
}
i += 2;
}
return string.Join(", ", list.ToArray());
}
private static string GetEcPointFormats(byte[] data)
{
List<string> list = new List<string>();
if (data.Length < 1)
{
return string.Empty;
}
int i = 1;
while (i < data.Length)
{
switch (data[i])
{
case 0:
list.Add("uncompressed [0x0]");
break;
case 1:
list.Add("ansiX962_compressed_prime [0x1]");
break;
case 2:
list.Add("ansiX962_compressed_char2 [0x2]");
break;
default:
list.Add($"unknown [0x{data[i]:X2}]");
break;
}
i += 2;
}
return string.Join(", ", list.ToArray());
}
private static string GetSignatureAlgorithms(byte[] data)
{
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
int num = (data[0] << 8) + data[1];
var sb = new StringBuilder();
int index = 2;
while (index < num + 2)
{
switch (data[index])
{
case 0:
sb.Append("none");
break;
case 1:
sb.Append("md5");
break;
case 2:
sb.Append("sha1");
break;
case 3:
sb.Append("sha224");
break;
case 4:
sb.Append("sha256");
break;
case 5:
sb.Append("sha384");
break;
case 6:
sb.Append("sha512");
break;
case 8:
sb.Append("Intrinsic");
break;
default:
sb.AppendFormat("Unknown[0x{0:X2}]", data[index]);
break;
}
sb.AppendFormat("_");
switch (data[index + 1])
{
case 0:
sb.Append("anonymous");
break;
case 1:
sb.Append("rsa");
break;
case 2:
sb.Append("dsa");
break;
case 3:
sb.Append("ecdsa");
break;
case 7:
sb.Append("ed25519");
break;
case 8:
sb.Append("ed448");
break;
default:
sb.AppendFormat("Unknown[0x{0:X2}]", data[index + 1]);
break;
}
sb.AppendFormat(", ");
index += 2;
}
if (sb.Length > 1)
sb.Length -= 2;
return sb.ToString();
}
private static string GetApplicationLayerProtocolNegotiation(byte[] data)
{
List<string> stringList = new List<string>();
int index = 2;
while (index < data.Length)
{
int count = data[index];
stringList.Add(Encoding.ASCII.GetString(data, index + 1, count));
index += 1 + count;
}
return string.Join(", ", stringList.ToArray());
}
private static string GetExtensionName(int value)
{
//https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch (value)
{
case 0:
return "server_name";
case 1:
return "max_fragment_length";
case 2:
return "client_certificate_url";
case 3:
return "trusted_ca_keys";
case 4:
return "truncated_hmac";
case 5:
return "status_request";
case 6:
return "user_mapping";
case 7:
return "client_authz";
case 8:
return "server_authz";
case 9:
return "cert_type";
case 10:
return "supported_groups"; // renamed from "elliptic_curves" (RFC 7919 / TLS 1.3)
case 11:
return "ec_point_formats";
case 12:
return "srp";
case 13:
return "signature_algorithms";
case 14:
return "use_srtp";
case 15:
return "heartbeat";
case 16:
return "ALPN"; // application_layer_protocol_negotiation
case 17:
return "status_request_v2";
case 18:
return "signed_certificate_timestamp";
case 19:
return "client_certificate_type";
case 20:
return "server_certificate_type";
case 21:
return "padding";
case 22:
return "encrypt_then_mac";
case 23:
return "extended_master_secret";
case 24:
return "token_binding"; // TEMPORARY - registered 2016-02-04, extension registered 2017-01-12, expires 2018-02-04
case 25:
return "cached_info";
case 26:
return "quic_transports_parameters"; // Not yet assigned by IANA (QUIC-TLS Draft04)
case 35:
return "SessionTicket TLS";
// TLS 1.3 draft: https://tools.ietf.org/html/draft-ietf-tls-tls13
case 40:
return "key_share";
case 41:
return "pre_shared_key";
case 42:
return "early_data";
case 43:
return "supported_versions";
case 44:
return "cookie";
case 45:
return "psk_key_exchange_modes";
case 46:
return "ticket_early_data_info";
case 47:
return "certificate_authorities";
case 48:
return "oid_filters";
case 49:
return "post_handshake_auth";
case 2570: // 0a0a
case 6682: // 1a1a
case 10794: // 2a2a
case 14906: // 3a3a
case 19018: // 4a4a
case 23130: // 5a5a
case 27242: // 6a6a
case 31354: // 7a7a
case 35466: // 8a8a
case 39578: // 9a9a
case 43690: // aaaa
case 47802: // baba
case 51914: // caca
case 56026: // dada
case 60138: // eaea
case 64250: // fafa
return "Reserved (GREASE)";
case 13172:
return "next_protocol_negotiation";
case 30031:
return "channel_id_old"; // Google
case 30032:
return "channel_id"; // Google
case 35655:
return "draft-agl-tls-padding";
case 65281:
return "renegotiation_info";
case 65282:
return "Draft version of TLS 1.3"; // for experimentation only https://www.ietf.org/mail-archive/web/tls/current/msg20853.html
default:
return $"unknown_{value:x2}";
}
}
private static string ByteArrayToString(byte[] data)
{
return string.Join(" ", data.Select(x => x.ToString("X2")));
}
}
}
using StreamExtended.Models;
using StreamExtended.Network;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended
{
/// <summary>
/// Use this class to peek SSL client/server hello information.
/// </summary>
public class SslTools
{
/// <summary>
/// Is the given stream starts with an SSL client hello?
/// </summary>
/// <param name="stream"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<bool> IsClientHello(CustomBufferedStream stream, IBufferPool bufferPool, CancellationToken cancellationToken)
{
var clientHello = await PeekClientHello(stream, bufferPool, cancellationToken);
return clientHello != null;
}
/// <summary>
/// Peek the SSL client hello information.
/// </summary>
/// <param name="clientStream"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<ClientHelloInfo> PeekClientHello(CustomBufferedStream clientStream, IBufferPool bufferPool, CancellationToken cancellationToken = default (CancellationToken))
{
//detects the HTTPS ClientHello message as it is described in the following url:
//https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await clientStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1)
{
return null;
}
if ((recordType & 0x80) == 0x80)
{
//SSL 2
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1);
// length value + minimum length
if (!await peekStream.EnsureBufferLength(10, cancellationToken))
{
return null;
}
int recordLength = ((recordType & 0x7f) << 8) + peekStream.ReadByte();
if (recordLength < 9)
{
// Message body too short.
return null;
}
if (peekStream.ReadByte() != 0x01)
{
// should be ClientHello
return null;
}
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
int ciphersCount = peekStream.ReadInt16() / 3;
int sessionIdLength = peekStream.ReadInt16();
int randomLength = peekStream.ReadInt16();
if (!await peekStream.EnsureBufferLength(ciphersCount * 3 + sessionIdLength + randomLength, cancellationToken))
{
return null;
}
int[] ciphers = new int[ciphersCount];
for (int i = 0; i < ciphers.Length; i++)
{
ciphers[i] = (peekStream.ReadByte() << 16) + (peekStream.ReadByte() << 8) + peekStream.ReadByte();
}
byte[] sessionId = peekStream.ReadBytes(sessionIdLength);
byte[] random = peekStream.ReadBytes(randomLength);
var clientHelloInfo = new ClientHelloInfo
{
HandshakeVersion = 2,
MajorVersion = majorVersion,
MinorVersion = minorVersion,
Random = random,
SessionId = sessionId,
Ciphers = ciphers,
ClientHelloLength = peekStream.Position,
};
return clientHelloInfo;
}
else if (recordType == 0x16)
{
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1);
//should contain at least 43 bytes
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{
return null;
}
//SSL 3.0 or TLS 1.0, 1.1 and 1.2
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
int recordLength = peekStream.ReadInt16();
if (peekStream.ReadByte() != 0x01)
{
// should be ClientHello
return null;
}
var length = peekStream.ReadInt24();
majorVersion = peekStream.ReadByte();
minorVersion = peekStream.ReadByte();
byte[] random = peekStream.ReadBytes(32);
length = peekStream.ReadByte();
// sessionid + 2 ciphersData length
if (!await peekStream.EnsureBufferLength(length + 2, cancellationToken))
{
return null;
}
byte[] sessionId = peekStream.ReadBytes(length);
length = peekStream.ReadInt16();
// ciphersData + compressionData length
if (!await peekStream.EnsureBufferLength(length + 1, cancellationToken))
{
return null;
}
byte[] ciphersData = peekStream.ReadBytes(length);
int[] ciphers = new int[ciphersData.Length / 2];
for (int i = 0; i < ciphers.Length; i++)
{
ciphers[i] = (ciphersData[2 * i] << 8) + ciphersData[2 * i + 1];
}
length = peekStream.ReadByte();
if (length < 1)
{
return null;
}
// compressionData
if (!await peekStream.EnsureBufferLength(length, cancellationToken))
{
return null;
}
byte[] compressionData = peekStream.ReadBytes(length);
int extenstionsStartPosition = peekStream.Position;
Dictionary<string, SslExtension> extensions = null;
if(extenstionsStartPosition < recordLength + 5)
{
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, bufferPool, cancellationToken);
}
var clientHelloInfo = new ClientHelloInfo
{
HandshakeVersion = 3,
MajorVersion = majorVersion,
MinorVersion = minorVersion,
Random = random,
SessionId = sessionId,
Ciphers = ciphers,
CompressionData = compressionData,
ClientHelloLength = peekStream.Position,
EntensionsStartPosition = extenstionsStartPosition,
Extensions = extensions,
};
return clientHelloInfo;
}
return null;
}
/// <summary>
/// Is the given stream starts with an SSL client hello?
/// </summary>
/// <param name="stream"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<bool> IsServerHello(CustomBufferedStream stream, IBufferPool bufferPool, CancellationToken cancellationToken)
{
var serverHello = await PeekServerHello(stream, bufferPool, cancellationToken);
return serverHello != null;
}
/// <summary>
/// Peek the SSL client hello information.
/// </summary>
/// <param name="serverStream"></param>
/// <param name="bufferPool"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<ServerHelloInfo> PeekServerHello(CustomBufferedStream serverStream, IBufferPool bufferPool, CancellationToken cancellationToken = default(CancellationToken))
{
//detects the HTTPS ClientHello message as it is described in the following url:
//https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await serverStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1)
{
return null;
}
if ((recordType & 0x80) == 0x80)
{
//SSL 2
// not tested. SSL2 is deprecated
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1);
// length value + minimum length
if (!await peekStream.EnsureBufferLength(39, cancellationToken))
{
return null;
}
int recordLength = ((recordType & 0x7f) << 8) + peekStream.ReadByte();
if (recordLength < 38)
{
// Message body too short.
return null;
}
if (peekStream.ReadByte() != 0x04)
{
// should be ServerHello
return null;
}
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
// 32 bytes random + 1 byte sessionId + 2 bytes cipherSuite
if (!await peekStream.EnsureBufferLength(35, cancellationToken))
{
return null;
}
byte[] random = peekStream.ReadBytes(32);
byte[] sessionId = peekStream.ReadBytes(1);
int cipherSuite = peekStream.ReadInt16();
var serverHelloInfo = new ServerHelloInfo
{
HandshakeVersion = 2,
MajorVersion = majorVersion,
MinorVersion = minorVersion,
Random = random,
SessionId = sessionId,
CipherSuite = cipherSuite,
ServerHelloLength = peekStream.Position,
};
return serverHelloInfo;
}
else if (recordType == 0x16)
{
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1);
//should contain at least 43 bytes
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{
return null;
}
//SSL 3.0 or TLS 1.0, 1.1 and 1.2
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
int recordLength = peekStream.ReadInt16();
if (peekStream.ReadByte() != 0x02)
{
// should be ServerHello
return null;
}
var length = peekStream.ReadInt24();
majorVersion = peekStream.ReadByte();
minorVersion = peekStream.ReadByte();
byte[] random = peekStream.ReadBytes(32);
length = peekStream.ReadByte();
// sessionid + cipherSuite + compressionMethod
if (!await peekStream.EnsureBufferLength(length + 2 + 1, cancellationToken))
{
return null;
}
byte[] sessionId = peekStream.ReadBytes(length);
int cipherSuite = peekStream.ReadInt16();
byte compressionMethod = peekStream.ReadByte();
int extenstionsStartPosition = peekStream.Position;
Dictionary<string, SslExtension> extensions = null;
if (extenstionsStartPosition < recordLength + 5)
{
extensions = await ReadExtensions(majorVersion, minorVersion, peekStream, bufferPool, cancellationToken);
}
var serverHelloInfo = new ServerHelloInfo
{
HandshakeVersion = 3,
MajorVersion = majorVersion,
MinorVersion = minorVersion,
Random = random,
SessionId = sessionId,
CipherSuite = cipherSuite,
CompressionMethod = compressionMethod,
ServerHelloLength = peekStream.Position,
EntensionsStartPosition = extenstionsStartPosition,
Extensions = extensions,
};
return serverHelloInfo;
}
return null;
}
private static async Task<Dictionary<string, SslExtension>> ReadExtensions(int majorVersion, int minorVersion, CustomBufferedPeekStream peekStream, IBufferPool bufferPool, CancellationToken cancellationToken)
{
Dictionary<string, SslExtension> extensions = null;
if (majorVersion > 3 || majorVersion == 3 && minorVersion >= 1)
{
if (await peekStream.EnsureBufferLength(2, cancellationToken))
{
int extensionsLength = peekStream.ReadInt16();
if (await peekStream.EnsureBufferLength(extensionsLength, cancellationToken))
{
extensions = new Dictionary<string, SslExtension>();
int idx = 0;
while (extensionsLength > 3)
{
int id = peekStream.ReadInt16();
int length = peekStream.ReadInt16();
byte[] data = peekStream.ReadBytes(length);
var extension = SslExtensions.GetExtension(id, data, idx++);
extensions[extension.Name] = extension;
extensionsLength -= 4 + length;
}
}
}
}
return extensions;
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongKey.snk</AssemblyOriginatorKeyFile>
<Version>1.0.0</Version>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Description>Package Description</Description>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Network\ClientHelloAlpnAdderStream.cs" />
<Compile Remove="Network\ServerHelloAlpnAdderStream.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="StreamExtended.nuspec" />
</ItemGroup>
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StreamExtended
{
/// <summary>
/// Mimic a Task<T> but you can set AsyncState
/// </summary>
/// <typeparam name="T"></typeparam>
public class TaskResult<T> : IAsyncResult
{
Task<T> Task;
object mAsyncState;
public TaskResult(Task<T> pTask, object state)
{
Task = pTask;
mAsyncState = state;
}
public object AsyncState => mAsyncState;
public WaitHandle AsyncWaitHandle => ((IAsyncResult)Task).AsyncWaitHandle;
public bool CompletedSynchronously => ((IAsyncResult)Task).CompletedSynchronously;
public bool IsCompleted => Task.IsCompleted;
public T Result => Task.Result;
}
}
...@@ -23,7 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BC1E0789 ...@@ -23,7 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BC1E0789
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "Titanium.Web.Proxy\Titanium.Web.Proxy.csproj", "{91018B6D-A7A9-45BE-9CB3-79CBB8B169A6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "Titanium.Web.Proxy\Titanium.Web.Proxy.csproj", "{91018B6D-A7A9-45BE-9CB3-79CBB8B169A6}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.UnitTests", "..\tests\Titanium.Web.Proxy.UnitTests\Titanium.Web.Proxy.UnitTests.csproj", "{B517E3D0-D03B-436F-AB03-34BA0D5321AF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.UnitTests", "..\tests\Titanium.Web.Proxy.UnitTests\Titanium.Web.Proxy.UnitTests.csproj", "{B517E3D0-D03B-436F-AB03-34BA0D5321AF}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Examples.Basic", "..\examples\Titanium.Web.Proxy.Examples.Basic\Titanium.Web.Proxy.Examples.Basic.csproj", "{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.Examples.Basic", "..\examples\Titanium.Web.Proxy.Examples.Basic\Titanium.Web.Proxy.Examples.Basic.csproj", "{1FAC4205-4445-4F2B-BB8F-618E8A0C15FD}"
EndProject EndProject
...@@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.Examples ...@@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Titanium.Web.Proxy.Examples
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.IntegrationTests", "..\tests\Titanium.Web.Proxy.IntegrationTests\Titanium.Web.Proxy.IntegrationTests.csproj", "{1D053D72-DCB4-4517-ACDD-D35ADC186950}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy.IntegrationTests", "..\tests\Titanium.Web.Proxy.IntegrationTests\Titanium.Web.Proxy.IntegrationTests.csproj", "{1D053D72-DCB4-4517-ACDD-D35ADC186950}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreamExtended", "StreamExtended\StreamExtended.csproj", "{61539DC1-CE80-41E6-A696-8F455ACE8D15}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -79,6 +81,14 @@ Global ...@@ -79,6 +81,14 @@ Global
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|Any CPU.Build.0 = Release|Any CPU {1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|Any CPU.Build.0 = Release|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.ActiveCfg = Release|Any CPU {1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.ActiveCfg = Release|Any CPU
{1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.Build.0 = Release|Any CPU {1D053D72-DCB4-4517-ACDD-D35ADC186950}.Release|x64.Build.0 = Release|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Debug|x64.ActiveCfg = Debug|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Debug|x64.Build.0 = Debug|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Release|Any CPU.Build.0 = Release|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Release|x64.ActiveCfg = Release|Any CPU
{61539DC1-CE80-41E6-A696-8F455ACE8D15}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
...@@ -90,7 +100,7 @@ Global ...@@ -90,7 +100,7 @@ Global
{1D053D72-DCB4-4517-ACDD-D35ADC186950} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64} {1D053D72-DCB4-4517-ACDD-D35ADC186950} = {BC1E0789-D348-49CF-8B67-5E99D50EDF64}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {625C1EB5-44CF-47DE-A85A-B4C8C40ED90A}
EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35 EnterpriseLibraryConfigurationToolBinariesPath = .1.505.2\lib\NET35
SolutionGuid = {625C1EB5-44CF-47DE-A85A-B4C8C40ED90A}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
...@@ -19,16 +19,19 @@ ...@@ -19,16 +19,19 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MTA/@EntryIndexedValue">MTA</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MTA/@EntryIndexedValue">MTA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OID/@EntryIndexedValue">OID</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OID/@EntryIndexedValue">OID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OIDS/@EntryIndexedValue">OIDS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OIDS/@EntryIndexedValue">OIDS</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpNaming/ApplyAutoDetectedRules/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a4ab2e69_002D4d9c_002D4345_002Dbcd1_002D5541dacf5d38/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Method (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a4ab2e69_002D4d9c_002D4345_002Dbcd1_002D5541dacf5d38/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Method (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=dda2ffa1_002D435c_002D4111_002D88eb_002D1a7c93c382f0/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Property (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=dda2ffa1_002D435c_002D4111_002D88eb_002D1a7c93c382f0/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Property (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
......
...@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy.EventArguments
public X509Certificate RemoteCertificate { get; internal set; } public X509Certificate RemoteCertificate { get; internal set; }
/// <summary> /// <summary>
/// Acceptable issuers as listed by remoted server. /// Acceptable issuers as listed by remote server.
/// </summary> /// </summary>
public string[] AcceptableIssuers { get; internal set; } public string[] AcceptableIssuers { get; internal set; }
......
...@@ -4,6 +4,7 @@ using System.IO; ...@@ -4,6 +4,7 @@ using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using StreamExtended; using StreamExtended;
using StreamExtended.Network; using StreamExtended.Network;
using Titanium.Web.Proxy.Exceptions;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
{ {
...@@ -60,7 +61,11 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -60,7 +61,11 @@ namespace Titanium.Web.Proxy.EventArguments
chunkHead = chunkHead.Substring(0, idx); chunkHead = chunkHead.Substring(0, idx);
} }
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber); if (!int.TryParse(chunkHead, NumberStyles.HexNumber, null, out int chunkSize))
{
throw new ProxyHttpException($"Invalid chunk length: '{chunkHead}'", null, null);
}
bytesRemaining = chunkSize; bytesRemaining = chunkSize;
if (chunkSize == 0) if (chunkSize == 0)
......
...@@ -28,6 +28,11 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -28,6 +28,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
private bool reRequest; private bool reRequest;
/// <summary>
/// Is this session a HTTP/2 promise?
/// </summary>
public bool IsPromise { get; internal set; }
/// <summary> /// <summary>
/// Constructor to initialize the proxy /// Constructor to initialize the proxy
/// </summary> /// </summary>
...@@ -89,13 +94,35 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -89,13 +94,35 @@ namespace Titanium.Web.Proxy.EventArguments
// If not already read (not cached yet) // If not already read (not cached yet)
if (!request.IsBodyRead) if (!request.IsBodyRead)
{ {
var body = await readBodyAsync(true, cancellationToken); if (request.HttpVersion == HttpHeader.Version20)
request.Body = body; {
// do not send to the remote endpoint
request.Http2IgnoreBodyFrames = true;
request.Http2BodyData = new MemoryStream();
var tcs = new TaskCompletionSource<bool>();
request.ReadHttp2BodyTaskCompletionSource = tcs;
// signal to HTTP/2 copy frame method to continue
request.ReadHttp2BeforeHandlerTaskCompletionSource.SetResult(true);
await tcs.Task;
// Now set the flag to true
// So that next time we can deliver body from cache
request.IsBodyRead = true;
}
else
{
var body = await readBodyAsync(true, cancellationToken);
request.Body = body;
// Now set the flag to true // Now set the flag to true
// So that next time we can deliver body from cache // So that next time we can deliver body from cache
request.IsBodyRead = true; request.IsBodyRead = true;
OnDataSent(body, 0, body.Length); OnDataSent(body, 0, body.Length);
}
} }
} }
...@@ -117,7 +144,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -117,7 +144,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
catch (Exception ex) catch (Exception ex)
{ {
exceptionFunc(new Exception("Exception thrown in user event", ex)); ExceptionFunc(new Exception("Exception thrown in user event", ex));
} }
} }
...@@ -140,13 +167,35 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -140,13 +167,35 @@ namespace Titanium.Web.Proxy.EventArguments
// If not already read (not cached yet) // If not already read (not cached yet)
if (!response.IsBodyRead) if (!response.IsBodyRead)
{ {
var body = await readBodyAsync(false, cancellationToken); if (response.HttpVersion == HttpHeader.Version20)
response.Body = body; {
// do not send to the remote endpoint
response.Http2IgnoreBodyFrames = true;
response.Http2BodyData = new MemoryStream();
var tcs = new TaskCompletionSource<bool>();
response.ReadHttp2BodyTaskCompletionSource = tcs;
// signal to HTTP/2 copy frame method to continue
response.ReadHttp2BeforeHandlerTaskCompletionSource.SetResult(true);
await tcs.Task;
// Now set the flag to true // Now set the flag to true
// So that next time we can deliver body from cache // So that next time we can deliver body from cache
response.IsBodyRead = true; response.IsBodyRead = true;
OnDataReceived(body, 0, body.Length); }
else
{
var body = await readBodyAsync(false, cancellationToken);
response.Body = body;
// Now set the flag to true
// So that next time we can deliver body from cache
response.IsBodyRead = true;
OnDataReceived(body, 0, body.Length);
}
} }
} }
...@@ -154,7 +203,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -154,7 +203,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, bufferPool, bufferSize); var writer = new HttpWriter(bodyStream, BufferPool, BufferSize);
if (isRequest) if (isRequest)
{ {
...@@ -186,7 +235,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -186,7 +235,7 @@ namespace Titanium.Web.Proxy.EventArguments
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, bufferPool, bufferSize); var writer = new HttpWriter(bodyStream, BufferPool, BufferSize);
await copyBodyAsync(isRequest, true, writer, TransformationMode.None, null, cancellationToken); await copyBodyAsync(isRequest, true, writer, TransformationMode.None, null, cancellationToken);
} }
} }
...@@ -207,7 +256,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -207,7 +256,7 @@ namespace Titanium.Web.Proxy.EventArguments
var reader = getStreamReader(true); var reader = getStreamReader(true);
string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType); string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType);
using (var copyStream = new CopyStream(reader, writer, bufferPool, bufferSize)) using (var copyStream = new CopyStream(reader, writer, BufferPool, BufferSize))
{ {
while (contentLength > copyStream.ReadBytes) while (contentLength > copyStream.ReadBytes)
{ {
...@@ -259,7 +308,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -259,7 +308,7 @@ namespace Titanium.Web.Proxy.EventArguments
string contentEncoding = useOriginalHeaderValues ? requestResponse.OriginalContentEncoding : requestResponse.ContentEncoding; string contentEncoding = useOriginalHeaderValues ? requestResponse.OriginalContentEncoding : requestResponse.ContentEncoding;
Stream s = limitedStream = new LimitedStream(stream, bufferPool, isChunked, contentLength); Stream s = limitedStream = new LimitedStream(stream, BufferPool, isChunked, contentLength);
if (transformation == TransformationMode.Uncompress && contentEncoding != null) if (transformation == TransformationMode.Uncompress && contentEncoding != null)
{ {
...@@ -268,7 +317,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -268,7 +317,7 @@ namespace Titanium.Web.Proxy.EventArguments
try try
{ {
using (var bufStream = new CustomBufferedStream(s, bufferPool, bufferSize, true)) using (var bufStream = new CustomBufferedStream(s, BufferPool, BufferSize, true))
{ {
await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken); await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken);
} }
...@@ -290,7 +339,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -290,7 +339,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
int bufferDataLength = 0; int bufferDataLength = 0;
var buffer = bufferPool.GetBuffer(bufferSize); var buffer = BufferPool.GetBuffer(BufferSize);
try try
{ {
int boundaryLength = boundary.Length + 4; int boundaryLength = boundary.Length + 4;
...@@ -340,7 +389,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -340,7 +389,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
finally finally
{ {
bufferPool.ReturnBuffer(buffer); BufferPool.ReturnBuffer(buffer);
} }
} }
......
...@@ -24,14 +24,14 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -24,14 +24,14 @@ namespace Titanium.Web.Proxy.EventArguments
internal TcpServerConnection ServerConnection => HttpClient.Connection; internal TcpServerConnection ServerConnection => HttpClient.Connection;
internal TcpClientConnection ClientConnection => ProxyClient.Connection; internal TcpClientConnection ClientConnection => ProxyClient.Connection;
protected readonly int bufferSize; protected readonly int BufferSize;
protected readonly IBufferPool bufferPool; protected readonly IBufferPool BufferPool;
protected readonly ExceptionHandler exceptionFunc; protected readonly ExceptionHandler ExceptionFunc;
/// <summary> /// <summary>
/// Relative milliseconds for various events. /// Relative milliseconds for various events.
/// </summary> /// </summary>
public Dictionary<string, DateTime> TimeLine { get; set; } = new Dictionary<string, DateTime>(); public Dictionary<string, DateTime> TimeLine { get; } = new Dictionary<string, DateTime>();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class. /// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class.
...@@ -39,9 +39,9 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -39,9 +39,9 @@ namespace Titanium.Web.Proxy.EventArguments
private SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, private SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint,
CancellationTokenSource cancellationTokenSource) CancellationTokenSource cancellationTokenSource)
{ {
bufferSize = server.BufferSize; BufferSize = server.BufferSize;
bufferPool = server.BufferPool; BufferPool = server.BufferPool;
exceptionFunc = server.ExceptionFunc; ExceptionFunc = server.ExceptionFunc;
TimeLine["Session Created"] = DateTime.Now; TimeLine["Session Created"] = DateTime.Now;
} }
...@@ -55,25 +55,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -55,25 +55,7 @@ namespace Titanium.Web.Proxy.EventArguments
HttpClient = new HttpWebClient(request); HttpClient = new HttpWebClient(request);
LocalEndPoint = endPoint; LocalEndPoint = endPoint;
HttpClient.ProcessId = new Lazy<int>(() => HttpClient.ProcessId = new Lazy<int>(() => ProxyClient.Connection.GetProcessId(endPoint));
{
if (RunTime.IsWindows)
{
var remoteEndPoint = ClientEndPoint;
// If client is localhost get the process id
if (NetworkHelper.IsLocalIpAddress(remoteEndPoint.Address))
{
var ipVersion = endPoint.IpV6Enabled ? IpVersion.Ipv6 : IpVersion.Ipv4;
return TcpHelper.GetProcessIdByLocalPort(ipVersion, remoteEndPoint.Port);
}
// can't access process Id of remote request from remote machine
return -1;
}
throw new PlatformNotSupportedException();
});
} }
/// <summary> /// <summary>
...@@ -161,7 +143,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -161,7 +143,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
catch (Exception ex) catch (Exception ex)
{ {
exceptionFunc(new Exception("Exception thrown in user event", ex)); ExceptionFunc(new Exception("Exception thrown in user event", ex));
} }
} }
...@@ -173,7 +155,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -173,7 +155,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
catch (Exception ex) catch (Exception ex)
{ {
exceptionFunc(new Exception("Exception thrown in user event", ex)); ExceptionFunc(new Exception("Exception thrown in user event", ex));
} }
} }
......
...@@ -31,12 +31,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -31,12 +31,12 @@ namespace Titanium.Web.Proxy.EventArguments
public bool DenyConnect { get; set; } public bool DenyConnect { get; set; }
/// <summary> /// <summary>
/// Is this a connect request to secure HTTP server? Or is it to someother protocol. /// Is this a connect request to secure HTTP server? Or is it to some other protocol.
/// </summary> /// </summary>
public bool IsHttpsConnect public bool IsHttpsConnect
{ {
get => isHttpsConnect ?? get => isHttpsConnect ??
throw new Exception("The value of this property is known in the BeforeTunnectConnectResponse event"); throw new Exception("The value of this property is known in the BeforeTunnelConnectResponse event");
internal set => isHttpsConnect = value; internal set => isHttpsConnect = value;
} }
......
...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Exceptions ...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Exceptions
/// Initializes a new instance of the <see cref="ProxyException" /> class. /// Initializes a new instance of the <see cref="ProxyException" /> class.
/// - must be invoked by derived classes' constructors /// - must be invoked by derived classes' constructors
/// </summary> /// </summary>
/// <param name="message">Excception message</param> /// <param name="message">Exception message</param>
/// <param name="innerException">Inner exception associated</param> /// <param name="innerException">Inner exception associated</param>
protected ProxyException(string message, Exception innerException) : base(message, innerException) protected ProxyException(string message, Exception innerException) : base(message, innerException)
{ {
......
...@@ -47,8 +47,7 @@ namespace Titanium.Web.Proxy ...@@ -47,8 +47,7 @@ namespace Titanium.Web.Proxy
{ {
string connectHostname = null; string connectHostname = null;
TunnelConnectSessionEventArgs connectArgs = null; TunnelConnectSessionEventArgs connectArgs = null;
// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
if (await HttpHelper.IsConnectMethod(clientStream) == 1) if (await HttpHelper.IsConnectMethod(clientStream) == 1)
{ {
...@@ -103,7 +102,7 @@ namespace Titanium.Web.Proxy ...@@ -103,7 +102,7 @@ namespace Titanium.Web.Proxy
if (await checkAuthorization(connectArgs) == false) if (await checkAuthorization(connectArgs) == false)
{ {
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc); await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc);
// send the response // send the response
await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
...@@ -111,8 +110,8 @@ namespace Titanium.Web.Proxy ...@@ -111,8 +110,8 @@ namespace Titanium.Web.Proxy
return; return;
} }
// write back successfull CONNECT response // write back successful CONNECT response
var response = ConnectResponse.CreateSuccessfullConnectResponse(version); var response = ConnectResponse.CreateSuccessfulConnectResponse(version);
// Set ContentLength explicitly to properly handle HTTP 1.0 // Set ContentLength explicitly to properly handle HTTP 1.0
response.ContentLength = 0; response.ContentLength = 0;
...@@ -126,10 +125,11 @@ namespace Titanium.Web.Proxy ...@@ -126,10 +125,11 @@ namespace Titanium.Web.Proxy
bool isClientHello = clientHelloInfo != null; bool isClientHello = clientHelloInfo != null;
if (isClientHello) if (isClientHello)
{ {
connectRequest.TunnelType = TunnelType.Https;
connectRequest.ClientHelloInfo = clientHelloInfo; connectRequest.ClientHelloInfo = clientHelloInfo;
} }
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc, isClientHello); await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc, isClientHello);
if (decryptSsl && isClientHello) if (decryptSsl && isClientHello)
{ {
...@@ -141,15 +141,22 @@ namespace Titanium.Web.Proxy ...@@ -141,15 +141,22 @@ namespace Titanium.Web.Proxy
if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2)) if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2))
{ {
// test server HTTP/2 support // test server HTTP/2 support
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently try
var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, {
isConnect: true, applicationProtocols: SslExtensions.Http2ProtocolAsList, // todo: this is a hack, because Titanium does not support HTTP protocol changing currently
noCache: true, cancellationToken: cancellationToken); var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: SslExtensions.Http2ProtocolAsList,
http2Supported = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2; noCache: true, cancellationToken: cancellationToken);
//release connection back to pool intead of closing when connection pool is enabled. http2Supported = connection.NegotiatedApplicationProtocol ==
await tcpConnectionFactory.Release(connection, true); SslApplicationProtocol.Http2;
//release connection back to pool instead of closing when connection pool is enabled.
await tcpConnectionFactory.Release(connection, true);
}
catch (Exception)
{
// ignore
}
} }
if (EnableTcpServerConnectionPrefetch) if (EnableTcpServerConnectionPrefetch)
...@@ -183,7 +190,7 @@ namespace Titanium.Web.Proxy ...@@ -183,7 +190,7 @@ namespace Titanium.Web.Proxy
// Successfully managed to authenticate the client using the fake certificate // Successfully managed to authenticate the client using the fake certificate
var options = new SslServerAuthenticationOptions(); var options = new SslServerAuthenticationOptions();
if (http2Supported) if (EnableHttp2 && http2Supported)
{ {
options.ApplicationProtocols = clientHelloInfo.GetAlpn(); options.ApplicationProtocols = clientHelloInfo.GetAlpn();
if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0) if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0)
...@@ -208,9 +215,9 @@ namespace Titanium.Web.Proxy ...@@ -208,9 +215,9 @@ namespace Titanium.Web.Proxy
} }
catch (Exception e) catch (Exception e)
{ {
var certname = certificate?.GetNameInfo(X509NameType.SimpleName, false); var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false);
throw new ProxyConnectException( throw new ProxyConnectException(
$"Couldn't authenticate host '{connectHostname}' with certificate '{certname}'.", e, connectArgs); $"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs);
} }
if (await HttpHelper.IsConnectMethod(clientStream) == -1) if (await HttpHelper.IsConnectMethod(clientStream) == -1)
...@@ -233,6 +240,11 @@ namespace Titanium.Web.Proxy ...@@ -233,6 +240,11 @@ namespace Titanium.Web.Proxy
// Hostname is excluded or it is not an HTTPS connect // Hostname is excluded or it is not an HTTPS connect
if (!decryptSsl || !isClientHello) if (!decryptSsl || !isClientHello)
{ {
if (!isClientHello)
{
connectRequest.TunnelType = TunnelType.Websocket;
}
// create new connection to server. // create new connection to server.
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then // If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// this connection should not be HTTPS. // this connection should not be HTTPS.
...@@ -253,7 +265,7 @@ namespace Titanium.Web.Proxy ...@@ -253,7 +265,7 @@ namespace Titanium.Web.Proxy
try try
{ {
await clientStream.ReadAsync(data, 0, available, cancellationToken); await clientStream.ReadAsync(data, 0, available, cancellationToken);
// clientStream.Available sbould be at most BufferSize because it is using the same buffer size // clientStream.Available should be at most BufferSize because it is using the same buffer size
await connection.StreamWriter.WriteAsync(data, 0, available, true, cancellationToken); await connection.StreamWriter.WriteAsync(data, 0, available, true, cancellationToken);
} }
finally finally
...@@ -286,6 +298,8 @@ namespace Titanium.Web.Proxy ...@@ -286,6 +298,8 @@ namespace Titanium.Web.Proxy
string httpCmd = await clientStream.ReadLineAsync(cancellationToken); string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (httpCmd == "PRI * HTTP/2.0") if (httpCmd == "PRI * HTTP/2.0")
{ {
connectArgs.HttpClient.ConnectRequest.TunnelType = TunnelType.Http2;
// HTTP/2 Connection Preface // HTTP/2 Connection Preface
string line = await clientStream.ReadLineAsync(cancellationToken); string line = await clientStream.ReadLineAsync(cancellationToken);
if (line != string.Empty) if (line != string.Empty)
...@@ -318,9 +332,16 @@ namespace Titanium.Web.Proxy ...@@ -318,9 +332,16 @@ namespace Titanium.Web.Proxy
await Http2Helper.SendHttp2(clientStream, connection.Stream, BufferSize, await Http2Helper.SendHttp2(clientStream, connection.Stream, BufferSize,
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); },
() => new SessionEventArgs(this, endPoint, cancellationTokenSource)
{
ProxyClient = { Connection = clientConnection },
HttpClient = { ConnectRequest = connectArgs?.HttpClient.ConnectRequest },
UserData = connectArgs?.UserData
},
async args => { await invokeBeforeRequest(args); },
async args => { await invokeBeforeResponse(args); },
connectArgs.CancellationTokenSource, clientConnection.Id, ExceptionFunc); connectArgs.CancellationTokenSource, clientConnection.Id, ExceptionFunc);
#endif #endif
} }
finally finally
{ {
......
...@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -17,6 +17,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="input"></param> /// <param name="input"></param>
/// <param name="output"></param> /// <param name="output"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="bufferPool"></param>
/// <param name="bufferSize"></param> /// <param name="bufferSize"></param>
internal static Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy, internal static Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy,
IBufferPool bufferPool, int bufferSize) IBufferPool bufferPool, int bufferSize)
...@@ -30,6 +31,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -30,6 +31,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="input"></param> /// <param name="input"></param>
/// <param name="output"></param> /// <param name="output"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="bufferPool"></param>
/// <param name="bufferSize"></param> /// <param name="bufferSize"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
internal static async Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy, internal static async Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy,
......
...@@ -146,8 +146,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -146,8 +146,8 @@ namespace Titanium.Web.Proxy.Helpers
private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, string expectedStart) private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, string expectedStart)
{ {
bool isExpected = true; bool isExpected = true;
int legthToCheck = 10; int lengthToCheck = 10;
for (int i = 0; i < legthToCheck; i++) for (int i = 0; i < lengthToCheck; i++)
{ {
int b = await clientStreamReader.PeekByteAsync(i); int b = await clientStreamReader.PeekByteAsync(i);
if (b == -1) if (b == -1)
......
...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Helpers
internal async Task WriteRequestAsync(Request request, bool flush = true, internal async Task WriteRequestAsync(Request request, bool flush = true,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
await WriteLineAsync(Request.CreateRequestLine(request.Method, request.OriginalUrl, request.HttpVersion), await WriteLineAsync(Request.CreateRequestLine(request.Method, request.RequestUriString, request.HttpVersion),
cancellationToken); cancellationToken);
await WriteAsync(request, flush, cancellationToken); await WriteAsync(request, flush, cancellationToken);
} }
......
namespace Titanium.Web.Proxy.Helpers
{
internal class Ref<T>
{
internal Ref()
{
}
internal Ref(T value)
{
Value = value;
}
internal T Value { get; set; }
public override string ToString()
{
var value = Value;
return value == null ? string.Empty : value.ToString();
}
public static implicit operator T(Ref<T> r)
{
return r.Value;
}
public static implicit operator Ref<T>(T value)
{
return new Ref<T>(value);
}
}
}
...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Helpers
internal static bool IsRunningAsUwp() internal static bool IsRunningAsUwp()
{ {
if (IsWindows7OrLower) if (isWindows7OrLower)
{ {
return false; return false;
} }
...@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -87,7 +87,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
} }
private static bool IsWindows7OrLower private static bool isWindows7OrLower
{ {
get get
{ {
......
...@@ -80,7 +80,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -80,7 +80,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="protocolType"></param> /// <param name="protocolType"></param>
internal void SetProxy(string hostname, int port, ProxyProtocolType protocolType) internal void SetProxy(string hostname, int port, ProxyProtocolType protocolType)
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -127,7 +127,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
internal void RemoveProxy(ProxyProtocolType protocolType, bool saveOriginalConfig = true) internal void RemoveProxy(ProxyProtocolType protocolType, bool saveOriginalConfig = true)
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
internal void DisableAllProxy() internal void DisableAllProxy()
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -186,7 +186,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -186,7 +186,7 @@ namespace Titanium.Web.Proxy.Helpers
internal void SetAutoProxyUrl(string url) internal void SetAutoProxyUrl(string url)
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -201,7 +201,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -201,7 +201,7 @@ namespace Titanium.Web.Proxy.Helpers
internal void SetProxyOverride(string proxyOverride) internal void SetProxyOverride(string proxyOverride)
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -286,7 +286,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -286,7 +286,7 @@ namespace Titanium.Web.Proxy.Helpers
internal ProxyInfo GetProxyInfoFromRegistry() internal ProxyInfo GetProxyInfoFromRegistry()
{ {
using (var reg = OpenInternetSettingsKey()) using (var reg = openInternetSettingsKey())
{ {
if (reg == null) if (reg == null)
{ {
...@@ -347,7 +347,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -347,7 +347,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// Opens the registry key with the internet settings /// Opens the registry key with the internet settings
/// </summary> /// </summary>
private static RegistryKey OpenInternetSettingsKey() private static RegistryKey openInternetSettingsKey()
{ {
return Registry.CurrentUser.OpenSubKey(regKeyInternetSettings, true); return Registry.CurrentUser.OpenSubKey(regKeyInternetSettings, true);
} }
......
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
...@@ -96,11 +96,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -96,11 +96,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers /// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers
/// as prefix /// as prefix
/// Usefull for websocket requests /// Useful for websocket requests
/// Task-based Asynchronous Pattern /// Task-based Asynchronous Pattern
/// </summary> /// </summary>
/// <param name="clientStream"></param> /// <param name="clientStream"></param>
/// <param name="serverStream"></param> /// <param name="serverStream"></param>
/// <param name="bufferPool"></param>
/// <param name="bufferSize"></param> /// <param name="bufferSize"></param>
/// <param name="onDataSend"></param> /// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param> /// <param name="onDataReceive"></param>
...@@ -128,10 +129,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -128,10 +129,11 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers /// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers
/// as prefix /// as prefix
/// Usefull for websocket requests /// Useful for websocket requests
/// </summary> /// </summary>
/// <param name="clientStream"></param> /// <param name="clientStream"></param>
/// <param name="serverStream"></param> /// <param name="serverStream"></param>
/// <param name="bufferPool"></param>
/// <param name="bufferSize"></param> /// <param name="bufferSize"></param>
/// <param name="onDataSend"></param> /// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param> /// <param name="onDataReceive"></param>
......
...@@ -12,6 +12,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -12,6 +12,8 @@ namespace Titanium.Web.Proxy.Http
Method = "CONNECT"; Method = "CONNECT";
} }
public TunnelType TunnelType { get; internal set; }
public ClientHelloInfo ClientHelloInfo { get; set; } public ClientHelloInfo ClientHelloInfo { get; set; }
} }
} }
...@@ -12,11 +12,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -12,11 +12,11 @@ namespace Titanium.Web.Proxy.Http
public ServerHelloInfo ServerHelloInfo { get; set; } public ServerHelloInfo ServerHelloInfo { get; set; }
/// <summary> /// <summary>
/// Creates a successfull CONNECT response /// Creates a successful CONNECT response
/// </summary> /// </summary>
/// <param name="httpVersion"></param> /// <param name="httpVersion"></param>
/// <returns></returns> /// <returns></returns>
internal static ConnectResponse CreateSuccessfullConnectResponse(Version httpVersion) internal static ConnectResponse CreateSuccessfulConnectResponse(Version httpVersion)
{ {
var response = new ConnectResponse var response = new ConnectResponse
{ {
......
...@@ -67,7 +67,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -67,7 +67,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Returns all headers with given name if exists /// Returns all headers with given name if exists
/// Returns null if does'nt exist /// Returns null if doesn't exist
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns></returns> /// <returns></returns>
......
...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http
// prepare the request & headers // prepare the request & headers
await writer.WriteLineAsync(Request.CreateRequestLine(Request.Method, await writer.WriteLineAsync(Request.CreateRequestLine(Request.Method,
useUpstreamProxy || isTransparent ? Request.OriginalUrl : Request.RequestUri.PathAndQuery, useUpstreamProxy || isTransparent ? Request.RequestUriString : Request.RequestUri.PathAndQuery,
Request.HttpVersion), cancellationToken); Request.HttpVersion), cancellationToken);
var headerBuilder = new StringBuilder(); var headerBuilder = new StringBuilder();
......
...@@ -6,28 +6,28 @@ ...@@ -6,28 +6,28 @@
public static class KnownHeaders public static class KnownHeaders
{ {
// Both // Both
public const string Connection = "connection"; public const string Connection = "Connection";
public const string ConnectionClose = "close"; public const string ConnectionClose = "close";
public const string ConnectionKeepAlive = "keep-alive"; public const string ConnectionKeepAlive = "keep-alive";
public const string ContentLength = "content-length"; public const string ContentLength = "Content-Length";
public const string ContentType = "content-type"; public const string ContentType = "Content-Type";
public const string ContentTypeCharset = "charset"; public const string ContentTypeCharset = "charset";
public const string ContentTypeBoundary = "boundary"; public const string ContentTypeBoundary = "boundary";
public const string Upgrade = "upgrade"; public const string Upgrade = "Upgrade";
public const string UpgradeWebsocket = "websocket"; public const string UpgradeWebsocket = "websocket";
// Request headers // Request headers
public const string AcceptEncoding = "accept-encoding"; public const string AcceptEncoding = "Accept-Encoding";
public const string Authorization = "Authorization"; public const string Authorization = "Authorization";
public const string Expect = "expect"; public const string Expect = "Expect";
public const string Expect100Continue = "100-continue"; public const string Expect100Continue = "100-continue";
public const string Host = "host"; public const string Host = "Host";
public const string ProxyAuthorization = "Proxy-Authorization"; public const string ProxyAuthorization = "Proxy-Authorization";
public const string ProxyAuthorizationBasic = "basic"; public const string ProxyAuthorizationBasic = "basic";
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
public const string ProxyConnectionClose = "close"; public const string ProxyConnectionClose = "close";
// Response headers // Response headers
public const string ContentEncoding = "content-encoding"; public const string ContentEncoding = "Content-Encoding";
public const string ContentEncodingDeflate = "deflate"; public const string ContentEncodingDeflate = "deflate";
public const string ContentEncodingGzip = "gzip"; public const string ContentEncodingGzip = "gzip";
public const string ContentEncodingBrotli = "br"; public const string ContentEncodingBrotli = "br";
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
public const string ProxyAuthenticate = "Proxy-Authenticate"; public const string ProxyAuthenticate = "Proxy-Authenticate";
public const string TransferEncoding = "transfer-encoding"; public const string TransferEncoding = "Transfer-Encoding";
public const string TransferEncodingChunked = "chunked"; public const string TransferEncodingChunked = "chunked";
} }
} }
...@@ -14,6 +14,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -14,6 +14,8 @@ namespace Titanium.Web.Proxy.Http
[TypeConverter(typeof(ExpandableObjectConverter))] [TypeConverter(typeof(ExpandableObjectConverter))]
public class Request : RequestResponseBase public class Request : RequestResponseBase
{ {
private string originalUrl;
/// <summary> /// <summary>
/// Request Method. /// Request Method.
/// </summary> /// </summary>
...@@ -32,7 +34,20 @@ namespace Titanium.Web.Proxy.Http ...@@ -32,7 +34,20 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// The original request Url. /// The original request Url.
/// </summary> /// </summary>
public string OriginalUrl { get; set; } public string OriginalUrl
{
get => originalUrl;
internal set
{
originalUrl = value;
RequestUriString = value;
}
}
/// <summary>
/// The request uri as it is in the HTTP header
/// </summary>
public string RequestUriString { get; set; }
/// <summary> /// <summary>
/// Has request body? /// Has request body?
...@@ -140,7 +155,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -140,7 +155,7 @@ namespace Titanium.Web.Proxy.Http
get get
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append($"{CreateRequestLine(Method, OriginalUrl, HttpVersion)}{ProxyConstants.NewLine}"); sb.Append($"{CreateRequestLine(Method, RequestUriString, HttpVersion)}{ProxyConstants.NewLine}");
foreach (var header in Headers) foreach (var header in Headers)
{ {
sb.Append($"{header.ToString()}{ProxyConstants.NewLine}"); sb.Append($"{header.ToString()}{ProxyConstants.NewLine}");
......
...@@ -3,6 +3,7 @@ using System.ComponentModel; ...@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Compression; using Titanium.Web.Proxy.Compression;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
...@@ -49,6 +50,21 @@ namespace Titanium.Web.Proxy.Http ...@@ -49,6 +50,21 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
internal string OriginalContentEncoding { get; set; } internal string OriginalContentEncoding { get; set; }
internal TaskCompletionSource<bool> ReadHttp2BeforeHandlerTaskCompletionSource;
internal TaskCompletionSource<bool> ReadHttp2BodyTaskCompletionSource;
internal MemoryStream Http2BodyData;
internal bool Http2IgnoreBodyFrames;
internal Task Http2BeforeHandlerTask;
/// <summary>
/// Priority used only in HTTP/2
/// </summary>
internal long? Priority;
/// <summary> /// <summary>
/// Keeps the body data after the session is finished. /// Keeps the body data after the session is finished.
/// </summary> /// </summary>
...@@ -189,11 +205,13 @@ namespace Titanium.Web.Proxy.Http ...@@ -189,11 +205,13 @@ namespace Titanium.Web.Proxy.Http
public bool IsBodyRead { get; internal set; } public bool IsBodyRead { get; internal set; }
/// <summary> /// <summary>
/// Is the request/response no more modifyable by user (user callbacks complete?) /// Is the request/response no more modifiable by user (user callbacks complete?)
/// Also if user set this as a custom response then this should be true. /// Also if user set this as a custom response then this should be true.
/// </summary> /// </summary>
internal bool Locked { get; set; } internal bool Locked { get; set; }
internal bool BodyAvailable => BodyInternal != null;
internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true); internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true);
/// <summary> /// <summary>
......
namespace Titanium.Web.Proxy.Http
{
public enum TunnelType
{
Unknown,
Https,
Websocket,
Http2,
}
}
...@@ -61,7 +61,9 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -61,7 +61,9 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <param name="name">Name.</param> /// <param name="name">Name.</param>
/// <param name="value">Value.</param> /// <param name="value">Value.</param>
/// <param name="sensitive">If set to <c>true</c> sensitive.</param> /// <param name="sensitive">If set to <c>true</c> sensitive.</param>
public void EncodeHeader(BinaryWriter output, string name, string value, bool sensitive = false) /// <param name="indexType">Index type.</param>
/// <param name="useStaticName">Use static name.</param>
public void EncodeHeader(BinaryWriter output, string name, string value, bool sensitive = false, HpackUtil.IndexType indexType = HpackUtil.IndexType.Incremental, bool useStaticName = true)
{ {
// If the header value is sensitive then it must never be indexed // If the header value is sensitive then it must never be indexed
if (sensitive) if (sensitive)
...@@ -116,10 +118,9 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -116,10 +118,9 @@ namespace Titanium.Web.Proxy.Http2.Hpack
} }
else else
{ {
int nameIndex = getNameIndex(name); int nameIndex = useStaticName ? getNameIndex(name) : -1;
ensureCapacity(headerSize); ensureCapacity(headerSize);
var indexType = HpackUtil.IndexType.Incremental;
encodeLiteral(output, name, value, indexType, nameIndex); encodeLiteral(output, name, value, indexType, nameIndex);
add(name, value); add(name, value);
} }
...@@ -309,7 +310,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -309,7 +310,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
int i = index(h); int i = index(h);
for (var e = headerFields[i]; e != null; e = e.Next) for (var e = headerFields[i]; e != null; e = e.Next)
{ {
if (e.Hash == h && Equals(name, e.Name) && Equals(value, e.Value)) if (e.Hash == h && name.Equals(e.Name, StringComparison.OrdinalIgnoreCase) && Equals(value, e.Value))
{ {
return e; return e;
} }
...@@ -336,7 +337,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -336,7 +337,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
int index = -1; int index = -1;
for (var e = headerFields[i]; e != null; e = e.Next) for (var e = headerFields[i]; e != null; e = e.Next)
{ {
if (e.Hash == h && HpackUtil.Equals(name, e.Name)) if (e.Hash == h && name.Equals(e.Name, StringComparison.OrdinalIgnoreCase))
{ {
index = e.Index; index = e.Index;
break; break;
...@@ -513,7 +514,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -513,7 +514,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <param name="value">Value.</param> /// <param name="value">Value.</param>
/// <param name="index">Index.</param> /// <param name="index">Index.</param>
/// <param name="next">Next.</param> /// <param name="next">Next.</param>
public HeaderEntry(int hash, string name, string value, int index, HeaderEntry next) : base(name, value) public HeaderEntry(int hash, string name, string value, int index, HeaderEntry next) : base(name, value, true)
{ {
Index = index; Index = index;
Hash = hash; Hash = hash;
......
...@@ -59,102 +59,102 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -59,102 +59,102 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/* 14 */ /* 14 */
new HttpHeader(":status", "500"), new HttpHeader(":status", "500"),
/* 15 */ /* 15 */
new HttpHeader("accept-charset", string.Empty), new HttpHeader("Accept-Charset", string.Empty),
/* 16 */ /* 16 */
new HttpHeader("accept-encoding", "gzip, deflate"), new HttpHeader("Accept-Encoding", "gzip, deflate"),
/* 17 */ /* 17 */
new HttpHeader("accept-language", string.Empty), new HttpHeader("Accept-Language", string.Empty),
/* 18 */ /* 18 */
new HttpHeader("accept-ranges", string.Empty), new HttpHeader("Accept-Ranges", string.Empty),
/* 19 */ /* 19 */
new HttpHeader("accept", string.Empty), new HttpHeader("Accept", string.Empty),
/* 20 */ /* 20 */
new HttpHeader("access-control-allow-origin", string.Empty), new HttpHeader("Access-Control-Allow-Origin", string.Empty),
/* 21 */ /* 21 */
new HttpHeader("age", string.Empty), new HttpHeader("Age", string.Empty),
/* 22 */ /* 22 */
new HttpHeader("allow", string.Empty), new HttpHeader("Allow", string.Empty),
/* 23 */ /* 23 */
new HttpHeader("authorization", string.Empty), new HttpHeader("Authorization", string.Empty),
/* 24 */ /* 24 */
new HttpHeader("cache-control", string.Empty), new HttpHeader("Cache-Control", string.Empty),
/* 25 */ /* 25 */
new HttpHeader("content-disposition", string.Empty), new HttpHeader("Content-Disposition", string.Empty),
/* 26 */ /* 26 */
new HttpHeader("content-encoding", string.Empty), new HttpHeader("Content-Encoding", string.Empty),
/* 27 */ /* 27 */
new HttpHeader("content-language", string.Empty), new HttpHeader("Content-Language", string.Empty),
/* 28 */ /* 28 */
new HttpHeader("content-length", string.Empty), new HttpHeader("Content-Length", string.Empty),
/* 29 */ /* 29 */
new HttpHeader("content-location", string.Empty), new HttpHeader("Content-Location", string.Empty),
/* 30 */ /* 30 */
new HttpHeader("content-range", string.Empty), new HttpHeader("Content-Range", string.Empty),
/* 31 */ /* 31 */
new HttpHeader("content-type", string.Empty), new HttpHeader("Content-Type", string.Empty),
/* 32 */ /* 32 */
new HttpHeader("cookie", string.Empty), new HttpHeader("Cookie", string.Empty),
/* 33 */ /* 33 */
new HttpHeader("date", string.Empty), new HttpHeader("Date", string.Empty),
/* 34 */ /* 34 */
new HttpHeader("etag", string.Empty), new HttpHeader("ETag", string.Empty),
/* 35 */ /* 35 */
new HttpHeader("expect", string.Empty), new HttpHeader("Expect", string.Empty),
/* 36 */ /* 36 */
new HttpHeader("expires", string.Empty), new HttpHeader("Expires", string.Empty),
/* 37 */ /* 37 */
new HttpHeader("from", string.Empty), new HttpHeader("From", string.Empty),
/* 38 */ /* 38 */
new HttpHeader("host", string.Empty), new HttpHeader("Host", string.Empty),
/* 39 */ /* 39 */
new HttpHeader("if-match", string.Empty), new HttpHeader("If-Match", string.Empty),
/* 40 */ /* 40 */
new HttpHeader("if-modified-since", string.Empty), new HttpHeader("If-Modified-Since", string.Empty),
/* 41 */ /* 41 */
new HttpHeader("if-none-match", string.Empty), new HttpHeader("If-None-Match", string.Empty),
/* 42 */ /* 42 */
new HttpHeader("if-range", string.Empty), new HttpHeader("If-Range", string.Empty),
/* 43 */ /* 43 */
new HttpHeader("if-unmodified-since", string.Empty), new HttpHeader("If-Unmodified-Since", string.Empty),
/* 44 */ /* 44 */
new HttpHeader("last-modified", string.Empty), new HttpHeader("Last-Modified", string.Empty),
/* 45 */ /* 45 */
new HttpHeader("link", string.Empty), new HttpHeader("Link", string.Empty),
/* 46 */ /* 46 */
new HttpHeader("location", string.Empty), new HttpHeader("Location", string.Empty),
/* 47 */ /* 47 */
new HttpHeader("max-forwards", string.Empty), new HttpHeader("Max-Forwards", string.Empty),
/* 48 */ /* 48 */
new HttpHeader("proxy-authenticate", string.Empty), new HttpHeader("Proxy-Authenticate", string.Empty),
/* 49 */ /* 49 */
new HttpHeader("proxy-authorization", string.Empty), new HttpHeader("Proxy-Authorization", string.Empty),
/* 50 */ /* 50 */
new HttpHeader("range", string.Empty), new HttpHeader("Range", string.Empty),
/* 51 */ /* 51 */
new HttpHeader("referer", string.Empty), new HttpHeader("Referer", string.Empty),
/* 52 */ /* 52 */
new HttpHeader("refresh", string.Empty), new HttpHeader("Refresh", string.Empty),
/* 53 */ /* 53 */
new HttpHeader("retry-after", string.Empty), new HttpHeader("Retry-After", string.Empty),
/* 54 */ /* 54 */
new HttpHeader("server", string.Empty), new HttpHeader("Server", string.Empty),
/* 55 */ /* 55 */
new HttpHeader("set-cookie", string.Empty), new HttpHeader("Set-Cookie", string.Empty),
/* 56 */ /* 56 */
new HttpHeader("strict-transport-security", string.Empty), new HttpHeader("Strict-Transport-Security", string.Empty),
/* 57 */ /* 57 */
new HttpHeader("transfer-encoding", string.Empty), new HttpHeader("Transfer-Encoding", string.Empty),
/* 58 */ /* 58 */
new HttpHeader("user-agent", string.Empty), new HttpHeader("User-Agent", string.Empty),
/* 59 */ /* 59 */
new HttpHeader("vary", string.Empty), new HttpHeader("Vary", string.Empty),
/* 60 */ /* 60 */
new HttpHeader("via", string.Empty), new HttpHeader("Via", string.Empty),
/* 61 */ /* 61 */
new HttpHeader("www-authenticate", string.Empty) new HttpHeader("WWW-Authenticate", string.Empty)
}; };
private static readonly Dictionary<string, int> staticIndexByName = CreateMap(); private static readonly Dictionary<string, int> staticIndexByName = createMap();
/// <summary> /// <summary>
/// The number of header fields in the static table. /// The number of header fields in the static table.
...@@ -180,12 +180,12 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -180,12 +180,12 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// <param name="name">Name.</param> /// <param name="name">Name.</param>
public static int GetIndex(string name) public static int GetIndex(string name)
{ {
if (!staticIndexByName.ContainsKey(name)) if (!staticIndexByName.TryGetValue(name, out int index))
{ {
return -1; return -1;
} }
return staticIndexByName[name]; return index;
} }
/// <summary> /// <summary>
...@@ -207,7 +207,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -207,7 +207,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
while (index <= Length) while (index <= Length)
{ {
var entry = Get(index); var entry = Get(index);
if (!HpackUtil.Equals(name, entry.Name)) if (!name.Equals(entry.Name, StringComparison.OrdinalIgnoreCase))
{ {
break; break;
} }
...@@ -227,7 +227,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -227,7 +227,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
/// create a map of header name to index value to allow quick lookup /// create a map of header name to index value to allow quick lookup
/// </summary> /// </summary>
/// <returns>The map.</returns> /// <returns>The map.</returns>
private static Dictionary<string, int> CreateMap() private static Dictionary<string, int> createMap()
{ {
int length = staticTable.Count; int length = staticTable.Count;
var ret = new Dictionary<string, int>(length); var ret = new Dictionary<string, int>(length);
...@@ -237,11 +237,11 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -237,11 +237,11 @@ namespace Titanium.Web.Proxy.Http2.Hpack
for (int index = length; index > 0; index--) for (int index = length; index > 0; index--)
{ {
var entry = Get(index); var entry = Get(index);
string name = entry.Name; string name = entry.Name.ToLower();
ret[name] = index; ret[name] = index;
} }
return ret; return ret;
} }
} }
} }
\ No newline at end of file
using System;
namespace Titanium.Web.Proxy.Http2
{
[Flags]
internal enum Http2FrameFlag : byte
{
Ack = 0x01,
EndStream = 0x01,
EndHeaders = 0x04,
Padded = 0x08,
Priority = 0x20,
}
}
\ No newline at end of file
namespace Titanium.Web.Proxy.Http2
{
internal class Http2FrameHeader
{
public int Length;
public Http2FrameType Type;
public Http2FrameFlag Flags;
public int StreamId;
public byte[] Buffer;
public byte[] CopyToBuffer()
{
int length = Length;
var buf = /*new byte[9];*/Buffer;
buf[0] = (byte)((length >> 16) & 0xff);
buf[1] = (byte)((length >> 8) & 0xff);
buf[2] = (byte)(length & 0xff);
buf[3] = (byte)Type;
buf[4] = (byte)Flags;
int streamId = StreamId;
//buf[5] = (byte)((streamId >> 24) & 0xff);
//buf[6] = (byte)((streamId >> 16) & 0xff);
//buf[7] = (byte)((streamId >> 8) & 0xff);
//buf[8] = (byte)(streamId & 0xff);
return buf;
}
}
}
namespace Titanium.Web.Proxy.Http2
{
internal enum Http2FrameType : byte
{
Data = 0x00,
Headers = 0x01,
Priority = 0x02,
RstStream = 0x03,
Settings = 0x04,
PushPromise = 0x05,
Ping = 0x06,
GoAway = 0x07,
WindowUpdate = 0x08,
Continuation = 0x09,
}
}
\ No newline at end of file
#if NETCOREAPP2_1 #if NETCOREAPP2_1
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Compression;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http2.Hpack; using Titanium.Web.Proxy.Http2.Hpack;
namespace Titanium.Web.Proxy.Http2 namespace Titanium.Web.Proxy.Http2
{ {
[Flags]
internal enum Http2FrameFlag
{
Ack = 0x01,
EndStream = 0x01,
EndHeaders = 0x04,
Padded = 0x08,
Priority = 0x20,
}
internal class Http2Helper internal class Http2Helper
{ {
/// <summary> /// <summary>
/// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers /// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers
/// as prefix /// as prefix
/// Usefull for websocket requests /// Useful for websocket requests
/// Task-based Asynchronous Pattern /// Task-based Asynchronous Pattern
/// </summary> /// </summary>
/// <param name="clientStream"></param>
/// <param name="serverStream"></param>
/// <param name="bufferSize"></param>
/// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param>
/// <param name="connectionId"></param>
/// <param name="exceptionFunc"></param>
/// <returns></returns> /// <returns></returns>
internal static async Task SendHttp2(Stream clientStream, Stream serverStream, int bufferSize, internal static async Task SendHttp2(Stream clientStream, Stream serverStream, int bufferSize,
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive, Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive,
Func<SessionEventArgs> sessionFactory,
Func<SessionEventArgs, Task> onBeforeRequest, Func<SessionEventArgs, Task> onBeforeResponse,
CancellationTokenSource cancellationTokenSource, Guid connectionId, CancellationTokenSource cancellationTokenSource, Guid connectionId,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
var clientSettings = new Http2Settings();
var serverSettings = new Http2Settings();
var sessions = new ConcurrentDictionary<int, SessionEventArgs>();
// Now async relay all server=>client & client=>server data // Now async relay all server=>client & client=>server data
var sendRelay = var sendRelay =
CopyHttp2FrameAsync(clientStream, serverStream, onDataSend, bufferSize, connectionId, copyHttp2FrameAsync(clientStream, serverStream, onDataSend, clientSettings, serverSettings,
true, cancellationTokenSource.Token); sessionFactory, sessions, onBeforeRequest,
bufferSize, connectionId, true, cancellationTokenSource.Token, exceptionFunc);
var receiveRelay = var receiveRelay =
CopyHttp2FrameAsync(serverStream, clientStream, onDataReceive, bufferSize, connectionId, copyHttp2FrameAsync(serverStream, clientStream, onDataReceive, serverSettings, clientSettings,
false, cancellationTokenSource.Token); sessionFactory, sessions, onBeforeResponse,
bufferSize, connectionId, false, cancellationTokenSource.Token, exceptionFunc);
await Task.WhenAny(sendRelay, receiveRelay); await Task.WhenAny(sendRelay, receiveRelay);
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
...@@ -53,77 +52,366 @@ namespace Titanium.Web.Proxy.Http2 ...@@ -53,77 +52,366 @@ namespace Titanium.Web.Proxy.Http2
await Task.WhenAll(sendRelay, receiveRelay); await Task.WhenAll(sendRelay, receiveRelay);
} }
private static async Task CopyHttp2FrameAsync(Stream input, Stream output, Action<byte[], int, int> onCopy, private static async Task copyHttp2FrameAsync(Stream input, Stream output, Action<byte[], int, int> onCopy,
int bufferSize, Guid connectionId, bool isClient, CancellationToken cancellationToken) Http2Settings localSettings, Http2Settings remoteSettings,
Func<SessionEventArgs> sessionFactory, ConcurrentDictionary<int, SessionEventArgs> sessions,
Func<SessionEventArgs, Task> onBeforeRequestResponse,
int bufferSize, Guid connectionId, bool isClient, CancellationToken cancellationToken,
ExceptionHandler exceptionFunc)
{ {
var decoder = new Decoder(8192, 4096); int headerTableSize = 0;
Decoder decoder = null;
var headerBuffer = new byte[9]; var frameHeader = new Http2FrameHeader();
var buffer = new byte[32768]; frameHeader.Buffer = new byte[9];
byte[] buffer = null;
while (true) while (true)
{ {
int read = await ForceRead(input, headerBuffer, 0, 9, cancellationToken); var frameHeaderBuffer = frameHeader.Buffer;
int read = await forceRead(input, frameHeaderBuffer, 0, 9, cancellationToken);
onCopy(frameHeaderBuffer, 0, read);
if (read != 9) if (read != 9)
{ {
return; return;
} }
int length = (headerBuffer[0] << 16) + (headerBuffer[1] << 8) + headerBuffer[2]; int length = (frameHeaderBuffer[0] << 16) + (frameHeaderBuffer[1] << 8) + frameHeaderBuffer[2];
byte type = headerBuffer[3]; var type = (Http2FrameType)frameHeaderBuffer[3];
byte flags = headerBuffer[4]; var flags = (Http2FrameFlag)frameHeaderBuffer[4];
int streamId = ((headerBuffer[5] & 0x7f) << 24) + (headerBuffer[6] << 16) + (headerBuffer[7] << 8) + int streamId = ((frameHeaderBuffer[5] & 0x7f) << 24) + (frameHeaderBuffer[6] << 16) +
headerBuffer[8]; (frameHeaderBuffer[7] << 8) + frameHeaderBuffer[8];
read = await ForceRead(input, buffer, 0, length, cancellationToken); frameHeader.Length = length;
frameHeader.Type = type;
frameHeader.Flags = flags;
frameHeader.StreamId = streamId;
if (buffer == null || buffer.Length < localSettings.MaxFrameSize)
{
buffer = new byte[localSettings.MaxFrameSize];
}
read = await forceRead(input, buffer, 0, length, cancellationToken);
onCopy(buffer, 0, read);
if (read != length) if (read != length)
{ {
return; return;
} }
if (isClient) bool sendPacket = true;
bool endStream = false;
SessionEventArgs args = null;
RequestResponseBase rr = null;
if (type == Http2FrameType.Data || type == Http2FrameType.Headers/* || type == Http2FrameType.PushPromise*/)
{
if (!sessions.TryGetValue(streamId, out args))
{
//if (type == Http2FrameType.Data)
//{
// throw new ProxyHttpException("HTTP Body data received before any header frame.", null, args);
//}
//if (type == Http2FrameType.Headers && !isClient)
//{
// throw new ProxyHttpException("HTTP Response received before any Request header frame.", null, args);
//}
if (type == Http2FrameType.PushPromise && isClient)
{
throw new ProxyHttpException("HTTP Push promise received from the client.", null, args);
}
}
}
//System.Diagnostics.Debug.WriteLine("CONN: " + connectionId + ", CLIENT: " + isClient + ", STREAM: " + streamId + ", TYPE: " + type);
if (type == Http2FrameType.Data && args != null)
{ {
if (type == 1 /*headers*/) rr = isClient ? (RequestResponseBase)args.HttpClient.Request : args.HttpClient.Response;
bool padded = (flags & Http2FrameFlag.Padded) != 0;
bool endStreamFlag = (flags & Http2FrameFlag.EndStream) != 0;
if (endStreamFlag)
{
endStream = true;
}
if (rr.Http2IgnoreBodyFrames)
{ {
bool endHeaders = (flags & (int)Http2FrameFlag.EndHeaders) != 0; sendPacket = false;
bool padded = (flags & (int)Http2FrameFlag.Padded) != 0; }
bool priority = (flags & (int)Http2FrameFlag.Priority) != 0;
System.Diagnostics.Debug.WriteLine("HEADER: " + streamId + " end: " + endHeaders); if (rr.ReadHttp2BodyTaskCompletionSource != null)
{
// Get body method was called in the "before" event handler
var data = rr.Http2BodyData;
int offset = 0; int offset = 0;
if (padded) if (padded)
{ {
offset = 1; offset++;
length--;
length -= buffer[0];
}
data.Write(buffer, offset, length);
}
}
else if (type == Http2FrameType.Headers/* || type == Http2FrameType.PushPromise*/)
{
bool endHeaders = (flags & Http2FrameFlag.EndHeaders) != 0;
bool padded = (flags & Http2FrameFlag.Padded) != 0;
bool priority = (flags & Http2FrameFlag.Priority) != 0;
bool endStreamFlag = (flags & Http2FrameFlag.EndStream) != 0;
if (endStreamFlag)
{
endStream = true;
}
int offset = 0;
if (padded)
{
offset = 1;
breakpoint();
}
if (type == Http2FrameType.PushPromise)
{
int promisedStreamId = (buffer[offset++] << 24) + (buffer[offset++] << 16) + (buffer[offset++] << 8) + buffer[offset++];
if (!sessions.TryGetValue(streamId, out args))
{
args = sessionFactory();
args.IsPromise = true;
sessions.TryAdd(streamId, args);
sessions.TryAdd(promisedStreamId, args);
}
System.Diagnostics.Debug.WriteLine("PROMISE STREAM: " + streamId + ", " + promisedStreamId +
", CONN: " + connectionId);
rr = args.HttpClient.Request;
if (isClient)
{
// push_promise from client???
breakpoint();
}
}
else
{
if (!sessions.TryGetValue(streamId, out args))
{
args = sessionFactory();
sessions.TryAdd(streamId, args);
} }
rr = isClient ? (RequestResponseBase)args.HttpClient.Request : args.HttpClient.Response;
if (priority) if (priority)
{ {
offset += 5; var priorityData = ((long)buffer[offset++] << 32) + ((long)buffer[offset++] << 24) +
(buffer[offset++] << 16) + (buffer[offset++] << 8) + buffer[offset++];
rr.Priority = priorityData;
}
}
int dataLength = length - offset;
if (padded)
{
dataLength -= buffer[0];
}
var headerListener = new MyHeaderListener(
(name, value) =>
{
var headers = isClient ? args.HttpClient.Request.Headers : args.HttpClient.Response.Headers;
headers.AddHeader(name, value);
});
try
{
// recreate the decoder when new value is bigger
// should we recreate when smaller, too?
if (decoder == null || headerTableSize < localSettings.HeaderTableSize)
{
headerTableSize = localSettings.HeaderTableSize;
decoder = new Decoder(8192, headerTableSize);
} }
int dataLength = length - offset; decoder.Decode(new BinaryReader(new MemoryStream(buffer, offset, dataLength)),
if (padded) headerListener);
decoder.EndHeaderBlock();
if (rr is Request request)
{
request.HttpVersion = HttpVersion.Version20;
request.Method = headerListener.Method;
request.OriginalUrl = headerListener.Path;
request.RequestUri = headerListener.GetUri();
}
else
{
var response = (Response)rr;
response.HttpVersion = HttpVersion.Version20;
int.TryParse(headerListener.Status, out int statusCode);
response.StatusCode = statusCode;
}
}
catch (Exception ex)
{
exceptionFunc(new ProxyHttpException("Failed to decode HTTP/2 headers", ex, args));
}
if (!endHeaders)
{
breakpoint();
}
if (endHeaders)
{
var tcs = new TaskCompletionSource<bool>();
rr.ReadHttp2BeforeHandlerTaskCompletionSource = tcs;
var handler = onBeforeRequestResponse(args);
rr.Http2BeforeHandlerTask = handler;
if (handler == await Task.WhenAny(tcs.Task, handler))
{
rr.ReadHttp2BeforeHandlerTaskCompletionSource = null;
tcs.SetResult(true);
await sendHeader(remoteSettings, frameHeader, rr, endStream, output, args.IsPromise);
}
else
{
rr.Http2IgnoreBodyFrames = true;
}
rr.Locked = true;
}
sendPacket = false;
}
else if (type == Http2FrameType.Continuation)
{
// todo: implementing this type is mandatory for multi-part headers
breakpoint();
}
else if (type == Http2FrameType.Settings)
{
if (length % 6 != 0)
{
// https://httpwg.org/specs/rfc7540.html#SETTINGS
// 6.5. SETTINGS
// A SETTINGS frame with a length other than a multiple of 6 octets MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR
throw new ProxyHttpException("Invalid settings length", null, null);
}
int pos = 0;
while (pos < length)
{
int identifier = (buffer[pos++] << 8) + buffer[pos++];
int value = (buffer[pos++] << 24) + (buffer[pos++] << 16) + (buffer[pos++] << 8) + buffer[pos++];
if (identifier == 1 /*SETTINGS_HEADER_TABLE_SIZE*/)
{
//System.Diagnostics.Debug.WriteLine("HEADER SIZE CONN: " + connectionId + ", CLIENT: " + isClient + ", value: " + value);
remoteSettings.HeaderTableSize = value;
}
else if (identifier == 5 /*SETTINGS_MAX_FRAME_SIZE*/)
{ {
dataLength -= buffer[0]; remoteSettings.MaxFrameSize = value;
} }
}
}
if (type == Http2FrameType.RstStream)
{
int errorCode = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
if (streamId == 0)
{
// connection error
exceptionFunc(new ProxyHttpException("HTTP/2 connection error. Error code: " + errorCode, null, args));
return;
}
else
{
// stream error
sessions.TryRemove(streamId, out _);
var headerListener = new MyHeaderListener(); if (errorCode != 8 /*cancel*/)
try
{ {
decoder.Decode(new BinaryReader(new MemoryStream(buffer, offset, dataLength)), exceptionFunc(new ProxyHttpException("HTTP/2 stream error. Error code: " + errorCode, null, args));
headerListener);
decoder.EndHeaderBlock();
} }
catch (Exception) }
}
if (endStream && rr.ReadHttp2BodyTaskCompletionSource != null)
{
if (!rr.BodyAvailable)
{
var data = rr.Http2BodyData;
var body = data.ToArray();
if (rr.ContentEncoding != null)
{ {
using (var ms = new MemoryStream())
{
using (var zip =
DecompressionFactory.Create(rr.ContentEncoding, new MemoryStream(body)))
{
zip.CopyTo(ms);
}
body = ms.ToArray();
}
} }
rr.Body = body;
}
rr.IsBodyRead = true;
var tcs = rr.ReadHttp2BodyTaskCompletionSource;
rr.ReadHttp2BodyTaskCompletionSource = null;
if (!tcs.Task.IsCompleted)
{
tcs.SetResult(true);
}
rr.Http2BodyData = null;
if (rr.Http2BeforeHandlerTask != null)
{
await rr.Http2BeforeHandlerTask;
}
if (args.IsPromise)
{
breakpoint();
} }
await sendBody(remoteSettings, rr, frameHeader, buffer, output);
}
if (!isClient && endStream)
{
sessions.TryRemove(streamId, out _);
System.Diagnostics.Debug.WriteLine("REMOVED CONN: " + connectionId + ", CLIENT: " + isClient + ", STREAM: " + streamId + ", TYPE: " + type);
}
if (sendPacket)
{
// do not cancel the write operation
var buf = frameHeader.CopyToBuffer();
await output.WriteAsync(buf, 0, buf.Length/*, cancellationToken*/);
await output.WriteAsync(buffer, 0, length /*, cancellationToken*/);
} }
await output.WriteAsync(headerBuffer, 0, headerBuffer.Length, cancellationToken); if (cancellationToken.IsCancellationRequested)
await output.WriteAsync(buffer, 0, length, cancellationToken); {
return;
}
/*using (var fs = new System.IO.FileStream($@"c:\11\{connectionId}.{streamId}.dat", FileMode.Append)) /*using (var fs = new System.IO.FileStream($@"c:\temp\{connectionId}.{streamId}.dat", FileMode.Append))
{ {
fs.Write(headerBuffer, 0, headerBuffer.Length); fs.Write(headerBuffer, 0, headerBuffer.Length);
fs.Write(buffer, 0, length); fs.Write(buffer, 0, length);
...@@ -131,14 +419,112 @@ namespace Titanium.Web.Proxy.Http2 ...@@ -131,14 +419,112 @@ namespace Titanium.Web.Proxy.Http2
} }
} }
private static async Task<int> ForceRead(Stream input, byte[] buffer, int offset, int bytesToRead, [Conditional("DEBUG")]
private static void breakpoint()
{
// when this method is called something received which is not yet implemented
;
}
private static async Task sendHeader(Http2Settings settings, Http2FrameHeader frameHeader, RequestResponseBase rr, bool endStream, Stream output, bool pushPromise)
{
var encoder = new Encoder(settings.HeaderTableSize);
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
if (rr.Priority.HasValue)
{
long p = rr.Priority.Value;
writer.Write((byte)((p >> 32) & 0xff));
writer.Write((byte)((p >> 24) & 0xff));
writer.Write((byte)((p >> 16) & 0xff));
writer.Write((byte)((p >> 8) & 0xff));
writer.Write((byte)(p & 0xff));
}
if (rr is Request request)
{
encoder.EncodeHeader(writer, ":method", request.Method);
encoder.EncodeHeader(writer, ":authority", request.RequestUri.Host);
encoder.EncodeHeader(writer, ":scheme", request.RequestUri.Scheme);
encoder.EncodeHeader(writer, ":path", request.RequestUriString, false,
HpackUtil.IndexType.None, false);
}
else
{
var response = (Response)rr;
encoder.EncodeHeader(writer, ":status", response.StatusCode.ToString());
}
foreach (var header in rr.Headers)
{
encoder.EncodeHeader(writer, header.Name.ToLower(), header.Value);
}
var data = ms.ToArray();
int newLength = data.Length;
frameHeader.Length = newLength;
frameHeader.Type = pushPromise ? Http2FrameType.PushPromise : Http2FrameType.Headers;
var flags = Http2FrameFlag.EndHeaders;
if (endStream)
{
flags |= Http2FrameFlag.EndStream;
}
if (rr.Priority.HasValue)
{
flags |= Http2FrameFlag.Priority;
}
frameHeader.Flags = flags;
// clear the padding flag
//headerBuffer[4] = (byte)(flags & ~((int)Http2FrameFlag.Padded));
// send the header
var buf = frameHeader.CopyToBuffer();
await output.WriteAsync(buf, 0, buf.Length/*, cancellationToken*/);
await output.WriteAsync(data, 0, data.Length /*, cancellationToken*/);
}
private static async Task sendBody(Http2Settings settings, RequestResponseBase rr, Http2FrameHeader frameHeader, byte[] buffer, Stream output)
{
var body = rr.CompressBodyAndUpdateContentLength();
await sendHeader(settings, frameHeader, rr, !(rr.HasBody && rr.IsBodyRead), output, false);
if (rr.HasBody && rr.IsBodyRead)
{
int pos = 0;
while (pos < body.Length)
{
int bodyFrameLength = Math.Min(buffer.Length, body.Length - pos);
Buffer.BlockCopy(body, pos, buffer, 0, bodyFrameLength);
pos += bodyFrameLength;
frameHeader.Length = bodyFrameLength;
frameHeader.Type = Http2FrameType.Data;
frameHeader.Flags = pos < body.Length ? (Http2FrameFlag)0 : Http2FrameFlag.EndStream;
var buf = frameHeader.CopyToBuffer();
await output.WriteAsync(buf, 0, buf.Length/*, cancellationToken*/);
await output.WriteAsync(buffer, 0, bodyFrameLength /*, cancellationToken*/);
}
}
else
{
;
}
}
private static async Task<int> forceRead(Stream input, byte[] buffer, int offset, int bytesToRead,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
int totalRead = 0; int totalRead = 0;
while (bytesToRead > 0) while (bytesToRead > 0)
{ {
int read = await input.ReadAsync(buffer, offset, bytesToRead, cancellationToken); int read = await input.ReadAsync(buffer, offset, bytesToRead, cancellationToken);
if (read == -1) if (read == 0)
{ {
break; break;
} }
...@@ -151,13 +537,71 @@ namespace Titanium.Web.Proxy.Http2 ...@@ -151,13 +537,71 @@ namespace Titanium.Web.Proxy.Http2
return totalRead; return totalRead;
} }
class Http2Settings
{
public int HeaderTableSize { get; set; } = 4096;
public int MaxFrameSize { get; set; } = 16384;
}
class MyHeaderListener : IHeaderListener class MyHeaderListener : IHeaderListener
{ {
private readonly Action<string, string> addHeaderFunc;
public string Method { get; private set; }
public string Status { get; private set; }
private string authority;
private string scheme;
public string Path { get; private set; }
public MyHeaderListener(Action<string, string> addHeaderFunc)
{
this.addHeaderFunc = addHeaderFunc;
}
public void AddHeader(string name, string value, bool sensitive) public void AddHeader(string name, string value, bool sensitive)
{ {
Console.WriteLine(name + ": " + value + " " + sensitive); if (name[0] == ':')
{
switch (name)
{
case ":method":
Method = value;
return;
case ":authority":
authority = value;
return;
case ":scheme":
scheme = value;
return;
case ":path":
Path = value;
return;
case ":status":
Status = value;
return;
}
}
addHeaderFunc(name, value);
}
public Uri GetUri()
{
if (authority == null)
{
// todo
authority = "abc.abc";
}
return new Uri(scheme + "://" + authority + Path);
} }
} }
} }
} }
#endif #endif
\ No newline at end of file
...@@ -31,7 +31,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -31,7 +31,7 @@ namespace Titanium.Web.Proxy.Models
/// Intercept tunnel connect request. /// Intercept tunnel connect request.
/// Valid only for explicit endpoints. /// Valid only for explicit endpoints.
/// Set the <see cref="TunnelConnectSessionEventArgs.DecryptSsl" /> property to false if this HTTP connect request /// Set the <see cref="TunnelConnectSessionEventArgs.DecryptSsl" /> property to false if this HTTP connect request
/// should'nt be decrypted and instead be relayed. /// shouldn't be decrypted and instead be relayed.
/// </summary> /// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectRequest; public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectRequest;
...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Models
} }
} }
internal async Task InvokeBeforeTunnectConnectResponse(ProxyServer proxyServer, internal async Task InvokeBeforeTunnelConnectResponse(ProxyServer proxyServer,
TunnelConnectSessionEventArgs connectArgs, ExceptionHandler exceptionFunc, bool isClientHello = false) TunnelConnectSessionEventArgs connectArgs, ExceptionHandler exceptionFunc, bool isClientHello = false)
{ {
if (BeforeTunnelConnectResponse != null) if (BeforeTunnelConnectResponse != null)
......
...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Models
public int Port { get; set; } public int Port { get; set; }
/// <summary> /// <summary>
/// Get cache key for Tcp connection cahe. /// Get cache key for Tcp connection cache.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal string GetCacheKey() internal string GetCacheKey()
......
...@@ -35,17 +35,24 @@ namespace Titanium.Web.Proxy.Models ...@@ -35,17 +35,24 @@ namespace Titanium.Web.Proxy.Models
{ {
if (string.IsNullOrEmpty(name)) if (string.IsNullOrEmpty(name))
{ {
throw new Exception("Name cannot be null"); throw new Exception("Name cannot be null or empty");
} }
Name = name.Trim(); Name = name.Trim();
Value = value.Trim(); Value = value.Trim();
} }
protected HttpHeader(string name, string value, bool headerEntry)
{
// special header entry created in inherited class with empty name
Name = name.Trim();
Value = value.Trim();
}
/// <summary> /// <summary>
/// Header Name. /// Header Name.
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; }
/// <summary> /// <summary>
/// Header Value. /// Header Value.
......
...@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary> /// <summary>
/// A list of pending certificate creation tasks. /// A list of pending certificate creation tasks.
/// Usefull to prevent multiple threads working on same certificate generation /// Useful to prevent multiple threads working on same certificate generation
/// when burst certificate generation requests happen for same certificate. /// when burst certificate generation requests happen for same certificate.
/// </summary> /// </summary>
private readonly ConcurrentDictionary<string, Task<X509Certificate2>> pendingCertificateCreationTasks private readonly ConcurrentDictionary<string, Task<X509Certificate2>> pendingCertificateCreationTasks
......
...@@ -7,6 +7,8 @@ using System.Net.Security; ...@@ -7,6 +7,8 @@ using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Network.Tcp namespace Titanium.Web.Proxy.Network.Tcp
{ {
...@@ -34,11 +36,42 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -34,11 +36,42 @@ namespace Titanium.Web.Proxy.Network.Tcp
private readonly TcpClient tcpClient; private readonly TcpClient tcpClient;
private int? processId;
public Stream GetStream() public Stream GetStream()
{ {
return tcpClient.GetStream(); return tcpClient.GetStream();
} }
public int GetProcessId(ProxyEndPoint endPoint)
{
if (processId.HasValue)
{
return processId.Value;
}
if (RunTime.IsWindows)
{
var remoteEndPoint = (IPEndPoint)RemoteEndPoint;
// If client is localhost get the process id
if (NetworkHelper.IsLocalIpAddress(remoteEndPoint.Address))
{
var ipVersion = endPoint.IpV6Enabled ? IpVersion.Ipv6 : IpVersion.Ipv4;
processId = TcpHelper.GetProcessIdByLocalPort(ipVersion, remoteEndPoint.Port);
}
else
{
// can't access process Id of remote request from remote machine
processId = -1;
}
return processId.Value;
}
throw new PlatformNotSupportedException();
}
/// <summary> /// <summary>
/// Dispose. /// Dispose.
/// </summary> /// </summary>
......
...@@ -38,11 +38,11 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -38,11 +38,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal TcpConnectionFactory(ProxyServer server) internal TcpConnectionFactory(ProxyServer server)
{ {
this.server = server; this.Server = server;
Task.Run(async () => await clearOutdatedConnections()); Task.Run(async () => await clearOutdatedConnections());
} }
internal ProxyServer server { get; set; } internal ProxyServer Server { get; }
internal string GetConnectionCacheKey(string remoteHostName, int remotePort, internal string GetConnectionCacheKey(string remoteHostName, int remotePort,
bool isHttps, List<SslApplicationProtocol> applicationProtocols, bool isHttps, List<SslApplicationProtocol> applicationProtocols,
...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
//http version is ignored since its an application level decision b/w HTTP 1.0/1.1 //http version is ignored since its an application level decision b/w HTTP 1.0/1.1
//also when doing connect request MS Edge browser sends http 1.0 but uses 1.1 after server sends 1.1 its response. //also when doing connect request MS Edge browser sends http 1.0 but uses 1.1 after server sends 1.1 its response.
//That can create cache miss for same server connection unneccessarily expecially when prefetcing with Connect. //That can create cache miss for same server connection unnecessarily especially when prefetching with Connect.
//http version 2 is separated using applicationProtocols below. //http version 2 is separated using applicationProtocols below.
var cacheKeyBuilder = new StringBuilder($"{remoteHostName}-{remotePort}-" + var cacheKeyBuilder = new StringBuilder($"{remoteHostName}-{remotePort}-" +
//when creating Tcp client isConnect won't matter //when creating Tcp client isConnect won't matter
...@@ -232,7 +232,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -232,7 +232,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
//deny connection to proxy end points to avoid infinite connection loop. //deny connection to proxy end points to avoid infinite connection loop.
if (server.ProxyEndPoints.Any(x => x.Port == remotePort) if (Server.ProxyEndPoints.Any(x => x.Port == remotePort)
&& NetworkHelper.IsLocalIpAddress(remoteHostName)) && NetworkHelper.IsLocalIpAddress(remoteHostName))
{ {
throw new Exception($"A client is making HTTP request to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); throw new Exception($"A client is making HTTP request to one of the listening ports of this proxy {remoteHostName}:{remotePort}");
...@@ -240,7 +240,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -240,7 +240,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (externalProxy != null) if (externalProxy != null)
{ {
if (server.ProxyEndPoints.Any(x => x.Port == externalProxy.Port) if (Server.ProxyEndPoints.Any(x => x.Port == externalProxy.Port)
&& NetworkHelper.IsLocalIpAddress(externalProxy.HostName)) && NetworkHelper.IsLocalIpAddress(externalProxy.HostName))
{ {
throw new Exception($"A client is making HTTP request via external proxy to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); throw new Exception($"A client is making HTTP request via external proxy to one of the listening ports of this proxy {remoteHostName}:{remotePort}");
...@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
tcpClient = new TcpClient(upStreamEndPoint) tcpClient = new TcpClient(upStreamEndPoint)
{ {
NoDelay = proxyServer.NoDelay, NoDelay = proxyServer.NoDelay,
ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000,
SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000,
LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds) LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds)
...@@ -416,7 +416,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -416,7 +416,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
return; return;
} }
if (close || connection.IsWinAuthenticated || !server.EnableConnectionPool) if (close || connection.IsWinAuthenticated || !Server.EnableConnectionPool || connection.IsClosed)
{ {
disposalBag.Add(connection); disposalBag.Add(connection);
return; return;
...@@ -432,7 +432,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -432,7 +432,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
if (cache.TryGetValue(connection.CacheKey, out var existingConnections)) if (cache.TryGetValue(connection.CacheKey, out var existingConnections))
{ {
while (existingConnections.Count >= server.MaxCachedConnections) while (existingConnections.Count >= Server.MaxCachedConnections)
{ {
if (existingConnections.TryDequeue(out var staleConnection)) if (existingConnections.TryDequeue(out var staleConnection))
{ {
...@@ -489,8 +489,8 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -489,8 +489,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
if (queue.TryDequeue(out var connection)) if (queue.TryDequeue(out var connection))
{ {
var cutOff = DateTime.Now.AddSeconds(-1 * server.ConnectionTimeOutSeconds); var cutOff = DateTime.Now.AddSeconds(-1 * Server.ConnectionTimeOutSeconds);
if (!server.EnableConnectionPool if (!Server.EnableConnectionPool
|| connection.LastAccess < cutOff) || connection.LastAccess < cutOff)
{ {
disposalBag.Add(connection); disposalBag.Add(connection);
...@@ -530,7 +530,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -530,7 +530,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
} }
catch (Exception e) catch (Exception e)
{ {
server.ExceptionFunc(new Exception("An error occurred when disposing server connections.", e)); Server.ExceptionFunc(new Exception("An error occurred when disposing server connections.", e));
} }
finally finally
{ {
......
...@@ -27,6 +27,8 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -27,6 +27,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
private ProxyServer proxyServer { get; } private ProxyServer proxyServer { get; }
internal bool IsClosed => Stream.IsClosed;
internal ExternalProxy UpStreamProxy { get; set; } internal ExternalProxy UpStreamProxy { get; set; }
internal string HostName { get; set; } internal string HostName { get; set; }
......
// //
// Mono.Security.BitConverterLE.cs // Mono.Security.BitConverterLE.cs
// Like System.BitConverter but always little endian // Like System.BitConverter but always little endian
// //
......
...@@ -144,9 +144,17 @@ namespace Titanium.Web.Proxy ...@@ -144,9 +144,17 @@ namespace Titanium.Web.Proxy
/// Defaults to false. /// Defaults to false.
/// </summary> /// </summary>
public bool EnableWinAuth { get; set; } public bool EnableWinAuth { get; set; }
/// <summary>
/// Enable disable HTTP/2 support.
/// Warning: HTTP/2 support is very limited
/// - only enabled when both client and server supports it (no protocol changing in proxy)
/// - cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored)
/// </summary>
public bool EnableHttp2 { get; set; } = false;
/// <summary> /// <summary>
/// Should we check for certificare revocation during SSL authentication to servers /// Should we check for certificate revocation during SSL authentication to servers
/// Note: If enabled can reduce performance. Defaults to false. /// Note: If enabled can reduce performance. Defaults to false.
/// </summary> /// </summary>
public X509RevocationMode CheckCertificateRevocation { get; set; } public X509RevocationMode CheckCertificateRevocation { get; set; }
...@@ -169,7 +177,7 @@ namespace Titanium.Web.Proxy ...@@ -169,7 +177,7 @@ namespace Titanium.Web.Proxy
/// When enabled, as soon as we receive a client connection we concurrently initiate /// When enabled, as soon as we receive a client connection we concurrently initiate
/// corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request /// corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request
/// we will have the server connection immediately ready or in the process of getting ready. /// we will have the server connection immediately ready or in the process of getting ready.
/// If a server connection is available in cache then this prefetch task will immediatly return with the available connection from cache. /// If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache.
/// Defaults to true. /// Defaults to true.
/// </summary> /// </summary>
public bool EnableTcpServerConnectionPrefetch { get; set; } = true; public bool EnableTcpServerConnectionPrefetch { get; set; } = true;
...@@ -380,7 +388,7 @@ namespace Titanium.Web.Proxy ...@@ -380,7 +388,7 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Remove a proxy end point. /// Remove a proxy end point.
/// Will throw error if the end point does'nt exist. /// Will throw error if the end point doesn't exist.
/// </summary> /// </summary>
/// <param name="endPoint">The existing endpoint to remove.</param> /// <param name="endPoint">The existing endpoint to remove.</param>
public void RemoveEndPoint(ProxyEndPoint endPoint) public void RemoveEndPoint(ProxyEndPoint endPoint)
...@@ -743,13 +751,11 @@ namespace Titanium.Web.Proxy ...@@ -743,13 +751,11 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Change the ThreadPool.WorkerThread minThread /// Change the ThreadPool.WorkerThread minThread
/// </summary> /// </summary>
/// <param name="workerThreadsToAdd">minimum Threads allocated in the ThreadPool</param> /// <param name="workerThreads">minimum Threads allocated in the ThreadPool</param>
private void setThreadPoolMinThread(int workerThreads) private void setThreadPoolMinThread(int workerThreads)
{ {
int minWorkerThreads, minCompletionPortThreads, maxWorkerThreads; ThreadPool.GetMinThreads(out int minWorkerThreads, out int minCompletionPortThreads);
ThreadPool.GetMaxThreads(out int maxWorkerThreads, out _);
ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
ThreadPool.GetMaxThreads(out maxWorkerThreads, out _);
minWorkerThreads = Math.Min(maxWorkerThreads, Math.Max(workerThreads, Environment.ProcessorCount)); minWorkerThreads = Math.Min(maxWorkerThreads, Math.Max(workerThreads, Environment.ProcessorCount));
......
...@@ -44,7 +44,7 @@ namespace Titanium.Web.Proxy ...@@ -44,7 +44,7 @@ namespace Titanium.Web.Proxy
/// The https hostname as appeared in CONNECT request if this is a HTTPS request from /// The https hostname as appeared in CONNECT request if this is a HTTPS request from
/// explicit endpoint. /// explicit endpoint.
/// </param> /// </param>
/// <param name="connectRequest">The Connect request if this is a HTTPS request from explicit endpoint.</param> /// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param>
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param> /// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection, private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter, CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
...@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy ...@@ -61,7 +61,7 @@ namespace Titanium.Web.Proxy
{ {
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
// Loop through each subsequest request on this particular client connection // Loop through each subsequent request on this particular client connection
// (assuming HTTP connection is kept alive by client) // (assuming HTTP connection is kept alive by client)
while (true) while (true)
{ {
...@@ -312,6 +312,8 @@ namespace Titanium.Web.Proxy ...@@ -312,6 +312,8 @@ namespace Titanium.Web.Proxy
if (args.HttpClient.Request.UpgradeToWebSocket) if (args.HttpClient.Request.UpgradeToWebSocket)
{ {
args.HttpClient.ConnectRequest.TunnelType = TunnelType.Websocket;
// if upgrading to websocket then relay the request without reading the contents // if upgrading to websocket then relay the request without reading the contents
await handleWebSocketUpgrade(httpCmd, args, args.HttpClient.Request, await handleWebSocketUpgrade(httpCmd, args, args.HttpClient.Request,
args.HttpClient.Response, args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamWriter, args.HttpClient.Response, args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamWriter,
...@@ -373,7 +375,7 @@ namespace Titanium.Web.Proxy ...@@ -373,7 +375,7 @@ namespace Titanium.Web.Proxy
} }
/// <summary> /// <summary>
/// Prepare the request headers so that we can avoid encodings not parsable by this proxy /// Prepare the request headers so that we can avoid encodings not parseable by this proxy
/// </summary> /// </summary>
private void prepareRequestHeaders(HeaderCollection requestHeaders) private void prepareRequestHeaders(HeaderCollection requestHeaders)
{ {
......
...@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy ...@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy
public partial class ProxyServer public partial class ProxyServer
{ {
/// <summary> /// <summary>
/// Called asynchronously when a request was successfull and we received the response. /// Called asynchronously when a request was successful and we received the response.
/// </summary> /// </summary>
/// <param name="args">The session event arguments.</param> /// <param name="args">The session event arguments.</param>
/// <returns> The task.</returns> /// <returns> The task.</returns>
...@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy ...@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy
// clear current response // clear current response
await args.ClearResponse(cancellationToken); await args.ClearResponse(cancellationToken);
var httpCmd = Request.CreateRequestLine(args.HttpClient.Request.Method, var httpCmd = Request.CreateRequestLine(args.HttpClient.Request.Method,
args.HttpClient.Request.OriginalUrl, args.HttpClient.Request.HttpVersion); args.HttpClient.Request.RequestUriString, args.HttpClient.Request.HttpVersion);
await handleHttpSessionRequest(httpCmd, args, null, args.ClientConnection.NegotiatedApplicationProtocol, await handleHttpSessionRequest(httpCmd, args, null, args.ClientConnection.NegotiatedApplicationProtocol,
cancellationToken, args.CancellationTokenSource); cancellationToken, args.CancellationTokenSource);
return; return;
...@@ -125,7 +125,6 @@ namespace Titanium.Web.Proxy ...@@ -125,7 +125,6 @@ namespace Titanium.Web.Proxy
} }
args.TimeLine["Response Sent"] = DateTime.Now; args.TimeLine["Response Sent"] = DateTime.Now;
} }
/// <summary> /// <summary>
......
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BrotliSharpLib" Version="0.3.1" /> <PackageReference Include="BrotliSharpLib" Version="0.3.3" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.3" /> <PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="StreamExtended" Version="1.0.188-beta" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StreamExtended\StreamExtended.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'"> <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Web" /> <Reference Include="System.Web" />
......
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BrotliSharpLib" Version="0.3.1" /> <PackageReference Include="BrotliSharpLib" Version="0.3.3" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.3" /> <PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="StreamExtended" Version="1.0.188-beta" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
...@@ -35,6 +34,10 @@ ...@@ -35,6 +34,10 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StreamExtended\StreamExtended.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'"> <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Web" /> <Reference Include="System.Web" />
</ItemGroup> </ItemGroup>
......
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks> <TargetFrameworks>net45;netstandard2.0;netcoreapp2.1</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace> <RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly> <SignAssembly>True</SignAssembly>
...@@ -15,24 +15,23 @@ ...@@ -15,24 +15,23 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="BrotliSharpLib" Version="0.3.3" /> <PackageReference Include="BrotliSharpLib" Version="0.3.3" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.5" /> <PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="StreamExtended" Version="1.0.201" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Win32.Registry"> <PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version> <Version>4.5.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="System.Security.Principal.Windows"> <PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version> <Version>4.5.1</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'"> <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Win32.Registry"> <PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version> <Version>4.5.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="System.Security.Principal.Windows"> <PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version> <Version>4.5.1</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
...@@ -40,6 +39,10 @@ ...@@ -40,6 +39,10 @@
<Reference Include="System.Web" /> <Reference Include="System.Web" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StreamExtended\StreamExtended.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Network\WinAuth\Security\Common.cs"> <Compile Update="Network\WinAuth\Security\Common.cs">
<ExcludeFromSourceAnalysis>True</ExcludeFromSourceAnalysis> <ExcludeFromSourceAnalysis>True</ExcludeFromSourceAnalysis>
......
...@@ -15,16 +15,20 @@ ...@@ -15,16 +15,20 @@
<tags></tags> <tags></tags>
<dependencies> <dependencies>
<group targetFramework="net45"> <group targetFramework="net45">
<dependency id="StreamExtended" version="1.0.201" />
<dependency id="Portable.BouncyCastle" version="1.8.5" /> <dependency id="Portable.BouncyCastle" version="1.8.5" />
<dependency id="BrotliSharpLib" version="0.3.3" /> <dependency id="BrotliSharpLib" version="0.3.3" />
</group> </group>
<group targetFramework="netstandard2.0"> <group targetFramework="netstandard2.0">
<dependency id="StreamExtended" version="1.0.201" />
<dependency id="Portable.BouncyCastle" version="1.8.5" /> <dependency id="Portable.BouncyCastle" version="1.8.5" />
<dependency id="BrotliSharpLib" version="0.3.3" /> <dependency id="BrotliSharpLib" version="0.3.3" />
<dependency id="Microsoft.Win32.Registry" version="4.4.0" /> <dependency id="Microsoft.Win32.Registry" version="4.5.0" />
<dependency id="System.Security.Principal.Windows" version="4.4.1" /> <dependency id="System.Security.Principal.Windows" version="4.5.1" />
</group>
<group targetFramework="netcoreapp2.1">
<dependency id="Portable.BouncyCastle" version="1.8.5" />
<dependency id="BrotliSharpLib" version="0.3.3" />
<dependency id="Microsoft.Win32.Registry" version="4.5.0" />
<dependency id="System.Security.Principal.Windows" version="4.5.1" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>
......
...@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy ...@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy
var data = BufferPool.GetBuffer(BufferSize); var data = BufferPool.GetBuffer(BufferSize);
try try
{ {
// clientStream.Available sbould be at most BufferSize because it is using the same buffer size // clientStream.Available should be at most BufferSize because it is using the same buffer size
await clientStream.ReadAsync(data, 0, available, cancellationToken); await clientStream.ReadAsync(data, 0, available, cancellationToken);
serverStream = connection.Stream; serverStream = connection.Stream;
await serverStream.WriteAsync(data, 0, available, cancellationToken); await serverStream.WriteAsync(data, 0, available, cancellationToken);
......
...@@ -150,7 +150,7 @@ namespace Titanium.Web.Proxy ...@@ -150,7 +150,7 @@ namespace Titanium.Web.Proxy
} }
// Need to revisit this. // Need to revisit this.
// Should we cache all Set-Cokiee headers from server during auth process // Should we cache all Set-Cookie headers from server during auth process
// and send it to client after auth? // and send it to client after auth?
// Let ResponseHandler send the updated request // Let ResponseHandler send the updated request
......
...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers ...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers
var request = new Request var request = new Request
{ {
Method = "POST", Method = "POST",
OriginalUrl = "/", RequestUriString = "/",
HttpVersion = new Version(1, 1) HttpVersion = new Version(1, 1)
}; };
request.Headers.AddHeader(KnownHeaders.Host, server); request.Headers.AddHeader(KnownHeaders.Host, server);
......
...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers ...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers
RequestResponseBase request = new Request() RequestResponseBase request = new Request()
{ {
Method = method, Method = method,
OriginalUrl = url, RequestUriString = url,
HttpVersion = version HttpVersion = version
}; };
while (!string.IsNullOrEmpty(line = reader.ReadLine())) while (!string.IsNullOrEmpty(line = reader.ReadLine()))
...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers ...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers
if (!requireBody) if (!requireBody)
return request as Request; return request as Request;
if (ParseBody(reader, ref request)) if (parseBody(reader, ref request))
return request as Request; return request as Request;
} }
catch { } catch { }
...@@ -84,7 +84,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers ...@@ -84,7 +84,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers
if (line?.Length != 0) if (line?.Length != 0)
return null; return null;
if (ParseBody(reader, ref response)) if (parseBody(reader, ref response))
return response as Response; return response as Response;
} }
catch { } catch { }
...@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers ...@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy.IntegrationTests.Helpers
return null; return null;
} }
private static bool ParseBody(StringReader reader, ref RequestResponseBase obj) private static bool parseBody(StringReader reader, ref RequestResponseBase obj)
{ {
obj.OriginalContentLength = obj.ContentLength; obj.OriginalContentLength = obj.ContentLength;
if (obj.ContentLength <= 0) if (obj.ContentLength <= 0)
......
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp2.2</TargetFramework>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" /> <PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" /> <PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
</ItemGroup> </ItemGroup>
......
...@@ -11,22 +11,22 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -11,22 +11,22 @@ namespace Titanium.Web.Proxy.UnitTests
public class SystemProxyTest public class SystemProxyTest
{ {
[TestMethod] [TestMethod]
public void CompareProxyAdddressReturendByWebProxyAndWinHttpProxyResolver() public void CompareProxyAddressReturnedByWebProxyAndWinHttpProxyResolver()
{ {
var proxyManager = new SystemProxyManager(); var proxyManager = new SystemProxyManager();
try try
{ {
CompareUrls(); compareUrls();
proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.Http); proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.Http);
CompareUrls(); compareUrls();
proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.Https); proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.Https);
CompareUrls(); compareUrls();
proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.AllHttp); proxyManager.SetProxy("127.0.0.1", 8000, ProxyProtocolType.AllHttp);
CompareUrls(); compareUrls();
// for this test you need to add a proxy.pac file to a local webserver // for this test you need to add a proxy.pac file to a local webserver
//function FindProxyForURL(url, host) //function FindProxyForURL(url, host)
...@@ -43,25 +43,25 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -43,25 +43,25 @@ namespace Titanium.Web.Proxy.UnitTests
//CompareUrls(); //CompareUrls();
proxyManager.SetProxyOverride("<-loopback>"); proxyManager.SetProxyOverride("<-loopback>");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("<local>"); proxyManager.SetProxyOverride("<local>");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("yahoo.com"); proxyManager.SetProxyOverride("yahoo.com");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("*.local"); proxyManager.SetProxyOverride("*.local");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("http://*.local"); proxyManager.SetProxyOverride("http://*.local");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("<-loopback>;*.local"); proxyManager.SetProxyOverride("<-loopback>;*.local");
CompareUrls(); compareUrls();
proxyManager.SetProxyOverride("<-loopback>;*.local;<local>"); proxyManager.SetProxyOverride("<-loopback>;*.local;<local>");
CompareUrls(); compareUrls();
} }
finally finally
{ {
...@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.UnitTests
} }
} }
private void CompareUrls() private void compareUrls()
{ {
var webProxy = WebRequest.GetSystemWebProxy(); var webProxy = WebRequest.GetSystemWebProxy();
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" /> <PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" /> <PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
</ItemGroup> </ItemGroup>
......
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