{"action":"reopened","issue":{"url":"https://api.github.com/repos/golang/go/issues/16481","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/16481/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/16481/comments","events_url":"https://api.github.com/repos/golang/go/issues/16481/events","html_url":"https://github.com/golang/go/issues/16481","id":167221309,"number":16481,"title":"x/net/http2: return flow control when stream closes with buffered data","user":{"login":"wujieliulan","id":2224380,"avatar_url":"https://avatars.githubusercontent.com/u/2224380?v=3","gravatar_id":"","url":"https://api.github.com/users/wujieliulan","html_url":"https://github.com/wujieliulan","followers_url":"https://api.github.com/users/wujieliulan/followers","following_url":"https://api.github.com/users/wujieliulan/following{/other_user}","gists_url":"https://api.github.com/users/wujieliulan/gists{/gist_id}","starred_url":"https://api.github.com/users/wujieliulan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wujieliulan/subscriptions","organizations_url":"https://api.github.com/users/wujieliulan/orgs","repos_url":"https://api.github.com/users/wujieliulan/repos","events_url":"https://api.github.com/users/wujieliulan/events{/privacy}","received_events_url":"https://api.github.com/users/wujieliulan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"bradfitz","id":2621,"avatar_url":"https://avatars.githubusercontent.com/u/2621?v=3","gravatar_id":"","url":"https://api.github.com/users/bradfitz","html_url":"https://github.com/bradfitz","followers_url":"https://api.github.com/users/bradfitz/followers","following_url":"https://api.github.com/users/bradfitz/following{/other_user}","gists_url":"https://api.github.com/users/bradfitz/gists{/gist_id}","starred_url":"https://api.github.com/users/bradfitz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bradfitz/subscriptions","organizations_url":"https://api.github.com/users/bradfitz/orgs","repos_url":"https://api.github.com/users/bradfitz/repos","events_url":"https://api.github.com/users/bradfitz/events{/privacy}","received_events_url":"https://api.github.com/users/bradfitz/received_events","type":"User","site_admin":false},"assignees":[{"login":"bradfitz","id":2621,"avatar_url":"https://avatars.githubusercontent.com/u/2621?v=3","gravatar_id":"","url":"https://api.github.com/users/bradfitz","html_url":"https://github.com/bradfitz","followers_url":"https://api.github.com/users/bradfitz/followers","following_url":"https://api.github.com/users/bradfitz/following{/other_user}","gists_url":"https://api.github.com/users/bradfitz/gists{/gist_id}","starred_url":"https://api.github.com/users/bradfitz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bradfitz/subscriptions","organizations_url":"https://api.github.com/users/bradfitz/orgs","repos_url":"https://api.github.com/users/bradfitz/repos","events_url":"https://api.github.com/users/bradfitz/events{/privacy}","received_events_url":"https://api.github.com/users/bradfitz/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/40","html_url":"https://github.com/golang/go/milestones/Go1.7Maybe","labels_url":"https://api.github.com/repos/golang/go/milestones/40/labels","id":1714149,"number":40,"title":"Go1.7Maybe","description":"Things that might be okay for Go 1.7 if they get done in time.\r\n","creator":{"login":"bradfitz","id":2621,"avatar_url":"https://avatars.githubusercontent.com/u/2621?v=3","gravatar_id":"","url":"https://api.github.com/users/bradfitz","html_url":"https://github.com/bradfitz","followers_url":"https://api.github.com/users/bradfitz/followers","following_url":"https://api.github.com/users/bradfitz/following{/other_user}","gists_url":"https://api.github.com/users/bradfitz/gists{/gist_id}","starred_url":"https://api.github.com/users/bradfitz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bradfitz/subscriptions","organizations_url":"https://api.github.com/users/bradfitz/orgs","repos_url":"https://api.github.com/users/bradfitz/repos","events_url":"https://api.github.com/users/bradfitz/events{/privacy}","received_events_url":"https://api.github.com/users/bradfitz/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":95,"state":"open","created_at":"2016-04-18T15:44:35Z","updated_at":"2016-07-26T22:20:08Z","due_on":"2016-07-31T07:00:00Z","closed_at":null},"comments":17,"created_at":"2016-07-24T07:19:38Z","updated_at":"2016-07-26T22:20:08Z","closed_at":null,"body":"\r\nI ran into a case where my http2 transport cannot send any data to my http2 server with the existing connection. The issue is client sent some data in a stream, when server receives it, there was a stream error (or stream closed) and the data received was discarded., server never got a chance to send windowupdate for this client connection, client can no longer send more data, even for new streams.  \r\n\r\nI did some simple changes and this issue is fixed, but I am not sure if this is the right way to fix. Could you advice? Is there a similar issue for server sending to client?\r\n\r\n    Here is the change I made:\r\n\r\n    diff --git a/http2/server.go b/http2/server.go\r\n    index f368738..b924c3d 100644\r\n    --- a/http2/server.go\r\n    +++ b/http2/server.go\r\n    @@ -1277,6 +1277,9 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {\r\n     \r\n     func (sc *serverConn) processData(f *DataFrame) error {\r\n            sc.serveG.check()\r\n    +       if len(f.Data()) > 0 {\r\n    +               sc.sendWindowUpdate(nil, len(f.Data())) // conn-level\r\n    +       }\r\n            // \"If a DATA frame is received whose stream is not in \"open\"\r\n            // or \"half closed (local)\" state, the recipient MUST respond\r\n            // with a stream error (Section 5.4.2) of type STREAM_CLOSED.\"\r\n    @@ -1764,7 +1767,7 @@ func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) {\r\n     \r\n     func (sc *serverConn) noteBodyRead(st *stream, n int) {\r\n            sc.serveG.check()\r\n    -       sc.sendWindowUpdate(nil, n) // conn-level\r\n    +       //sc.sendWindowUpdate(nil, n) // conn-level\r\n            if st.state != stateHalfClosedRemote && st.state != stateClosed {\r\n                    // Don't send this WINDOW_UPDATE if the stream is closed\r\n                    // remotely.\r\n"}}
{"actor":{"display_login":"bradfitz"}}