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

Commit

Permalink
do not allow to read body twice
Browse files Browse the repository at this point in the history
  • Loading branch information
honfika committed Jan 28, 2022
1 parent cf98fdf commit 5734f5f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ private async Task readRequestBodyAsync(CancellationToken cancellationToken)
// If not already read (not cached yet)
if (!request.IsBodyRead)
{
if (request.IsBodyReceived)
{
throw new Exception("Request body was already received.");
}

if (request.HttpVersion == HttpHeader.Version20)
{
// do not send to the remote endpoint
Expand All @@ -103,6 +108,7 @@ private async Task readRequestBodyAsync(CancellationToken cancellationToken)
// Now set the flag to true
// So that next time we can deliver body from cache
request.IsBodyRead = true;
request.IsBodyReceived = true;
}
else
{
Expand All @@ -115,6 +121,7 @@ private async Task readRequestBodyAsync(CancellationToken cancellationToken)
// Now set the flag to true
// So that next time we can deliver body from cache
request.IsBodyRead = true;
request.IsBodyReceived = true;
}
}
}
Expand Down Expand Up @@ -160,6 +167,11 @@ private async Task readResponseBodyAsync(CancellationToken cancellationToken)
// If not already read (not cached yet)
if (!response.IsBodyRead)
{
if (response.IsBodyReceived)
{
throw new Exception("Response body was already received.");
}

if (response.HttpVersion == HttpHeader.Version20)
{
// do not send to the remote endpoint
Expand All @@ -178,6 +190,7 @@ private async Task readResponseBodyAsync(CancellationToken cancellationToken)
// Now set the flag to true
// So that next time we can deliver body from cache
response.IsBodyRead = true;
response.IsBodyReceived = true;
}
else
{
Expand All @@ -190,6 +203,7 @@ private async Task readResponseBodyAsync(CancellationToken cancellationToken)
// Now set the flag to true
// So that next time we can deliver body from cache
response.IsBodyRead = true;
response.IsBodyReceived = true;
}
}
}
Expand Down Expand Up @@ -221,14 +235,15 @@ private async Task<byte[]> readBodyAsync(bool isRequest, CancellationToken cance
internal async Task SyphonOutBodyAsync(bool isRequest, CancellationToken cancellationToken)
{
var requestResponse = isRequest ? (RequestResponseBase)HttpClient.Request : HttpClient.Response;
if (requestResponse.IsBodyRead || !requestResponse.OriginalHasBody)
if (requestResponse.IsBodyReceived || !requestResponse.OriginalHasBody)
{
return;
}

var reader = isRequest ? (HttpStream)ClientStream : HttpClient.Connection.Stream;

await reader.CopyBodyAsync(requestResponse, true, NullWriter.Instance, TransformationMode.None, isRequest, this, cancellationToken);
requestResponse.IsBodyReceived = true;
}

/// <summary>
Expand Down Expand Up @@ -272,11 +287,15 @@ internal async Task CopyRequestBodyAsync(IHttpStreamWriter writer, Transformatio
{
await reader.CopyBodyAsync(request, false, writer, transformation, true, this, cancellationToken);
}

request.IsBodyReceived = true;
}

private async Task copyResponseBodyAsync(IHttpStreamWriter writer, TransformationMode transformation, CancellationToken cancellationToken)
{
await HttpClient.Connection.Stream.CopyBodyAsync(HttpClient.Response, false, writer, transformation, false, this, cancellationToken);
var response = HttpClient.Response;
await HttpClient.Connection.Stream.CopyBodyAsync(response, false, writer, transformation, false, this, cancellationToken);
response.IsBodyReceived = true;
}

/// <summary>
Expand Down
15 changes: 15 additions & 0 deletions src/Titanium.Web.Proxy/Http/RequestResponseBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ internal set

internal bool BodyAvailable => BodyInternal != null;

private bool isBodyReceived;

internal bool IsBodyReceived
{
get => isBodyReceived;
set
{
if (isBodyReceived)
{
;
}
isBodyReceived = value;
}
}

internal bool IsBodySent { get; set; }

internal abstract void EnsureBodyAvailable(bool throwWhenNotReadYet = true);
Expand Down
1 change: 1 addition & 0 deletions src/Titanium.Web.Proxy/Http2/Http2Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ private static async Task copyHttp2FrameAsync(Stream input, Stream output,
}

rr.IsBodyRead = true;
rr.IsBodyReceived = true;

var tcs = rr.ReadHttp2BodyTaskCompletionSource;
rr.ReadHttp2BodyTaskCompletionSource = null;
Expand Down
2 changes: 2 additions & 0 deletions src/Titanium.Web.Proxy/ResponseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ await handleHttpSessionRequest(args, null, args.ClientConnection.NegotiatedAppli
await serverStream.CopyBodyAsync(response, false, clientStream, TransformationMode.None,
false, args, cancellationToken);
}

response.IsBodyReceived = true;
}

args.TimeLine["Response Sent"] = DateTime.UtcNow;
Expand Down

0 comments on commit 5734f5f

Please sign in to comment.