add X-Origin to GET requests, so isso.dispatch works on a single host

legacy/0.5
Martin Zimmermann 11 years ago
parent 8a408aea1d
commit 2e9c21db15

@ -7,6 +7,7 @@ try:
except ImportError:
from urllib.parse import urlparse
from werkzeug.wrappers import Request
from werkzeug.exceptions import ImATeapot
from isso import make_app, wsgi
@ -34,13 +35,13 @@ class Dispatcher(object):
def __call__(self, environ, start_response):
if "HTTP_ORIGIN" in environ:
origin = environ["HTTP_ORIGIN"]
elif "HTTP_REFERER" in environ:
rv = urlparse(environ["HTTP_REFERER"])
origin = rv.scheme + "://" + rv.hostname + (":" + str(rv.port) if rv.port else "")
else:
origin = wsgi.host(environ)
if Request(environ).url.endswith((".js", ".css")):
return self.isso.values()[0](environ, start_response)
if "HTTP_X_ORIGIN" in environ and "HTTP_ORIGIN" not in environ:
environ["HTTP_ORIGIN"] = environ["HTTP_X_ORIGIN"]
origin = environ.get("HTTP_ORIGIN", wsgi.host(environ))
try:
# logger.info("dispatch %s", origin)

@ -216,11 +216,9 @@ comments for a relative URL to support HTTP, HTTPS and even domain transfers
without manual intervention. But you can chain Isso to support multiple
websites on different domains.
The following example uses `gunicorn <http://gunicorn.org/>`_ as WSGI server (you
can use uWSGI as well). It is *not* possible to run the isso executable for
multiple sites.
Let's say you maintain two websites, like foo.example and other.foo:
The following example uses `gunicorn <http://gunicorn.org/>`_ as WSGI server (
you can use uWSGI as well). Let's say you maintain two websites, like
foo.example and other.foo:
.. code-block:: bash
@ -234,67 +232,38 @@ Let's say you maintain two websites, like foo.example and other.foo:
host = http://other.foo/
dbpath = /var/lib/isso/other.foo.db
Then you run Isso with gunicorn like this:
Then you run Isso using gunicorn:
.. code-block:: bash
$ export ISSO_SETTINGS="/etc/isso.d/foo.example.cfg;/etc/isso.d/other.foo.cfg"
$ gunicorn isso.dispatch -b localhost:8080
Now, there are two options to configure the webserver:
1. using a single host to serve comments for both websites
2. different hosts for both websites
In the former case, Isso dispatches based on the HTTP Referer and (if provided)
HTTP Origin. If you expect users to supress their referer completely, you
should use the second option.
1. Using a single host to serve comments.
.. code-block:: nginx
In your webserver configuration, proxy Isso as usual:
server {
listen [::]:80;
server_name comments.example;
.. code-block:: nginx
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen [::]:80;
server_name comments.example;
To verify the setup, run:
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
.. code-block:: bash
To verify the setup, run:
$ curl -vH "Origin: http://foo.example" http://comments.example/
...
$ curl -vH "Origin: http://other.foo" http://comments.example/
...
In case of a 418 (I'm a teapot), the setup is *not* correctly configured.
2. Using different hosts for both websites (no need for a dedicated domain,
you can also proxy Isso on a sub-uri like /isso).
.. code-block:: nginx
server {
listen [::]:80;
server_name comments.foo.example comments.other.foo;
.. code-block:: bash
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
$ curl -vH "Origin: http://foo.example" http://comments.example/
...
$ curl -vH "Origin: http://other.foo" http://comments.example/
...
No need to verify this setup, here the webserver automatically sets the
proper host.
In case of a 418 (I'm a teapot), the setup is *not* correctly configured.
Appendum

@ -92,7 +92,12 @@ define(["q"], function(Q) {
try {
xhr.open(method, url, true);
xhr.withCredentials = true; // fuck you, fuck you, fuck you IE
xhr.withCredentials = true;
if (method === "GET") {
xhr.setRequestHeader("X-Origin", window.location.origin);
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
onload();

@ -59,7 +59,7 @@ class CORSMiddleware(object):
def add_cors_headers(status, headers, exc_info=None):
headers = Headers(headers)
headers.add("Access-Control-Allow-Origin", self.origin(environ))
headers.add("Access-Control-Allow-Headers", "Origin, Content-Type")
headers.add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Origin")
headers.add("Access-Control-Allow-Credentials", "true")
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
headers.add("Access-Control-Expose-Headers", "X-Set-Cookie")

Loading…
Cancel
Save