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

Commit 9279e79

Browse files
StephaneGrazianojustcoding121
authored andcommitted
Optimisation : Rewrite startsWith with PeekBytesAsync instead of looping on PeekByteAsync
1 parent 6a18615 commit 9279e79

File tree

2 files changed

+18
-30
lines changed

2 files changed

+18
-30
lines changed

src/Titanium.Web.Proxy/ExplicitClientHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
4949
TunnelConnectSessionEventArgs connectArgs = null;
5050

5151
// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
52-
if (await HttpHelper.IsConnectMethod(clientStream) == 1)
52+
if (await HttpHelper.IsConnectMethod(clientStream, cancellationToken) == 1)
5353
{
5454
// read the first line HTTP command
5555
string httpCmd = await clientStream.ReadLineAsync(cancellationToken);

src/Titanium.Web.Proxy/Helpers/HttpHelper.cs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Text;
3+
using System.Text.RegularExpressions;
4+
using System.Threading;
35
using System.Threading.Tasks;
46
using StreamExtended.Network;
57
using Titanium.Web.Proxy.Extensions;
@@ -120,19 +122,19 @@ internal static string GetWildCardDomainName(string hostname)
120122
/// </summary>
121123
/// <param name="clientStreamReader">The client stream reader.</param>
122124
/// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns>
123-
internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader)
125+
internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader, CancellationToken cancellationToken = default(CancellationToken))
124126
{
125-
return startsWith(clientStreamReader, "CONNECT");
127+
return startsWith(clientStreamReader, "CONNECT", cancellationToken);
126128
}
127129

128130
/// <summary>
129131
/// Determines whether is pri method (HTTP/2).
130132
/// </summary>
131133
/// <param name="clientStreamReader">The client stream reader.</param>
132134
/// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns>
133-
internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader)
135+
internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader, CancellationToken cancellationToken = default(CancellationToken))
134136
{
135-
return startsWith(clientStreamReader, "PRI");
137+
return startsWith(clientStreamReader, "PRI", cancellationToken);
136138
}
137139

138140
/// <summary>
@@ -143,37 +145,23 @@ internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader)
143145
/// <returns>
144146
/// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise
145147
/// </returns>
146-
private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, string expectedStart)
148+
private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, string expectedStart, CancellationToken cancellationToken = default(CancellationToken))
147149
{
148-
bool isExpected = true;
150+
int iRet = -1;
149151
int lengthToCheck = 10;
150-
for (int i = 0; i < lengthToCheck; i++)
151-
{
152-
int b = await clientStreamReader.PeekByteAsync(i);
153-
if (b == -1)
154-
{
155-
return -1;
156-
}
157-
158-
if (b == ' ' && i > 2)
159-
{
160-
return isExpected ? 1 : 0;
161-
}
162152

163-
char ch = (char)b;
164-
if (!char.IsLetter(ch))
165-
{
166-
return -1;
167-
}
153+
var vBuffer = await clientStreamReader.PeekBytesAsync(0, lengthToCheck, cancellationToken);
154+
if (vBuffer != null)
155+
{
156+
var httpMethod = defaultEncoding.GetString(vBuffer);
168157

169-
if (i >= expectedStart.Length || ch != expectedStart[i])
170-
{
171-
isExpected = false;
172-
}
158+
if (httpMethod.StartsWith(expectedStart))
159+
iRet = 1;
160+
else if (Regex.Match(httpMethod, @"^[a-z]{3,} ", RegexOptions.IgnoreCase).Success) //valid HTTP requests start by at least 3 letters + space
161+
iRet = 0;
173162
}
174163

175-
// only letters
176-
return isExpected ? 1 : 0;
164+
return iRet;
177165
}
178166
}
179167
}

0 commit comments

Comments
 (0)