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

Middlewares are executed altough url doesnt exist in openapi spec #1913

Open
jasonlazo opened this issue Apr 18, 2024 · 2 comments
Open

Middlewares are executed altough url doesnt exist in openapi spec #1913

jasonlazo opened this issue Apr 18, 2024 · 2 comments

Comments

@jasonlazo
Copy link

Description

I am using Connexion with flask, i have some custom ASGI Middlewares and hooks in flask (methods decorated with before_request). both are executed altought url path doesnt exist.

Expected behaviour

I expect this code shouldnt be executed and the 404 should be returned cause connexion framework has a routingmiddleware that is called previously.

Actual behaviour

The middlewares and hooks are called, and Working outside of operation context error is raised cause context and request connexion object are not accesible

Steps to reproduce

Download this example project , and follow the steps on readme to replicate the errors.

@jasonlazo jasonlazo changed the title Middlewares are executed altough url doesnt exist in openapi spec #1911 Middlewares are executed altough url doesnt exist in openapi spec Apr 18, 2024
@carloscbl
Copy link

Same here

if u have this valid URL

localhost:6079/subsystems/cb/registration
but by mistake you double the "/" like
localhost:6079//subsystems/cb/registration

Starts failing, in the past this was just working ommiting the double "//" but even if is correct to no longer support this behave, this is the traceback:

2024-07-31T14:51:35Z    AnyIO worker thread MainProcess exceptions.py:107       common_error_handler    RuntimeError("Working outside of operation context. Make sure your app is wrapped in a ContextMiddleware and you're processing a request while accessing the context.")
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/swagger_ui.py", line 222, in __call__
    await self.router(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 485, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 806, in app
    await self.default(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/swagger_ui.py", line 235, in default_fn
    await self.app(original_scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/routing.py", line 154, in __call__
    await self.router(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 485, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 806, in app
    await self.default(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/routing.py", line 48, in __call__
    await self.next_app(original_scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/abstract.py", line 261, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/abstract.py", line 261, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.11/site-packages/connexion/middleware/abstract.py", line 261, in __call__
    await self.app(scope, receive, send)
  [Previous line repeated 1 more time]
  File "/usr/local/lib/python3.11/site-packages/a2wsgi/wsgi.py", line 200, in __call__
    await self.loop.run_in_executor(
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/a2wsgi/wsgi.py", line 256, in wsgi
    iterable = self.app(environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 1476, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 1473, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 882, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 880, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 865, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/connexion/apps/flask.py", line 68, in __call__
    return self.fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/connexion/decorators/main.py", line 132, in wrapper
    request = self.framework.get_request(uri_parser=self.uri_parser)
                                                    ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/connexion/decorators/main.py", line 72, in uri_parser
    uri_parser_class = self.uri_parser_class or operation.uri_parser_class
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/werkzeug/local.py", line 318, in __get__
    obj = instance._get_current_object()
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/werkzeug/local.py", line 519, in _get_current_object
    raise RuntimeError(unbound_message) from None
RuntimeError: Working outside of operation context. Make sure your app is wrapped in a ContextMiddleware and you're processing a request while accessing the context.

returns 500 internal error

@RobbeSneyders
Copy link
Member

Thanks for the report @jasonlazo.

Connexion routing passes unknown requests to the application, since the OpenAPI spec does not have to be an exhaustive description of the API. Connexion even provides functionality to directly add additional paths not in the spec, but it could also be done on the underlying Flask app directly.

Agree that it could be useful to provide a base middleware that is only called for known paths though. We actually have such a base middleware, but it's probably too complex to expose to users directly. If you do want to use it, you can have a look at the ContextMiddleware.

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

3 participants