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 guettli 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

comment:1 Changed 8 years ago by ElliottM

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from FORCR_SCRIPT_NAME does not work at all in dev server to FORCE_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 changed from FORCE_SCRIPT_NAME does not work at all in dev server to FORCE_SCRIPT_NAME does not work with dev server
  • Triage Stage changed from Unreviewed to Design decision needed

(changed title to be less histrionic)

comment:4 Changed 8 years ago by guettli

  • Cc hv@… added
  • Has patch set

I can reproduce this. Patch attached.

Changed 8 years ago by guettli

comment:5 Changed 5 years ago by lukeplant

  • Severity set to Normal
  • Type set to Bug

comment:6 Changed 5 years ago by Alex

  • Easy pickings unset
  • Resolution set to duplicate
  • Status changed from new to closed
  • 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 jezdez

  • Resolution duplicate deleted
  • Status changed from closed to reopened

@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 jezdez

  • Triage Stage changed from Design decision needed to Accepted

comment:9 Changed 5 years ago by guettli

  • 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 3 years ago by aaugustin

  • Status changed from reopened to new

comment:12 Changed 3 years ago by julien

@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 3 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 timo

  • Resolution set to wontfix
  • Status changed from new to closed

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