diff -u -r django/core/handlers/modpython.py django/core/handlers/modpython.py
--- django/core/handlers/modpython.py	2008-11-19 00:44:20.000000000 -0500
+++ django/core/handlers/modpython.py	2009-02-10 17:22:02.000000000 -0500
@@ -209,6 +209,9 @@
 
         # Convert our custom HttpResponse object back into the mod_python req.
         req.content_type = response['Content-Type']
+        if hasattr(http_response, 'sendfile_filename'):
+            mod_python_req.sendfile(http_response.sendfile_filename)
+            return
         for key, value in response.items():
             if key != 'content-type':
                 req.headers_out[str(key)] = str(value)
diff -u -r django/core/handlers/wsgi.py django/core/handlers/wsgi.py
--- django/core/handlers/wsgi.py	2008-11-19 00:44:20.000000000 -0500
+++ django/core/handlers/wsgi.py	2009-02-10 20:52:33.000000000 -0500
@@ -250,9 +250,20 @@
         except KeyError:
             status_text = 'UNKNOWN STATUS CODE'
         status = '%s %s' % (response.status_code, status_text)
+
+        if hasattr(response, 'sendfile_filename') and response.has_header('Content-Length'):
+            del response['Content-Length']
         response_headers = [(str(k), str(v)) for k, v in response.items()]
         for c in response.cookies.values():
             response_headers.append(('Set-Cookie', str(c.output(header=''))))
         start_response(status, response_headers)
+        if hasattr(response, 'sendfile_filename'):
+            filelike = open(response.sendfile_filename, 'rb')
+            block_size = response.block_size
+            if 'wsgi.file_wrapper' in environ:
+                return environ['wsgi.file_wrapper'](filelike, block_size)
+            else:
+                return iter(lambda: filelike.read(block_size), '')
+
         return response
 
diff -u -r django/core/servers/basehttp.py django/core/servers/basehttp.py
--- django/core/servers/basehttp.py	2008-11-19 00:44:20.000000000 -0500
+++ django/core/servers/basehttp.py	2009-02-10 17:22:02.000000000 -0500
@@ -313,10 +313,9 @@
         in the event loop to iterate over the data, and to call
         'self.close()' once the response is finished.
         """
-        if not self.result_is_file() and not self.sendfile():
-            for data in self.result:
-                self.write(data)
-            self.finish_content()
+        for data in self.result:
+            self.write(data)
+        self.finish_content()
         self.close()
 
     def get_scheme(self):
diff -u -r django/http/__init__.py django/http/__init__.py
--- django/http/__init__.py	2008-11-19 00:44:05.000000000 -0500
+++ django/http/__init__.py	2009-02-10 17:22:02.000000000 -0500
@@ -393,6 +393,19 @@
             raise Exception("This %s instance cannot tell its position" % self.__class__)
         return sum([len(chunk) for chunk in self._container])
 
+class HttpResponseSendFile(HttpResponse):
+    def __init__(self, path_to_file, content_type=None):
+        HttpResponse.__init__(self)
+        if not content_type:
+            from mimetypes import guess_type
+            content_type = guess_type(path_to_file)[0]
+            if content_type == None: # probably windows w/o proper mimetype lookup
+                content_type = "application/octet-stream"
+        self['Content-Type'] = content_type
+        self.sendfile_filename = path_to_file
+        self.block_size = 8192
+        self.status_code = 200
+
 class HttpResponseRedirect(HttpResponse):
     status_code = 302
 
