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

Make toolbar compatible with FORCE_SCRIPT_NAME #1970

Merged
merged 2 commits into from
Jul 26, 2024

Conversation

dmartin
Copy link
Contributor

@dmartin dmartin commented Jul 22, 2024

Description

Previously, if a project used the FORCE_SCRIPT_NAME setting (such as when hosting a Django application under a subdirectory path via a reverse proxy), is_toolbar_request() would always return False.

This is because request.resolver_match is not yet available in the middleware context, so django.urls.resolve() is called instead. resolve() then raised Resolver404, because it does not take FORCE_SCRIPT_NAME into account.

This caused internal toolbar URLs to be inspected, leading to a request loop when refreshing the history panel.

This PR makes calls to django.urls.resolve() take request.path_info rather than request.path. This effectively strips the request's leading SCRIPT_NAME if one is present.

Fixes #1961

Checklist:

  • I have added the relevant tests for this change.
  • I have added an item to the Pending section of docs/changes.rst.

Previously, if a project used the `FORCE_SCRIPT_NAME` setting (common when
hosting a Django application on a subdirectory path via a reverse proxy),
the `django.urls.resolve()` call would always raise `Resolver404` in the
middleware. As a result, `is_toolbar_request()` always returned False.

This caused internal toolbar URLs to be inspected, and also indirectly
led to a request loop when refreshing the history panel.

In most cases (if `FORCE_SCRIPT_NAME` is unset), `get_script_prefix()` will
return "/" and the `replace()` will be a no-op.
@dmartin dmartin force-pushed the force-script-name-compatibility branch from 8f39e06 to e628c91 Compare July 22, 2024 18:14
Copy link
Member

@matthiask matthiask left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you try using request.path_info instead of request.path? The former should do the right thing if Django isn't mounted at '/' without having to use the script prefix explicitly. (I haven't tested it myself.)

@dmartin
Copy link
Contributor Author

dmartin commented Jul 22, 2024

Could you try using request.path_info instead of request.path? The former should do the right thing if Django isn't mounted at '/' without having to use the script prefix explicitly. (I haven't tested it myself.)

Oh, that does work and is a lot cleaner! Thanks for the suggestion. I can make that change, but what would you like to do with the existing tests that just override request.path? For example:

@override_settings(ROOT_URLCONF="tests.urls_invalid")
    def test_is_toolbar_request_override_request_urlconf(self):
        """Test cases when the toolbar URL is configured on the request."""
        self.request.path = "/__debug__/render_panel/"
        self.assertFalse(self.toolbar.is_toolbar_request(self.request))

I can also add matching request.path_info overrides to each of these, or I suppose they could be outright replaced with request.path_info overrides for all tests except mine which is explicitly testing the behavior when they differ.

@tim-schilling
Copy link
Contributor

tim-schilling commented Jul 22, 2024

@dmartin could we switch them with a RequestFactory().get('/__debug__/render_panel/') request?

Maintains support for `SCRIPT_NAME` without manually calling
`get_script_prefix()`.

Tests that involved manually setting the `path` attribute of a request
have been reworked to use a `RequestFactory` so that the `path` and
`path_info` attributes are both set appropriately.
@dmartin dmartin force-pushed the force-script-name-compatibility branch from f1e0929 to fb354f1 Compare July 22, 2024 19:36
@dmartin
Copy link
Contributor Author

dmartin commented Jul 22, 2024

I made those changes, though I didn't rework every test to use a RequestFactory to keep the scope of the PR under control, only the tests that were manually setting request.path.

Copy link
Contributor

@tim-schilling tim-schilling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this change.

It definitely highlights a problem we have in the test suite where we manipulate a request after initializing the toolbar. It's possible we may run into a bug where the the toolbar does something slightly differently because of this. However, if that were the case, I would have expected it to crop up before now.

@matthiask matthiask merged commit ee258fc into jazzband:main Jul 26, 2024
25 checks passed
@matthiask
Copy link
Member

Thank you!

@dmartin dmartin deleted the force-script-name-compatibility branch July 26, 2024 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

History sidebar panel keeps loading infinitely?
3 participants