Sending a flask request within a flask request

flask, python, python-2.7, web-services, webserver

Solution

This happens cause you're using the flask devserver. It's not for production use. In production environment you would use an application server (uWSGI, GUnicorn, Tornado, ...) with or without a webserver layer (NGINX, Apache,...) to proxy/balance connections to the workers protecting (not completely but in a lot of environments it's acceptable) from DoS attacks.

Problem

I am implementing an endpoint in my Flask application that receives a collection of HTTP requests, and returns a collection of the corresponding HTTP responses. In order to accomplish this, I need my endpoint to call other endpoints in order to construct the result. However, because Flask is blocking while processing the original request, it cannot process the nested requests and the application gets deadlocked. Is there any way to issue a request within a request in flask in a way that doesn't result in a deadlock? I included a segment of my code which I believe should be enough to illustrate the problem without overwhelming you. If you would like to see more of it please let me know and I'll share. ``` from requests import Session, Request def split(request): multipart = request.stream.read() boundary = request.content_type.split(';')[1] prefix = ' boundary"' suffix = '"' delimiter = '--%s' % boundary[len(prefix)+1:-len(suffix)] subrequests = [s.lstrip() for s in multipart.split(delimiter)] for sub in subrequests: status_line, _, more_lines = sub.partition('\n') method, path, version = status_line.split() headers, _, body = more_lines.partition('\n\n') url = 'http://localhost:3000' + path return Request(method, url, headers=headers, data=body) @app.route('/batch', methods=["GET", "POST"]) def batch(): subrequests = split(request) session = Session() responses = [] for sub in subrequests: response.append(s.send(sub.prepare())) # Deadlock! ``` There are two candidate solutions that I considered which I found to be unsatisfactory: Don't issue a full request. Instead, just call the function that is mapped to the endpoint of interest (url_for). I am unsatisfied by this approach because the nested requests have their own headers and cookies which are neglected by this approach. Furthermore, code in the 'before_request' and 'after_request' handlers won't get called automatically Run multiple instances of the application. This will solve the problem, but expose my service to a pretty simple DoS attack. If I have X instances running, All an attacker would need to do is to hit my service with X different requests to cause a deadlock. Thank you.

Original source