#29069: Static file serving does not call request_finished signal
-------------------------------------+-------------------------------------
     Reporter:  André Cruz           |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  HTTP handling        |                  Version:  1.11
     Severity:  Normal               |               Resolution:
     Keywords:  streamingresponse    |             Triage Stage:  Accepted
  request_finished                   |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Tom Forbes):

 I had another experiment today. As far as I can see we can pick only one:

 1. Support `sendfile` and other efficient means of sending static files
 2. Have the response ended signal fire

 The WSGI spec [has a section on
 this](https://www.python.org/dev/peps/pep-0333/#optional-platform-
 specific-file-handling). I'll try and summarize what I have found:

 We must give an iterable to `wsgi.file_wrapper`, which can optionally be a
 file like object. We currently pass the underlying file-like object given
 to the `FileResponse`, which is fine, but when it's `close()` method is
 called (or it finishes iterating) then the `FileResponse.close()` is not
 called. The `wsgi.file_wrapper` can try and detect if the file is a real
 file and if so use more efficient streaming methods.

 If we pass the entire `FileResponse` to `wsgi.file_wrapper` then we do not
 get fast streaming because the response is not an actual file, but the
 `close()` method is called

 If we give the underlying user-controlled value the `FileResponse` is
 given, we may get streaming but will not get the `FileResponse.close()`
 called.

 I can see two ways to hack around this:

 1. Return a mocked instance that wraps the user-supplied value, with a
 `close()` method that calls `FileResponse.close()`. This is tricky because
 it *cannot* have attributes or methods like `filenum()` if the
 *underlying* value does not, because `hasattr()` will be True and things
 will break. The spec gives an example of such a class (grep for `class
 FileWrapper:`), but... there are numerous issues with that.

 2. Somehow inject our own logic into the values `close()` method and pass
 that to `wsgi.wrapper`...

 {{{
 old_close = value.close
 function fake_close(*args, **kwargs):
     old_close(*args, **kwargs)
     our_response.close()   # send signals
 value.close = fake_close
 }}}

 I don't think either is nice.

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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.2fea4eb61e5a2101a67c2c559cec6ad6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to