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

Commit a007c1c

Browse files
authored
Merge pull request #395 from justcoding121/develop
merge to beta
2 parents 7eb8f29 + ef38da7 commit a007c1c

File tree

11 files changed

+273
-164
lines changed

11 files changed

+273
-164
lines changed

Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,18 @@ public bool ReRequest
107107
/// <summary>
108108
/// Constructor to initialize the proxy
109109
/// </summary>
110-
internal SessionEventArgs(int bufferSize,
111-
ProxyEndPoint endPoint,
112-
ExceptionHandler exceptionFunc)
110+
internal SessionEventArgs(int bufferSize, ProxyEndPoint endPoint, ExceptionHandler exceptionFunc)
111+
: this(bufferSize, endPoint, exceptionFunc, null)
112+
{
113+
}
114+
115+
protected SessionEventArgs(int bufferSize, ProxyEndPoint endPoint, ExceptionHandler exceptionFunc, Request request)
113116
{
114117
this.bufferSize = bufferSize;
115118
this.exceptionFunc = exceptionFunc;
116119

117120
ProxyClient = new ProxyClient();
118-
WebSession = new HttpWebClient(bufferSize);
121+
WebSession = new HttpWebClient(bufferSize, request);
119122
LocalEndPoint = endPoint;
120123

121124
WebSession.ProcessId = new Lazy<int>(() =>
@@ -138,6 +141,21 @@ internal SessionEventArgs(int bufferSize,
138141
});
139142
}
140143

144+
private CustomBufferedStream GetStream(bool isRequest)
145+
{
146+
return isRequest ? ProxyClient.ClientStream : WebSession.ServerConnection.Stream;
147+
}
148+
149+
private CustomBinaryReader GetStreamReader(bool isRequest)
150+
{
151+
return isRequest ? ProxyClient.ClientStreamReader : WebSession.ServerConnection.StreamReader;
152+
}
153+
154+
private HttpWriter GetStreamWriter(bool isRequest)
155+
{
156+
return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : WebSession.ServerConnection.StreamWriter;
157+
}
158+
141159
/// <summary>
142160
/// Read request body content as bytes[] for current session
143161
/// </summary>
@@ -150,7 +168,7 @@ private async Task ReadRequestBodyAsync()
150168
//If not already read (not cached yet)
151169
if (!request.IsBodyRead)
152170
{
153-
var body = await ReadBodyAsync(ProxyClient.ClientStreamReader, true);
171+
var body = await ReadBodyAsync(true);
154172
request.Body = body;
155173

156174
//Now set the flag to true
@@ -165,8 +183,8 @@ private async Task ReadRequestBodyAsync()
165183
/// </summary>
166184
internal async Task ClearResponse()
167185
{
168-
//siphon out the body
169-
await ReadResponseBodyAsync();
186+
//syphon out the response body from server
187+
await SyphonOutBodyAsync(false);
170188
WebSession.Response = new Response();
171189
}
172190

@@ -225,7 +243,7 @@ private async Task ReadResponseBodyAsync()
225243
//If not already read (not cached yet)
226244
if (!response.IsBodyRead)
227245
{
228-
var body = await ReadBodyAsync(WebSession.ServerConnection.StreamReader, false);
246+
var body = await ReadBodyAsync(false);
229247
response.Body = body;
230248

231249
//Now set the flag to true
@@ -235,11 +253,12 @@ private async Task ReadResponseBodyAsync()
235253
}
236254
}
237255

238-
private async Task<byte[]> ReadBodyAsync(CustomBinaryReader reader, bool isRequest)
256+
private async Task<byte[]> ReadBodyAsync(bool isRequest)
239257
{
240258
using (var bodyStream = new MemoryStream())
241259
{
242260
var writer = new HttpWriter(bodyStream, bufferSize);
261+
243262
if (isRequest)
244263
{
245264
await CopyRequestBodyAsync(writer, TransformationMode.Uncompress);
@@ -253,21 +272,35 @@ private async Task<byte[]> ReadBodyAsync(CustomBinaryReader reader, bool isReque
253272
}
254273
}
255274

275+
internal async Task SyphonOutBodyAsync(bool isRequest)
276+
{
277+
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;
278+
if (requestResponse.IsBodyRead || !requestResponse.OriginalHasBody)
279+
{
280+
return;
281+
}
282+
283+
using (var bodyStream = new MemoryStream())
284+
{
285+
var writer = new HttpWriter(bodyStream, bufferSize);
286+
await CopyBodyAsync(isRequest, writer, TransformationMode.None, null);
287+
}
288+
}
289+
256290
/// <summary>
257291
/// This is called when the request is PUT/POST/PATCH to read the body
258292
/// </summary>
259293
/// <returns></returns>
260294
internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation)
261295
{
262-
// End the operation
263296
var request = WebSession.Request;
264-
var reader = ProxyClient.ClientStreamReader;
265297

266298
long contentLength = request.ContentLength;
267299

268300
//send the request body bytes to server
269301
if (contentLength > 0 && hasMulipartEventSubscribers && request.IsMultipartFormData)
270302
{
303+
var reader = GetStreamReader(true);
271304
string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType);
272305

273306
using (var copyStream = new CopyStream(reader, writer, bufferSize))
@@ -294,21 +327,22 @@ internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode t
294327
}
295328
else
296329
{
297-
await CopyBodyAsync(ProxyClient.ClientStream, reader, writer, request, transformation, OnDataSent);
330+
await CopyBodyAsync(true, writer, transformation, OnDataSent);
298331
}
299332
}
300333

