// Handle takes the next handler as an argument and wraps it in this middleware. func (m *Middle) Handle(next httpware.Handler) httpware.Handler { return httpware.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { q := r.URL.Query() s := q.Get(m.startQuery) l := q.Get(m.limitQuery) page := Page{} var err error if s == "" { page.Start = 0 } else { page.Start, err = strconv.Atoi(s) if err != nil { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.startQuery, "must be an integer") } if page.Start < 0 { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.startQuery, "must not be negative") } } if l == "" { page.Limit = m.limitDefault } else { page.Limit, err = strconv.Atoi(l) if err != nil { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.limitQuery, "must not be an integer") } if page.Limit <= 0 { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.limitQuery, "must not be greater than zero") } } return next.ServeHTTPCtx(context.WithValue(ctx, httpware.PageKey, page), w, r) }) }
func TestLog(t *testing.T) { var buffer bytes.Buffer conf := Defaults conf.Logger.Out = &buffer m := httpware.Compose( httpware.DefaultErrHandler, New(conf), ) s := httptest.NewServer(m.ThenFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { if r.URL.Path == "/400" { return httpware.NewErr("didnt like your request", http.StatusBadRequest) } if r.URL.Path == "/500" { return httpware.NewErr("ahhhh it blew up", http.StatusInternalServerError) } if r.URL.Path == "/panic" { panic("PANIC!") } return nil })) cases := []struct { Path string Expected string }{ { Path: "/", Expected: "success", }, { Path: "/400", Expected: "didnt like your request", }, { Path: "/500", Expected: "ahhhh it blew up", }, { Path: "/panic", Expected: "PANIC!", }, } for _, c := range cases { resp, err := http.Get(s.URL + c.Path) if err != nil { t.Fatal("failed to make request:", err) } resp.Body.Close() got := buffer.String() if !strings.Contains(got, c.Expected) { t.Fatalf("expected log output to contain: '%s', got: \n%s", c.Expected, got) } } }
// handle is meant to demonstrate a POST or PUT endpoint. func handle(ctx context.Context, w http.ResponseWriter, r *http.Request) error { u := &User{} rqt := contentware.ResponseTypeFromCtx(ctx) // Decode from JSON or XML based on the 'Content-Type' header. if err := rqt.Decode(r.Body, u); err != nil { return httpware.NewErr("could not parse body: "+err.Error(), http.StatusBadRequest) } if err := u.validate(); err != nil { return httpware.NewErr("invalid entity", http.StatusBadRequest).WithField("invalid", err.Error()) } // Store user to db here. rst := contentware.ResponseTypeFromCtx(ctx) // Write the user back in the response as JSON or XML based on the // 'Accept' header. rst.Encode(w, u) return nil }
// Handle takes the next handler as an argument and wraps it in this middleware. func (m *Middle) Handle(next httpware.Handler) httpware.Handler { return httpware.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { remote := strings.Split(r.RemoteAddr, ":") if len(remote) != 2 { return next.ServeHTTPCtx(ctx, w, r) } if m.increment(remote[0]) { defer m.decrement(remote[0]) return next.ServeHTTPCtx(ctx, w, r) } // Send a 429 response (Too Many Requests). m.retryHeader(w) return httpware.NewErr("exceeded request rate limit", 429) }) }
// Handle takes the next handler as an argument and wraps it in this middleware. func (m *Middle) Handle(next httpware.Handler) httpware.Handler { return httpware.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { token, err := request.ParseFromRequest( r, request.AuthorizationHeaderExtractor, func(token *jwt.Token) (interface{}, error) { return m.conf.Secret, nil }, ) if err == nil && token.Valid { newCtx := context.WithValue(ctx, httpware.TokenKey, token) return next.ServeHTTPCtx(newCtx, w, r) } // No soup for you. return httpware.NewErr("invalid token", http.StatusUnauthorized) }) }