Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Malformed path parameter returns 404 instead of 400 #770

Closed
starhawking opened this issue Nov 9, 2018 · 5 comments
Closed

Malformed path parameter returns 404 instead of 400 #770

starhawking opened this issue Nov 9, 2018 · 5 comments

Comments

@starhawking
Copy link

Description

The documentation says that strict_validation should return a 400, however it appears to be returning a 404 instead

Per the documentation at https://connexion.readthedocs.io/en/latest/request.html#parameter-validation

Connexion can apply strict parameter validation for query and form data parameters. When this is enabled, requests that include parameters not defined in the swagger spec return a 400 error.

Expected behaviour

Connexion returns a 400 Bad Request when a parameter does not match the schema

Actual behaviour

Connexion returns a 404 Not Found when a parameter does not match the schema

Steps to reproduce

Sample Curl Results

connexion issue> curl -i localhost:5000/has-param/1
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 2
Server: Werkzeug/0.14.1 Python/3.6.4
Date: Fri, 09 Nov 2018 19:31:03 GMT

1
connexion issue> curl -i localhost:5000/has-param/a
HTTP/1.0 404 NOT FOUND
Content-Type: application/problem+json
Content-Length: 206
Server: Werkzeug/0.14.1 Python/3.6.4
Date: Fri, 09 Nov 2018 19:30:55 GMT

{
  "detail": "The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.",
  "status": 404,
  "title": "Not Found",
  "type": "about:blank"
}

Sample Code

import connexion
from connexion.resolver import RestyResolver

def get_has_param(demoId):
    return demoId

if __name__ == '__main__':
    app = connexion.FlaskApp(__name__)
    app.add_api(
        'request-validation-demo.yaml',
        validate_responses=True,
        strict_validation=True,
    )
    app.run()

Sample OpenAPI v3 Document

openapi: 3.0.0
info:
  title: This should be returning a 400 on an invalid parameter
  version: '0'
paths:
  /has-param/{demoId}:
    get:
      summary: This should be returning a 400 when it gets an invalid parameter, not a 404
      operationId: main.get_has_param
      parameters:
        - name: demoId
          in: path
          required: true
          description: This should be a 400 when invalid
          schema:
            type: integer
      responses:
        200:
          description: Demo Result
          content:
            application/json:
              schema:
                type: integer
        400:
          description: Demo 400
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        404:
          description: Demo 404
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Error:
      required:
        - code
        - message
      properties:
        code:
          type: integer
        message:
          type: string

Additional info:

Output of the commands:

connexion issue> python3 --version
Python 3.6.4
connexion issue> pip3 show connexion | grep "^Version\:"
Version: 2.0.1
connexion issue>
@dtkav
Copy link
Collaborator

dtkav commented Nov 9, 2018

I think what's happening is that the path parameters generate routes for Flask.
The route that's being generated here is something like: /has-param/<demoId:int>: and so Flask is unable to match /has-param/a to this pattern, and returns a 404.

We could drop all types from Flask routes to ensure that parameters make it through to validation - I'm not sure yet what the full implications of that would be. I'll try to play around with it today.

@jrheling
Copy link

I just worked through an issue with similar symptoms (I'm guessing it's the same core issue, but someone with a deeper knowledge of connexion may know better).

I added a new path to an existing (and working) project, but was getting 404s in all cases while testing. I narrowed it down to this trivial reproduction case:

Openapi spec:

...
  /games/{game_id}:
    get:
      summary: Game_GET
      description: blah testing
      operationId: main.foo
      parameters:
        - name: game_id
          in: path
          description: ID of the game being played
          required: true
          schema:
            type: number
...

With the corresponding handler:

def foo(game_id):
    return {'hi': game_id}, 200

All calls to .../games/<n> would return a 404. Reading this bug led me to noticed I'd inadvertently specified the parameter type as number rather than integer - when I changed it back to integer all was well.

In my case, I intended the parameter to be an int, so number in the spec was just a mistake. But since number is the way to specify a float per the openapi spec, though, I wonder how one would get connexion routing to work with a float parameter.

@D3nn3
Copy link

D3nn3 commented Jul 19, 2021

Just a little push since the bug is still present in version 2.9.0. It's not breaking but the wrong error message and status code is very confusing for users of an API.

@RobbeSneyders RobbeSneyders changed the title strict_validation returning 404 instead of 400 as described in documentation Malformed path parameter returns 404 instead of 400 Jul 19, 2021
@RobbeSneyders
Copy link
Member

Hi @D3nn3, I'm afraid this issue is not at the top of our priority list at the moment. We currently match Flask behavior and while I agree that a 400 error would be better, I don't think a 404 error is completely wrong either. We would definitely welcome a PR though.

Note that this is not related to strict_validation, which applies strict parameter validation for query and form data parameters, but to malformed path parameters. I updated the title of the issue to reflect this. I think @dtkav was correct in his assessment of the underlying issue.

@jrheling routing with numbers is better supported since version 2.9.

@RobbeSneyders
Copy link
Member

Closing this as a wontfix since routing needs to happen before validation, so a 404 error is thrown before reaching validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants