-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Move BadHttpRequestException to Http.Abstractions #20339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@halter73 @anurse #15038 proposed making the old BadHttpRequestException derive from the new one to limit the breaking change impact. The servers would continue throwing the old ones for now. #17804 also proposed making the Reason enum public for more granular error management. These had both been resolved as duplicates of #11208 but the context didn't get pulled over. |
I reopened the Reason one, we can do that in a separate PR. |
@halter73 Let me recap what I think I need to do. Correct me if any points are wrong.
I also have a question about AllowedHeader. That is currently only used in the following two places
The property is then used to set the http header here
Can the response header be set in the place the exceptions are thrown in Http1Connection or is it too early in the request pipeline? |
@cado1982 Looks correct except one thing:
Keep obsoleting IIS's and Kestrel's BadHttpRequestException. You'll probably need add some pragmas to silence warnings about our own internal usage, but we want to encourage customers to catch the base type. Eventually we might remove the obsoleted derived types or make them internal. |
…s version - Mark existing BadHttpRequestException in IIS and Kestrel Obsolete - Add pragmas to ignore internal Obsolete usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. Most my comments are around reducing the need for pragmas.
@@ -122,7 +122,9 @@ private async Task ReadBody() | |||
|
|||
if (_consumedBytes > MaxRequestBodySize) | |||
{ | |||
#pragma warning disable CS0618 // Type or member is obsolete | |||
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets move the static Throw API to a non obsolete internal type so we don't have to use pragma everywhere. I know that's what you were trying to do with the KestrelBadHttpRequestException, but I think we only need to move the static API.
@@ -38,7 +38,9 @@ public static void UnexpectedError(ILogger logger, string className, Exception e | |||
_unexpectedError(logger, className, methodName, ex); | |||
} | |||
|
|||
#pragma warning disable CS0618 // Type or member is obsolete | |||
public static void ConnectionBadRequest(ILogger logger, string connectionId, BadHttpRequestException ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of these usages can switch to referencing the base type either inline or with a using statement in the file. That will avoid excess pragmas. The two places we need to directly reference the old types are when it's first created & thrown, as well as tests that check which type was thrown. All of the other catch blocks and fields can use the new base type.
@@ -150,7 +150,9 @@ public void StopProcessingNextRequest() | |||
|
|||
public void HandleRequestHeadersTimeout() | |||
{ | |||
#pragma warning disable CS0618 // Type or member is obsolete | |||
Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, GetException should move to a new static type as well.
@@ -90,11 +90,15 @@ public void ParseRequestLineThrowsOnInvalidRequestLine(string requestLine) | |||
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine)); | |||
var requestHandler = new RequestHandler(); | |||
|
|||
#pragma warning disable CS0618 // Type or member is obsolete | |||
var exception = Assert.Throws<BadHttpRequestException>(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good example of where we want to keep the pragmas so we can test that we're throwing the old exception type.
- StatusCode now simply returns the base.StatusCode - Static API from IIS and Kestrel BadHttpRequestException moved to respective IISBadHttpRequestException and KestrelBadHttpRequestException types - Most usages of deprecated IIS and Kestrel BadHttpRequestException moved to base type - Overload added to Microsoft.AspNetCore.Http.BadHttpRequestException to accept inner exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better.
@@ -52,7 +52,7 @@ protected override Task OnConsumeAsync() | |||
} | |||
} | |||
} | |||
catch (BadHttpRequestException ex) | |||
catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can use a using directive here but it must go inside the namespace again.
private BadHttpRequestException GetInvalidRequestTargetException(Span<byte> target) | ||
=> BadHttpRequestException.GetException( | ||
#pragma warning disable CS0618 // Type or member is obsolete | ||
private Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException GetInvalidRequestTargetException(Span<byte> target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base type/using?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again callers of this method throw the returned exception so I think it needs to be the old obsoleted version?
Looks like a test issue in IIS.Tests.MaxRequestBodySizeTests.EveryReadFailsWhenContentLengthHeaderExceedsGlobalLimit:
I think it's this part:
ThrowsAsync checks for the exact exception type, not derived types. You can use ThrowsAnyAsync or check for the derived type here. |
I applied the change you mentioned but I'm struggling to run the IIS tests locally. They run continuously and don't complete (for at least 2 hours). Was that the only one that was broken? |
Looks like you fixed it. The remaining issue with Node seems to be unrelated, I'll see to that. |
var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined)); | ||
#pragma warning restore CS0618 // Type or member is obsolete |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: we could get rid of a lot of these pragmas in the tests by using Assert.ThrowsAny.
@@ -87,7 +89,7 @@ protected async Task OnConsumeAsyncAwaited() | |||
AdvanceTo(result.Buffer.End); | |||
} while (!result.IsCompleted); | |||
} | |||
catch (BadHttpRequestException ex) | |||
catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: There's already a using that take's care of this, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked them to keep many of the test pragmas to make sure the right old exception type was being thrown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the test #pragma's could be removed, but nbd.
Thanks @cado1982 |
Summary of the changes (Less than 80 chars)
Addresses #11208
This is my first contribution so I'm open to any feedback you may have.