3

In a Go http server, I can get POST request body. Go net/http package seems to remove GET request body. I know it is better not to use http GET with request body,but I need to handle http GET with request body. Is it possible without changing the standard lib? Please help since I don't want to switch back to C with libevent!

When a client sends a POST with request body, below code will show the body content. But when a client sends a GET with request body, there is nothing in the body.

func handler(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    body, _ := ioutil.ReadAll(r.Body)

    log.Printf("body: %v", string(body))
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}
7
  • You "need to handle http GET with request body" ? Really ? There's probably a problem in your design. Commented Jul 16, 2013 at 12:21
  • I can't change the protocol. I wish I could. Commented Jul 16, 2013 at 12:22
  • Can you post an example of the code you want to implement? It's hard to understand what you're asking. Commented Jul 16, 2013 at 13:19
  • I took an admittedly quick look at Go's net/http source code, and I didn't find something like "drop the body if this is a GET". There are the expected conditions for server responses, like if method is a HEAD or if the status code is < 200, 204 or 304, I haven't seen nothing for client requests. Are you absolutely sure the client sends the body? Like checking the Request with Fiddler or something? Commented Jul 16, 2013 at 14:31
  • Somebody should edit the library so it's compliant, even if it's an uncommon use case. Commented Jul 16, 2013 at 15:38

1 Answer 1

4

Most of the magic happens in transfer.go. Here's what I found that looks relevant in the fixLength func:

if !isResponse && requestMethod == "GET" {
    // RFC 2616 doesn't explicitly permit nor forbid an
    // entity-body on a GET request so we permit one if
    // declared, but we default to 0 here (not -1 below)
    // if there's no mention of a body.
    return 0, nil
}

Looks like, as long as your client is ending a Content-Length header, you're all good. If not, the library will assume there's no body on a GET request.

You're kind of off the edge of the map as your client is doing some pretty unusual/broken stuff. If you can fix the client, that's your best bet.

That said, if you have a client you need to support that's doing this wrong, you're going to have to roll some things yourself. You don't need to go all the way down to C and libevent. Simply copy the net/http package from the standard library into your project and modify it. Then change your import statements to point at your version of the library.

Alternatively, if you know that the client is not using keep-alive, you can Hijack the connection and just read whatever's left on the socket.

Sign up to request clarification or add additional context in comments.

1 Comment

You're correct. When GET does not specify Content-Length, r.Body is an eofReader (eofReader is a non-nil io.ReadCloser that always returns EOF).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.