func (rs *RouteServiceConfig) ValidateSignature(headers *http.Header, requestUrl string) error { metadataHeader := headers.Get(RouteServiceMetadata) signatureHeader := headers.Get(RouteServiceSignature) signature, err := SignatureFromHeaders(signatureHeader, metadataHeader, rs.crypto) if err != nil { rs.logger.Info("proxy.route-service.current_key", lager.Data{"error": err.Error()}) // Decrypt the head again trying to use the old key. if rs.cryptoPrev != nil { rs.logger.Info("proxy.route-service.current_key", lager.Data{"error": err.Error()}) signature, err = SignatureFromHeaders(signatureHeader, metadataHeader, rs.cryptoPrev) if err != nil { rs.logger.Info("proxy.route-service.previous_key", lager.Data{"error": err.Error()}) } } return err } err = rs.validateSignatureTimeout(signature) if err != nil { return err } return rs.validateForwardedUrl(signature, requestUrl) }
func createHeaders(extraHeaders http.Header, credentials *auth.Credentials, contentType, rfc1123Date, apiVersion string, isMantaRequest bool) (http.Header, error) { headers := make(http.Header) if extraHeaders != nil { for header, values := range extraHeaders { for _, value := range values { headers.Add(header, value) } } } if extraHeaders.Get("Content-Type") == "" { headers.Add("Content-Type", contentType) } if extraHeaders.Get("Accept") == "" { headers.Add("Accept", contentType) } if rfc1123Date != "" { headers.Set("Date", rfc1123Date) } else { headers.Set("Date", getDateForRegion(credentials, isMantaRequest)) } authHeaders, err := auth.CreateAuthorizationHeader(headers, credentials, isMantaRequest) if err != nil { return http.Header{}, err } headers.Set("Authorization", authHeaders) if apiVersion != "" { headers.Set("X-Api-Version", apiVersion) } headers.Add("User-Agent", gojoyentAgent()) return headers, nil }
func (c *Client) prepareReq(method, rawurl string, header http.Header, in interface{}) (*http.Request, error) { var payload io.Reader switch v := in.(type) { case io.Reader: payload = v case nil: default: var err error payload, err = ToJSON(in) if err != nil { return nil, err } } req, err := http.NewRequest(method, rawurl, payload) if err != nil { return nil, err } if header == nil { header = make(http.Header) } if header.Get("Content-Type") == "" { header.Set("Content-Type", "application/json") } req.Header = header if c.Key != "" { req.SetBasicAuth("", c.Key) } if c.Host != "" { req.Host = c.Host } return req, nil }
func isVerifiedRequest(header http.Header, body []byte) bool { serverSignature := os.Getenv("SECRET") requestSignature := header.Get("X-Hub-Signature") // when not set up with a secret if len(serverSignature) < 1 { log.Println("http.request.signature.verification.skipped") return true } log.Println("http.request.signature.verification.started") if len(requestSignature) < 1 { log.Println("http.request.signature.verification.failed", "missing X-Hub-Signature header") return false } mac := hmac.New(sha1.New, []byte(serverSignature)) mac.Write(body) expectedMAC := mac.Sum(nil) expectedSignature := "sha1=" + hex.EncodeToString(expectedMAC) signatureMatched := hmac.Equal([]byte(expectedSignature), []byte(requestSignature)) if signatureMatched { log.Println("http.request.signature.verification.passed") } else { log.Println("http.request.signature.verification.failed") } return signatureMatched }
func checkHeaderValue(h http.Header, key, expected string) error { actual := h.Get(key) if actual != expected { return fmt.Errorf("Unexpected header value for %q: %q, expected %q", key, actual, expected) } return nil }
func (p *proxyWriter) cacheAge(hdr http.Header, statusCode int) (int64, bool) { if _, ok := hdr["Set-Cookie"]; ok { return 0, false } if v := hdr.Get("Expires"); v != "" { t, err := time.Parse(http.TimeFormat, v) if err != nil || time.Now().After(t) { return 0, false } } if vals, ok := hdr["Cache-Control"]; ok { for _, v := range vals { fields := strings.Fields(v) for _, f := range fields { if f == "no-store" || strings.HasPrefix(f, "no-cache") || strings.HasPrefix(f, "private") { return 0, false } if strings.HasPrefix(f, "max-age=") { age, err := strconv.ParseInt(f[len("max-age="):], 10, 64) if err != nil || age <= 0 { return 0, false } return age, true } } } } return int64(p.c.age(statusCode) / time.Second), true }
func intHeader(key string, h http.Header) (int, error) { if header := h.Get(key); header != "" { return strconv.Atoi(header) } else { return 0, errNoHeader } }
func (s *FwdSuite) TestCustomRewriter(c *C) { var outHeaders http.Header srv := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { outHeaders = req.Header w.Write([]byte("hello")) }) defer srv.Close() f, err := New(Rewriter(&HeaderRewriter{TrustForwardHeader: false, Hostname: "hello"})) c.Assert(err, IsNil) proxy := testutils.NewHandler(func(w http.ResponseWriter, req *http.Request) { req.URL = testutils.ParseURI(srv.URL) f.ServeHTTP(w, req) }) defer proxy.Close() headers := http.Header{ XForwardedProto: []string{"httpx"}, XForwardedFor: []string{"192.168.1.1"}, } re, _, err := testutils.Get(proxy.URL, testutils.Headers(headers)) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(outHeaders.Get(XForwardedProto), Equals, "http") c.Assert(strings.Contains(outHeaders.Get(XForwardedFor), "192.168.1.1"), Equals, false) }
func uploadFileReadParam(header *http.Header) (*meta.MetaInfo, string, error) { path := header.Get(headerPath) fragmentIndex := header.Get(headerIndex) bytesRange := header.Get(headerRange) isLast := header.Get(headerIsLast) version := header.Get(headerVersion) start, end, err := splitRange(bytesRange) if err != nil { fmt.Errorf("[OSS]splitRange error: %s \n", err) return nil, version, err } last := false if isLast == "true" || isLast == "TRUE" { last = true } index, err := strconv.ParseUint(fragmentIndex, 10, 64) if err != nil { fmt.Errorf("[OSS]parse fragmentIndex error: %s \n", err) return nil, version, err } fmt.Printf("[OSS][uploadFileReadParam] path: %s, fragmentIndex: %d, bytesRange: %d-%d, isLast: %v \n", path, index, start, end, last) metaInfoValue := &meta.MetaInfoValue{ Index: index, Start: start, End: end, IsLast: last, } metaInfo := &meta.MetaInfo{Path: path, Value: metaInfoValue} return metaInfo, version, nil }
// NewDecor returns a new decoder based on the HTTP header. func NewDecoder(r io.Reader, h http.Header) (Decoder, error) { ct := h.Get(hdrContentType) mediatype, params, err := mime.ParseMediaType(ct) if err != nil { return nil, fmt.Errorf("invalid Content-Type header %q: %s", ct, err) } const ( protoType = ProtoType + "/" + ProtoSubType textType = "text/plain" ) switch mediatype { case protoType: if p := params["proto"]; p != ProtoProtocol { return nil, fmt.Errorf("unrecognized protocol message %s", p) } if e := params["encoding"]; e != "delimited" { return nil, fmt.Errorf("unsupported encoding %s", e) } return &protoDecoder{r: r}, nil case textType: if v, ok := params["version"]; ok && v != "0.0.4" { return nil, fmt.Errorf("unrecognized protocol version %s", v) } return &textDecoder{r: r}, nil default: return nil, fmt.Errorf("unsupported media type %q, expected %q or %q", mediatype, protoType, textType) } }
// certExpirationTime computes a cert freshness based on Cache-Control // and Age headers of h. // // Returns 0 if one of the required headers is not present or cert lifetime // is expired. func certExpirationTime(h http.Header) time.Duration { // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 indicates only // a comma-separated header is valid, so it should be fine to split this on // commas. var max int for _, entry := range strings.Split(h.Get("Cache-Control"), ",") { max = maxAge(entry) if max > 0 { break } } if max <= 0 { return 0 } age, err := strconv.Atoi(h.Get("Age")) if err != nil { return 0 } remainingTime := max - age if remainingTime <= 0 { return 0 } return time.Duration(remainingTime) * time.Second }
func (rs *RouteServiceConfig) ValidateSignature(headers *http.Header) error { metadataHeader := headers.Get(RouteServiceMetadata) signatureHeader := headers.Get(RouteServiceSignature) signature, err := SignatureFromHeaders(signatureHeader, metadataHeader, rs.crypto) if err != nil { rs.logger.Warnd(map[string]interface{}{"error": err.Error()}, "proxy.route-service.current_key") // Decrypt the head again trying to use the old key. if rs.cryptoPrev != nil { rs.logger.Warnd(map[string]interface{}{"error": err.Error()}, "proxy.route-service.current_key") signature, err = SignatureFromHeaders(signatureHeader, metadataHeader, rs.cryptoPrev) if err != nil { rs.logger.Warnd(map[string]interface{}{"error": err.Error()}, "proxy.route-service.previous_key") } } return err } err = rs.validateSignatureTimeout(signature) if err != nil { return err } return rs.validateForwardedUrl(signature, headers) }
func baseURI(h *http.Header) string { baseURI := h.Get("X-Requested-Uri") if strings.HasSuffix(baseURI, "/") { baseURI = baseURI[:len(baseURI)-1] } return baseURI }
func (b *B2) readHeaderFileInfo(header http.Header) (*FileInfo, error) { var err error info := &FileInfo{conn: b} info.AccountID = b.AccountID info.Type = header.Get("Content-Type") info.ID = header.Get("X-Bz-File-Id") info.Length, err = strconv.ParseInt(header.Get("Content-Length"), 10, 64) if err != nil { return nil, err } info.Name, err = url.QueryUnescape(header.Get("X-Bz-File-Name")) if err != nil { return nil, err } info.Sha1 = header.Get("X-Bz-Content-Sha1") for headerName, val := range header { if !strings.HasPrefix(headerName, HeaderInfoPrefix) { continue } // B2 does not support multiple values per header info.Info[headerName[len(HeaderInfoPrefix):]] = val[0] } return info, nil }
// SignedInId returns the id of signed in user. func SignedInId(header http.Header, sess session.SessionStore) int64 { if !models.HasEngine { return 0 } if setting.Service.EnableReverseProxyAuth { webAuthUser := header.Get(setting.ReverseProxyAuthUser) if len(webAuthUser) > 0 { u, err := models.GetUserByName(webAuthUser) if err != nil { if err != models.ErrUserNotExist { log.Error("auth.user.SignedInId(GetUserByName): %v", err) } return 0 } return u.Id } } uid := sess.Get("userId") if uid == nil { return 0 } if id, ok := uid.(int64); ok { if _, err := models.GetUserById(id); err != nil { if err != models.ErrUserNotExist { log.Error("auth.user.SignedInId(GetUserById): %v", err) } return 0 } return id } return 0 }
// DoHTTPProbe checks if a GET request to the url succeeds. // If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Success. // If the HTTP response code is unsuccessful or HTTP communication fails, it returns Failure. // This is exported because some other packages may want to do direct HTTP probes. func DoHTTPProbe(url *url.URL, headers http.Header, client HTTPGetInterface) (probe.Result, string, error) { req, err := http.NewRequest("GET", url.String(), nil) if err != nil { // Convert errors into failures to catch timeouts. return probe.Failure, err.Error(), nil } req.Header = headers if headers.Get("Host") != "" { req.Host = headers.Get("Host") } res, err := client.Do(req) if err != nil { // Convert errors into failures to catch timeouts. return probe.Failure, err.Error(), nil } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { return probe.Failure, "", err } body := string(b) if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { glog.V(4).Infof("Probe succeeded for %s, Response: %v", url.String(), *res) return probe.Success, body, nil } glog.V(4).Infof("Probe failed for %s with request headers %v, response body: %v", url.String(), headers, body) return probe.Failure, fmt.Sprintf("HTTP probe failed with statuscode: %d", res.StatusCode), nil }
func ParseLXDFileHeaders(headers http.Header) (uid int, gid int, mode int, type_ string) { uid, err := strconv.Atoi(headers.Get("X-LXD-uid")) if err != nil { uid = -1 } gid, err = strconv.Atoi(headers.Get("X-LXD-gid")) if err != nil { gid = -1 } mode, err = strconv.Atoi(headers.Get("X-LXD-mode")) if err != nil { mode = -1 } else { rawMode, err := strconv.ParseInt(headers.Get("X-LXD-mode"), 0, 0) if err == nil { mode = int(os.FileMode(rawMode) & os.ModePerm) } } type_ = headers.Get("X-LXD-type") /* backwards compat: before "type" was introduced, we could only * manipulate files */ if type_ == "" { type_ = "file" } return uid, gid, mode, type_ }
// Generic Handler for HTTP request // Allows the passing of additional HTTP request header K/V pairs func (c *Client) request(req, url string, options *http.Header, buffer io.Reader) (*http.Response, error) { request, err := http.NewRequest(req, url, buffer) if err != nil { return nil, errors.New("Unable to create HTTP " + req + " Request") } // If header map passed in , add additional KV pairs request.Header = c.Header if options != nil && len(*options) > 0 { for k, v := range *options { for _, el := range v { request.Header.Add(k, el) } } } // If we are not sending data, delete the default content-Type if buffer == nil { request.Header.Del("Content-Type") } // TODO : Add extra field to signal serializing // Note : Determine if this has actual effect contentType := options.Get("Content-Type") if options.Get("Content-Type") != "" { request.Header.Set("Content-Type", contentType) } return c.hClient.Do(request) }
func timeHeader(key string, h http.Header) (time.Time, error) { if header := h.Get(key); header != "" { return http.ParseTime(header) } else { return time.Time{}, errNoHeader } }
// CheckSPNEGONegotiate checks for the presence of a Negotiate header. If // present, we return a gssapi Token created from the header value sent to us. func CheckSPNEGONegotiate(lib *gssapi.Lib, h http.Header, name string) (present bool, token *gssapi.Buffer) { var err error defer func() { if err != nil { lib.Debug(fmt.Sprintf("CheckSPNEGONegotiate: %v", err)) } }() v := h.Get(name) if len(v) == 0 || !strings.HasPrefix(v, "Negotiate") { return false, nil } present = true tbytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(v[len("Negotiate"):])) if err != nil { return false, nil } if len(tbytes) > 0 { token, err = lib.MakeBufferBytes(tbytes) if err != nil { return false, nil } } return present, token }
// sandstormPermissions extracts the permissions in the request header. func sandstormPermissions(h http.Header) []string { p := h.Get("X-Sandstorm-Permissions") if p == "" { return nil } return strings.Split(p, ",") }
// HTTPGetContentType returns the HTTP request `Content-Type' header value. func HTTPGetContentType(input interface{}) string { var ( header http.Header ) switch input.(type) { case *http.Request: header = input.(*http.Request).Header case *http.Response: header = input.(*http.Response).Header case http.ResponseWriter: header = input.(http.ResponseWriter).Header() default: return "" } contentType := header.Get("Content-Type") index := strings.Index(contentType, ";") if index != -1 { return contentType[:index] } return contentType }
// ParseValueAndParams parses a comma separated list of values with optional // semicolon separated name-value pairs. Content-Type and Content-Disposition // headers are in this format. func ParseValueAndParams(header http.Header, key string) (value string, params map[string]string) { params = make(map[string]string) s := header.Get(key) value, s = expectTokenSlash(s) if value == "" { return } value = strings.ToLower(value) s = skipSpace(s) for strings.HasPrefix(s, ";") { var pkey string pkey, s = expectToken(skipSpace(s[1:])) if pkey == "" { return } if !strings.HasPrefix(s, "=") { return } var pvalue string pvalue, s = expectTokenOrQuoted(s[1:]) if pvalue == "" { return } pkey = strings.ToLower(pkey) params[pkey] = pvalue s = skipSpace(s) } return }
// Parses a JSON MIME body, unmarshaling it into "into". func ReadJSONFromMIME(headers http.Header, input io.Reader, into interface{}) error { contentType := headers.Get("Content-Type") if contentType != "" && !strings.HasPrefix(contentType, "application/json") { return base.HTTPErrorf(http.StatusUnsupportedMediaType, "Invalid content type %s", contentType) } switch headers.Get("Content-Encoding") { case "gzip": var err error if input, err = gzip.NewReader(input); err != nil { return err } case "": break default: return base.HTTPErrorf(http.StatusUnsupportedMediaType, "Unsupported Content-Encoding; use gzip") } decoder := json.NewDecoder(input) if err := decoder.Decode(into); err != nil { base.Warn("Couldn't parse JSON in HTTP request: %v", err) return base.HTTPErrorf(http.StatusBadRequest, "Bad JSON") } return nil }
func assertHeaders(t *testing.T, resHeaders http.Header, reqHeaders map[string]string) { for name, value := range reqHeaders { if resHeaders.Get(name) != value { t.Errorf("Invalid header '%s', wanted '%s', got '%s'", name, value, resHeaders.Get(name)) } } }
func getEndToEndHeaders(respHeaders http.Header) []string { // These headers are always hop-by-hop hopByHopHeaders := map[string]struct{}{ "Connection": struct{}{}, "Keep-Alive": struct{}{}, "Proxy-Authenticate": struct{}{}, "Proxy-Authorization": struct{}{}, "Te": struct{}{}, "Trailers": struct{}{}, "Transfer-Encoding": struct{}{}, "Upgrade": struct{}{}, } for _, extra := range strings.Split(respHeaders.Get("connection"), ",") { // any header listed in connection, if present, is also considered hop-by-hop if strings.Trim(extra, " ") != "" { hopByHopHeaders[http.CanonicalHeaderKey(extra)] = struct{}{} } } endToEndHeaders := []string{} for respHeader, _ := range respHeaders { if _, ok := hopByHopHeaders[respHeader]; !ok { endToEndHeaders = append(endToEndHeaders, respHeader) } } return endToEndHeaders }
func (c *Context) newHTTPResponse(reqURL string, respURL string, body []byte, statusCode int, headers http.Header) otto.Value { respHeaders := make(map[string]string, len(headers)) for k := range headers { respHeaders[k] = headers.Get(k) } return c.mustCallValue("new M.http.Response", nil, respURL, string(body), statusCode, reqURL, respHeaders).val }
func TestSampleWithRequestHeaders(t *testing.T) { var header http.Header handler := func(w http.ResponseWriter, r *http.Request) { header = r.Header fmt.Fprintf(w, "ok") } ts := httptest.NewServer(http.HandlerFunc(handler)) defer ts.Close() target := Target{ URL: parseUrl(ts.URL), RequestHeaders: map[string]string{ "X-Foo": "bar", }, } sample, err := Ping(target, 1) if err != nil { t.Fatal(err) } if sample.StatusCode != 200 { t.Fatalf("Expected sampleStatus == 200, but got %d\n", sample.StatusCode) } h := header.Get("X-Foo") if h != "bar" { t.Fatalf("Expected request header X-Foo to be 'bar' but was '%s'", h) } }
// isContentType validates the Content-Type header // is contentType. That is, its type and subtype match. func isContentType(h http.Header, contentType string) bool { ct := h.Get("Content-Type") if i := strings.IndexRune(ct, ';'); i != -1 { ct = ct[0:i] } return ct == contentType }
func Authenticate(h http.Header, cfg config.Config) bool { session, err := mongo.OpenSession(cfg.MongoDB) defer mongo.CloseSession(session) if err != nil { panic(err) } query := bson.M{ "apiKey": h.Get("x-api-key"), } results := []Auth{} err = mongo.Find(session, cfg.MongoDB.Db, "authentication", query, "apiKey", &results) if err != nil { return false } if len(results) > 0 { return true } return false }