github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/util/http.go (about) 1 package util 2 3 import ( 4 "crypto/tls" 5 "encoding/json" 6 "net/http" 7 "strconv" 8 "strings" 9 10 "github.com/gorilla/mux" 11 "github.com/mongodb/grip" 12 "github.com/pkg/errors" 13 ) 14 15 // WriteJSON writes a json response with the supplied code on the given writer. 16 func WriteJSON(w *http.ResponseWriter, data interface{}, status int) { 17 // write the response 18 (*w).Header().Add("Content-Type", "application/json") 19 (*w).Header().Add("Connection", "close") 20 21 jsonBytes, err := json.Marshal(data) 22 if err != nil { 23 (*w).WriteHeader(500) 24 _, _ = (*w).Write([]byte("{}")) 25 return 26 } 27 28 (*w).WriteHeader(status) 29 _, err = (*w).Write(jsonBytes) 30 grip.Warning(err) 31 } 32 33 // MakeTlsConfig creates a TLS Config from a certificate and key. 34 func MakeTlsConfig(cert string, key string) (*tls.Config, error) { 35 // Adapted from http.ListenAndServeTLS 36 tlsConfig := &tls.Config{} 37 tlsConfig.NextProtos = []string{"http/1.1"} 38 tlsConfig.Certificates = make([]tls.Certificate, 1) 39 var err error 40 tlsConfig.Certificates[0], err = 41 tls.X509KeyPair([]byte(cert), []byte(key)) 42 if err != nil { 43 return nil, errors.WithStack(err) 44 } 45 return tlsConfig, nil 46 } 47 48 // MountHandler routes all requests to the given mux.Router under the prefix to be handled by 49 // the http.Handler, which the request's path rooted under that prefix. 50 // So for example, if a router configured with the path /foo is given to 51 // MountHandler(r, "/bar/baz", newHandler) 52 // Then a request to the router at /foo/bar/baz/hello will be handled by newHandler, 53 // appearing with the path "/baz/hello" 54 func MountHandler(r *mux.Router, prefix string, h http.Handler) http.Handler { 55 root := r.PathPrefix(prefix) 56 root.Handler( 57 http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) { 58 flattened := make([]string, 0) 59 for k, v := range mux.Vars(rq) { 60 flattened = append(flattened, k) 61 flattened = append(flattened, v) 62 } 63 url, err := root.URL(flattened...) 64 if err != nil { 65 http.NotFound(w, rq) 66 return 67 } 68 strip := strings.TrimSuffix(url.String(), "/") 69 http.StripPrefix(strip, h).ServeHTTP(w, rq) 70 })) 71 return r 72 } 73 74 // GetIntValue returns a form value as an integer 75 func GetIntValue(r *http.Request, valueKey string, defaultValue int) (int, error) { 76 val := r.FormValue(valueKey) 77 if val == "" { 78 return defaultValue, nil 79 } 80 intVal, err := strconv.Atoi(val) 81 if err != nil { 82 return 0, errors.Errorf("%v: cannot convert %v to integer: %v", valueKey, val, err.Error()) 83 } 84 return intVal, nil 85 } 86 87 // GetBoolValue returns a form value as an integer 88 func GetBoolValue(r *http.Request, valueKey string, defaultValue bool) (bool, error) { 89 val := r.FormValue(valueKey) 90 if val == "" { 91 return defaultValue, nil 92 } 93 boolVal, err := strconv.ParseBool(val) 94 if err != nil { 95 return defaultValue, errors.Errorf("%v: cannot convert %v to boolean: %v", valueKey, val, err.Error()) 96 } 97 return boolVal, nil 98 } 99 100 // GetStringArrayValue returns a form value as a string array 101 func GetStringArrayValue(r *http.Request, valueKey string, defaultValue []string) []string { 102 val := r.FormValue(valueKey) 103 if val == "" { 104 return defaultValue 105 } 106 return strings.Split(val, ",") 107 }