Starscream
Starscream copied to clipboard
"Origin" header has to be set
Previous versions of Starscream (pre 3.0.0) allowed the Origin to be left unset by setting socket.origin = nil
, whereas in newer versions will set the Origin header automatically if it wasn't set on the request.
Is there any chance we have this original behavior restored?
Hi @AndrewX192 could you help with PR? Thanks!
@AndrewX192 is there a reason you don't want the Origin header set? It is a fairly common header to include. Does setting the origin to an empty string resolve the issue? Also 4.0.0 was released which I was suggest upgrading to (but it still contains the origin setting logic if it isn't included).
Hi @daltoniam, sorry I haven't had cycles to look at this in more detail. The problem I'm having is that different backends and clients have different understandings of how the Origin
header should be utilized. Generally, web browsers are good about setting the Origin
header on HTTP requests other than an HTTP GET
, but use cases outside of browsers are less predictable (as has been the behavior of Starscream thus far).
In my specific case, a server accepts requests from both a web browser, and a mobile (iOS app). When a user utilizes a websocket from their browser the origin is correct (app.example.com) connects to client.app.example.com, however in a mobile context there's no root origin, so the origin becomes the same as the hostname we are connecting to (client.app.example.com). Since this wasn't expected, it wasn't on the Origin whitelist and caused requests to fail, however removing the Origin
header means that the server recognizes this is a non-browser use-case and the request is permitted.
Realistically, this is not a big problem for me - I'm happy to continue whitelisting the secnd origin, but as someone who went through the effort of updating Starscream in my application, I figured I'd raise this in the event someone else will run into this issue. If you feel that it's not a significant enough issue, then I'm happy to see this resolved as-is if you're comfortable with the current behavior. As far as I'm aware, there's no specific direction from RFCs in regards to when to set the Origin header beyond "The user agent MAY include an Origin header field in any HTTP request".
I'm currently engaging a bug witch caused by Starscream and golang websocket library Gorilla.
Starscream set Origin to upgrade request header with a port even it is default 80 or 443 just if the port is written into socket initial method's URL parameter, like "wss://example.com:443", then the origin header is set to "wss://example.com:443" too.
Gorilla initialize a websocket server with a default origin checker method "checkSameOrigin":
func checkSameOrigin(r *http.Request) bool {
origin := r.Header["Origin"]
if len(origin) == 0 {
return true
}
u, err := url.Parse(origin[0])
if err != nil {
return false
}
return equalASCIIFold(u.Host, r.Host)
}
Here is Golang's URL structure from net/url package:
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // host or host:port
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method); added in Go 1.5
ForceQuery bool // append a query ('?') even if RawQuery is empty; added in Go 1.7
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
}
You can see the Host
cloud be host:port
format, so compare between request's host and origin's host will fail.
That's what @AndrewX192 was talking about, neither Starscream or Gorilla goes wrong, but it is a problem indeed.
I use the lib to connect to LG TV, It returns error "invalid origin" with code 1008. When I remove these lines:
if request.value(forHTTPHeaderField: HTTPWSHeader.originName) == nil {
var origin = url.absoluteString
if let hostUrl = URL (string: "/", relativeTo: url) {
origin = hostUrl.absoluteString
origin.remove(at: origin.index(before: origin.endIndex))
}
req.setValue(origin, forHTTPHeaderField: HTTPWSHeader.originName)
}
It works fine. So It's better if we can set it as optional, should not must to set
I have the same problem as anlam87, would be great if you did it optionally
I also have the same problem as @anlam87 and @benjaminhuebner . Also trying to connect to an LG Smart TV. Did you guys find a solution to connect to the TV?
+1.
Unexpected origin header can cause very subtle issues. For my case, some server checks for reachability to Origin
address only if it exists. If library inserts Origin
implicitly, it's very difficult to find out why it fails and doesn't work. We were very lucky as the server was under our control so we could check the logs, but if we need to deal with external servers, it will be very very very difficult to figure out what the problem is.
Also, it's not easy to "define" origin address for mobile apps. Unlike websites which browsers tracks proper origin values, apps do not have such origin address and just have endpoint. Websocket endpoint addresses with deleted path component are not guaranteed to work and server can refuse service.