Commits

Marcin Kuzminski committed 058e274

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

Comments (0)

Files changed (2)

rhodecode/controllers/files.py

         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)
+        fd, archive = tempfile.mkstemp()
+        t = open(archive, 'wb')
+        cs.fill_archive(stream=t, kind=fileformat, subrepos=subrepos)
+        t.close()
 
-        content_disposition = 'attachment; filename=%s-%s%s' \
-            % (repo_name, revision[:12], ext)
-        content_length = os.path.getsize(_archive_name)
+        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
 
-        headers = [('Content-Disposition', str(content_disposition)),
-                   ('Content-Type', str(content_type)),
-                   ('Content-Length', str(content_length))]
-
-        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')

rhodecode/tests/functional/test_files.py

 
             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)
 
         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')
     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')