Skip to content
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

net/http: http.response not flushing body after writing 1XX headers when client has header Expect: 100-continue #57696

Open
WeidiDeng opened this issue Jan 9, 2023 · 1 comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@WeidiDeng
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.19.4 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
Not relevant

What did you do?

func runServer() {
	panic(http.ListenAndServe(":80", http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		_, _ = io.Copy(io.Discard, request.Body)
		writer.WriteHeader(100)
		writer.WriteHeader(201)
		_, _ = io.WriteString(writer, "CREATED")
	})))
}

func Test100Http(t *testing.T) {
	go runServer()
	time.Sleep(time.Second)
	conn, _ := net.Dial("tcp", "127.0.0.1:80")
	file, _ := os.Open("/tmp/go1.20rc2.src.tar.gz")
	req, _ := http.NewRequest(http.MethodPut, "http://127.0.0.1/go.tar.gz", file)
	req.Header.Set("Expect", "100-continue")
	_ = req.Write(conn)
	_, _ = io.Copy(os.Stdout, conn)
}

What did you expect to see?

output

HTTP/1.1 100 Continue

HTTP/1.1 100 Continue

HTTP/1.1 201 Created
Date: Mon, 09 Jan 2023 09:00:36 GMT
Content-Length: 7
Content-Type: text/plain; charset=utf-8

CREATED

What did you see instead?

The program hangs with the following output

HTTP/1.1 100 Continue

HTTP/1.1 100 Continue

HTTP/1.1 201 Created
Date: Mon, 09 Jan 2023 09:00:36 GMT
Content-Length: 7
Content-Type: text/plain; charset=utf-8

notice response body is not written CREATED

Additional Info

This problem was first discovered when a caddy user find his webdav server not longer works when he upgraded caddy version. Caddy is using a heavily modified reverse_proxy handler from stdlib and merged 1xx status codes which was backported from 53164.

After some digging in caddy, I determined it's a problem with golang http. The handler is a reduced version of caddy reverse_proxy which forwards 1XX from backend. And the example file is small 25MB, using large files like 134MB will produce the correct output.

@bcmills
Copy link
Member

bcmills commented Jan 9, 2023

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 9, 2023
@bcmills bcmills added this to the Backlog milestone Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

2 participants