#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 [email protected].
To post to this group, send email to [email protected].
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