Sammitch
Sammitch

Reputation: 32272

Can't get uploaded file in Twisted

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.

Upvotes: 1

Views: 1769

Answers (1)

glu
glu

Reputation: 195

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.

Upvotes: 1

Related Questions