Closed jamesmehorter closed 6 years ago
Hi,
Thank you for this report. The thing is webapi doesn't deal with Twisted response objects directly. The other thing is that Allow-Origin set to * sounds to me like a security issue.
So we probably need to work out a possible solution the with that in mind. Nowadays I have but a little time to attend to the project, and so can't say for sure when this one will be resolved.
Hi Igor, thanks for your response!
Hmmm, is webapi (and deluge plugins in general) capable of adding/adjusting the Twisted headers?
I do agree, in many cases adding these headers could allow cross site forgery requests. Though, because webapi implements sessions/cookie authentication I think we'd be safe. Maybe it could be enabled via a setting, and set to disabled by default? That way folks like myself could enable CORS for the webapi. I also feel like as a rule of thumb any api should allow requests from any source—i.e. as it stands I can only POST to webapi (from within a browser) while on localhost, which is quite restrictive. Also, because the webui is accessible from any external browser (visiting http://my-deluge-server:8112 [if port forwarding is enabled on your router]) would you agree that it seems logical for webapi to allow that same level of access?
A little background.. I'm running deluge on a server in my home local network, and plan to use this JavaScript to add torrents via a bookmarklet on other computers also in my home network. My deluge server is behind my router (I am not using port forwarding either). In my case the CORS error is preventing machines with the same 192.168.0.* ip range from POSTing to the webapi.
Lastly, I've read a little more on this and believe the 'Access-Control-Allow-Credentials: true' would also need to be set in order to send/receive cookies from CORS requests. (And likewise XHR requests from JavaScript like I'm doing would need to include the 'withCredentials' header.)
Thanks Igor!!!
I too would like to be able to query the webapi from within a browser. Very much looking forward to a solution.
Thanks!
Implementation hint: could possibly be achieved with subclassing deluge.ui.web.json_api.JSON
and overriding _send_response
with request.setHeader('Access-Control-Allow-Origin', '*')
, and using a subclass of WebPluginBase
where in __init__
subclassed JSON is used.
Probably some option is required to fine tune that *
so access is restricted to trusted hosts.
I needed that feature for a project related to deluge json rpc API. Here's a fast implementation of it, without any config editor inside deluge at the moment.
webapi/core.py
import logging
from deluge import component
from deluge.plugins.pluginbase import CorePluginBase
from deluge.ui.web.json_api import JSON
from twisted.web import http, server
LOGGER = logging.getLogger(__name__)
class Core(CorePluginBase):
def enable(self):
""""""
LOGGER.info('Enabling WebAPI plugin CORE ...')
self.patch_web_ui()
def disable(self):
""""""
LOGGER.info('Disabling WebAPI plugin CORE ...')
def update(self):
""""""
def patch_web_ui(self):
LOGGER.info('Patching webui for CORS...')
JSON_instance = component.get('JSON')
self.old_render = JSON_instance.render
self.old_send_request = JSON_instance._send_response
JSON_instance.render = self.render_patch
JSON_instance._send_response = self._send_response_patch
def render_patch(self, request):
LOGGER.debug("json-CORS PROXY")
if request.method == "OPTIONS":
request.setResponseCode(http.OK)
# should use config for allowed origin
request.setHeader('Access-Control-Allow-Origin', 'http://lvh.me:3000')
request.setHeader('Access-Control-Allow-Headers', 'content-type')
request.setHeader('Access-Control-Allow-Methods', 'POST')
request.setHeader('Access-Control-Allow-Credentials', 'true')
request.write('')
request.finish()
return server.NOT_DONE_YET
return self.old_render(request)
def _send_response_patch(self, request, response):
if request._disconnected:
return ''
# should use config for allowed origin
request.setHeader('Access-Control-Allow-Origin', 'http://lvh.me:3000')
request.setHeader('Access-Control-Allow-Credentials', 'true')
return self.old_send_request(request, response)
By the way this is a monkey-patch that override the existing render method of JSON class from webui plugins. webui method patched : def render(self, request):
This seems to be resolved in 0.3.0 by Brandon in #12 This version is available on GitHub, I'll upload PyPI dist eventually.
Hello,
When I use Postman to POST to the webapi everything works perfectly. I can send requests and receive responses. Now I'm attempting to write JavaScript to interact with my deluged server using AJAX while I'm browsing the web (using Chrome). However, when I POST to the server with JavaScript (in my browser) I receive the following error:
For reference, the JavaScript I'm using is below.
This error seems to be very common when performing CORS requests like this in a web browser. And the simple workaround is for the server to send the following header with each response:
Access-Control-Allow-Origin: *
It also appears that the web-ui uses the Twisted HTTP server, and I was able to locate this post about Twisted and CORS: https://msoulier.wordpress.com/2010/06/05/cross-origin-requests-in-twisted/
Is there any possibility that you could add this header to the webapi responses? Or do you have any suggestions? I'd love to query this webapi from within a browser. Thanks!!
JavaScript I'm using..