diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index a604616894..cc1666d387 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -254,8 +254,9 @@ class WebPlugin(BeetsPlugin): def __init__(self): super(WebPlugin, self).__init__() self.config.add({ - 'host': u'', + 'host': u'127.0.0.1', 'port': 8337, + 'cors': '', }) def commands(self): @@ -271,6 +272,16 @@ def func(lib, opts, args): self.config['port'] = int(args.pop(0)) app.config['lib'] = lib + # Enable CORS if required. + if self.config['cors']: + print "Enabling cors" + from flask.ext.cors import CORS + app.config['CORS_ALLOW_HEADERS'] = "Content-Type" + app.config['CORS_RESOURCES'] = { + r"/*": {"origins": self.config['cors'].get(str)} + } + CORS(app) + # Start the web application. app.run(host=self.config['host'].get(unicode), port=self.config['port'].get(int), debug=opts.debug, threaded=True) diff --git a/docs/plugins/web.rst b/docs/plugins/web.rst index 63c679e2b5..66b7f110b2 100644 --- a/docs/plugins/web.rst +++ b/docs/plugins/web.rst @@ -20,6 +20,12 @@ flask``. .. _Flask: http://flask.pocoo.org/ +If you require `CORS`_ (Cross-origin resource sharing), then you also +need `flask-cors`_. This can be installed by running ``pip install flask-cors``. + +.. _flask-cors: https://github.com/CoryDolphin/flask-cors +.. _CORS: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing + Finally, enable the ``web`` plugin in your configuration (see :ref:`using-plugins`). @@ -52,10 +58,12 @@ Configuration To configure the plugin, make a ``web:`` section in your configuration file. The available options are: -- **host**: The server hostname. - Default: Bind to all interfaces. +- **host**: The server hostname. Set this to 0.0.0.0 to bind to all interfaces. + Default: Bind to 127.0.0.1. - **port**: The server port. Default: 8337. +- **cors**: The CORS origin. See below. + Default: CORS is disabled. Implementation -------------- @@ -78,6 +86,28 @@ for unsupported formats/browsers. There are a number of options for this: .. _html5media: http://html5media.info/ .. _MediaElement.js: http://mediaelementjs.com/ +Cross-origin resource sharing (CORS) +------------------------------------ + +This is only required if you intend to access the API from a browser using JavaScript and +the JavaScript is not hosted by the beets web server. + +The browser will check if the resources the JavaScript is trying to access is coming from the +same source as the the Script and give an error similar to the following: + +``XMLHttpRequest cannot load http://beets:8337/item/xx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://webserver' is therefore not allowed access.`` + +To prevent this, `CORS`_ is used. To enable CORS, set the ``cors`` configuration option to the origin +of your JavaScript or set it to ``'*'`` to enable access from all origins. Note that there are +security implications if you set the origin to ``'*'``, please research this before enabling it. + +For example:: + + web: + host: 0.0.0.0 + cors: 'http://webserver' + + JSON API -------- diff --git a/setup.py b/setup.py index 36998d39aa..a4d35c6bf8 100755 --- a/setup.py +++ b/setup.py @@ -102,7 +102,7 @@ def _read(fn): 'echonest': ['pyechonest'], 'lastgenre': ['pylast'], 'mpdstats': ['python-mpd'], - 'web': ['flask'], + 'web': ['flask', 'flask-cors'], 'import': ['rarfile'], }, # Non-Python/non-PyPI plugin dependencies: