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: server-side expect 100-continue behavior seem broken on persistent connections #11549

Closed
redbo opened this issue Jul 2, 2015 · 3 comments

Comments

Projects
None yet
5 participants
@redbo
Copy link

commented Jul 2, 2015

When a net/http server receives an "Expect: 100-continue" request and doesn't read from the request body (and thus doesn't emit a "100 Continue" response or receive the body from the client), the server still seems to discard Content-Length bytes from the socket, which will consume some or all of the next request when using persistent connections, messing up the connection state.

package main

import (
        "io"
        "io/ioutil"
        "net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path == "/readbody" {
                ioutil.ReadAll(r.Body)
        }
        io.WriteString(w, "Hello world!")
}

func main() {
        http.HandleFunc("/", hello)
        http.ListenAndServe(":9000", nil)
}
redbo@precise-saio:~/$ nc 127.0.0.1 9000
PUT /noreadbody HTTP/1.1
User-Agent: PycURL/7.22.0
Host: 127.0.0.1:9000
Accept: */*
Expect: 100-continue
Content-Length: 10

HTTP/1.1 200 OK
Date: Thu, 02 Jul 2015 23:19:06 GMT
Content-Length: 12
Content-Type: text/plain; charset=utf-8

Hello world!PUT /readbody HTTP/1.1
User-Agent: PycURL/7.22.0
Host: 127.0.0.1:9000
Accept: */*
Expect: 100-continue
Content-Length: 10

HTTP/1.1 400 Bad Request

If I go into net/http and print out the error that leads to the 400, it's: malformed HTTP request "ody HTTP/1.1", which is 10 bytes (Content-Length) cut off from the first line of the next request.

@kolach

This comment has been minimized.

Copy link

commented Jul 3, 2015

Many thanks for the hint, I was hitting the wall for 4 hours, trying to understand what is wrong with my go server code that was accepting "100 Continue" requests.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Jul 4, 2015

The server should instead reply with Connection: close on the response to the first request, to make that connection as dead, since the server can't know for sure whether the client got bored of waiting for a 100-continue and sent the body anyway. Since the connection is in an unknown state, we have to just close the connection and have the client send a new one.

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Jul 11, 2015

@bradfitz bradfitz modified the milestones: Go1.5, Unplanned Jul 15, 2015

@gopherbot

This comment has been minimized.

Copy link

commented Jul 15, 2015

CL https://golang.org/cl/12262 mentions this issue.

@bradfitz bradfitz closed this in 88fc358 Jul 15, 2015

@golang golang locked and limited conversation to collaborators Jul 18, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.