changeset 2318:058e2743e7b7 beta

fixes issue #455 Creating an archive generates an exception on Windows - reverted the FileIter implementation as it had the same issue on windows and probably on unix as ref #448
author Marcin Kuzminski <marcin@python-works.com>
date Sun, 20 May 2012 14:41:03 +0200
parents c4d8ed624728
children 4c239e0dcbb7
files rhodecode/controllers/files.py rhodecode/tests/functional/test_files.py
diffstat 2 files changed, 27 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/files.py	Sun May 20 14:34:45 2012 +0200
+++ b/rhodecode/controllers/files.py	Sun May 20 14:41:03 2012 +0200
@@ -361,26 +361,26 @@
         except (ImproperArchiveTypeError, KeyError):
             return _('Unknown archive type')
 
-        fd, _archive_name = tempfile.mkstemp(suffix='rcarchive')
-        with open(_archive_name, 'wb') as f:
-            cs.fill_archive(stream=f, kind=fileformat, subrepos=subrepos)
-
-        content_disposition = 'attachment; filename=%s-%s%s' \
-            % (repo_name, revision[:12], ext)
-        content_length = os.path.getsize(_archive_name)
+        fd, archive = tempfile.mkstemp()
+        t = open(archive, 'wb')
+        cs.fill_archive(stream=t, kind=fileformat, subrepos=subrepos)
+        t.close()
 
-        headers = [('Content-Disposition', str(content_disposition)),
-                   ('Content-Type', str(content_type)),
-                   ('Content-Length', str(content_length))]
+        def get_chunked_archive(archive):
+            stream = open(archive, 'rb')
+            while True:
+                data = stream.read(16 * 1024)
+                if not data:
+                    stream.close()
+                    os.close(fd)
+                    os.remove(archive)
+                    break
+                yield data
 
-        class _DestroyingFileWrapper(_FileIter):
-            def close(self):
-                self.file.close
-                os.remove(self.file.name)
-
-        request.environ['wsgi.file_wrapper'] = _DestroyingFileWrapper
-        fapp = FileApp(_archive_name, headers=headers)
-        return fapp(request.environ, self.start_response)
+        response.content_disposition = str('attachment; filename=%s-%s%s' \
+                                           % (repo_name, revision[:12], ext))
+        response.content_type = str(content_type)
+        return get_chunked_archive(archive)
 
     @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
                                    'repository.admin')
--- a/rhodecode/tests/functional/test_files.py	Sun May 20 14:34:45 2012 +0200
+++ b/rhodecode/tests/functional/test_files.py	Sun May 20 14:41:03 2012 +0200
@@ -200,9 +200,10 @@
 
             self.assertEqual(response.status, '200 OK')
             heads = [
-            ('Content-Type', 'text/html; charset=utf-8'),
-            ('Content-Length', '0'), ('Pragma', 'no-cache'),
-            ('Cache-Control', 'no-cache')
+                ('Pragma', 'no-cache'), 
+                ('Cache-Control', 'no-cache'), 
+                ('Content-Disposition', 'attachment; filename=%s' % filename),
+                ('Content-Type', '%s; charset=utf-8' % info[0]),
             ]
             self.assertEqual(response.response._headers.items(), heads)
 
@@ -212,7 +213,8 @@
         for arch_ext in ['tar', 'rar', 'x', '..ax', '.zipz']:
             fname = '27cd5cce30c96924232dffcd24178a07ffeb5dfc%s' % arch_ext
 
-            response = self.app.get(url(controller='files', action='archivefile',
+            response = self.app.get(url(controller='files', 
+                                        action='archivefile',
                                         repo_name=HG_REPO,
                                         fname=fname))
             response.mustcontain('Unknown archive type')
@@ -220,10 +222,11 @@
     def test_archival_wrong_revision(self):
         self.log_user()
 
-        for rev in ['00x000000', 'tar', 'wrong', '@##$@$424213232', '232dffcd']:
+        for rev in ['00x000000', 'tar', 'wrong', '@##$@$42413232', '232dffcd']:
             fname = '%s.zip' % rev
 
-            response = self.app.get(url(controller='files', action='archivefile',
+            response = self.app.get(url(controller='files',
+                                        action='archivefile',
                                         repo_name=HG_REPO,
                                         fname=fname))
             response.mustcontain('Unknown revision')