After upgrade version 2.2 not connection from mopidy mobile

I updated to version 2.2. I dont have a connection with Mopidy mobile now. The log mopidy say this :

2018-10-06 10:10:33,407 WARNING [27441:HttpServer] tornado.access: 403 GET /mopidy/ws/ ( 11.65ms

If the downgrade version of the mopid (2.1) all works again. What are the changes in version 2.2?

I do not know if there is a problem in mopid or mopid mobile. Everything is possible :slight_smile:


The changes are documented in the changelog.

Haven’t yet upgraded, but Mopidy 2.2 introduces
So if you’re talking about the Android app, your device’s IP address will probably have to be included here.

Ok. I’ll try it. Thanks.

@kingosticks: Sorry, but I can’t make any sense of the http/allowed_origins docs… What would you actually put in there if WS requests originate from an app? It connects to the Mopidy server, so you shouldn’t have to configure anything, if I read correctly?

You do read correctly. You should not normally require anything to be set in that new option.

Browsers will always be sending the Origin header in their request. It specifies the domain the request is executed from (where the
Http/javascript originates from). So if host is serving your files, your client will be putting as the Origin and the same origin check will pass. It’s possible older browsers / non-browsers don’t do this correctly but it should be happening…

I see the same issue myself. Will investigate tonight.

@tkem can you help me understand what the android packaged version does? Does it start it’s own local http server for those www/app/servers/view.html files? And then open a websocket connection from that Origin so everything is cross-site? Or does it just use that stuff for discovery and then immediately switch over to a regular Webview with all files being served from the Mopidy sever you are talking to?

It’s basically an Apache Cordova app, so it uses the system’s WebView with local content. No HTTP server involved. So I think it’s quite likely that the Origin header is set to a file: URI (or maybe the mobile device’s address, or no Origin header at all).
Will try and check tonight.

I think that’s it. If there’s no Origin header at all we print a debug message so I guess it’s sending file:// or something else a bit weird. Can you override what Cordova sends?

I regret not logging something when the request is denied, that would have been helpful.

Can you override what Cordova sends?

No. At least, I don’t think so. Security, you know.
But we should check what really gets send - it’s all guess-work from my side, so far.

Am I correct in assuming that HTTP requests without any Origin header will be rejected by Mopidy v2.2?

So that means that the example at
will no longer work, too, since curl (version 7.52.1 at least) does not send an Origin header by default.

Not quite. We don’t actually require Origin to be set in our post() handler, we require Content-Type: application/json to be set. This non-standard Content-Type for the request triggers the user’s browser to do an OPTIONS request before the actual POST request. Browsers will always set the Origin header for this OPTIONS request so we can just check the Origin value in our options() handler.

But for curl and other non-browser things you only need to set the Content-Type header as they won’t do the OPTIONS request and so it doesn’t matter what Origin your request has. And there is a debug message at least for when your requests are missing the correct Content-Type header.

curl -i -d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_state"}' http://localhost:6680/mopidy/rpc
HTTP/1.1 415 Content-Type must be application/json
Date: Mon, 08 Oct 2018 15:58:19 GMT
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Server: TornadoServer/4.5.3


curl -i -d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_state"}' -H "Content-Type: application/json" http://localhost:6680/mopidy/rpc
HTTP/1.1 200 OK
Content-Length: 48
Accept: application/json
Server: TornadoServer/4.5.3
X-Mopidy-Version: 3.0.0a1
Cache-Control: no-cache
Date: Mon, 08 Oct 2018 16:07:39 GMT
Content-Type: application/json; utf-8

{"jsonrpc": "2.0", "id": 1, "result": "playing"}

So yeh, that example (and any others) are outdated, oops - good catch! Note that this is different to the websocket case where browsers should always be sending the Origin header, I guess that came later so it’s simpler.

Thanks for the clarification. I’m still trying to get my head around this CORS thing…
However, so my assumption is correct that this breaking change not only affects Cordova apps, but also probably a large fraction of clients that are not browser-based, e.g. custom scripts, home automation integration, etc.?

Did a quick check after coming home with Mopidy Mobile: Origin header sent by Cordova (or Android’s WebView) is actually file://. However, in mopidy/http/ this is effectively converted to the empty string for comparison with allowed_origins:

parsed_origin = urllib.parse.urlparse(origin).netloc.lower()
return parsed_origin and parsed_origin in allowed_origins

@Feryy: Sorry for “hijacking” this thread, but to answer your initial question:

No, sorry, it doesn’t look like you can use the Mopidy Mobile Android app with Mopidy v2.2.0.

Yeh… I was skirting around the fact it is a breaking change. I think we can legitimately change to accept a missing or empty parsed Origin, which would fix your websocket. But requiring the Content-Type is the only way I know to force browsers to always send their Origin header when doing POST requests. We are breaking non-browser-based clients with this but I don’t see a way around that. I am open to suggestions.

Well, a disable_cors option (or whatever you may call it) might be a rather easy (temporary) workaround for those who don’t want to (or even can’t, think home automation plugins) update their clients. I’d suggest making the Mopidy v2.1 behavior the default, but your mileage may vary (depending on how much traffic you want to generate on this site :grinning:)…