Sony's website provided a example to use WebSockets to works with their api in Node.js
https://developer.sony.com/develop/audio-control-api/get-started/websocket-example#tutorial-step-3
it worked fine for me. But when i was trying to implement it in Python, it does not seems to work
i use websocket_client
import websocket
ws = websocket.WebSocket()
ws.connect("ws://192.168.0.34:54480/sony/avContent",sslopt={"cert_reqs": ssl.CERT_NONE})
gives
websocket._exceptions.WebSocketBadStatusException: Handshake status 403 Forbidden
but in their example code, there is not any kinds of authrization or authentication
I recently had the same problem. Here is what I found out:
Normal HTTP responses can contain
Access-Control-Allow-Origin
headers to explicitly allow other websites to request data. Otherwise, web browsers block such "cross-origin" requests, because the user could be logged in there for example.This "same-origin-policy" apparently does not apply to WebSockets and the handshakes can't have these headers. Therefore any website could connect to your Sony device. You probably wouldn't want some website to set your speaker/receiver volume to 100% or maybe upload a defective firmware, right?
That's why the audio control API checks the
Origin
header of the handshake. It always contains the website the request is coming from.The Python WebSocket client you use assumes
http://192.168.0.34:54480/sony/avContent
as the origin by default in your case. However, it seems that the API ignores the content of theOrigin
header and just checks whether it's there.The
WebSocket#connect
method has a parameter namedsuppress_origin
which can be used to exclude theOrigin
header.TL;DR
The Sony audio control API doesn't accept WebSocket handshakes that contain an
Origin
header.You can fix it like this: