> Hi there,
>
> I wonder if this can be done with uwsgi:
>
> I want to use uwsgi to do custom HTTP routing, generally a mixture to what
> is described here
>
> http://uwsgi-docs.readthedocs.org/en/latest/Fastrouter.html (in section
> "Way 5 - fastrouter-use-code-string")
>
> and
>
> http://projects.unbit.it/uwsgi/wiki/CustomRouting (old documentation)
>
> I need to route HTTP requests, based on information in the HTTP request
> body.
>
> What I have:
>
> - a uwsgi server started in emperor mode serving 2 custom apps (app_a on
> socket 3065, app_b on socket 3066) and a custom router (on socket 3031).
>
> - both app_a and app_b are python wsgi apps in my current setup, e.g.
>
> # app a
> def application(env, start_response):
> start_response('200 OK',
> [('Content-Type','text/html')])
> return "<html><body>Hello World
> <b>A</b>!</body></html>"
>
> but should be anything that uwsgi does support as a uwsgi app.
>
> - all HTTP requests (e.g. from nginx) go to the custom router.
>
> - the custom router reads the body, decides if app_a or app_b is
> responsible for handling the HTTP request and forwards the request to the
> corresponding socket, like this (pseudo code):
>
> import uwsgi
>
> def handle(env):
> # I need to read the whole body here, e.g.
> env['wsgi.input'].read()
> # but how to "rewind" the read so that
> subsequent uwsgi.send_message
> work as expected?
> # decide on the port based on the body
> port = ...
> return port
>
> def application(env, start_response):
> port = handle(env)
> fd = ':30' + str(port)
> # how to forward the unaltered body to the
> other uwsgi workers
> (app_a/app_b)?
> for part in uwsgi.send_message(fd, 0, 0, env, 0,
> env['wsgi.input'].fileno(), env['uwsgi.cl']:
> yield part
>
> My problem is with reading and rewinding the body for the upcoming
> uwsgi.send_message call. I tried various means to read the body to a
> temporary file, and use that for the .send_message call but I had no
> success so far.
>
> I tried to solve this problem with an older version uwsgi (1.2 I believe)
> but to no avail. I'm happy to upgrade to 1.4 or even more recent
> work-in-progress versions as long as I can create a working prototype with
> uwsgi.
>
> Is this possible with uwsgi?
>
> Any help is appreciated.
>
> Kind regards,
> K.
>
In 1.9 we are writing a new uwsgi.route() general function that should
allows you to use internal routing api in a general way.
in your case you would have something like that:
def application(e, sr):
body = e['wsgi.input'].read()
# requires post buffering
e['wsgi.input'].seek(0)
if body == 'foo':
uwsgi.route('uwsgi','127.0.0.1:3065')
else:
uwsgi.route('uwsgi','127.0.0.1:3066')
basically you will be able to call the functions you find here:
http://uwsgi-docs.readthedocs.org/en/latest/InternalRouting.html
the only problem is in rewinding, but if you enable post-buffering you are
always able to rewind.
The important thing is that all of this approach is non-blocking, so a
single process can manage hundreds of transactions with technologies like
gevent
In 1.4 there is a uwsgi.route() function but works in a different way (no
way to rewind the body)
--
Roberto De Ioris
http://unbit.it
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi