diff --git a/dispatch.py b/dispatch.py
index 08758c6..04d64f7 100644
--- a/dispatch.py
+++ b/dispatch.py
@@ -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)
diff --git a/docs/CONFIGURATION.rst b/docs/CONFIGURATION.rst
index d8b8c46..3e3cd6f 100644
--- a/docs/CONFIGURATION.rst
+++ b/docs/CONFIGURATION.rst
@@ -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 `_ 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 `_ 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:
+In your webserver configuration, proxy Isso as usual:
-1. using a single host to serve comments for both websites
-2. different hosts for both websites
+.. code-block:: nginx
-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.
+ server {
+ listen [::]:80;
+ 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 {
- listen [::]:80;
- server_name comments.example;
+.. code-block:: bash
- 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;
- }
- }
+ $ curl -vH "Origin: http://foo.example" http://comments.example/
+ ...
+ $ curl -vH "Origin: http://other.foo" http://comments.example/
+ ...
- To verify the setup, run:
-
- .. 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.
+In case of a 418 (I'm a teapot), the setup is *not* correctly configured.
Appendum
diff --git a/isso/js/app/api.js b/isso/js/app/api.js
index 157d36f..144415e 100644
--- a/isso/js/app/api.js
+++ b/isso/js/app/api.js
@@ -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();
diff --git a/isso/wsgi.py b/isso/wsgi.py
index 891aaeb..1b3e202 100644
--- a/isso/wsgi.py
+++ b/isso/wsgi.py
@@ -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")