1

I am trying to get a simple service running that will accept file uploads via an HTTP POST, however I'm having some trouble figuring out where the actual file data resides after the post request completes.

The code I have thusfar is:

from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor

#import cgi

class FormPage(Resource):
    def render_GET(self, request):
        return """
<html>
<body>
<form method="POST">
    Text: <input name="text1" type="text" /><br />
    File: <input name="file1" type="file" /><br />
    <input type="submit" />
</form>
</body>
</html>
"""

    def render_POST(self, request):
        response = '<p>File: %s</p>' % request.args['file1'][0]
        response += '<p>Content: %s</p>' % request.content.read()
        return '<html><body>You submitted: %s</body></html>' % (response)

root = Resource()
root.putChild("form", FormPage())
factory = Site(root)
reactor.listenTCP(8080, factory)
reactor.run()

And the response I get is:

You submitted:

File: test.txt

Content: text1=sdfsd&file1=test.txt

Most everything else I can find on the subject refers to using an IRequest object which supposedly has an IRequest.files property, but it is not listed in the documentation, and it throws an error when I run it.

The end goal after receiving the file will be to move it to a particular folder, and then run some further code.

Community
  • 1
  • 1
Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • Just a quick note since I don't have time for a full answer at the moment: the other questions you link to are for `twisted.web2`, a now-removed partial rewrite of `twisted.web`. File uploads do kind of suck in Twisted, as you can see from one of our oldest tickets: http://twistedmatrix.com/trac/ticket/288 and the documentation has also had serious problems: http://twistedmatrix.com/trac/ticket/6181 Sorry you're having a hard time with it! – Glyph Jun 27 '13 at 20:58
  • @Glyph it turns out that I'm missing the multipart `enctype` in my form HTML. I have the *data*, but now I find that the filename is no longer in the post data. Is it gone forever? – Sammitch Jun 27 '13 at 22:17
  • I believe so, yeah. Sorry. Web browsers are not great either :). – Glyph Jun 28 '13 at 17:14
  • 1
    @Glyph it's not the browser, I can see the filename in the raw POST data. twisted.web just doesn't do anything with it. – Sammitch Jun 28 '13 at 22:19

1 Answers1

1

I had similar problem. In a fact you solved that in comments under your question but to clarify and sum up I am writing this answer.

In order to upload file you need to set form's enctype to multipart/form-data like that:

<form enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" name="submit" value="Submit">
</form>

Now you can access raw file's data by request.args['file']. To get original name you need to parse request.content, ie:

import re
filename = re.search(r'name="file"; filename="(.*)"', content).group(1)

I am not sure if those arguments (name and filename) are always going to be in this particular order though, so be careful with that. Also keep in mind that it will not work if you have multiple file input.

glu
  • 185
  • 2
  • 10