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.
* 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>
* 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>
* 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>
* 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>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:5>
* 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>
* 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>
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>
* 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>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:10>
* 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>
* cc: clokep@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:12>
* 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>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/25619#comment:14>
* 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>
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>
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>