[Twisted-web] Trouble with flex file-uploading and twisted.web2 FileSaver

Daniel Yang daniel.yang.zhenyu at gmail.com
Thu Aug 20 11:20:43 EDT 2009


Hi team,

I've been trying to upload files to twisted.web2 backend(FileSaver) with
Adobe Flex and I am always getting IOError.
(code see below)
After some sniffing work, I found the error messages returned by
twisted.web2:

Unexpected data on same line as boundary: '--'

I believe this flex app works with php backend. So this might be with
twisted.web2 or flash player's malformed post data.

It seems the twisted error comes from fileupload.py:
(I added 2 prints)
    def _readBoundaryLine(self):
        print "_readBoundaryLine"
        line = self.stream.readline(size=1024)
        if isinstance(line, defer.Deferred):
            line = defer.waitForDeferred(line)
            yield line
            line = line.getResult()
        print line
        if line == "--\r\n":
            # THE END!
            yield False
            return
        elif line != "\r\n":
            raise MimeFormatError("Unexpected data on same line as boundary:
%r" % (line,))
        yield True
        return
    _readBoundaryLine = defer.deferredGenerator(_readBoundaryLine)

with html uploading form, it outputs:

2009-08-20 23:06:08+0800 [-] _readBoundaryLine
2009-08-20 23:06:08+0800 [-] --
2009-08-20 23:06:08+0800 [-]
2009-08-20 23:06:08+0800 [-] <POST /upload (1, 1)> --------
2009-08-20 23:06:08+0800 [-] FileUpload


but with flex uploading:

2009-08-20 23:06:27+0800 [-] _readBoundaryLine
2009-08-20 23:06:27+0800 [-]
2009-08-20 23:06:27+0800 [-]
2009-08-20 23:06:27+0800 [-] _readBoundaryLine
2009-08-20 23:06:27+0800 [-]
2009-08-20 23:06:27+0800 [-]
2009-08-20 23:06:27+0800 [-] _readBoundaryLine
2009-08-20 23:06:27+0800 [-] --


Same file, different posted data.

Any ideas?

Does this happen to be a bug, or is there any way to walk around this?


My testing code:

python code:

from twisted.web2 import http_headers, resource, \
static, server, channel, http, responsecode
from twisted.python import util

FORMHTML = """
<html>
<p>for test</p>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="FileUpload" />
<input type="submit" value="Upload"/>
</form>
</html>
"""

class MyFileSaver(static.FileSaver):
"""for test only"""
def render(self, req):
print req, '--------'
if req.files:
for fieldName in req.files:
print fieldName

return http.Response(responsecode.OK, {}, stream='ok')


class Toplevel(resource.Resource):
  addSlash = True
  def render(self, ctx):
return http.Response(stream=FORMHTML)

  child_upload = MyFileSaver(util.sibpath(__file__, ''),
   expectedFields=['FileUpload'],
   allowedTypes=(
   http_headers.MimeType('image', 'jpeg'),
   http_headers.MimeType('image', 'png'),
   http_headers.MimeType('image', 'gif'),
   )
   )
  child_swf = static.File(util.sibpath(__file__, 'FileUpload.swf'))
site = server.Site(Toplevel())

# Standard twisted application Boilerplate
from twisted.application import service, strports
application = service.Application("demoserver")
s = strports.service('tcp:8080', channel.HTTPFactory(site))
s.setServiceParent(application)


My flex code:

<?xml version="1.0" encoding="utf-8"?>

<!--
http://blog.flexexamples.com/2007/09/21/uploading-files-in-flex-using-the-filereference-class/-->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

        layout="vertical"

        verticalAlign="middle"

        backgroundColor="white"

        creationComplete="init();">


    <mx:Script>

        <![CDATA[

            private var fileRef:FileReference;


            private const FILE_UPLOAD_URL:String = "
http://127.0.0.1:8080/upload";


            private function init():void {

                fileRef = new FileReference();

                fileRef.addEventListener(Event.SELECT, fileRef_select);

                fileRef.addEventListener(ProgressEvent.PROGRESS,
fileRef_progress);

                fileRef.addEventListener(Event.COMPLETE, fileRef_complete);


fileRef.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);

                fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
onSec);

            }


            private function browseAndUpload():void {

                fileRef.browse();

                message.text = "";

            }



            private function ioErrorHandler(event:IOErrorEvent):void {

            trace(event);

            }



            private function onSec(event:SecurityErrorEvent):void{

            trace(event);

            }


            private function fileRef_select(evt:Event):void {

                try {

                    message.text = "size (bytes): " +
numberFormatter.format(fileRef.size);



                    var req:URLRequest = new URLRequest();

                    req.url = FILE_UPLOAD_URL;

                    req.method = URLRequestMethod.POST;



                    fileRef.upload(req, "FileUpload");

                } catch (err:Error) {

                    message.text = "ERROR: zero-byte file";

                }

            }


            private function fileRef_progress(evt:ProgressEvent):void {

                progressBar.visible = true;

            }


            private function fileRef_complete(evt:Event):void {

                message.text += " (complete)";

                progressBar.visible = false;

            }

        ]]>

    </mx:Script>


    <mx:NumberFormatter id="numberFormatter" />


    <mx:Button label="Upload file"

            click="browseAndUpload();" />

    <mx:Label id="message" />

    <mx:ProgressBar id="progressBar"

            indeterminate="true"

            visible="false" />


</mx:Application>


-- 
-----------------------------------------------
Yours
Faithfully

Daniel Yang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-web/attachments/20090820/942d938b/attachment-0001.htm 


More information about the Twisted-web mailing list