Opened 8 years ago

Closed 2 years ago

#7930 closed Bug (wontfix)

FORCE_SCRIPT_NAME does not work with dev server

Reported by: ElliottM Owned by: nobody
Component: HTTP handling Version: master
Severity: Normal Keywords:
Cc: flosch, nkryptic Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


In order to ensure that FORCE_SCRIPT_NAME would work on my production server, I first wanted to test it on the dev server. So I took an already existing project and added FORCE_SCRIPT_NAME to it., then did python runserver.

The expected result is that it would behave exactly as if I had followed all of the setup instructions for lighttpd+fcgi. (IE if I got to the
URL specified by FORCE_SCRIPT_NAME, I should get the root of the site)

The result was an absolutely unusable site.
First, I got a 404 when trying to access the site root, including the FORCE_SCRIPT_NAME. In order to get the root of the site, I have to go to "/".
Second, reverse() appears to work, because any links that are generated with URL tags or reverse() appear as expected.
Third, when I click on one of those links, I get another 404, but for a strange reason. The 404 page sent when debug=True acts as if I enter the value for FORCE_SCRIPT_NAME twice before entering the rest of the URL and submitting, which is utterly confusing.

I think either this should be fixed, the FORCE_SCRIPT_NAME should be outright ignored when using the dev server, or it should be documented that it does not work with the dev server.

Attached is a bare-bones all-default project that shows the behavior.

Attachments (3) (4.9 KB) - added by ElliottM 8 years ago.
dev_server__force_script_name.diff (1.2 KB) - added by Thomas Güttler 8 years ago.
handle-force-script-name.diff (10.8 KB) - added by nkryptic 4 years ago.

Download all attachments as: .zip

Change History (17)

Changed 8 years ago by ElliottM

Attachment: added

comment:1 Changed 8 years ago by ElliottM

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Summary: FORCR_SCRIPT_NAME does not work at all in dev serverFORCE_SCRIPT_NAME does not work at all in dev server

comment:2 Changed 8 years ago by flosch

Cc: flosch added

comment:3 Changed 8 years ago by Jacob

Summary: FORCE_SCRIPT_NAME does not work at all in dev serverFORCE_SCRIPT_NAME does not work with dev server
Triage Stage: UnreviewedDesign decision needed

(changed title to be less histrionic)

comment:4 Changed 8 years ago by Thomas Güttler

Cc: hv@… added
Has patch: set

I can reproduce this. Patch attached.

Changed 8 years ago by Thomas Güttler

comment:5 Changed 6 years ago by Luke Plant

Severity: Normal
Type: Bug

comment:6 Changed 5 years ago by Alex Gaynor

Easy pickings: unset
Resolution: duplicate
Status: newclosed
UI/UX: unset

Discussion with Jacob: Closing as a dupe of #16360, this should be fixed via having all of Django's HTTP handling go through a common endpoint, not adding further cruft to the development specific server.

comment:7 Changed 5 years ago by Jannis Leidel

Resolution: duplicate
Status: closedreopened

@jacob I'm not convinced this is a duplicate of #16360 as it's about a specific bug in how we handle the script prefix, not about adding a new WSGI entrypoint. Re-opening.

comment:8 Changed 5 years ago by Jannis Leidel

Triage Stage: Design decision neededAccepted

comment:9 Changed 5 years ago by Thomas Güttler

Cc: hv@… removed

comment:10 Changed 4 years ago by nkryptic

Cc: nkryptic added

Im attaching a patch, but you can also view the work on Github at

I think this issue is more widespread than just the development runserver command. Changing FORCE_SCRIPT_NAME will also break the LiveServerTestCase. Finally, it looks like there is an issue if you change FORCE_SCRIPT_NAME with override_settings while testing, if the test does any request processing and therefore calls django.core.urlresolvers.set_script_prefix. SInce set_script_prefix changes the global _prefixes object, it doesn't get unset and will remain present for tests afterwards. The patch includes a test signal handler for setting_changed which addresses this.

What the patch does is add a new UrlPrefixedAwareHandler that is applied in the base runserver command, wrapping the normal handler. This wsgi middleware only performs when FORCE_SCRIPT_NAME is present. If it is, the script will ensure incoming requests begin with FORCE_SCRIPT_NAME and then strip it from then environ's PATH_INFO before passing environ on to the normal handler. If the incoming request doesn't begin with FORCE_SCRIPT_NAME, a 400 Bad Request is raised.

Also, the StaticFilesHandler has to become aware of FORCE_SCRIPT_NAME, as it will check both the PATH_INFO from the incoming environ and also request.path later (which will be prepended with FORCE_SCRIPT_NAME).

I don't know if the new tests written are enough to ensure this patch's validity, or if there is need for additional documentation from this. I open to suggestions. I'd also be happy to claim this issue, although I didn't see an 'accept' option, even though it is owned by nobody.

Changed 4 years ago by nkryptic

comment:11 Changed 4 years ago by Aymeric Augustin

Status: reopenednew

comment:12 Changed 4 years ago by Julien Phalip

@nkryptic: Thanks for your work on this patch. I've just quickly tried out your patch but it seems like it only works for the home page (e.g. '/PREFIX/'). Every other URL (e.g. '/PREFIX/blah/') returns a 404.

Am I missing something?

comment:13 Changed 4 years ago by nkryptic

@julien, when I wrote the patch, it was effectively a port of code I was using in local development so that my settings with runserver would mirror my production settings. It worked on my entire project then and the tests all passed. I developed the practice because, at some previous time, my nginx+gunicorn production setup wouldn't work without setting force_script_name. My guess it is was an issue with gunicorn, which has since been fixed.

After some discussion with @apollo13 on IRC, he pointed out that force_script_name was legacy and it's use intended only to address broken web servers, but that normal setups should never require it. I then tested with nginx+gunicorn using only SCRIPT_NAME in my nginx.conf (with a few others) and everything worked (and has continued to work) without issue since. Given what @apollo13 said, and that I don't need force_script_name in production, I changed my dev practices to simply not use prefixed urls, as I considered this to be a dead end.

If there is some desire for this to work going forward, I'll be happy to figure out why it's not working now and update the patch as needed.

comment:14 Changed 2 years ago by Tim Graham

Resolution: wontfix
Status: newclosed

Given the last comment, I'm going to close this as "won't fix."

Note: See TracTickets for help on using tickets.
Back to Top