-
Notifications
You must be signed in to change notification settings - Fork 18k
x/net/http2: MS Edge RST_STREAM cancel on a POST #19948
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
Comments
Can you clarify which exact version of Go you're using? The http2 code has changed over time. |
In any case, this seems like a bug in Edge. Logs says:
At this point, the client (Edge) has sent all its declared data, but not closed the stream. In theory it could still send Trailers if it wanted to. Go's handler runs, reads all the body data, and sends its response. Your Handler (ServeHTTP) now exits, and Go knows you're never going to read any Trailers now, so Go sends a RST_STREAM (ErrCode == Cancel) to Edge, letting the client know the Server's gone away. Now Edge gets confused, and doesn't even process the completed response HEADERS + DATA w/ END_STREAM we sent? |
Current debug output is with the released Go 1.8.1. |
I'm comparing with chrome, you are right.
Edge:
|
I agree with Brad, this looks like a bug in Edge, so I'm closing this. |
/cc @MikeBishop |
@tombergan, we should probably escalate to the Edge team, though. (Update: you replied at the same time I did :)) We could also consider working around this. Maybe we don't send the cancel for a couple seconds? |
I think @MikeBishop is the Edge contact for HTTP/2. I'm not sure it's worth delaying the cancel. The client should receive the full response (up to END_STREAM) before receiving the RST_STREAM and could in theory send that response up to the XHR layer. Do we know what Apache does in this case? Do they leave the stream open indefinitely? |
/cc @icing for the Apache question. |
Stefan, if Edge sends a request with a Content-Length and all the DATA, but no END_STREAM bit ever, and then you finish processing the request & finish sending the response, what does Apache do? Go sends a RST_STREAM with err code CANCEL after our (Go's) END_STREAM. But Edge doesn't like that. |
Well, I’m inclined to say that sending behavior is an error on Edge’s part to begin with – if there's an obvious repro, I'd like to make sure that’s looked at.
On the server side, this appears to be a special case of an early response, in which case the error code should be NO_ERROR rather than CANCEL, shouldn’t it?
…Sent from my Windows 10 phone
From: Brad Fitzpatrick<mailto:notifications@github.com>
Sent: Wednesday, April 12, 2017 4:04 PM
To: golang/go<mailto:go@noreply.github.com>
Cc: Mike Bishop<mailto:Michael.Bishop@microsoft.com>; Mention<mailto:mention@noreply.github.com>
Subject: Re: [golang/go] x/net/http2: MS Edge RST_STREAM cancel on a POST (#19948)
Stefan, if IE sends a request with a Content-Length and all the DATA, but no END_STREAM bit ever, and then you finish processing the request & finish sending the response, what does Apache do? Go sends a RST_STREAM with err code CANCEL after our END_STREAM. But Edge doesn't like that.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgolang%2Fgo%2Fissues%2F19948%23issuecomment-293731596&data=02%7C01%7CMichael.Bishop%40microsoft.com%7Cc221c1f69c964230a7b508d481f83ef6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636276350583039876&sdata=iqfl%2BZWw67rLczTRNSAX%2BZOXiVcf9b%2F4yo%2F9UiZo5A0%3D&reserved=0>, or mute the thread<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAEE2hVLZSA8B-b7Vr_yGYFDkgRskQ_Dvks5rvVhwgaJpZM4M718J&data=02%7C01%7CMichael.Bishop%40microsoft.com%7Cc221c1f69c964230a7b508d481f83ef6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636276350583039876&sdata=gu3dGFfKlAySfz%2BQe7kAlerSJeWE%2FCGiNTtKynZZ99g%3D&reserved=0>.
|
@hexadecy, can you provide a repro for @MikeBishop?
Both seem reasonable by my reading. NO_ERROR is "not the result of an error" and "might ... indicate graceful shutdown". CANCEL indicates that "the stream is no longer needed". Is there some part of the spec which says that NO_ERROR should be used to close a stream after sending an early response? |
@MikeBishop, thanks! Sounds like we should change to NO_ERROR, then:
|
Just added a test for this. Apache is happy when the content is provided by the client as announced. The request is then served, the response is sent and the stream is closed. I have not tested with a trailer announcement and such, but overall this seems to work. This is however more an artefact of the HTTP/1.1 request handling than intentional design of the 2 implementation, I must say. |
@icing, but do you keep any state around for the client, since they've never sent END_STREAM? Or does Edge eventually send it? |
@bradfitz The server has closed down the processing, but the stream is still hanging around and timeouts do not trigger for it any longer. So, this needs to be fixed as it will otherwise block resources. RST_STREAM with NO_ERROR is probably the way to go here. No idea if Edge does send it eventually. A GOAWAY will tear it all down properly in the end. |
CL https://golang.org/cl/40630 mentions this issue. |
…est is finished This is required by RFC 7540 Section 8.1. Bug pointed out by Mike Bishop. Updates golang/go#19948 Change-Id: I58d4f499609fd493d33115f4e1f64caf4bcbbc03 Reviewed-on: https://go-review.googlesource.com/40630 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Potential difference from Chrome: Our stream will end with a separate, zero-length payload DATA frame with END_STREAM set. Any chance you're discarding empty frames before looking at the flags? If not, it would be good to get traces for the client's view. |
@MikeBishop, I just double-checked: we don't bail out early on zero length. It still processes flags. |
Don't know if that question included httpd, but just for the record: we do not discriminate against 0 lenght frames. :-)
… Am 13.04.2017 um 20:03 schrieb Brad Fitzpatrick ***@***.***>:
Any chance you're discarding empty frames before looking at the flags?
@MikeBishop, I just double-checked: we don't bail out early on zero length. It still processes flags.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
netsh trace was sent @MikeBishop. |
I think I know why it wasn't reported before.
Now Edge have the time to send the END_STREAM flag.
To be local with Edge, you need a local domain (like active directory) + install a valid CA and run this line: |
CL https://golang.org/cl/41753 mentions this issue. |
This updates the bundled http2 package from git rev 5602c733f70afc6dcec6766be0d5034d4c4f14de of the x/net repo for: http2: Use NO_ERROR instead of CANCEL when responding before the request is finished https://golang.org/cl/40630 http2: enforce write deadline per stream https://golang.org/cl/34727 Updates #19948 Fixes #18437 Change-Id: I14500476e91551fa8f27a1aeb8ae3cac9600b74c Reviewed-on: https://go-review.googlesource.com/41753 Reviewed-by: Kale Blankenship <kale@lemnisys.com> Reviewed-by: Tom Bergan <tombergan@google.com> Run-TryBot: Kale Blankenship <kale@lemnisys.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
The Go side of this bug was fixed by the above change. |
…est is finished This is required by RFC 7540 Section 8.1. Bug pointed out by Mike Bishop. Updates golang/go#19948 Change-Id: I58d4f499609fd493d33115f4e1f64caf4bcbbc03 Reviewed-on: https://go-review.googlesource.com/40630 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
What version of Go are you using?
go version go1.8.1 windows/amd64
What operating system and processor architecture are you using?
set GOARCH=amd64
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
Windows version 10.0.14393
What did you do?
What did you expect to see?
No error in browser console like in http1.
In chrome there is just one WINDOW_UPDATE:
2017/04/12 14:46:20 http2: Framer 0xc0420572b0: wrote WINDOW_UPDATE len=4 (conn) incr=176
and RST_STREAM is not cancelled.
What did you see instead?
In the browser console:
SCRIPT7002: XMLHttpRequest: Network Error 0x2eff, Could not complete the operation due to error 00002eff.
And Edge is waiting after the post response.
On the server with GODEBUG=http2debug=2
The text was updated successfully, but these errors were encountered: