Skip to content

Instantly share code, notes, and snippets.

@jmervine
Last active March 17, 2016 04:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmervine/959835490e63cd28772c to your computer and use it in GitHub Desktop.
Save jmervine/959835490e63cd28772c to your computer and use it in GitHub Desktop.
/*Example Usage:
*
* $ PORT=3000 HOST=0.0.0.0 STATIC=./static PROXY_TARGET=http://localhost:5000 PROXY_PATH=/api go run main.go
*/
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
)
var (
port string
host string
static string
proxyURL *url.URL
proxyPath string
)
func init() {
// Set basic logging defaults.
log.SetFlags(0)
log.SetOutput(os.Stdout)
// Get or set PORT
port = os.Getenv("PORT")
if port == "" {
port = "3000"
}
// Get or set HOST
host = os.Getenv("HOST")
if host == "" {
host = "localhost"
}
// Get or set STATIC
// - source location for static file server
static = os.Getenv("STATIC")
if static == "" {
static = "./static"
}
// Get (if present) PROXY_TARGET
// - target URL to proxy requests to
proxyTarget := os.Getenv("PROXY_TARGET")
if proxyTarget != "" {
var err error
proxyURL, err = url.Parse(proxyTarget)
if err != nil {
log.Fatalf("ns=init at=proxyURL error=%q", err)
}
}
// Get (if present) PROXY_PATH
// - path matcher for proxied requests
proxyPath = os.Getenv("PROXY_PATH")
}
func logRequest(r *http.Request, isProxy bool) {
log.Printf("method=%s proto=%s path=%s referer=%s user_agent=%q content_length=%d proxy=%v",
r.Method,
r.Proto,
r.URL.String(),
r.Referer(),
r.UserAgent(),
r.ContentLength,
isProxy,
)
}
func main() {
// Handle reverse proxy on 'proxyPath' to 'proxyURL' when both are set.
if proxyPath != "" && proxyURL != nil {
// Reverse proxy handler.
proxy := httputil.NewSingleHostReverseProxy(proxyURL)
http.HandleFunc(proxyPath, func(w http.ResponseWriter, r *http.Request) {
// Set any custom headers here.
//w.Header().Set("X-Go-Proxy", "Go-Proxy")
// Serve proxy request
proxy.ServeHTTP(w, r)
// Log request
logRequest(r, true)
})
}
// Static file handler.
server := http.FileServer(http.Dir(static))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Set any custom headers here.
//w.Header().Set("X-Go-Proxy", "Go-Proxy")
// Serve static request
server.ServeHTTP(w, r)
// Log request
logRequest(r, false)
})
// Log start up.
log.Printf("ns=main at=http.ListenAndServe on=start host=%s port=%s", host, port)
// Format listener string.
listener := fmt.Sprintf("%s:%s", host, port)
// Start http server.
err := http.ListenAndServe(listener, nil)
// Log http server fatal error and exit.
log.Fatalf("ns=main at=http.ListenAndServe error=%q", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment