func Test_RecoveryMiddleware(t *testing.T) { called := false recoverFunc := func(rw http.ResponseWriter, r *http.Request) { assert.False(t, called) called = true } next := func(w http.ResponseWriter, r *http.Request) { // recover func is defered until after next() assert.False(t, called) } r, err := http.NewRequest("GET", "http://example.com/foo/bar", nil) assert.Nil(t, err) // sanity rw := negroni.NewResponseWriter(httptest.NewRecorder()) middleware := RecoveryMiddleware(recoverFunc) assert.Equal(t, reflect.ValueOf(recoverFunc), reflect.ValueOf(middleware.(*recoveryMiddleware).recoverFunc)) middleware.ServeHTTP(rw, r, next) assert.True(t, called) }
func (m *modified) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // TODO: Somehow find out if response is already set to not modified, so we // we exit immediately. // Set any possible cache control headers if none have been set yet. if m.cacheControl != `` && rw.Header().Get(headerCacheControl) == `` { rw.Header().Set(headerCacheControl, m.cacheControl) } // Override default writer. nrw := negroni.NewResponseWriter(rw) crw := &modifiedResponseWriter{ bufio.NewWriter(rw), nrw, } next(crw, r) // Check if both client and server are using cache capabilities. if IfModifiedSince(r, rw.Header().Get(headerLastModified)) { // Either of the required headers are not set. Write whatever we have // to regular writer and return. // TODO: Error check. crw.c.Flush() return } // Discard any data because user agent already has the latest version. crw.c.Reset(ioutil.Discard) rw.WriteHeader(http.StatusNotModified) }
func Logging(h http.Handler) http.Handler { l := &negroni.Logger{log.New(os.Stdout, "[api] ", 0)} return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { nw := negroni.NewResponseWriter(w) l.ServeHTTP(nw, r, h.ServeHTTP) }) }
func (c *NoCache) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http.HandlerFunc) { newRw := negroni.NewResponseWriter(rw) newRw.Before(func(rw negroni.ResponseWriter) { c.setNoCacheHeader(rw) }) next(newRw, req) }
func TestCounters(t *testing.T) { c := mockClient{} m := Middleware{client: &c, prefix: "prefix"} recorder := negroni.NewResponseWriter(httptest.NewRecorder()) recorder.WriteHeader(200) m.countResponse(recorder) assert.Equal(t, "prefix.request.200", c.counterName) }
func (s *S) TestResponseHeaderMiddleware(c *check.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("PUT", "/my/path", nil) c.Assert(err, check.IsNil) middle := responseHeaderMiddleware{name: "Server", value: "super-server/0.1"} middle.ServeHTTP(negroni.NewResponseWriter(recorder), request, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello")) })) c.Assert(recorder.Header().Get("Server"), check.Equals, "super-server/0.1") }
func Logging(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { nw := negroni.NewResponseWriter(w) l := &negroni.Logger{ log.New(os.Stdout, fmt.Sprintf("api %s ", cryptoutils.RandToken(5)), 0), } l.ServeHTTP(nw, r, h.ServeHTTP) }) }
func TestTokenVerificationMiddlewarePutWithoutTokenAndNoTokenEnforcement(t *testing.T) { h := NewTokenVerificationMiddleware() h.Initialize() r, _ := http.NewRequest("PUT", "/", strings.NewReader("")) r.Header.Add("Accept", "application/json") rec := httptest.NewRecorder() rw := negroni.NewResponseWriter(rec) rw.Header().Set("Content-Type", "application/json") h.Run(rw, r, DummyHandler) assert.Equal(t, http.StatusOK, rec.Code) }
// ServeHTTP wraps the http.ResponseWriter with a gzip.Writer. func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // Skip compression if the client doesn't accept gzip encoding. if !strings.Contains(r.Header.Get(headerAcceptEncoding), encodingGzip) { next(w, r) return } // Skip compression if client attempt WebSocket connection if len(r.Header.Get(headerSecWebSocketKey)) > 0 { next(w, r) return } // Skip compression if already compressed if w.Header().Get(headerContentEncoding) == encodingGzip { next(w, r) return } // Retrieve gzip writer from the pool. Reset it to use the ResponseWriter. // This allows us to re-use an already allocated buffer rather than // allocating a new buffer for every request. // We defer g.pool.Put here so that the gz writer is returned to the // pool if any thing after here fails for some reason (functions in // next could potentially panic, etc) gz := h.pool.Get().(*gzip.Writer) defer h.pool.Put(gz) gz.Reset(w) // Set the appropriate gzip headers. headers := w.Header() headers.Set(headerContentEncoding, encodingGzip) headers.Set(headerVary, headerAcceptEncoding) // Wrap the original http.ResponseWriter with negroni.ResponseWriter // and create the gzipResponseWriter. nrw := negroni.NewResponseWriter(w) grw := gzipResponseWriter{ gz, nrw, } // Call the next handler supplying the gzipResponseWriter instead of // the original. next(grw, r) // Delete the content length after we know we have been written to. grw.Header().Del(headerContentLength) gz.Close() }
func (s *S) TestLoggerMiddleware(c *check.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("PUT", "/my/path", nil) c.Assert(err, check.IsNil) var out bytes.Buffer middle := loggerMiddleware{ logger: log.New(&out, "", 0), } middle.ServeHTTP(negroni.NewResponseWriter(recorder), request, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello")) })) timePart := time.Now().Format(time.RFC3339Nano)[:19] c.Assert(out.String(), check.Matches, fmt.Sprintf(`(?m)%s\..+? PUT /my/path 200 in [\d.]+ms$`, timePart)) }
// ServeHTTP wraps the http.ResponseWriter with a gzip.Writer. func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // Skip compression if the client doesn't accept gzip encoding. if !strings.Contains(r.Header.Get(headerAcceptEncoding), encodingGzip) { next(w, r) return } // Skip compression if client attempt WebSocket connection if len(r.Header.Get(headerSecWebSocketKey)) > 0 { next(w, r) return } // Skip compression if already compressed if w.Header().Get(headerContentEncoding) == encodingGzip { next(w, r) return } // Create new gzip Writer. Skip compression if an invalid compression // level was set. gz, err := gzip.NewWriterLevel(w, h.compressionLevel) if err != nil { next(w, r) return } // Wrap the original http.ResponseWriter with negroni.ResponseWriter // and create the gzipResponseWriter. nrw := negroni.NewResponseWriter(w) grw := gzipResponseWriter{ r: r, w: gz, ResponseWriter: nrw, allowCompression: h.allowCompression, status: COMPRESSION_CHECK, } defer func() { if grw.status == COMPRESSION_ENABLED { // Calling .Close() does write the GZIP header. // This should only happend when compression is enabled. gz.Close() } }() // Call the next handler supplying the gzipResponseWriter instead of // the original. next(&grw, r) }
func TestModifiedResponseWriter_Write(t *testing.T) { rw := &respWriteTest{ h: make(http.Header), } nrw := negroni.NewResponseWriter(rw) crw := &modifiedResponseWriter{ bufio.NewWriter(rw), nrw, } if n, err := crw.Write([]byte(`test`)); n != 4 || err != nil { t.Errorf(`negronimodified.modifiedResponseWriter.Write(%s) = %d, %v; want %d, nil`, []byte(`test`), n, err, 4) } // TODO: Check if correct data has been written. }
// ServeHTTP wraps the http.ResponseWriter with a gzip.Writer. func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // Skip compression if the client doesn't accept gzip encoding. if !strings.Contains(r.Header.Get(headerAcceptEncoding), encodingGzip) { next(w, r) return } // Skip compression if client attempt WebSocket connection if len(r.Header.Get(headerSecWebSocketKey)) > 0 { next(w, r) return } // Skip compression if already compressed if w.Header().Get(headerContentEncoding) == encodingGzip { next(w, r) return } // Create new gzip Writer. Skip compression if an invalid compression // level was set. gz, err := gzip.NewWriterLevel(w, h.compressionLevel) if err != nil { next(w, r) return } defer gz.Close() // Set the appropriate gzip headers. headers := w.Header() headers.Set(headerContentEncoding, encodingGzip) headers.Set(headerVary, headerAcceptEncoding) // Wrap the original http.ResponseWriter with negroni.ResponseWriter // and create the gzipResponseWriter. nrw := negroni.NewResponseWriter(w) grw := gzipResponseWriter{ gz, nrw, } // Call the next handler supplying the gzipResponseWriter instead of // the original. next(grw, r) // Delete the content length after we know we have been written to. grw.Header().Del(headerContentLength) }
func TestTokenVerificationMiddlewareGetWithoutTokenAndTokenEnforcement(t *testing.T) { os.Setenv("STREAMMARKER_DATA_ACCESS_API_TOKENS", "abc123,foobar") defer os.Setenv("STREAMMARKER_DATA_ACCESS_API_TOKENS", "") h := NewTokenVerificationMiddleware() h.Initialize() r, _ := http.NewRequest("GET", "/", strings.NewReader("")) r.Header.Add("Accept", "application/json") rec := httptest.NewRecorder() rw := negroni.NewResponseWriter(rec) rw.Header().Set("Content-Type", "application/json") h.Run(rw, r, DummyHandler) assert.Equal(t, http.StatusUnauthorized, rec.Code) }
func (s *S) TestLoggerMiddleware(c *check.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("PUT", "/my/path", nil) c.Assert(err, check.IsNil) h, handlerLog := doHandler() handlerLog.sleep = 100 * time.Millisecond handlerLog.response = http.StatusOK var out bytes.Buffer middle := loggerMiddleware{ logger: log.New(&out, "", 0), } middle.ServeHTTP(negroni.NewResponseWriter(recorder), request, h) c.Assert(handlerLog.called, check.Equals, true) timePart := time.Now().Format(time.RFC3339Nano)[:19] c.Assert(out.String(), check.Matches, fmt.Sprintf(`%s\..+? PUT /my/path 200 in 10\d\.\d+ms`+"\n", timePart)) }
func Test_RecoveryMiddleware_nilRecoverFunc(t *testing.T) { nextCalled := false next := func(w http.ResponseWriter, r *http.Request) { nextCalled = true } r, err := http.NewRequest("GET", "http://example.com/foo/bar", nil) assert.Nil(t, err) // sanity rw := negroni.NewResponseWriter(httptest.NewRecorder()) middleware := RecoveryMiddleware(nil) assert.Nil(t, middleware.(*recoveryMiddleware).recoverFunc) middleware.ServeHTTP(rw, r, next) assert.True(t, nextCalled) }
func setupServeHTTP(t *testing.T) (*Middleware, negroni.ResponseWriter, *http.Request) { req, err := http.NewRequest("GET", "http://example.com/stuff?rly=ya", nil) assert.Nil(t, err) req.RequestURI = "http://example.com/stuff?rly=ya" req.Method = "GET" req.Header.Set("X-Request-Id", "22035D08-98EF-413C-BBA0-C4E66A11B28D") req.Header.Set("X-Real-IP", "10.10.10.10") mw := NewMiddleware() mw.Logger.Formatter = &logrus.JSONFormatter{ TimestampFormat: "2006-01-02", } mw.Logger.Out = &bytes.Buffer{} mw.clock = &testClock{} return mw, negroni.NewResponseWriter(httptest.NewRecorder()), req }
func (s *S) TestLoggerMiddlewareWithRequestID(c *check.C) { config.Set("request-id-header", "Request-ID") defer config.Unset("request-id-header") recorder := httptest.NewRecorder() request, err := http.NewRequest("PUT", "/my/path", nil) c.Assert(err, check.IsNil) context.SetRequestID(request, "Request-ID", "my-rid") h, handlerLog := doHandler() handlerLog.sleep = 100 * time.Millisecond handlerLog.response = http.StatusOK var out bytes.Buffer middle := loggerMiddleware{ logger: log.New(&out, "", 0), } middle.ServeHTTP(negroni.NewResponseWriter(recorder), request, h) c.Assert(handlerLog.called, check.Equals, true) timePart := time.Now().Format(time.RFC3339Nano)[:19] c.Assert(out.String(), check.Matches, fmt.Sprintf(`%s\..+? PUT /my/path 200 in 1\d{2}\.\d+ms \[Request-ID: my-rid\]`+"\n", timePart)) }
func Test_LoggingMiddleware(t *testing.T) { state := "start" t0 := time.Now() var t1 time.Time prelogFunc := func(method, path string, start time.Time) { assert.Equal(t, "start", state) state = "prelogCalled" assert.Equal(t, "GET", method) assert.Equal(t, "/foo/bar", path) assert.True(t, t0.Before(start)) t1 = start } next := func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "prelogCalled", state) state = "nextCalled" w.WriteHeader(200) } postlogFunc := func(method, path string, status int, dur time.Duration) { assert.Equal(t, "nextCalled", state) state = "postlogCalled" assert.Equal(t, "GET", method) assert.Equal(t, "/foo/bar", path) assert.Equal(t, 200, status) assert.True(t, dur <= time.Since(t1)) } r, err := http.NewRequest("GET", "http://example.com/foo/bar", nil) assert.Nil(t, err) // sanity rw := negroni.NewResponseWriter(httptest.NewRecorder()) middleware := LoggingMiddleware(prelogFunc, postlogFunc) assert.Equal(t, reflect.ValueOf(prelogFunc), reflect.ValueOf(middleware.(*loggingMiddleware).preLogFunc)) assert.Equal(t, reflect.ValueOf(postlogFunc), reflect.ValueOf(middleware.(*loggingMiddleware).postLogFunc)) middleware.ServeHTTP(rw, r, next) assert.Equal(t, "postlogCalled", state) }
func Test_LoggingMiddleware_nilFuncs(t *testing.T) { state := "start" next := func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "start", state) state = "nextCalled" } r, err := http.NewRequest("GET", "http://example.com/foo/bar", nil) assert.Nil(t, err) // sanity rw := negroni.NewResponseWriter(httptest.NewRecorder()) middleware := LoggingMiddleware(nil, nil) assert.Nil(t, middleware.(*loggingMiddleware).preLogFunc) assert.Nil(t, middleware.(*loggingMiddleware).postLogFunc) middleware.ServeHTTP(rw, r, next) assert.Equal(t, "nextCalled", state) }
func (dr *DisallowRobots) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http.HandlerFunc) { if dr.Env { next(rw, req) return } file := req.URL.Path wh := rw.Header() if file == "/robots.txt" { wh.Set("User-Agent", "*\nDisallow: /") wh.Set("Content-Type", "text/plain") rw.WriteHeader(http.StatusOK) return } newRw := negroni.NewResponseWriter(rw) newRw.Before(func(rw negroni.ResponseWriter) { rw.Header().Set("X-Robots-Tag", "noindex, nofollow, noarchive") }) next(newRw, req) }