from Hacker News

Creating a Proxy Server with Go

by jokeofweek on 9/22/13, 12:50 PM with 18 comments

  • by tptacek on 9/22/13, 3:38 PM

    I know it's irrational, but it drives me a little nuts how the proxy idiom in go is "two goroutines implementing socket-to-socket copy". The inner handler loop of a proxy is a place where, to me, select/poll might actually make the code easier to follow; also, the idiom doubles the number of goroutines required to handle a given connection load, and while goroutines are cheap, they aren't free.

    I know it's possible to pull select() into Golang programs (I ended up having to, to write a fast port scanner), but Golang people look at you weirdly when you tell them you did that.

  • by mcot2 on 9/22/13, 1:45 PM

    I'm not sure I agree with how channels are used here. What's the point of this spaces chan? Why couldn't a simple atomic counter solve this (see sync/atomic)? Why allocate a thousand bools?

        // The booleans representing the free active connection spaces.
        spaces := make(chan bool, *maxConnections)
        // Initialize the spaces
        for i := 0; i < *maxConnections; i++ {
            spaces <- true
        }
    }

    Is this really how people use go???

  • by farslan on 9/22/13, 8:37 PM

    The inbuilt reverseproxy is also handy for small tasks:

        package main
    
        import (
        	"net/http"
        	"net/http/httputil"
        	"net/url"
        )
    
        func main() {
        	target, _ := url.Parse("http://127.0.0.1:8000")
        	http.ListenAndServe(":80", httputil.NewSingleHostReverseProxy(target))
        }
    
    This will http proxy :80 to :8000.