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

Commit 4f3240e

Browse files
authored
Merge pull request #369 from justcoding121/develop
beta | develop
2 parents f560e29 + 5e8daf5 commit 4f3240e

File tree

13 files changed

+172
-116
lines changed

13 files changed

+172
-116
lines changed

Titanium.Web.Proxy/Extensions/StringExtensions.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
using System.Globalization;
1+
using System;
2+
using System.Globalization;
23

34
namespace Titanium.Web.Proxy.Extensions
45
{
56
internal static class StringExtensions
67
{
8+
internal static bool EqualsIgnoreCase(this string str, string value)
9+
{
10+
return str.Equals(value, StringComparison.CurrentCultureIgnoreCase);
11+
}
12+
713
internal static bool ContainsIgnoreCase(this string str, string value)
814
{
915
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(str, value, CompareOptions.IgnoreCase) >= 0;

Titanium.Web.Proxy/Helpers/HttpHelper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Text;
3+
using Titanium.Web.Proxy.Extensions;
34
using Titanium.Web.Proxy.Http;
45
using Titanium.Web.Proxy.Shared;
56

@@ -29,7 +30,7 @@ internal static Encoding GetEncodingFromContentType(string contentType)
2930
foreach (string parameter in parameters)
3031
{
3132
var split = parameter.Split(ProxyConstants.EqualSplit, 2);
32-
if (split.Length == 2 && split[0].Trim().Equals(KnownHeaders.ContentTypeCharset, StringComparison.CurrentCultureIgnoreCase))
33+
if (split.Length == 2 && split[0].Trim().EqualsIgnoreCase(KnownHeaders.ContentTypeCharset))
3334
{
3435
string value = split[1];
3536
if (value.Equals("x-user-defined", StringComparison.OrdinalIgnoreCase))
@@ -66,7 +67,7 @@ internal static string GetBoundaryFromContentType(string contentType)
6667
foreach (string parameter in parameters)
6768
{
6869
var split = parameter.Split(ProxyConstants.EqualSplit, 2);
69-
if (split.Length == 2 && split[0].Trim().Equals(KnownHeaders.ContentTypeBoundary, StringComparison.CurrentCultureIgnoreCase))
70+
if (split.Length == 2 && split[0].Trim().EqualsIgnoreCase(KnownHeaders.ContentTypeBoundary))
7071
{
7172
string value = split[1];
7273
if (value.Length > 2 && value[0] == '"' && value[value.Length - 1] == '"')

Titanium.Web.Proxy/Helpers/Tcp.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ internal static TcpTable GetExtendedTcpTable(IpVersion ipVersion)
3030
int tcpTableLength = 0;
3131

3232
int ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6;
33+
int allPid = (int)NativeMethods.TcpTableType.OwnerPidAll;
3334

34-
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
35+
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, allPid, 0) != 0)
3536
{
3637
try
3738
{
3839
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
39-
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
40+
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, allPid, 0) == 0)
4041
{
4142
var table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
4243

@@ -71,13 +72,14 @@ internal static TcpRow GetTcpRowByLocalPort(IpVersion ipVersion, int localPort)
7172
int tcpTableLength = 0;
7273

7374
int ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6;
75+
int allPid = (int)NativeMethods.TcpTableType.OwnerPidAll;
7476

75-
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
77+
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, allPid, 0) != 0)
7678
{
7779
try
7880
{
7981
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
80-
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
82+
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, allPid, 0) == 0)
8183
{
8284
var table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
8385

@@ -142,7 +144,8 @@ internal static async Task SendRawApm(Stream clientStream, Stream serverStream,
142144
}
143145
}
144146

145-
private static void BeginRead(Stream inputStream, Stream outputStream, byte[] buffer, CancellationTokenSource cts, Action<byte[], int, int> onCopy, Action<Exception> exceptionFunc)
147+
private static void BeginRead(Stream inputStream, Stream outputStream, byte[] buffer, CancellationTokenSource cts, Action<byte[], int, int> onCopy,
148+
Action<Exception> exceptionFunc)
146149
{
147150
if (cts.IsCancellationRequested)
148151
{
@@ -231,5 +234,27 @@ internal static async Task SendRawTap(Stream clientStream, Stream serverStream,
231234

232235
await Task.WhenAll(sendRelay, receiveRelay);
233236
}
237+
238+
/// <summary>
239+
/// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers as prefix
240+
/// Usefull for websocket requests
241+
/// </summary>
242+
/// <param name="clientStream"></param>
243+
/// <param name="serverStream"></param>
244+
/// <param name="bufferSize"></param>
245+
/// <param name="onDataSend"></param>
246+
/// <param name="onDataReceive"></param>
247+
/// <param name="exceptionFunc"></param>
248+
/// <returns></returns>
249+
internal static Task SendRaw(Stream clientStream, Stream serverStream, int bufferSize,
250+
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive, Action<Exception> exceptionFunc)
251+
{
252+
#if NET45
253+
return SendRawApm(clientStream, serverStream, bufferSize, onDataSend, onDataReceive, exceptionFunc);
254+
#else
255+
// todo: Apm hangs in dotnet core
256+
return SendRawTap(clientStream, serverStream, bufferSize, onDataSend, onDataReceive, exceptionFunc);
257+
#endif
258+
}
234259
}
235260
}

Titanium.Web.Proxy/Http/HeaderCollection.cs

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
45
using System.ComponentModel;
56
using System.Linq;
67
using Titanium.Web.Proxy.Models;
@@ -10,23 +11,29 @@ namespace Titanium.Web.Proxy.Http
1011
[TypeConverter(typeof(ExpandableObjectConverter))]
1112
public class HeaderCollection : IEnumerable<HttpHeader>
1213
{
14+
private readonly Dictionary<string, HttpHeader> headers;
15+
16+
private readonly Dictionary<string, List<HttpHeader>> nonUniqueHeaders;
17+
1318
/// <summary>
1419
/// Unique Request header collection
1520
/// </summary>
16-
public Dictionary<string, HttpHeader> Headers { get; }
21+
public ReadOnlyDictionary<string, HttpHeader> Headers { get; }
1722

1823
/// <summary>
1924
/// Non Unique headers
2025
/// </summary>
21-
public Dictionary<string, List<HttpHeader>> NonUniqueHeaders { get; }
26+
public ReadOnlyDictionary<string, List<HttpHeader>> NonUniqueHeaders { get; }
2227

2328
/// <summary>
2429
/// Initializes a new instance of the <see cref="HeaderCollection"/> class.
2530
/// </summary>
2631
public HeaderCollection()
2732
{
28-
Headers = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
29-
NonUniqueHeaders = new Dictionary<string, List<HttpHeader>>(StringComparer.OrdinalIgnoreCase);
33+
headers = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
34+
nonUniqueHeaders = new Dictionary<string, List<HttpHeader>>(StringComparer.OrdinalIgnoreCase);
35+
Headers = new ReadOnlyDictionary<string, HttpHeader>(headers);
36+
NonUniqueHeaders = new ReadOnlyDictionary<string, List<HttpHeader>>(nonUniqueHeaders);
3037
}
3138

3239
/// <summary>
@@ -36,7 +43,7 @@ public HeaderCollection()
3643
/// <returns></returns>
3744
public bool HeaderExists(string name)
3845
{
39-
return Headers.ContainsKey(name) || NonUniqueHeaders.ContainsKey(name);
46+
return headers.ContainsKey(name) || nonUniqueHeaders.ContainsKey(name);
4047
}
4148

4249
/// <summary>
@@ -47,32 +54,32 @@ public bool HeaderExists(string name)
4754
/// <returns></returns>
4855
public List<HttpHeader> GetHeaders(string name)
4956
{
50-
if (Headers.ContainsKey(name))
57+
if (headers.ContainsKey(name))
5158
{
5259
return new List<HttpHeader>
5360
{
54-
Headers[name]
61+
headers[name]
5562
};
5663
}
5764

58-
if (NonUniqueHeaders.ContainsKey(name))
65+
if (nonUniqueHeaders.ContainsKey(name))
5966
{
60-
return new List<HttpHeader>(NonUniqueHeaders[name]);
67+
return new List<HttpHeader>(nonUniqueHeaders[name]);
6168
}
6269

6370
return null;
6471
}
6572

6673
public HttpHeader GetFirstHeader(string name)
6774
{
68-
if (Headers.TryGetValue(name, out var header))
75+
if (headers.TryGetValue(name, out var header))
6976
{
7077
return header;
7178
}
7279

73-
if (NonUniqueHeaders.TryGetValue(name, out var headers))
80+
if (nonUniqueHeaders.TryGetValue(name, out var h))
7481
{
75-
return headers.FirstOrDefault();
82+
return h.FirstOrDefault();
7683
}
7784

7885
return null;
@@ -86,8 +93,8 @@ public List<HttpHeader> GetAllHeaders()
8693
{
8794
var result = new List<HttpHeader>();
8895

89-
result.AddRange(Headers.Select(x => x.Value));
90-
result.AddRange(NonUniqueHeaders.SelectMany(x => x.Value));
96+
result.AddRange(headers.Select(x => x.Value));
97+
result.AddRange(nonUniqueHeaders.SelectMany(x => x.Value));
9198

9299
return result;
93100
}
@@ -108,26 +115,29 @@ public void AddHeader(string name, string value)
108115
/// <param name="newHeader"></param>
109116
public void AddHeader(HttpHeader newHeader)
110117
{
111-
if (NonUniqueHeaders.ContainsKey(newHeader.Name))
118+
// if header exist in non-unique header collection add it there
119+
if (nonUniqueHeaders.ContainsKey(newHeader.Name))
112120
{
113-
NonUniqueHeaders[newHeader.Name].Add(newHeader);
121+
nonUniqueHeaders[newHeader.Name].Add(newHeader);
114122
return;
115123
}
116124

117-
if (Headers.ContainsKey(newHeader.Name))
125+
// if header is already in unique header collection then move both to non-unique collection
126+
if (headers.ContainsKey(newHeader.Name))
118127
{
119-
var existing = Headers[newHeader.Name];
120-
Headers.Remove(newHeader.Name);
128+
var existing = headers[newHeader.Name];
129+
headers.Remove(newHeader.Name);
121130

122-
NonUniqueHeaders.Add(newHeader.Name, new List<HttpHeader>
131+
nonUniqueHeaders.Add(newHeader.Name, new List<HttpHeader>
123132
{
124133
existing,
125134
newHeader
126135
});
127136
}
128137
else
129138
{
130-
Headers.Add(newHeader.Name, newHeader);
139+
// add to unique header collection
140+
headers.Add(newHeader.Name, newHeader);
131141
}
132142
}
133143

@@ -195,10 +205,10 @@ public void AddHeaders(IEnumerable<KeyValuePair<string, HttpHeader>> newHeaders)
195205
/// False if no header exists with given name</returns>
196206
public bool RemoveHeader(string headerName)
197207
{
198-
bool result = Headers.Remove(headerName);
208+
bool result = headers.Remove(headerName);
199209

200210
// do not convert to '||' expression to avoid lazy evaluation
201-
if (NonUniqueHeaders.Remove(headerName))
211+
if (nonUniqueHeaders.Remove(headerName))
202212
{
203213
result = true;
204214
}
@@ -212,17 +222,17 @@ public bool RemoveHeader(string headerName)
212222
/// <param name="header">Returns true if header exists and was removed </param>
213223
public bool RemoveHeader(HttpHeader header)
214224
{
215-
if (Headers.ContainsKey(header.Name))
225+
if (headers.ContainsKey(header.Name))
216226
{
217-
if (Headers[header.Name].Equals(header))
227+
if (headers[header.Name].Equals(header))
218228
{
219-
Headers.Remove(header.Name);
229+
headers.Remove(header.Name);
220230
return true;
221231
}
222232
}
223-
else if (NonUniqueHeaders.ContainsKey(header.Name))
233+
else if (nonUniqueHeaders.ContainsKey(header.Name))
224234
{
225-
if (NonUniqueHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
235+
if (nonUniqueHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
226236
{
227237
return true;
228238
}
@@ -236,13 +246,13 @@ public bool RemoveHeader(HttpHeader header)
236246
/// </summary>
237247
public void Clear()
238248
{
239-
Headers.Clear();
240-
NonUniqueHeaders.Clear();
249+
headers.Clear();
250+
nonUniqueHeaders.Clear();
241251
}
242252

243253
internal string GetHeaderValueOrNull(string headerName)
244254
{
245-
if (Headers.TryGetValue(headerName, out var header))
255+
if (headers.TryGetValue(headerName, out var header))
246256
{
247257
return header.Value;
248258
}
@@ -252,13 +262,13 @@ internal string GetHeaderValueOrNull(string headerName)
252262

253263
internal void SetOrAddHeaderValue(string headerName, string value)
254264
{
255-
if (Headers.TryGetValue(headerName, out var header))
265+
if (headers.TryGetValue(headerName, out var header))
256266
{
257267
header.Value = value;
258268
}
259269
else
260270
{
261-
Headers.Add(headerName, new HttpHeader(headerName, value));
271+
headers.Add(headerName, new HttpHeader(headerName, value));
262272
}
263273
}
264274

@@ -285,7 +295,7 @@ internal void FixProxyHeaders()
285295
/// </returns>
286296
public IEnumerator<HttpHeader> GetEnumerator()
287297
{
288-
return Headers.Values.Concat(NonUniqueHeaders.Values.SelectMany(x => x)).GetEnumerator();
298+
return headers.Values.Concat(nonUniqueHeaders.Values.SelectMany(x => x)).GetEnumerator();
289299
}
290300

291301
IEnumerator IEnumerable.GetEnumerator()

Titanium.Web.Proxy/Http/HeaderParser.cs

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,11 @@ internal static class HeaderParser
1111
{
1212
internal static async Task ReadHeaders(CustomBinaryReader reader, HeaderCollection headerCollection)
1313
{
14-
var nonUniqueResponseHeaders = headerCollection.NonUniqueHeaders;
15-
var headers = headerCollection.Headers;
16-
1714
string tmpLine;
1815
while (!string.IsNullOrEmpty(tmpLine = await reader.ReadLineAsync()))
1916
{
2017
var header = tmpLine.Split(ProxyConstants.ColonSplit, 2);
21-
22-
var newHeader = new HttpHeader(header[0], header[1]);
23-
24-
//if header exist in non-unique header collection add it there
25-
if (nonUniqueResponseHeaders.ContainsKey(newHeader.Name))
26-
{
27-
nonUniqueResponseHeaders[newHeader.Name].Add(newHeader);
28-
}
29-
//if header is already in unique header collection then move both to non-unique collection
30-
else if (headers.ContainsKey(newHeader.Name))
31-
{
32-
var existing = headers[newHeader.Name];
33-
34-
var nonUniqueHeaders = new List<HttpHeader>
35-
{
36-
existing,
37-
newHeader
38-
};
39-
40-
nonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders);
41-
headers.Remove(newHeader.Name);
42-
}
43-
//add to unique header collection
44-
else
45-
{
46-
headers.Add(newHeader.Name, newHeader);
47-
}
18+
headerCollection.AddHeader(header[0], header[1]);
4819
}
4920
}
5021

0 commit comments

Comments
 (0)