301334
internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation)
302335
{
303-
var response = WebSession.Response;
304-
var reader = WebSession.ServerConnection.StreamReader;
305-
306-
await CopyBodyAsync(WebSession.ServerConnection.Stream, reader, writer, response, transformation, OnDataReceived);
336+
await CopyBodyAsync(false, writer, transformation, OnDataReceived);
307337
}
308338

309-
private async Task CopyBodyAsync(CustomBufferedStream stream, CustomBinaryReader reader, HttpWriter writer,
310-
RequestResponseBase requestResponse, TransformationMode transformation, Action<byte[], int, int> onCopy)
339+
private async Task CopyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy)
311340
{
341+
var stream = GetStream(isRequest);
342+
var reader = GetStreamReader(isRequest);
343+
344+
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;
345+
312346
bool isChunked = requestResponse.IsChunked;
313347
long contentLength = requestResponse.ContentLength;
314348
if (transformation == TransformationMode.None)
@@ -440,42 +474,29 @@ public async Task<string> GetRequestBodyAsString()
440474
/// Sets the request body
441475
/// </summary>
442476
/// <param name="body"></param>
443-
public async Task SetRequestBody(byte[] body)
477+
public void SetRequestBody(byte[] body)
444478
{
445479
var request = WebSession.Request;
446480
if (request.Locked)
447481
{
448482
throw new Exception("You cannot call this function after request is made to server.");
449483
}
450484

451-
//syphon out the request body from client before setting the new body
452-
if (!request.IsBodyRead)
453-
{
454-
await ReadRequestBodyAsync();
455-
}
456-
457485
request.Body = body;
458-
request.UpdateContentLength();
459486
}
460487

461488
/// <summary>
462489
/// Sets the body with the specified string
463490
/// </summary>
464491
/// <param name="body"></param>
465-
public async Task SetRequestBodyString(string body)
492+
public void SetRequestBodyString(string body)
466493
{
467494
if (WebSession.Request.Locked)
468495
{
469496
throw new Exception("You cannot call this function after request is made to server.");
470497
}
471498

472-
//syphon out the request body from client before setting the new body
473-
if (!WebSession.Request.IsBodyRead)
474-
{
475-
await ReadRequestBodyAsync();
476-
}
477-
478-
await SetRequestBody(WebSession.Request.Encoding.GetBytes(body));
499+
SetRequestBody(WebSession.Request.Encoding.GetBytes(body));
479500
}
480501

481502
/// <summary>
@@ -510,47 +531,31 @@ public async Task<string> GetResponseBodyAsString()
510531
/// Set the response body bytes
511532
/// </summary>
512533
/// <param name="body"></param>
513-
public async Task SetResponseBody(byte[] body)
534+
public void SetResponseBody(byte[] body)
514535
{
515536
if (!WebSession.Request.Locked)
516537
{
517538
throw new Exception("You cannot call this function before request is made to server.");
518539
}
519540

520541
var response = WebSession.Response;
521-
522-
//syphon out the response body from server before setting the new body
523-
if (response.Body == null)
524-
{
525-
await GetResponseBody();
526-
}
527-
528542
response.Body = body;
529-
530-
//If there is a content length header update it
531-
response.UpdateContentLength();
532543
}
533544

534545
/// <summary>
535546
/// Replace the response body with the specified string
536547
/// </summary>
537548
/// <param name="body"></param>
538-
public async Task SetResponseBodyString(string body)
549+
public void SetResponseBodyString(string body)
539550
{
540551
if (!WebSession.Request.Locked)
541552
{
542553
throw new Exception("You cannot call this function before request is made to server.");
543554
}
544555

545-
//syphon out the response body from server before setting the new body
546-
if (!WebSession.Response.IsBodyRead)
547-
{
548-
await GetResponseBody();
549-
}
550-
551556
var bodyBytes = WebSession.Response.Encoding.GetBytes(body);
552557

553-
await SetResponseBody(bodyBytes);
558+
SetResponseBody(bodyBytes);
554559
}
555560

556561
/// <summary>
@@ -651,17 +656,29 @@ public void Respond(Response response)
651656
{
652657
if (WebSession.Request.Locked)
653658
{
654-
throw new Exception("You cannot call this function after request is made to server.");
655-
}
659+
if (WebSession.Response.Locked)
660+
{
661+
throw new Exception("You cannot call this function after response is sent to the client.");
662+
}
656663

657-
WebSession.Request.Locked = true;
664+
response.Locked = true;
665+
response.TerminateResponse = WebSession.Response.TerminateResponse;
666+
WebSession.Response = response;
667+
}
668+
else
669+
{
670+
WebSession.Request.Locked = true;
658671

659-
response.Locked = true;
660-
response.IsBodyRead = true;
672+
response.Locked = true;
673+
WebSession.Response = response;
661674

662-
WebSession.Response = response;
675+
WebSession.Request.CancelRequest = true;
676+
}
677+
}
663678

