Skip to content

Commit

Permalink
Merge pull request #42 from FireTail-io/allow-undefined-routes
Browse files Browse the repository at this point in the history
Allow undefined routes
  • Loading branch information
TheTeaCat authored Dec 11, 2024
2 parents 377e994 + 8685eeb commit 45f4dbb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
10 changes: 7 additions & 3 deletions middlewares/http/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro
var pathParams map[string]string
if router != nil && (options.EnableRequestValidation || options.EnableResponseValidation) {
route, pathParams, err = router.FindRoute(r)
if err == routers.ErrMethodNotAllowed {
if options.AllowUndefinedRoutes && err == routers.ErrPathNotFound {
// If the router couldn't find the path & undefined routes are allowed, fallback to using the request path as the resource
logEntry.Request.Resource = r.URL.Path
} else if err == routers.ErrMethodNotAllowed {
options.ErrCallback(ErrorUnsupportedMethod{r.URL.Path, r.Method}, localResponseWriter, r)
return
} else if err == routers.ErrPathNotFound {
Expand All @@ -125,9 +128,10 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro
} else if err != nil {
options.ErrCallback(ErrorAtRequestUnspecified{err}, localResponseWriter, r)
return
} else {
// We now know the resource that was requested, so we can fill it into our log entry
logEntry.Request.Resource = route.Path
}
// We now know the resource that was requested, so we can fill it into our log entry
logEntry.Request.Resource = route.Path
}

// If it has been enabled, and we were able to determine the route and path params, validate the request against the openapi spec
Expand Down
26 changes: 26 additions & 0 deletions middlewares/http/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,32 @@ func TestRequestToInvalidRoute(t *testing.T) {
assert.Equal(t, "{\"code\":404,\"title\":\"the resource \\\"/not-implemented\\\" could not be found\",\"detail\":\"a path for \\\"/not-implemented\\\" could not be found in your appspec\"}", string(respBody))
}

func TestRequestToInvalidRouteWithAllowUndefinedRoutesEnabled(t *testing.T) {
middleware, err := GetMiddleware(&Options{
OpenapiSpecPath: "./test-spec.yaml",
DebugErrs: true,
EnableRequestValidation: true,
AllowUndefinedRoutes: true,
})
require.Nil(t, err)
handler := middleware(healthHandler)
responseRecorder := httptest.NewRecorder()

request := httptest.NewRequest("GET", "/not-implemented", nil)
handler.ServeHTTP(responseRecorder, request)

assert.Equal(t, 200, responseRecorder.Code)

require.Contains(t, responseRecorder.HeaderMap, "Content-Type")
require.GreaterOrEqual(t, len(responseRecorder.HeaderMap["Content-Type"]), 1)
assert.Len(t, responseRecorder.HeaderMap["Content-Type"], 1)
assert.Equal(t, "application/json", responseRecorder.HeaderMap["Content-Type"][0])

respBody, err := io.ReadAll(responseRecorder.Body)
require.Nil(t, err)
assert.Equal(t, "{\"description\":\"test description\"}", string(respBody))
}

func TestDebugErrsDisabled(t *testing.T) {
middleware, err := GetMiddleware(&Options{
OpenapiSpecPath: "./test-spec.yaml",
Expand Down
5 changes: 5 additions & 0 deletions middlewares/http/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ type Options struct {
// if no openapi spec is provided, then no validation will be performed
EnableResponseValidation bool

// AllowUndefinedRoutes is an optional flag which, if set to true, allows requests to routes which are not defined in the openapi spec
// to pass through the middleware without validation. If set to false (default), requests to undefined routes will be rejected and a
// 404 response will be returned
AllowUndefinedRoutes bool

// CustomBodyDecoders is a map of Content-Type header values to openapi3 decoders - if the kin-openapi module does not support your
// Content-Type by default, you will need to add a custom decoder here
CustomBodyDecoders map[string]openapi3filter.BodyDecoder
Expand Down

0 comments on commit 45f4dbb

Please sign in to comment.