[Django] #25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was 1.1

61 views
Skip to first unread message

Django

unread,
Oct 27, 2015, 4:02:19 PM10/27/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+--------------------
Reporter: gabn88 | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.7
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
And http_version 1.0 is not working with websockets.

I don't know exactly why this is happening, but I don't think it is meant
to be like this.

I think HTTP/1.1 is fine to use for the development runserver.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 27, 2015, 7:16:31 PM10/27/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+--------------------------------------

Reporter: gabn88 | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by timgraham):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

What methodology are you using to test? Can you bisect Django's commit
history to determine where the behavior changed?

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:1>

Django

unread,
Oct 28, 2015, 3:22:24 AM10/28/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+--------------------------------------
Reporter: gabn88 | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 1.7
Severity: Normal | Resolution: worksforme
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by claudep):

* status: new => closed
* resolution: => worksforme


Comment:

I cannot confirm this, I've checked with one of my site with Django 1.8
and the response was `HTTP/1.1 200 OK`.
By the way, this is probably controlled by the Web server, not Django.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:2>

Django

unread,
Oct 28, 2015, 3:24:00 AM10/28/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+--------------------------------------

Reporter: gabn88 | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by claudep):

* status: closed => new
* resolution: worksforme =>


Comment:

Oh, sorry, I didn't pay attention to the `runserver` part...

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:3>

Django

unread,
Oct 28, 2015, 4:04:08 AM10/28/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+------------------------------------

Reporter: gabn88 | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by claudep):

* version: 1.7 => master
* stage: Unreviewed => Accepted


Comment:

Looks like that change would be required:
{{{
#!patch
diff --git a/django/core/servers/basehttp.py
b/django/core/servers/basehttp.py
index 4e2f8dd..1e0f0c2 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -86,6 +86,7 @@ class WSGIServer(simple_server.WSGIServer, object):

# Inheriting from object required on Python 2.
class ServerHandler(simple_server.ServerHandler, object):
+ http_version = "1.1"
def handle_error(self):
# Ignore broken pipe errors, otherwise pass on
if not is_broken_pipe_error():
}}}

However, I didn't find the possible faulty commit.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:4>

Django

unread,
Oct 30, 2015, 7:40:53 PM10/30/15
to django-...@googlegroups.com
#25619: Since Django ~1.6.4 the dev runserver uses http_version 1.0, before it was
1.1
-------------------------------+------------------------------------

Reporter: gabn88 | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by claudep):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:5>

Django

unread,
Oct 31, 2015, 9:08:29 AM10/31/15
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------------+-------------------------------------
Reporter: gabn88 | Owner: nobody
Type: New feature | Status: new

Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* type: Bug => New feature
* stage: Accepted => Ready for checkin


Comment:

[https://github.com/django/django/pull/5524 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:6>

Django

unread,
Oct 31, 2015, 6:16:56 PM10/31/15
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------+------------------------------------
Reporter: gabn88 | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted


Comment:

As noted on the pull request , it looks to me like we'd also need to set
[https://docs.python.org/3.5/library/http.server.html?highlight=protocol_version#http.server.BaseHTTPRequestHandler.protocol_version
WSGIServer.protocol_version]() too. Not sure this is trivial given the
sentence in the Python docs, "If set to 'HTTP/1.1', the server will permit
HTTP persistent connections; however, your server must then include an
accurate Content-Length header (using send_header()) in all of its
responses to clients." Given that, I'd be surprised if older versions of
runserver really used HTTP 1.1.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:7>

Django

unread,
Dec 10, 2015, 2:54:05 PM12/10/15
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------+------------------------------------
Reporter: gabn88 | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by claudep):

Seems this ticket depends on #5897 (setting Content-Length on non-
streaming responses).

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:8>

Django

unread,
Jun 18, 2016, 12:54:24 AM6/18/16
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------+------------------------------------
Reporter: gabn88 | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by marfire):

* cc: k@… (added)


Comment:

This issue bit me recently because Chrome refuses to use ETags if the
server responds with `HTTP/1.0` (see
[[http://stackoverflow.com/a/28033770/2395796|here]], which I can
confirm). That led to some frustrating debugging.

So +1 to fixing this and #5897.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:9>

Django

unread,
Jun 27, 2016, 12:45:41 PM6/27/16
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------+------------------------------------
Reporter: gabn88 | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by claudep):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:10>

Django

unread,
Jun 27, 2016, 2:35:45 PM6/27/16
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------+------------------------------------
Reporter: gabn88 | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


Comment:

As noted on the PR, this causes problems when running the selenium tests,
at least on Chrome.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:11>

Django

unread,
Oct 26, 2016, 3:34:47 PM10/26/16
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
--------------------------------+------------------------------------
Reporter: Gerben Morsink | Owner: nobody

Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Patrick Cloke):

