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

Running Kinto with provided app.wsgi does not remove SCRIPT_NAME from URL #1692

Open
dstaley opened this issue Jun 20, 2018 · 3 comments
Open
Labels
bug stale For marking issues as stale. Labeled issues will be closed soon if label is not removed.

Comments

@dstaley
Copy link
Member

dstaley commented Jun 20, 2018

I'm currently working on running Kinto on AWS Lambda, using the provided app.wsgi file to load Kinto.

My Kinto instance is deployed at a URL containing a prefix, https://api.gateway.amazon/dev/v1.

When translating Lambda events to WSGI environment parameters, I'm setting SCRIPT_NAME to /dev, and PATH_INFO to /v1. If I do this, Kinto complains that /dev/v1 is not a valid route. If I explicitly remove SCRIPT_NAME from the environment variables before calling the app, it works fine.

I believe this is due to Pyramid/Waitress combining the SCRIPT_NAME and PATH_INFO when passing the URL to Kinto. I'm doing some research into how this can be disabled (and if this is even the cause), and I'll send a PR if I find the appropriate config option.

Here's a short reproduction:

import os
import sys
from werkzeug.wrappers import Response
from werkzeug._compat import (BytesIO, to_bytes)
import configparser
import logging.config

from kinto import main


here = os.path.dirname(__file__)

ini_path = os.path.join(here, 'config', 'kinto.ini')

# Set up logging
logging.config.fileConfig(ini_path)

# Parse config and create WSGI app
config = configparser.ConfigParser()
config.read(ini_path)

application = main(config.items('DEFAULT'), **dict(config.items('app:main')))

body = to_bytes(
    '{"data": {"description": "Write a tutorial explaining Kinto", "status": "todo"}}\n',
    charset='utf-8'
)

environ = {
    'CONTENT_LENGTH': str(len(body)),
    'CONTENT_TYPE': 'application/json',
    'PATH_INFO': '/v1/buckets/default/collections/tasks/records',
    'QUERY_STRING': {},
    'REMOTE_ADDR': '',
    'REMOTE_USER': '',
    'REQUEST_METHOD': 'POST',
    'SCRIPT_NAME': '/dev',
    'SERVER_NAME': 'oggaoggabooga.execute-api.us-east-1.amazonaws.com',
    'SERVER_PORT': '443',
    'SERVER_PROTOCOL': 'HTTP/1.1',
    'wsgi.errors': sys.stderr,
    'wsgi.input': BytesIO(body),
    'wsgi.multiprocess': False,
    'wsgi.multithread': False,
    'wsgi.run_once': False,
    'wsgi.url_scheme': 'https',
    'wsgi.version': (1, 0),
    'HTTP_AUTHORIZATION': 'Basic ZHN0YWxleTpwYXNzd29yZA==',
    'HTTP_CONTENT_TYPE': 'application/json',
    'HTTP_HOST': 'oggaoggabooga.execute-api.us-east-1.amazonaws.com',
}

response = Response.from_app(application, environ)

print(response.status_code)

This is the error I'm getting:

"POST  /dev/v1/buckets/default/collections/tasks/records?" ? (? ms) URI has no route errno=999
Traceback (most recent call last):
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/pyramid/tweens.py", line 39, in excview_tween
    response = handler(request)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/core/events.py", line 76, in tween
    response = handler(request)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/pyramid/router.py", line 156, in handle_request
    view_name
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/pyramid/view.py", line 642, in _call_view
    response = view_callable(context, request)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 410, in viewresult_to_response
    result = view(context, request)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 148, in _requestonly_view
    response = view(request)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/plugins/default_bucket/__init__.py", line 145, in default_bucket
    create_bucket(request, bucket_id)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/plugins/default_bucket/__init__.py", line 35, in create_bucket
    uri=bucket_uri)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/plugins/default_bucket/__init__.py", line 79, in resource_create_object
    resource_name, matchdict = view_lookup(request, uri)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/core/utils.py", line 448, in view_lookup
    return view_lookup_registry(request.registry, uri)
  File "/Users/dylanstaley/Desktop/kinto-wsgi/.venv/lib/python3.6/site-packages/kinto/core/utils.py", line 472, in view_lookup_registry
    raise ValueError('URI has no route')

Changing the SCRIPT_NAME attribute to '' eliminates the error.

@leplatrem leplatrem added the bug label Jul 5, 2018
@leplatrem
Copy link
Contributor

@dstaley Do you have suggestion for this?

@Natim
Copy link
Member

Natim commented Aug 13, 2019

Do you need SCRIPT_NAME for anything or is it a sufficient fix to change it into an empty string?

@dstaley
Copy link
Member Author

dstaley commented Aug 14, 2019

The reproduction that manually specifies the WSGI variables was just to demonstrate the error. In a proper WSGI environment, SCRIPT_NAME is set by the web server. I imagine this would be an issue for any WSGI host that has Kinto at a non-root level.

@alexcottner alexcottner added the stale For marking issues as stale. Labeled issues will be closed soon if label is not removed. label Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug stale For marking issues as stale. Labeled issues will be closed soon if label is not removed.
Projects
None yet
Development

No branches or pull requests

4 participants