diff --git a/httpbin/handlers.go b/httpbin/handlers.go index 29ed07d4067783d19e1c39c99dfbcb897157fbf1..64bed3f8cf29e1e06099726c28c4fe4ddf197f8b 100644 --- a/httpbin/handlers.go +++ b/httpbin/handlers.go @@ -11,6 +11,8 @@ import ( "strconv" "strings" "time" + + "github.com/mccutchen/go-httpbin/httpbin/digest" ) var acceptedMediaTypes = []string{ @@ -841,3 +843,47 @@ func doImage(w http.ResponseWriter, kind string) { func (h *HTTPBin) XML(w http.ResponseWriter, r *http.Request) { writeResponse(w, http.StatusOK, "application/xml", MustAsset("sample.xml")) } + +// DigestAuth blah +// +// /digest-auth/<qop>/<user>/<passwd> +// /digest-auth/<qop>/<user>/<passwd>/<algorithm> +func (h *HTTPBin) DigestAuth(w http.ResponseWriter, r *http.Request) { + parts := strings.Split(r.URL.Path, "/") + count := len(parts) + + if count != 5 && count != 6 { + http.Error(w, "Not Found", http.StatusNotFound) + return + } + + qop := strings.ToLower(parts[2]) + user := parts[3] + password := parts[4] + + algorithm := "MD5" + if count == 6 { + algorithm = strings.ToUpper(parts[5]) + } + + if qop != "auth" { + http.Error(w, "Invalid QOP directive", http.StatusBadRequest) + return + } + if algorithm != "MD5" && algorithm != "SHA-256" { + http.Error(w, "Invalid algorithm", http.StatusBadRequest) + return + } + + if !digest.Check(r, user, password) { + w.Header().Set("WWW-Authenticate", digest.Challenge("go-httpbin", algorithm)) + w.WriteHeader(http.StatusUnauthorized) + return + } + + resp, _ := json.Marshal(&authResponse{ + Authorized: true, + User: user, + }) + writeJSON(w, resp, http.StatusOK) +} diff --git a/httpbin/helpers.go b/httpbin/helpers.go index 682996e2de720cd7e0e950b988855a3072e39e95..e1d94fd7c398d432203f7f5d9e5fd4a4a6c15437 100644 --- a/httpbin/helpers.go +++ b/httpbin/helpers.go @@ -77,6 +77,7 @@ func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse, maxMe // Restrict size of request body r.Body = http.MaxBytesReader(w, r.Body, maxMemory) + defer r.Body.Close() ct := r.Header.Get("Content-Type") switch { diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go index 69d38cdb484508697ac9d8683ace7ece816f66e0..1c2a462752e17d82b8c103426a581077aff2c774 100644 --- a/httpbin/httpbin.go +++ b/httpbin/httpbin.go @@ -114,6 +114,7 @@ func (h *HTTPBin) Handler() http.Handler { mux.HandleFunc("/basic-auth/", h.BasicAuth) mux.HandleFunc("/hidden-basic-auth/", h.HiddenBasicAuth) + mux.HandleFunc("/digest-auth/", h.DigestAuth) mux.HandleFunc("/deflate", h.Deflate) mux.HandleFunc("/gzip", h.Gzip) @@ -140,9 +141,6 @@ func (h *HTTPBin) Handler() http.Handler { mux.HandleFunc("/image/", h.Image) mux.HandleFunc("/xml", h.XML) - // Not implemented - mux.HandleFunc("/digest-auth/", notImplementedHandler) - // Make sure our ServeMux doesn't "helpfully" redirect these invalid // endpoints by adding a trailing slash. See the ServeMux docs for more // info: https://golang.org/pkg/net/http/#ServeMux