* cc: clokep@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:12>

Django

unread,
Feb 10, 2017, 5:04:33 AM2/10/17
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
--------------------------------+------------------------------------
Reporter: Gerben Morsink | Owner: nobody
Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Claude Paroz):

* needs_better_patch: 1 => 0


Comment:

I've recreated a [https://github.com/django/django/pull/8043 pull request]
after #20238 has been fixed. Hopefully selenium tests will pass now.

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:13>

Django

unread,
Feb 10, 2017, 7:01:37 PM2/10/17
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------------+-------------------------------------

Reporter: Gerben Morsink | Owner: nobody
Type: New feature | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:14>

Django

unread,
Feb 23, 2017, 3:06:34 AM2/23/17
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------------+-------------------------------------
Reporter: Gerben Morsink | Owner: nobody
Type: New feature | Status: closed

Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz <claude@…>):

* status: new => closed

* resolution: => fixed


Comment:

In [changeset:"e6065c7b8363202c5eb13ba10c97a8c24d014b45" e6065c7]:
{{{
#!CommitTicketReference repository=""
revision="e6065c7b8363202c5eb13ba10c97a8c24d014b45"
Fixed #25619 -- Made runserver serve with HTTP 1.1 protocol

Thanks Tim Graham for the review.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:15>

Django

unread,
Nov 10, 2018, 7:55:27 AM11/10/18
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------------+-------------------------------------
Reporter: Gerben Morsink | Owner: nobody
Type: New feature | Status: closed
Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Florian Apolloner <apollo13@…>):

In [changeset:"934acf1126995f6e6ccba5947ec8f7561633c27f" 934acf11]:
{{{
#!CommitTicketReference repository=""
revision="934acf1126995f6e6ccba5947ec8f7561633c27f"
Fixed keep-alive support in manage.py runserver.

Ticket #25619 changed the default protocol to HTTP/1.1 but did not
properly implement keep-alive. As a "fix" keep-alive was disabled in
ticket #28440 to prevent clients from hanging (they expect the server to
send more data if the connection is not closed and there is no content
length set).

The combination of those two fixes resulted in yet another problem:
HTTP/1.1 by default allows a client to assume that keep-alive is
supported unless the server disables it via 'Connection: close' -- see
RFC2616 8.1.2.1 for details on persistent connection negotiation. Now if
the client receives a response from Django without 'Connection: close'
and immediately sends a new request (on the same tcp connection) before
our server closes the tcp connection, it will error out at some point
because the connection does get closed a few milli seconds later.

This patch fixes the mentioned issues by always sending 'Connection:
close' if we cannot determine a content length. The code is inefficient
in the sense that it does not allow for persistent connections when
chunked responses are used, but that should not really cause any
problems (Django does not generate those) and it only affects the
development server anyways.

Refs #25619, #28440.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:16>

Django

unread,
Nov 20, 2018, 5:45:50 PM11/20/18
to django-...@googlegroups.com
#25619: Make runserver use HTTP 1.1
-------------------------------------+-------------------------------------
Reporter: Gerben Morsink | Owner: nobody
Type: New feature | Status: closed
Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"e1721ece485b35ab5543f134203a8a8ce9f31a7c" e1721ece]:
{{{
#!CommitTicketReference repository=""
revision="e1721ece485b35ab5543f134203a8a8ce9f31a7c"
[2.1.x] Fixed #29849 -- Fixed keep-alive support in runserver.

Ticket #25619 changed the default protocol to HTTP/1.1 but did not
properly implement keep-alive. As a "fix" keep-alive was disabled in
ticket #28440 to prevent clients from hanging (they expect the server to
send more data if the connection is not closed and there is no content
length set).

The combination of those two fixes resulted in yet another problem:
HTTP/1.1 by default allows a client to assume that keep-alive is
supported unless the server disables it via 'Connection: close' -- see
RFC2616 8.1.2.1 for details on persistent connection negotiation. Now if
the client receives a response from Django without 'Connection: close'
and immediately sends a new request (on the same tcp connection) before
our server closes the tcp connection, it will error out at some point
because the connection does get closed a few milli seconds later.

This patch fixes the mentioned issues by always sending 'Connection:
close' if we cannot determine a content length. The code is inefficient
in the sense that it does not allow for persistent connections when
chunked responses are used, but that should not really cause any
problems (Django does not generate those) and it only affects the
development server anyways.

Refs #25619, #28440.

Regression in ac756f16c5bbbe544ad82a8f3ab2eac6cccdb62e.
Backport of 934acf1126995f6e6ccba5947ec8f7561633c27f from master.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:17>

Reply all
Reply to author
Forward
0 new messages