664-
WebSession.Request.CancelRequest = true;
679+
public void TerminateServerConnection()
680+
{
681+
WebSession.Response.TerminateResponse = true;
665682
}
666683

667684
/// <summary>

Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ public class TunnelConnectSessionEventArgs : SessionEventArgs
1111
public bool IsHttpsConnect { get; internal set; }
1212

1313
internal TunnelConnectSessionEventArgs(int bufferSize, ProxyEndPoint endPoint, ConnectRequest connectRequest, ExceptionHandler exceptionFunc)
14-
: base(bufferSize, endPoint, exceptionFunc)
14+
: base(bufferSize, endPoint, exceptionFunc, connectRequest)
1515
{
16-
WebSession.Request = connectRequest;
1716
}
1817
}
1918
}

Titanium.Web.Proxy/Helpers/HttpResponseWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public HttpResponseWriter(Stream stream, int bufferSize) : base(stream, bufferSi
2020
public async Task WriteResponseAsync(Response response, bool flush = true)
2121
{
2222
await WriteResponseStatusAsync(response.HttpVersion, response.StatusCode, response.StatusDescription);
23-
await WriteHeadersAsync(response.Headers, flush);
23+
await WriteAsync(response, flush);
2424
}
2525

2626
/// <summary>

Titanium.Web.Proxy/Helpers/HttpWriter.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Threading.Tasks;
66
using StreamExtended.Helpers;
77
using StreamExtended.Network;
8-
using Titanium.Web.Proxy.EventArguments;
8+
using Titanium.Web.Proxy.Compression;
99
using Titanium.Web.Proxy.Http;
1010
using Titanium.Web.Proxy.Shared;
1111

@@ -94,12 +94,9 @@ public Task WriteLineAsync(string value)
9494
/// <returns></returns>
9595
public async Task WriteHeadersAsync(HeaderCollection headers, bool flush = true)
9696
{
97-
if (headers != null)
97+
foreach (var header in headers)
9898
{
99-
foreach (var header in headers)
100-
{
101-
await header.WriteToStreamAsync(this);
102-
}
99+
await header.WriteToStreamAsync(this);
103100
}
104101

105102
await WriteLineAsync();
@@ -265,5 +262,22 @@ private async Task CopyBytesFromStream(CustomBinaryReader reader, long count, Ac
265262
onCopy?.Invoke(buffer, 0, bytesRead);
266263
}
267264
}
265+
266+
/// <summary>
267+
/// Writes the request/response headers and body.
268+
/// </summary>
269+
/// <param name="requestResponse"></param>
270+
/// <param name="flush"></param>
271+
/// <returns></returns>
272+
protected async Task WriteAsync(RequestResponseBase requestResponse, bool flush = true)
273+
{
274+
var body = requestResponse.CompressBodyAndUpdateContentLength();
275+
await WriteHeadersAsync(requestResponse.Headers, flush);
276+
277+
if (body != null)
278+
{
279+
await WriteBodyAsync(body, requestResponse.IsChunked);
280+
}
281+
}
268282
}
269283
}

Titanium.Web.Proxy/Http/HttpWebClient.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class HttpWebClient
3838
/// <summary>
3939
/// Web Request.
4040
/// </summary>
41-
public Request Request { get; internal set; }
41+
public Request Request { get; }
4242

4343
/// <summary>
4444
/// Web Response.
@@ -56,13 +56,13 @@ public class HttpWebClient
5656
/// </summary>
5757
public bool IsHttps => Request.IsHttps;
5858

59-
internal HttpWebClient(int bufferSize)
59+
internal HttpWebClient(int bufferSize, Request request = null, Response response = null)
6060
{
6161
this.bufferSize = bufferSize;
6262

6363
RequestId = Guid.NewGuid();
64-
Request = new Request();
65-
Response = new Response();
64+
Request = request ?? new Request();
65+
Response = response ?? new Response();
6666
}
6767

6868
/// <summary>

0 commit comments

Comments
 (0)