Skip to content

Instantly share code, notes, and snippets.

@montanaflynn
Last active May 29, 2018 12:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save montanaflynn/de6c8b49911883978da3 to your computer and use it in GitHub Desktop.
Save montanaflynn/de6c8b49911883978da3 to your computer and use it in GitHub Desktop.
Golang HTTP Proxy
package main
import (
"log"
"flag"
"net"
"net/http"
"net/http/httputil"
"time"
"strconv"
)
const (
portMsg = "Port number to start proxy on"
responseTimeoutMsg = "Response timeout duration"
keepAliveMsg = "Disable keep alive connections"
keepaliveTimeMsg = "Time to keep connections alive for"
disableCompressionMsg = "Disable compression"
maxIdleConnectionsMsg = "Maximum idle connections"
schemeOverideHeaderMsg = "Header to look for to override scheme"
hostOverideHeaderMsg = "Header to look for to override host"
methodOverideHeaderMsg = "Header to look for to override method"
)
var (
port = flag.Int("port", 8080, portMsg)
responseTimeout = flag.Duration("timeout", 30 * time.Second, responseTimeoutMsg)
disableKeepAlive = flag.Bool("disable-keep-alive", false, keepAliveMsg)
keepaliveTime = flag.Duration("keep-alive-time", 30 * time.Second, keepaliveTimeMsg)
disableCompression = flag.Bool("compression", false, disableCompressionMsg)
maxIdleConnections = flag.Int("max-idle-connections", 10000, maxIdleConnectionsMsg)
schemeOverideHeader = flag.String("scheme-override-header", "x-scheme-override", schemeOverideHeaderMsg)
hostOverideHeader = flag.String("host-override-header", "x-host-override", hostOverideHeaderMsg)
methodOverideHeader = flag.String("method-override-header", "x-method-override", methodOverideHeaderMsg)
)
func init() {
flag.Parse()
}
func newTransport() *http.Transport {
return &http.Transport{
DisableKeepAlives: *disableKeepAlive,
MaxIdleConnsPerHost: *maxIdleConnections,
DisableCompression: *disableCompression,
ResponseHeaderTimeout: *responseTimeout,
Dial: (&net.Dialer{
Timeout: *responseTimeout,
KeepAlive: *keepaliveTime,
}).Dial,
}
}
func newDirector(r *http.Request) func(*http.Request) {
return func(req *http.Request) {
schemeOveride := r.Header.Get(*schemeOverideHeader)
hostOveride := r.Header.Get(*hostOverideHeader)
methodOveride := r.Header.Get(*methodOverideHeader)
if schemeOveride != "" {
req.URL.Scheme = schemeOveride
} else {
req.URL.Scheme = "http"
}
if hostOveride != "" {
req.URL.Host = hostOveride
} else {
req.URL.Host = r.Host
}
if methodOveride != "" {
req.Method = methodOveride
}
}
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
proxy := &httputil.ReverseProxy{
Transport: newTransport(),
Director: newDirector(r),
}
proxy.ServeHTTP(w, r)
})
log.Fatal(http.ListenAndServe(":" + strconv.Itoa(*port), nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment