diff --git a/NEWS b/NEWS index e7b9886..febc513 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +1.2.16: March 18, 2008 + * Fixed a bug that prevented the upload of filenames with special characters + in them. + 1.2.15: March 17, 2008 * Fixed the bugs introduced by the previous released. diff --git a/controller/Files.py b/controller/Files.py index 4892892..41bb1f1 100644 --- a/controller/Files.py +++ b/controller/Files.py @@ -168,7 +168,7 @@ class FieldStorage( cherrypy._cpcgifs.FieldStorage ): except ValueError: raise Upload_error( "The file_id is invalid." ) - self.filename = self.filename.split( "/" )[ -1 ].split( "\\" )[ -1 ].strip() + self.filename = unicode( self.filename.split( "/" )[ -1 ].split( "\\" )[ -1 ].strip(), "utf8" ) if not self.filename: raise Upload_error( "Please provide a filename." ) @@ -265,7 +265,9 @@ class Files( object ): db_file = self.__database.load( File, file_id ) cherrypy.response.headerMap[ u"Content-Type" ] = db_file.content_type - cherrypy.response.headerMap[ u"Content-Disposition" ] = u'attachment; filename="%s"' % db_file.filename.replace( '"', r"\"" ) + disposition = u'attachment; filename="%s"' % db_file.filename.replace( '"', r"\"" ) + disposition = disposition.encode( "utf8" ) + cherrypy.response.headerMap[ u"Content-Disposition" ] = disposition cherrypy.response.headerMap[ u"Content-Length" ] = db_file.size_bytes def stream(): diff --git a/controller/test/Test_controller.py b/controller/test/Test_controller.py index 4468d8b..8747840 100644 --- a/controller/test/Test_controller.py +++ b/controller/test/Test_controller.py @@ -535,7 +535,7 @@ class Test_controller( object ): if headers is None: headers = [] - post_data = str( "".join( post_data ) ) + post_data = "".join( post_data ).encode( "utf8" ) headers.append( ( "Content-Type", "multipart/form-data; boundary=%s" % boundary ) ) if "Content-Length" not in [ name for ( name, value ) in headers ]: diff --git a/controller/test/Test_files.py b/controller/test/Test_files.py index b660512..2110ec6 100644 --- a/controller/test/Test_files.py +++ b/controller/test/Test_files.py @@ -1,3 +1,5 @@ +# -*- coding: utf8 -*- + import time import types import cherrypy @@ -32,6 +34,7 @@ class Test_files( Test_controller ): self.session_id = None self.file_id = "22" self.filename = "file.png" + self.unicode_filename = u"ümlaut.png" self.new_filename = "newfile.png" self.file_data = "foobar\x07`-=[]\;',./ ~!@#$%^&*()_+{}|:\"<>?" * 100 self.weird_filename = self.file_data + ".png" @@ -116,7 +119,7 @@ class Test_files( Test_controller ): if self.upload_thread: self.upload_thread.join() - def test_download( self ): + def test_download( self, filename = None ): self.login() self.http_upload( @@ -125,7 +128,7 @@ class Test_files( Test_controller ): notebook_id = self.notebook.object_id, note_id = self.note.object_id, ), - filename = self.filename, + filename = filename or self.filename, file_data = self.file_data, content_type = self.content_type, session_id = self.session_id, @@ -139,7 +142,7 @@ class Test_files( Test_controller ): headers = result[ u"headers" ] assert headers assert headers[ u"Content-Type" ] == self.content_type - assert headers[ u"Content-Disposition" ] == u'attachment; filename="%s"' % self.filename + assert headers[ u"Content-Disposition" ] == ( u'attachment; filename="%s"' % ( filename or self.filename ) ).encode( "utf8" ) gen = result[ u"body" ] assert isinstance( gen, types.GeneratorType ) @@ -155,6 +158,9 @@ class Test_files( Test_controller ): file_data = "".join( pieces ) assert file_data == self.file_data + def test_download_with_unicode_filename( self ): + self.test_download( self.unicode_filename ) + def test_download_without_login( self ): self.login() @@ -229,7 +235,7 @@ class Test_files( Test_controller ): assert u"access" in result.get( u"error" ) - def test_upload( self ): + def test_upload( self, filename = None ): self.login() result = self.http_upload( @@ -238,7 +244,7 @@ class Test_files( Test_controller ): notebook_id = self.notebook.object_id, note_id = self.note.object_id, ), - filename = self.filename, + filename = filename or self.filename, file_data = self.file_data, content_type = self.content_type, session_id = self.session_id, @@ -252,7 +258,7 @@ class Test_files( Test_controller ): assert db_file assert db_file.notebook_id == self.notebook.object_id assert db_file.note_id == self.note.object_id - assert db_file.filename == self.filename + assert db_file.filename == filename or self.filename assert db_file.size_bytes == len( self.file_data ) assert db_file.content_type == self.content_type @@ -264,6 +270,9 @@ class Test_files( Test_controller ): user = self.database.load( User, self.user.object_id ) assert user.storage_bytes > orig_storage_bytes + def test_upload_with_unicode_filename( self ): + self.test_upload( self.unicode_filename ) + def test_upload_without_login( self ): result = self.http_upload( "/files/upload?file_id=%s" % self.file_id,