Closed
Description
Feature Request
Summary
RPC clients should infer an unspecified port number from the HTTP(S) default when applicable.
Problem Definition
Currently, the destination of every network-based RPC server must be specified with a URL including an explicit host port number (e.g., Cosmos SDK --node tcp://localhost:26657
). But the scheme part of such URLs can be e.g. "http" or "https", which imply a default port number (respectively, 80 or 443). MakeHTTPDialer
should respect those defaults, rather than causing behavior like this:
$ gaiad status --node https://cosmos-rpc.publicnode.com:443/
{"NodeInfo":{"protocol_version":{"p2p":"8","block":"11","app":"0"},"id":"821fa0f7ce74a211c5f5ec93cc6cc301564b92b6","listen_addr":"0.0.0.0:26656","network":"cosmoshub-4","version":"0.34.29","channels":"40202122233038606100","moniker":"Tendermint","other":{"tx_index":"on","rpc_address":"tcp://0.0.0.0:26657"}},"SyncInfo":{"latest_block_hash":"AA09142D55E38A406E5C3817FC03C2AE44832482FDBB5C311605130821D93AEC","latest_app_hash":"666EDA4B2A1F73BA5AB51D9F9AEC9E3489467DCF2199EB627FDAA156775D9DC6","latest_block_height":"18478442","latest_block_time":"2023-12-28T16:20:02.402318913Z","earliest_block_hash":"750D1D6B57311ACF430A243619DCFE4346EC4662FC4BEC83DE5A950856F10AB3","earliest_app_hash":"8C837EC300BC42DD737FF0C20D3A3AE689AC221C7DE127D4376616D3A574275A","earliest_block_height":"17875364","earliest_block_time":"2023-11-16T07:58:57.340253339Z","catching_up":false},"ValidatorInfo":{"Address":"0000000000000000000000000000000000000000","PubKey":{"type":"tendermint/PubKeySecp256k1","value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"VotingPower":"0"}}
$ gaiad status --node https://cosmos-rpc.publicnode.com/
Error: post failed: Post "https://cosmos-rpc.publicnode.com/": dial tcp: address cosmos-rpc.publicnode.com: missing port in address
Proposal
Update jsonrpc to use port 80 when scheme is "http" and no port number is specified and port 443 when scheme is "https" and no port number is specified, in accordance with RFC 9110.
Suggestion:
// GetDialAddress returns the endpoint to dial for the parsed URL.
func (u parsedURL) GetDialAddress() string {
- // if it's not a unix socket we return the host, example: localhost:443
+ // if it's not a unix socket we return the host with port, example: localhost:443
if !u.isUnixSocket {
+ hasPort, err := regexp.MatchString(`:[0-9]+$`, u.Host)
+ if err == nil && !hasPort {
+ if u.Scheme == protoHTTP || u.Scheme == protoWS {
+ return u.Host + `:80`
+ } else if u.Scheme == protoHTTPS || u.scheme == protoWSS {
+ return u.Host + `:443`
+ }
+ }
return u.Host
}
// otherwise we return the path of the unix socket, ex /tmp/socket
return u.GetHostWithPath()
}