-
-
Notifications
You must be signed in to change notification settings - Fork 483
Description
Hello, I'm not sure if this is a bug strictly-speaking, but we found it to be unexpected behavior.
Say you have a basic spec like this:
openapi: "3.0.0"
info:
title: Simple API Example
version: 0.1.0
servers:
- url: "https://example.com/api/"
description: Deployed absolute URL
- url: "http://localhost:8080/"
description: Running locally
paths:
/:
get:
summary: Application health-check.
responses:
200:
description: Application name and version.
content:
application/json:
schema:
properties:
data:
type: object
properties:
name:
type: string
example: "Sample App"
version:
type: string
example: "0.1.0"
And then a simple web app that includes validation using kin-openapi/openapi3filter:
package main
import (
"context"
"flag"
"fmt"
"io"
"log"
"net/http"
"path/filepath"
"github.com/getkin/kin-openapi/openapi3filter"
)
func main() {
// OpenAPIv3 request validation:
specPath, _ := filepath.Abs("./spec.yaml")
oa3router := openapi3filter.NewRouter().WithSwaggerFromFile(specPath)
validationHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.TODO()
log.Printf("request.URL is %s", r.URL)
route, pathParams, _ := oa3router.FindRoute(r.Method, r.URL)
// Validate request
requestValidationInput := &openapi3filter.RequestValidationInput{
Request: r,
PathParams: pathParams,
Route: route,
}
if err := openapi3filter.ValidateRequest(ctx, requestValidationInput); err != nil {
w.WriteHeader(400)
io.WriteString(w, err.Error()+"\n")
} else {
fmt.Fprint(w, "{\"version\": \"0.1.0\", \"name\": \"Sample App\"}\n")
}
})
httpAddr := flag.String("http.addr", ":8080", "HTTP listen address")
log.Printf("HTTP server starting on %v\n", *httpAddr)
log.Fatal(http.ListenAndServe(*httpAddr, validationHandler))
}If you run $ go run main.go and make a request using $ curl localhost:8080 you'll find you get an invalid route response.
The logging output is:
2019/09/27 14:24:17 HTTP server starting on :8080
2019/09/27 14:24:21 request.URL is /
As far as I can tell the issue is the same one described in this StackOverflow thread
what you get from Go's http.Request.URL is the raw URL (as parsed by the library). In the case you're getting, you're accessing the URL from a relative path, hence the lack of a Host or Scheme in the URL object.
Since the request is made from the same machine, it's only passing a relative URL, and openapi-kin doesn't know how to validate that request successfully. Even explicitly passing a Host header doesn't help:
$ curl localhost:8080/api -H 'Host: example.com'
invalid route
Maybe the FindRoute() method should take into account Host headers? Or maybe there's someplace that URL.ResolveReference() should be called and it's not?
I'm willing to work on putting together a PR, if there's consensus for what a good fix would look like. Otherwise, I'd just ask for extra documentation that kin-openapi validation doesn't work properly on localhost.
Thanks for your work on a very useful tool.