http.ReverseProxy

854 views
Skip to first unread message

Brian Ketelsen

unread,
Aug 10, 2011, 12:35:48 PM8/10/11
to golang-nuts
I must be doing it wrong. I'm trying to write a simple reverse proxy - accept connections on a port and proxy them to another host. This seems to be what http.ReverseProxy is made for.

package main

import "http"
import "log"

func main(){

proxy := http.NewSingleHostReverseProxy( &http.URL{Scheme:"http",Host:"www.brianketelsen.com",Path:"/"})


err := http.ListenAndServe(":8080", proxy)
if err != nil {
log.Fatal("ListenAndServe: ", err.String())
}

}

But no matter what I do, I get HTTP 411 "content length required" errors.

Help?

Brian

Brad Fitzpatrick

unread,
Aug 10, 2011, 1:30:53 PM8/10/11
to Brian Ketelsen, golang-nuts
If I run that program it just hangs there forever, waiting for an HTTP request.

I suppose there was a repro step you forgot to include, probably involving an HTTP request.  I'll speculate that your request involved a POST with a chunked body, which your origin server can't handle:

Trying 66.228.56.168...
Connected to www.brianketelsen.com.
Escape character is '^]'.
POST / HTTP/1.1
Transfer-Encoding: chunked

HTTP/1.1 411 Length Required
Server: nginx/1.0.0
Date: Wed, 10 Aug 2011 17:27:20 GMT
Content-Type: text/html
Content-Length: 180
Connection: close


.... so the bug is your server's and/or the request you're sending.

nginx or whatever is behind it claims to be HTTP/1.1 but can't handle chunking as HTTP/1.1 requires.

You'll need to include the Content-Length, but Go isn't going to pre-emptively guess that your server is non-compliant and buffer an unknown amount of data into memory just to count it and send a Content-Length header.  Go's just following the specs and forwarding along the request.

- Brad

Brian Ketelsen

unread,
Aug 10, 2011, 2:05:59 PM8/10/11
to Brad Fitzpatrick, golang-nuts

You assumed correctly. I poked around until I found a server that wasn't proxied/served by Nginx and got my simple reverse proxy to work. Thanks!

Dave Cheney

unread,
Aug 10, 2011, 9:27:25 PM8/10/11
to Brian Ketelsen, Brad Fitzpatrick, golang-nuts
Yup, Nginx doesn't currently (I think there is a 3rd party patch)
support requests with chunked bodies (so technically it's not HTTP/1.1
compliant). Clients that tend to hit this issue are WebDAV clients
using PUTs for dynamically generated content.

Cheers

Dave

Vasiliy G Tolstov

unread,
Aug 11, 2011, 1:27:18 AM8/11/11
to golan...@googlegroups.com

Yes, Nginx now officialy not support chunked bodies, but patch is
pending for adding to upstream now.

Dave Cheney

unread,
Aug 11, 2011, 2:08:19 AM8/11/11
to v.to...@selfip.ru, golan...@googlegroups.com
Thanks Vasiliy, that is good to know.

dli...@gmail.com

unread,
Nov 7, 2013, 1:52:46 PM11/7/13
to golan...@googlegroups.com
It was a long time when you wrote this post, but I tested your code  and I had some errors. I want to add working version of your program.

package main

import (
    "net/http"
    "net/http/httputil"
    "net/url"
    "log"
)

func main(){
        proxy := httputil.NewSingleHostReverseProxy( &url.URL{Scheme:"http",Host:"www.google.com",Path:"/"})


        err := http.ListenAndServe(":8080", proxy)
        if err != nil {
                log.Fatal("ListenAndServe: ", err)
        }
}


среда, 10 августа 2011 г., 23:35:48 UTC+7 пользователь Brian Ketelsen написал:
Reply all
Reply to author
Forward
0 new messages