Created
May 2, 2015 17:55
-
-
Save reedobrien/ec82d2bd3a92104152cb to your computer and use it in GitHub Desktop.
A basic auth protected proxy server
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 ( | |
"encoding/base64" | |
"flag" | |
"io" | |
"log" | |
"net/http" | |
"strings" | |
) | |
var ( | |
listen = flag.String("listen", "localhost:8080", "listen on address") | |
logit = flag.Bool("log", false, "enable logging") | |
) | |
func main() { | |
flag.Parse() | |
proxyHandler := http.HandlerFunc(proxyHandlerFunc) | |
log.Fatal(http.ListenAndServe(*listen, basicAuth(proxyHandler))) | |
} | |
func proxyHandlerFunc(w http.ResponseWriter, r *http.Request) { | |
// Log it. | |
if *logit { | |
log.Println(r.URL) | |
} | |
client := &http.Client{} | |
// Set up the request. | |
r.RequestURI = "" | |
r.Host = "avail-fe-dev.s3-website-us-east-1.amazonaws.com" | |
r.URL.Scheme = "http" | |
r.URL.Host = r.Host | |
// Proxy it! | |
resp, err := client.Do(r) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// Set up the response | |
for k, vv := range resp.Header { | |
for _, v := range vv { | |
w.Header().Add(k, v) | |
} | |
} | |
io.Copy(w, resp.Body) | |
resp.Body.Close() | |
} | |
// Set up an unauthorized response with auth header | |
func unauthorized(w http.ResponseWriter) { | |
w.Header().Add("WWW-Authenticate", "Basic realm=\"AVAIL\"") | |
http.Error(w, "Unauthorized", http.StatusUnauthorized) | |
} | |
// A basic auth HandleFunc to wrap our proxy handler in. | |
func basicAuth(next http.HandlerFunc) http.HandlerFunc { | |
return func(w http.ResponseWriter, r *http.Request) { | |
if len(r.Header["Authorization"]) == 0 { | |
unauthorized(w) | |
return | |
} | |
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2) | |
if len(auth) != 2 || auth[0] != "Basic" { | |
http.Error(w, "bad syntax", http.StatusBadRequest) | |
return | |
} | |
payload, _ := base64.StdEncoding.DecodeString(auth[1]) | |
pair := strings.SplitN(string(payload), ":", 2) | |
if len(pair) != 2 || !validate(pair[0], pair[1]) { | |
unauthorized(w) | |
return | |
} | |
next(w, r) | |
} | |
} | |
func validate(username, password string) bool { | |
if username == "specialuser" && password == "so seekrity" { | |
return true | |
} | |
return false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment