Opened 9 years ago

Closed 2 months ago

#5897 closed New feature (fixed)

Add Content-Length header in common middleware

Reported by: Scott Barr <scott@…> Owned by: ccahoon
Component: HTTP handling Version: master
Severity: Normal Keywords: Content-Length middleware
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I've modified to add a "Content-Length" header to the HTTP response if the response code is 200 and the "Content-Length" header hasn't already been supplied.

Attachments (1)

middleware.common.patch (515 bytes) - added by Scott Barr <scott@…> 9 years ago.

Download all attachments as: .zip

Change History (15)

Changed 9 years ago by Scott Barr <scott@…>


comment:1 Changed 9 years ago by Simon Greenhill <dev@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Ready for checkin

comment:2 Changed 8 years ago by adrian

Hmmm, what's the advantage of doing this? I don't necessarily like the overhead of doing a len() on every request...

comment:3 Changed 8 years ago by adrian

  • Triage Stage changed from Ready for checkin to Design decision needed

comment:4 Changed 8 years ago by fumanchu

The advantage is following the HTTP spec, which mandates that messages either:

  1. be length 0 by design (e.g. HEAD)
  2. use "chunked" encoding
  3. provide Content-Length
  4. use the multipart/byteranges media type, or
  5. close the connection.

Options 1, 2, and 4 are rare, so omitting C-L leaves us with (5) and therefore means conns can't ever use keepalive. I would say that any response with a buffered body, not just 200, should get a C-L response header.

In addition, the len(str) function seems to be nearly O(1) up to about 95MB:

>>> for size in range(10):
...     timeit.Timer("len(a)", "a = 'a' * %d" % (10 ** size)).timeit()
>>> 10 ** 8
>>> _ / 1024
>>> _ / 1024

comment:5 Changed 7 years ago by ccahoon

  • Owner changed from nobody to ccahoon

comment:6 Changed 7 years ago by ccahoon

Three things:

That said, I am going to investigate further. This is closely related to #7581, which incidentally has a very similar bit of code to the patch provided here.

When dealing with streaming responses, probably intended for chunked transfer encoding, we want to ensure that we don't consume the whole generator/iterator in any effort to send a header that is not strictly required.

comment:7 Changed 7 years ago by graham_king

ConditionalGetMiddleware already does this (amongst other things).
Is that not sufficient?

Also, Content-Length should be set for all header codes (Ajax and REST APIs will use a wider selection, 201 for example).
core/handlers/ will use http.conditional_content_removal to remove Content-Length for any response codes that shouldn't have it, so setting for all is safe.

comment:8 Changed 5 years ago by gabrielhurley

  • Severity set to Normal
  • Type set to New feature

comment:9 Changed 5 years ago by carljm

  • Easy pickings unset
  • Resolution set to wontfix
  • Status changed from new to closed
  • UI/UX unset

Discussion with Alex at sprint: since this is not required by spec, and is already available in ConditionalGetMiddleware for those who want it, we don't want to go exhausting iterator responses by default in CommonMiddleware.

comment:10 Changed 2 years ago by aaugustin

  • Has patch unset
  • Resolution wontfix deleted
  • Status changed from closed to new
  • Triage Stage changed from Design decision needed to Accepted

I'm reopening this ticket in the light of the introduction of explicit streaming responses, which removes the only objection to fixing this ticket.

I believe Content-Length should be added for non-streaming responses. Their content is consumed upon assignment. The overhead of computing response length will be negligible.

comment:11 Changed 12 months ago by dbaxa

Because some load balancers, such as Amazon "Elastic Load Balancing", require a content-length header django should at least document where the ConditionalGetMiddleware middleware may be required.

Last edited 12 months ago by dbaxa (previous) (diff)

comment:12 Changed 2 months ago by claudep

  • Has patch set

comment:13 Changed 2 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

comment:14 Changed 2 months ago by Claude Paroz <claude@…>

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

In 9588718:

Fixed #5897 -- Added the Content-Length response header in CommonMiddleware

Thanks Tim Graham for the review.

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