Hi, In case anyone stumbles upon this question, I eventually found a working solution, documented below. FYI, I am going to use 2. upon production deployments.
1. "standard" HTTP headers: this is the solution I tried to get to work earlier without understanding that: - the rewrite plugin rewrites the variables, not the input HTTP request - the http router plugin supports a third undocumented argument that is the PATH argument that will be injected in the forwarded query - uwsgi does not support the syntax "route = http:${VAR}" where VAR=val1,val2,val3. Instead, it requires "route = http:${VAR1},${VAR2},${VAR3}" The application side: 222 handler.response.headers['X-Sendurl'] = 'true' 223 handler.response.headers['X-Sendurl-IP'] = '%s:%d' % (socket.gethostbyname(url.hostname), url.port if url.port is not None else 80) 224 handler.response.headers['X-Sendurl-Host'] = url.hostname 225 handler.response.headers['X-Sendurl-Path-Query'] = "%s?%s" % (url.path, url.query) The configuration file: 29 collect-header = X-Sendurl X_SENDURL 30 response-route-if-not = empty:${X_SENDURL} goto:xsendurl 32 response-route-run = last: 45 response-route-label = xsendurl 46 collect-header = X-Sendurl-IP X_SENDURL_IP 47 collect-header = X-Sendurl-Host X_SENDURL_HOST 48 collect-header = X-Sendurl-Path-Query X_SENDURL_PATH_QUERY 49 response-route-run = http:${X_SENDURL_IP},${X_SENDURL_HOST},${X_SENDURL_PATH_QUERY} 51 response-route-run = last: 2. "variables". It is possible to shorten slightly the above to this: The application side: 216 import uwsgi 217 uwsgi.add_var("SEND_URL", "y") 218 uwsgi.add_var("SEND_URL_IP", '%s:%d' % (socket.gethostbyname(url.hostname), url.port if url.port is not None else 80)) 219 uwsgi.add_var("SEND_URL_HOST", url.hostname) 220 uwsgi.add_var("SEND_URL_PATH_QUERY", "%s?%s" % (url.path, url.query)) The configuration side: 31 response-route-if = equal:${SEND_URL};y goto:xsendurl 32 response-route-run = last: 44 45 response-route-label = xsendurl 50 response-route-run = http:${SEND_URL_IP},${SEND_URL_HOST},${SEND_URL_PATH_QUERY} 51 response-route-run = last: 3. Sadly, the even shorter version below does not work because of issue #1041 (https://github.com/unbit/uwsgi/issues/1041) which appears to be fixed by the unmerged patch: https://github.com/unbit/uwsgi/pull/1473/commits/b71dc90b82c1e8e640d0c449d535171b19a08d9d The application side: 216 import uwsgi 221 uwsgi.route("http", "%s:%d,%s,%s?%s" % (socket.gethostbyname(url.hostname), url.port if url.port is not None else 80, url.hostname, url.path, url.query)) The configuration side: none I hope this help, Mathieu Le mar. 28 mai 2019 à 15:29, mathieu lacage <mathieu.lac...@alcmeon.com> a écrit : > hi, > > I am trying to implement X-sendurl in my application using uwsgi. I > modified my app to generate a couple of http headers: > > 215 handler.response.headers['X-Sendurlhost'] = '%s:%d,%s' % > (socket.gethostbyname(url.hostname), url.port if url.port is not None else > 80, url.hostname) > 216 handler.response.headers['X-Sendurlpathqs'] = "%s?%s" % > (url.path, url.query) > 217 handler.response.set_status(200) > > and I configured my uwsgi server as follows: > > 29 collect-header = X-Sendurlpathqs X_SENDURLPATHQS > 30 collect-header = X-Sendurlhost X_SENDURLHOST > 31 response-route-if-not = empty:${X_SENDURLPATHQS} goto:xsendurl > 32 response-route-run = last: > > [snip] > > 45 response-route-label = xsendurl > 46 response-route-run = rewrite:${X_SENDURLPATHQS} > 48 response-route-run = http:${X_SENDURLHOST} > 49 response-route-run = last: > > The above configuration appears to hit and execute correctly line 48 above > > with the following values: > > X_SENDURLHOST=137.74.127.78:80,storage.gra3.cloud.ovh.net > > X_SENDURLPATHQS=/v1/AUTH_7542981824cf4bcb883cf4c4321195ae/prod/companies/8/users-profile-attachments/4165024?temp_url_sig=49d3ec9ee9d5fd5aa447fc70162e6fb72c564e99&temp_url_expires=1559049647 > > I read very carefully the documentation at > https://uwsgi-docs.readthedocs.io/en/latest/InternalRouting.html and I > would expect the above to forward an HTTP request to IP 137.74.127.78 on > port 80 with HTTP header HOST=storage.gra3.cloud.ovh.net and > PATH=/v1/AUTH_7542981824cf4... > > However, tcpdump shows instead the following request: > > GET > /admin/8/users-profile-attachments/?user_id=5172075&site_id=154&site_type=2 > HTTP/1.0 > Host: localhost:9090 > ... > > HTTP/1.1 401 Unauthorized > Content-Length: 131 > Content-Type: text/html; charset=UTF-8 > Www-Authenticate: Swift realm="8" > WWW-Authenticate: Keystone uri='https://auth.cloud.ovh.net/' > ... > > So, uwsgi is connecting to the right IP and port, but it's not sending > what I would expect for the HOST HTTP header and HTTP PATH. > > Is there something I should adjust in my uwsgi configuration to make it > forward the Host+PATH headers I want ? > > Mathieu > -- > Mathieu Lacage <mathieu.lac...@alcmeon.com> > -- Mathieu Lacage <mathieu.lac...@alcmeon.com>
_______________________________________________ uWSGI mailing list uWSGI@lists.unbit.it http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi