Repository: getkin/kin-openapi (go)

Issue:
Receiving incorrect error, when endpoint is path with unsupported method
Hi, I've found that when I send request to a path with unsupported method, error message in response is "Path was not found" instead of ["Path doesn't support the HTTP method"](https://github.com/getkin/kin-openapi/blob/master/openapi3filter/router.go#L199)

Steps to reproduce:
1. Run a server, generated from OpenAPI specification. For example, [Petstore](https://github.com/deepmap/oapi-codegen/blob/master/examples/petstore-expanded/chi/petstore.go#L16) from OpenAPI examples
2. Send request to a path with unsupported method, for example PUT /users

Actual result: 
```
{
    "message": "Path was not found"
}
```
Expected result:
```
{
    "message": "Path doesn't support the HTTP method"
}
```

Pull request:
Return correct router error when using bad method on existing path
Fixes #158 

Patch:
diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go
index 56ffe09..1a5fda1 100644
--- a/openapi3/swagger_loader.go
+++ b/openapi3/swagger_loader.go
@@ -794,8 +794,7 @@ func referencedDocumentPath(documentPath *url.URL, ref string) (*url.URL, error)
 			return nil, err
 		}
 		joinedDirectory := path.Join(path.Dir(documentPath.String()), refDirectory.String())
-		newDocumentPath, err = url.Parse(joinedDirectory + "/")
-		if err != nil {
+		if newDocumentPath, err = url.Parse(joinedDirectory + "/"); err != nil {
 			return nil, err
 		}
 	}
diff --git a/openapi3filter/router.go b/openapi3filter/router.go
index fefe313..91487d6 100644
--- a/openapi3filter/router.go
+++ b/openapi3filter/router.go
@@ -178,27 +178,28 @@ func (router *Router) FindRoute(method string, url *url.URL) (*Route, map[string
 		route, _ = node.Value.(*Route)
 	}
 	if route == nil {
-		return nil, nil, &RouteError{
-			Route: Route{
-				Swagger: swagger,
-				Server:  server,
-			},
-			Reason: "Path was not found",
+
+		// Get operation
+		pathItem := swagger.Paths[remainingPath]
+		if pathItem == nil || pathItem.GetOperation(method) == nil {
+			return nil, nil, &RouteError{
+				Route: Route{
+					Swagger: swagger,
+					Server:  server,
+				},
+				Reason: "Path doesn't support the HTTP method",
+			}
 		}
-	}
 
-	// Get operation
-	pathItem := route.PathItem
-	operation := pathItem.GetOperation(method)
-	if operation == nil {
 		return nil, nil, &RouteError{
 			Route: Route{
 				Swagger: swagger,
 				Server:  server,
 			},
-			Reason: "Path doesn't support the HTTP method",
+			Reason: "Path was not found",
 		}
 	}
+
 	if pathParams == nil {
 		pathParams = make(map[string]string, len(paramValues))
 	}
diff --git a/pathpattern/node.go b/pathpattern/node.go
index 883d63a..43e2959 100644
--- a/pathpattern/node.go
+++ b/pathpattern/node.go
@@ -267,15 +267,10 @@ func (currentNode *Node) Match(path string) (*Node, []string) {
 		path = path[:len(path)-1]
 	}
 	variableValues := make([]string, 0, 8)
-	return currentNode.matchRemaining(path, false, variableValues)
+	return currentNode.matchRemaining(path, variableValues)
 }
 
-func (currentNode *Node) matchRemaining(remaining string, hasExtraSlash bool, paramValues []string) (*Node, []string) {
-	// Remove "/" from the beginning
-	// if len(remaining) > 0 && remaining[0] == '/' {
-	// 	remaining = remaining[1:]
-	// }
-
+func (currentNode *Node) matchRemaining(remaining string, paramValues []string) (*Node, []string) {
 	// Check if this node matches
 	if len(remaining) == 0 && currentNode.Value != nil {
 		return currentNode, paramValues
@@ -290,9 +285,9 @@ func (currentNode *Node) matchRemaining(remaining string, hasExtraSlash bool, pa
 			pattern := suffix.Pattern
 			if strings.HasPrefix(remaining, pattern) {
 				newRemaining := remaining[len(pattern):]
-				resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, hasExtraSlash, paramValues)
+				resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, paramValues)
 			} else if len(remaining) == 0 && pattern == "/" {
-				resultNode, resultValues = suffix.Node.matchRemaining(remaining, hasExtraSlash, paramValues)
+				resultNode, resultValues = suffix.Node.matchRemaining(remaining, paramValues)
 			}
 		case SuffixKindVariable:
 			i := strings.IndexByte(remaining, '/')
@@ -301,7 +296,7 @@ func (currentNode *Node) matchRemaining(remaining string, hasExtraSlash bool, pa
 			}
 			newParamValues := append(paramValues, remaining[:i])
 			newRemaining := remaining[i:]
-			resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, hasExtraSlash, newParamValues)
+			resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, newParamValues)
 		case SuffixKindEverything:
 			newParamValues := append(paramValues, remaining)
 			resultNode, resultValues = suffix.Node, newParamValues
@@ -319,7 +314,7 @@ func (currentNode *Node) matchRemaining(remaining string, hasExtraSlash bool, pa
 				}
 				newParamValues := append(paramValues, paramValue)
 				newRemaining := remaining[i:]
-				resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, hasExtraSlash, newParamValues)
+				resultNode, resultValues = suffix.Node.matchRemaining(newRemaining, newParamValues)
 			}
 		}
 		if resultNode != nil && resultNode.Value != nil {


Test patch:
diff --git a/openapi3/swagger_loader_relative_refs_test.go b/openapi3/swagger_loader_relative_refs_test.go
index 6a8108f..0e4c19d 100644
--- a/openapi3/swagger_loader_relative_refs_test.go
+++ b/openapi3/swagger_loader_relative_refs_test.go
@@ -927,12 +927,12 @@ func TestLoadSpecWithRelativeDocumentRefs2(t *testing.T) {
 	// check response schema and example
 	require.Equal(t, nestedDirPath.Patch.Responses["200"].Value.Content["application/json"].Schema.Value.Type, "string")
 	expectedExample := "hello"
-	require.Equal(t,  expectedExample, nestedDirPath.Patch.Responses["200"].Value.Content["application/json"].Examples["CustomTestExample"].Value.Value)
+	require.Equal(t, expectedExample, nestedDirPath.Patch.Responses["200"].Value.Content["application/json"].Examples["CustomTestExample"].Value.Value)
 
 	// path in more nested directory
 	// check parameter
 	moreNestedDirPath := swagger.Paths["/pets/{id}/{city}"]
-	require.Equal(t, "param", moreNestedDirPath.Patch.Parameters[0].Value.Name, )
+	require.Equal(t, "param", moreNestedDirPath.Patch.Parameters[0].Value.Name)
 	require.Equal(t, "path", moreNestedDirPath.Patch.Parameters[0].Value.In)
 	require.Equal(t, true, moreNestedDirPath.Patch.Parameters[0].Value.Required)
 
diff --git a/openapi3filter/router_test.go b/openapi3filter/router_test.go
index 0582147..9f67660 100644
--- a/openapi3filter/router_test.go
+++ b/openapi3filter/router_test.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/getkin/kin-openapi/openapi3"
 	"github.com/getkin/kin-openapi/openapi3filter"
+	"github.com/stretchr/testify/require"
 )
 
 func TestRouter(t *testing.T) {
@@ -39,6 +40,9 @@ func TestRouter(t *testing.T) {
 				Put:     helloPUT,
 				Trace:   helloTRACE,
 			},
+			"/onlyGET": &openapi3.PathItem{
+				Get: helloGET,
+			},
 			"/params/{x}/{y}/{z*}": &openapi3.PathItem{
 				Get: paramsGET,
 			},
@@ -51,9 +55,7 @@ func TestRouter(t *testing.T) {
 	// Declare a helper function
 	expect := func(method string, uri string, operation *openapi3.Operation, params map[string]string) {
 		req, err := http.NewRequest(method, uri, nil)
-		if err != nil {
-			panic(err)
-		}
+		require.NoError(t, err)
 		route, pathParams, err := router.FindRoute(req.Method, req.URL)
 		if err != nil {
 			if operation == nil {
@@ -122,4 +124,17 @@ func TestRouter(t *testing.T) {
 		"d0": "domain0",
 		"d1": "domain1",
 	})
+
+	{
+		uri := "https://www.example.com/api/v1/onlyGET"
+		expect(http.MethodGet, uri, helloGET, nil)
+		req, err := http.NewRequest(http.MethodDelete, uri, nil)
+		require.NoError(t, err)
+		require.NotNil(t, req)
+		route, pathParams, err := router.FindRoute(req.Method, req.URL)
+		require.Error(t, err)
+		require.Equal(t, err.(*openapi3filter.RouteError).Reason, "Path doesn't support the HTTP method")
+		require.Nil(t, route)
+		require.Nil(t, pathParams)
+	}
 }