Last active
May 29, 2018 12:33
-
-
Save montanaflynn/de6c8b49911883978da3 to your computer and use it in GitHub Desktop.
Golang HTTP Proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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