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.<p>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.
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?<p><pre><code> // The booleans representing the free active connection spaces.
spaces := make(chan bool, *maxConnections)
// Initialize the spaces
for i := 0; i < *maxConnections; i++ {
spaces <- true
}</code></pre>
}<p>Is this really how people use go???
The inbuilt reverseproxy is also handy for small tasks:<p><pre><code> 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))
}
</code></pre>
This will http proxy :80 to :8000.