Skip to content
Advertisement

How do I handle POST requests in Twisted?

I’m trying to write a script where someone can type the name of a website into a box and my script will render the resources of that website. I’m not sure how to go about it, I’m thinking it would like something like this:

class FormPage(Resource):
    isLeaf = True
    def render_GET(self, request):
        return b"""<html><body><form method="POST"><input name="form-field" type="text"/><input type="submit" /></form></body></html>"""

    def render_POST(self, request):
        answer = request.content.read()[11:].decode()
        ReverseProxyResource(answer, 80, b'')

factory = Site(FormPage())
reactor.listenTCP(80, factory)
reactor.run()

This script just isn’t working, when the script I get an Error: Request did not return bytes. Could anybody tell me what I’m doing wrong or where I can learn more about this subject? thanks!!

Advertisement

Answer

I haven’t worked with Resources and Site objects in a while, but I’m pretty sure you have overload the Resource.getChild() method and return a ReverseProxyResource to achieve what you want. It can get a bit messy in my opinion if you go that route. However, in klein what you’re trying to do is trivial and can easily be solved. You basically set branch=True and that makes it so that a Resource object can be returned. For example:

from klein import Klein
from twisted.web.proxy import ReverseProxyResource

app = Klein()

@app.route('/', methods=['GET'])
def render_GET(request):
    return b"""<html><body><form method="POST"><input name="form-field" type="text"/><input type="submit" /></form></body></html>"""

@app.route('/', methods=['POST'])
def render_POST(request, branch=True):        # branch=True lets you return Resources
    answer = request.args.get(b'form-field', b'localhost').decode('utf-8')        # also use request.args instead
    return ReverseProxyResource(answer, 80, '')

app.run('localhost', 80)

Now for the final matter, you’re running this on Python 3.x and it seems like ReverseProxyResource hasn’t been fully ported over yet. So if you run this code in Python 3, you will get tracebacks.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement