New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rpc: implement websockets with github.com/gorilla/websocket #19866
Conversation
This change makes package rpc use the github.com/gorilla/websocket package for WebSockets instead of golang.org/x/net/websocket. The new library is more robust and supports all WebSocket features including continuation frames. There are new tests for two issues with the previously-used library: - TestWebsocketClientPing checks handling of Ping frames. - TestWebsocketLargeCall checks whether the request size limit is applied correctly.
The client used to put the local hostname into the Origin header because the server wanted an origin to accept the connection, but that's silly: Origin is for browsers/websites. The nobody would whitelist a particular hostname. Now that the server doesn't need Origin anymore, don't bother setting one for clients. Users who need an origin can use DialWebsocket to create a client with arbitrary origin if needed.
This makes it easier to debug failing connections.
4e42d69
to
9a1c7a8
Compare
log.Debug(fmt.Sprintf("Allowed origin(s) for WS RPC interface %v", origins.ToSlice())) | ||
|
||
f := func(cfg *websocket.Config, req *http.Request) error { | ||
f := func(req *http.Request) bool { | ||
// Skip origin verification if no Origin header is present. The origin check | ||
// is supposed to protect against browser based attacks. Browsers always set | ||
// Origin. Non-browser software can put anything in origin and checking it doesn't | ||
// provide additional security. | ||
if _, ok := req.Header["Origin"]; !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to use req.Header.Get
here, otherwise the code won't ignore the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's actually not true. net/http canonicalizes header keys, i.e. the keys in the map are assumed to be in the form returned by http.CanonicalHeaderKey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using req.Header.Get
is not great because it doesn't distinguish between absent and empty headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, can't say I'm confident nothing's borked, but I guess we'd find out soon enough if anything obvious went haywire.
I have connection issues via websocket with web3j. Is it related to these changes? |
Possibly. Please provide more information and a repro. |
I started having problems with Infura (same websocket connection issue) and for this reason I gave the go-ethereum client a shot (in order to have more debugging info possibly).
I know I had to use Websocket in the controller along with stomp probably, but before complicating things and get into an unexplored territory I wanted to be sure to be able to establish a connection and get some kind of result. |
EDIT
I would like to know why it doesn't work with Web3j though. |
…#19866) * rpc: implement websockets with github.com/gorilla/websocket This change makes package rpc use the github.com/gorilla/websocket package for WebSockets instead of golang.org/x/net/websocket. The new library is more robust and supports all WebSocket features including continuation frames. There are new tests for two issues with the previously-used library: - TestWebsocketClientPing checks handling of Ping frames. - TestWebsocketLargeCall checks whether the request size limit is applied correctly. * rpc: raise HTTP/WebSocket request size limit to 5MB * rpc: remove default origin for client connections The client used to put the local hostname into the Origin header because the server wanted an origin to accept the connection, but that's silly: Origin is for browsers/websites. The nobody would whitelist a particular hostname. Now that the server doesn't need Origin anymore, don't bother setting one for clients. Users who need an origin can use DialWebsocket to create a client with arbitrary origin if needed. * vendor: put golang.org/x/net/websocket back * rpc: don't set Origin header for empty (default) origin * rpc: add HTTP status code to handshake error This makes it easier to debug failing connections. * ethstats: use github.com/gorilla/websocket * rpc: fix lint
This change makes package rpc use the github.com/gorilla/websocket package
for WebSockets instead of golang.org/x/net/websocket. The new library is more robust
and supports all WebSocket features including continuation frames.
There are new tests for two issues with the previously-used library:
applied correctly.
DialWebsocket's handling of the default Origin header has changed. It used to set the
local machine's hostname as the origin, but that's weird and won't work with any
Internet-facing service. The new behavior is creating connections without an Origin
header unless one is provided explicitly.
This change also raises the request size limit for HTTP and WebSocket connections
to 5 MB. Quite a few people have reported issues where geth fails to deploy contracts
when they're too large, and retesteth needs a larger limit to upload the pre-state of large
tests.
Fixes #19798
Fixes #16846
Updates #19640
Updates #19001