From 761cb2c7400e05b0bf5357966f7b4aa6ea976498 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 7 Mar 2016 09:52:20 -0800 Subject: [PATCH] handlers: Cleanup time handlers helpers. --- api-headers_test.go | 2 +- generic-handlers.go | 94 +++++++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/api-headers_test.go b/api-headers_test.go index 847e70e9a..f8b13867d 100644 --- a/api-headers_test.go +++ b/api-headers_test.go @@ -22,7 +22,7 @@ import ( func TestGenerateRequestID(t *testing.T) { // Ensure that it returns an alphanumeric result of length 16. - var id []byte = generateRequestID() + var id = generateRequestID() if len(id) != 16 { t.Fail() diff --git a/generic-handlers.go b/generic-handlers.go index 2d7bd63ff..fe46762f5 100644 --- a/generic-handlers.go +++ b/generic-handlers.go @@ -45,49 +45,6 @@ func registerHandlers(mux *router.Router, handlerFns ...HandlerFunc) http.Handle return f } -// Attempts to parse date string into known date layouts. Date layouts -// currently supported are ``time.RFC1123``, ``time.RFC1123Z`` and -// special ``iso8601Format``. -func parseKnownLayouts(date string) (time.Time, error) { - parsedTime, e := time.Parse(time.RFC1123, date) - if e == nil { - return parsedTime, nil - } - parsedTime, e = time.Parse(time.RFC1123Z, date) - if e == nil { - return parsedTime, nil - } - parsedTime, e = time.Parse(iso8601Format, date) - if e == nil { - return parsedTime, nil - } - return time.Time{}, e -} - -// Parse date string from incoming header, current supports and verifies -// follow HTTP headers. -// -// - X-Amz-Date -// - X-Minio-Date -// - Date -// -// In following time layouts ``time.RFC1123``, ``time.RFC1123Z`` and ``iso8601Format``. -func parseDateHeader(req *http.Request) (time.Time, error) { - amzDate := req.Header.Get(http.CanonicalHeaderKey("x-amz-date")) - if amzDate != "" { - return parseKnownLayouts(amzDate) - } - minioDate := req.Header.Get(http.CanonicalHeaderKey("x-minio-date")) - if minioDate != "" { - return parseKnownLayouts(minioDate) - } - genericDate := req.Header.Get("Date") - if genericDate != "" { - return parseKnownLayouts(genericDate) - } - return time.Time{}, errors.New("Date header missing, invalid request.") -} - // Adds redirect rules for incoming requests. type redirectHandler struct { handler http.Handler @@ -163,6 +120,53 @@ func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ h.handler.ServeHTTP(w, r) } +// Supported incoming date formats. +var timeFormats = []string{ + time.RFC1123, + time.RFC1123Z, + iso8601Format, +} + +// Attempts to parse date string into known date layouts. Date layouts +// currently supported are +// - ``time.RFC1123`` +// - ``time.RFC1123Z`` +// - ``iso8601Format`` +func parseDate(date string) (parsedTime time.Time, e error) { + for _, layout := range timeFormats { + parsedTime, e = time.Parse(layout, date) + if e == nil { + return parsedTime, nil + } + } + return time.Time{}, e +} + +// Parse date string from incoming header, current supports and verifies +// follow HTTP headers. +// +// - X-Amz-Date +// - X-Minio-Date +// - Date +// +// In following time layouts ``time.RFC1123``, ``time.RFC1123Z`` and +// ``iso8601Format``. +var dateHeaders = []string{ + "x-amz-date", + "x-minio-date", + "date", +} + +func parseDateHeader(req *http.Request) (time.Time, error) { + for _, dateHeader := range dateHeaders { + date := req.Header.Get(http.CanonicalHeaderKey(dateHeader)) + if date != "" { + return parseDate(date) + } + } + return time.Time{}, errors.New("Date header missing, invalid request.") +} + type timeHandler struct { handler http.Handler } @@ -183,11 +187,9 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) return } - duration := time.Since(date) - minutes := time.Duration(5) * time.Minute // Verify if the request date header is more than 5minutes // late, reject such clients. - if duration.Minutes() > minutes.Minutes() { + if time.Now().UTC().Sub(date)/time.Minute > time.Duration(5)*time.Minute { writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) return }