def reconcile_wsgi_environ_with_public_url(event): """Event-listener that checks and tweaks WSGI environ based on public_url. This is a simple trick to help ensure that the configured public_url matches the actual deployed address. It fixes fixes parts of the WSGI environ where it makes sense (e.g. SCRIPT_NAME) and warns about any parts that seem obviously mis-configured (e.g. http:// versus https://). It's very important to get public_url and WSGI environ matching exactly, since they're used for browserid audience checking and HAWK signature validation, so mismatches can easily cause strange and cryptic errors. """ request = event.request public_url = request.registry.settings["syncserver.public_url"] p_public_url = urlparse(public_url) # If we don't have a SCRIPT_NAME, take it from the public_url. # This is often the case if we're behind e.g. an nginx proxy that # is serving us at some sub-path. if not request.script_name: request.script_name = p_public_url.path.rstrip("/") # Log a noisy error if the application url is different to what we'd # expect based on public_url setting. application_url = request.application_url if public_url != application_url: msg = "The public_url setting does not match the application url.\n" msg += "This will almost certainly cause authentication failures!\n" msg += " public_url setting is: %s\n" % (public_url,) msg += " application url is: %s\n" % (application_url,) logger.error(msg) raise _JSONError([msg], status_code=500)
def reconcile_wsgi_environ_with_public_url(event): """Event-listener that checks and tweaks WSGI environ based on public_url. This is a simple trick to help ensure that the configured public_url matches the actual deployed address. It fixes fixes parts of the WSGI environ where it makes sense (e.g. SCRIPT_NAME) and warns about any parts that seem obviously mis-configured (e.g. http:// versus https://). It's very important to get public_url and WSGI environ matching exactly, since they're used for browserid audience checking and HAWK signature validation, so mismatches can easily cause strange and cryptic errors. """ request = event.request public_url = request.registry.settings["syncserver.public_url"] p_public_url = urlparse(public_url) # If we don't have a SCRIPT_NAME, take it from the public_url. # This is often the case if we're behind e.g. an nginx proxy that # is serving us at some sub-path. if not request.script_name: request.script_name = p_public_url.path.rstrip("/") # If the environ does not match public_url, requests are almost certainly # going to fail due to auth errors. We can either bail out early, or we # can forcibly clobber the WSGI environ with the values from public_url. # This is a security risk if you've e.g. mis-configured the server, so # it's not enabled by default. application_url = request.application_url if public_url != application_url: if not request.registry.settings.get("syncserver.force_wsgi_environ"): msg = "\n".join( ( "The public_url setting doesn't match the application url.", "This will almost certainly cause authentication failures!", " public_url setting is: %s" % (public_url,), " application url is: %s" % (application_url,), "You can disable this check by setting the force_wsgi_environ", "option in your config file, but do so at your own risk.", ) ) logger.error(msg) raise _JSONError([msg], status_code=500) request.scheme = p_public_url.scheme request.host = p_public_url.netloc request.script_name = p_public_url.path.rstrip("/")
def reconcile_wsgi_environ_with_public_url(event): """Event-listener that checks and tweaks WSGI environ based on public_url. This is a simple trick to help ensure that the configured public_url matches the actual deployed address. It fixes fixes parts of the WSGI environ where it makes sense (e.g. SCRIPT_NAME) and warns about any parts that seem obviously mis-configured (e.g. http:// versus https://). It's very important to get public_url and WSGI environ matching exactly, since they're used for browserid audience checking and HAWK signature validation, so mismatches can easily cause strange and cryptic errors. """ request = event.request public_url = request.registry.settings["syncserver.public_url"] p_public_url = urlparse(public_url) # If we don't have a SCRIPT_NAME, take it from the public_url. # This is often the case if we're behind e.g. an nginx proxy that # is serving us at some sub-path. if not request.script_name: request.script_name = p_public_url.path.rstrip("/") # If the environ does not match public_url, requests are almost certainly # going to fail due to auth errors. We can either bail out early, or we # can forcibly clobber the WSGI environ with the values from public_url. # This is a security risk if you've e.g. mis-configured the server, so # it's not enabled by default. application_url = request.application_url if public_url != application_url: if not request.registry.settings.get("syncserver.force_wsgi_environ"): msg = "\n".join(( "The public_url setting doesn't match the application url.", "This will almost certainly cause authentication failures!", " public_url setting is: %s" % (public_url, ), " application url is: %s" % (application_url, ), "You can disable this check by setting the force_wsgi_environ", "option in your config file, but do so at your own risk.", )) logger.error(msg) raise _JSONError([msg], status_code=500) request.scheme = p_public_url.scheme request.host = p_public_url.netloc request.script_name = p_public_url.path.rstrip("/")