add X-Origin to GET requests, so isso.dispatch works on a single host
This commit is contained in:
parent
8a408aea1d
commit
2e9c21db15
15
dispatch.py
15
dispatch.py
@ -7,6 +7,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
from werkzeug.wrappers import Request
|
||||||
from werkzeug.exceptions import ImATeapot
|
from werkzeug.exceptions import ImATeapot
|
||||||
|
|
||||||
from isso import make_app, wsgi
|
from isso import make_app, wsgi
|
||||||
@ -34,13 +35,13 @@ class Dispatcher(object):
|
|||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
|
|
||||||
if "HTTP_ORIGIN" in environ:
|
if Request(environ).url.endswith((".js", ".css")):
|
||||||
origin = environ["HTTP_ORIGIN"]
|
return self.isso.values()[0](environ, start_response)
|
||||||
elif "HTTP_REFERER" in environ:
|
|
||||||
rv = urlparse(environ["HTTP_REFERER"])
|
if "HTTP_X_ORIGIN" in environ and "HTTP_ORIGIN" not in environ:
|
||||||
origin = rv.scheme + "://" + rv.hostname + (":" + str(rv.port) if rv.port else "")
|
environ["HTTP_ORIGIN"] = environ["HTTP_X_ORIGIN"]
|
||||||
else:
|
|
||||||
origin = wsgi.host(environ)
|
origin = environ.get("HTTP_ORIGIN", wsgi.host(environ))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# logger.info("dispatch %s", origin)
|
# 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
|
without manual intervention. But you can chain Isso to support multiple
|
||||||
websites on different domains.
|
websites on different domains.
|
||||||
|
|
||||||
The following example uses `gunicorn <http://gunicorn.org/>`_ as WSGI server (you
|
The following example uses `gunicorn <http://gunicorn.org/>`_ as WSGI server (
|
||||||
can use uWSGI as well). It is *not* possible to run the isso executable for
|
you can use uWSGI as well). Let's say you maintain two websites, like
|
||||||
multiple sites.
|
foo.example and other.foo:
|
||||||
|
|
||||||
Let's say you maintain two websites, like foo.example and other.foo:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -234,67 +232,38 @@ Let's say you maintain two websites, like foo.example and other.foo:
|
|||||||
host = http://other.foo/
|
host = http://other.foo/
|
||||||
dbpath = /var/lib/isso/other.foo.db
|
dbpath = /var/lib/isso/other.foo.db
|
||||||
|
|
||||||
Then you run Isso with gunicorn like this:
|
Then you run Isso using gunicorn:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ export ISSO_SETTINGS="/etc/isso.d/foo.example.cfg;/etc/isso.d/other.foo.cfg"
|
$ export ISSO_SETTINGS="/etc/isso.d/foo.example.cfg;/etc/isso.d/other.foo.cfg"
|
||||||
$ gunicorn isso.dispatch -b localhost:8080
|
$ gunicorn isso.dispatch -b localhost:8080
|
||||||
|
|
||||||
Now, there are two options to configure the webserver:
|
In your webserver configuration, proxy Isso as usual:
|
||||||
|
|
||||||
1. using a single host to serve comments for both websites
|
.. code-block:: nginx
|
||||||
2. different hosts for both websites
|
|
||||||
|
|
||||||
In the former case, Isso dispatches based on the HTTP Referer and (if provided)
|
server {
|
||||||
HTTP Origin. If you expect users to supress their referer completely, you
|
listen [::]:80;
|
||||||
should use the second option.
|
server_name comments.example;
|
||||||
|
|
||||||
1. Using a single host to serve comments.
|
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:: nginx
|
To verify the setup, run:
|
||||||
|
|
||||||
server {
|
.. code-block:: bash
|
||||||
listen [::]:80;
|
|
||||||
server_name comments.example;
|
|
||||||
|
|
||||||
location / {
|
$ curl -vH "Origin: http://foo.example" http://comments.example/
|
||||||
proxy_pass http://localhost:8080;
|
...
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
$ curl -vH "Origin: http://other.foo" http://comments.example/
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
...
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
To verify the setup, run:
|
In case of a 418 (I'm a teapot), the setup is *not* correctly configured.
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ 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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
No need to verify this setup, here the webserver automatically sets the
|
|
||||||
proper host.
|
|
||||||
|
|
||||||
|
|
||||||
Appendum
|
Appendum
|
||||||
|
@ -92,7 +92,12 @@ define(["q"], function(Q) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
xhr.open(method, url, true);
|
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 () {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
onload();
|
onload();
|
||||||
|
@ -59,7 +59,7 @@ class CORSMiddleware(object):
|
|||||||
def add_cors_headers(status, headers, exc_info=None):
|
def add_cors_headers(status, headers, exc_info=None):
|
||||||
headers = Headers(headers)
|
headers = Headers(headers)
|
||||||
headers.add("Access-Control-Allow-Origin", self.origin(environ))
|
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-Credentials", "true")
|
||||||
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
|
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
|
||||||
headers.add("Access-Control-Expose-Headers", "X-Set-Cookie")
|
headers.add("Access-Control-Expose-Headers", "X-Set-Cookie")
|
||||||
|
Loading…
Reference in New Issue
Block a user