Skip to content

Expect 100 Continue Hang - #38774

Merged
ManickaP merged 12 commits into
dotnet:masterfrom
ManickaP:mapichov/36717_expect100continue
Jul 28, 2020
Merged

Expect 100 Continue Hang#38774
ManickaP merged 12 commits into
dotnet:masterfrom
ManickaP:mapichov/36717_expect100continue

Conversation

@ManickaP

Copy link
Copy Markdown
Member

Inside sendRequestContentTask recognizes that it's invoked from a timer thread and if request content fails, unblocks SendAsyncCore and eventually propagates the exception from the content to the outside.

Fixes#36717

@Dotnet-GitSync-BotDotnet-GitSync-Bot added the area-Infrastructure-coreclr Only use for closed issues label Jul 3, 2020
@ManickaP
ManickaP requested a review from a teamJuly 3, 2020 21:22
@ManickaP
ManickaPforce-pushed the mapichov/36717_expect100continue branch 3 times, most recently from 5a90ae0 to 9bcbf28CompareJuly 4, 2020 15:04
@wfurt

wfurt commented Jul 7, 2020

Copy link
Copy Markdown
Member

test failure seems related

@wfurt

wfurt commented Jul 7, 2020

Copy link
Copy Markdown
Member

Why this is different than case without 100Continue? If server does not respond at all, we would also block until timeout fires, right?

@ManickaP

Copy link
Copy Markdown
MemberAuthor

Why this is different than case without 100Continue? If server does not respond at all, we would also block until timeout fires, right?

The hang happens only if we fail to send request content after expect100Continue timer expires. When the timer expires, we try to send the content anyway (without 100 from the server), but it fails (due to exception in custom HttpContent). At that moment, in non-100 scenario, we would have already reported that exception to the caller (content gets send before reading response headers). In 100 we don't, we wait for the timeout and eventually report timeout instead of the error in the content. Also, if the content sending didn't fail, the server would reply and we wouldn't end up with timeout.

For customers, the covering the content exception with timeout is making this issue supper hard to troubleshoot.
And since we added sync scenario and throwing in case of missing sync overrides, this hang is now much more probable to happen.

@ManickaP
ManickaPforce-pushed the mapichov/36717_expect100continue branch from 9bcbf28 to 05d4cadCompareJuly 7, 2020 14:39

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're adding a decent amount of complication to be able to pass around both sendRequestContent and timerExpired. Could we instead just always call Dispose in this case if SendRequestContentAsync throws? As you said, we're talking about the combination of a faulty request content + Expect: 100-continue. If we get an exception in that case, regardless of the timer, seems like it'd be fine to just get rid of the connection in that case.

@ManickaP
ManickaPforce-pushed the mapichov/36717_expect100continue branch from 05d4cad to d674782CompareJuly 7, 2020 20:58
@scalablecoryscalablecory added area-System.Net.Http and removed area-Infrastructure-coreclr Only use for closed issues labels Jul 9, 2020
@ghost

ghost commented Jul 9, 2020

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

Comment threadsrc/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs Outdated
Comment threadsrc/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs Outdated

@alnikolaalnikola left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for some small issues commented on below.

Comment threadsrc/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs Outdated
Comment threadsrc/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs Outdated
@ManickaP
ManickaPforce-pushed the mapichov/36717_expect100continue branch from cbfb705 to 5826443CompareJuly 18, 2020 21:02
@ManickaP

Copy link
Copy Markdown
MemberAuthor

Failing tests are unrelated.

@scalablecoryscalablecory left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

{
public partial class ThrowingContent : HttpContent
{
protected override void SerializeToStream(Stream stream, TransportContext context, CancellationToken cancellationToken)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

Shouldn't the default SerializeToStream(stream, context, cancellationToken) end up calling SerializeToStream(stream, context)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR yes

This is the only sync implementation we provide for ThrowingContent. The one in shared code is async and there's now automatic/default sync-over-async in any of our HttpContent classes.

@ManickaP

Copy link
Copy Markdown
MemberAuthor

triggering CI

@ManickaPManickaP reopened this Jul 28, 2020
@ManickaP
ManickaP merged commit 7a6ca80 into dotnet:masterJul 28, 2020
@ManickaP
ManickaP deleted the mapichov/36717_expect100continue branch July 28, 2020 14:58
Jacksondr5 pushed a commit to Jacksondr5/runtime that referenced this pull request Aug 10, 2020
Inside sendRequestContentTask recognizes that it's invoked from a timer thread and if request content fails, unblocks SendAsyncCore and eventually propagates the exception from the content to the outside.
Fixes the issue for H2 as well.
Fixesdotnet#36717
@karelzkarelz added this to the 5.0.0 milestone Aug 18, 2020
@ghostghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Faulty request HttpContent might causes a hang in expect 100 Continue scenario

7 participants

@ManickaP@wfurt@stephentoub@scalablecory@alnikola@karelz@Dotnet-GitSync-Bot