Skip to content

Commit 45f4dbb

Browse files
authored
Merge pull request #42 from FireTail-io/allow-undefined-routes
Allow undefined routes
2 parents 377e994 + 8685eeb commit 45f4dbb

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

middlewares/http/middleware.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro
116116
var pathParams map[string]string
117117
if router != nil && (options.EnableRequestValidation || options.EnableResponseValidation) {
118118
route, pathParams, err = router.FindRoute(r)
119-
if err == routers.ErrMethodNotAllowed {
119+
if options.AllowUndefinedRoutes && err == routers.ErrPathNotFound {
120+
// If the router couldn't find the path & undefined routes are allowed, fallback to using the request path as the resource
121+
logEntry.Request.Resource = r.URL.Path
122+
} else if err == routers.ErrMethodNotAllowed {
120123
options.ErrCallback(ErrorUnsupportedMethod{r.URL.Path, r.Method}, localResponseWriter, r)
121124
return
122125
} else if err == routers.ErrPathNotFound {
@@ -125,9 +128,10 @@ func GetMiddleware(options *Options) (func(next http.Handler) http.Handler, erro
125128
} else if err != nil {
126129
options.ErrCallback(ErrorAtRequestUnspecified{err}, localResponseWriter, r)
127130
return
131+
} else {
132+
// We now know the resource that was requested, so we can fill it into our log entry
133+
logEntry.Request.Resource = route.Path
128134
}
129-
// We now know the resource that was requested, so we can fill it into our log entry
130-
logEntry.Request.Resource = route.Path
131135
}
132136

133137
// If it has been enabled, and we were able to determine the route and path params, validate the request against the openapi spec

middlewares/http/middleware_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,32 @@ func TestRequestToInvalidRoute(t *testing.T) {
182182
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))
183183
}
184184

185+
func TestRequestToInvalidRouteWithAllowUndefinedRoutesEnabled(t *testing.T) {
186+
middleware, err := GetMiddleware(&Options{
187+
OpenapiSpecPath: "./test-spec.yaml",
188+
DebugErrs: true,
189+
EnableRequestValidation: true,
190+
AllowUndefinedRoutes: true,
191+
})
192+
require.Nil(t, err)
193+
handler := middleware(healthHandler)
194+
responseRecorder := httptest.NewRecorder()
195+
196+
request := httptest.NewRequest("GET", "/not-implemented", nil)
197+
handler.ServeHTTP(responseRecorder, request)
198+
199+
assert.Equal(t, 200, responseRecorder.Code)
200+
201+
require.Contains(t, responseRecorder.HeaderMap, "Content-Type")
202+
require.GreaterOrEqual(t, len(responseRecorder.HeaderMap["Content-Type"]), 1)
203+
assert.Len(t, responseRecorder.HeaderMap["Content-Type"], 1)
204+
assert.Equal(t, "application/json", responseRecorder.HeaderMap["Content-Type"][0])
205+
206+
respBody, err := io.ReadAll(responseRecorder.Body)
207+
require.Nil(t, err)
208+
assert.Equal(t, "{\"description\":\"test description\"}", string(respBody))
209+
}
210+
185211
func TestDebugErrsDisabled(t *testing.T) {
186212
middleware, err := GetMiddleware(&Options{
187213
OpenapiSpecPath: "./test-spec.yaml",

middlewares/http/options.go

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ type Options struct {
6464
// if no openapi spec is provided, then no validation will be performed
6565
EnableResponseValidation bool
6666

67+
// AllowUndefinedRoutes is an optional flag which, if set to true, allows requests to routes which are not defined in the openapi spec
68+
// to pass through the middleware without validation. If set to false (default), requests to undefined routes will be rejected and a
69+
// 404 response will be returned
70+
AllowUndefinedRoutes bool
71+
6772
// CustomBodyDecoders is a map of Content-Type header values to openapi3 decoders - if the kin-openapi module does not support your
6873
// Content-Type by default, you will need to add a custom decoder here
6974
CustomBodyDecoders map[string]openapi3filter.BodyDecoder

0 commit comments

Comments
 (0)