Browse Source

Remove the "URI" RPC client. (#7474)

The JSON-RPC endpoint accepts requests via URL (GET) and JSON (POST).  There is
no real point in having client libraries for both modes.

A search of the SDK and on GitHub suggests that most usage is via the JSON
client (via the New constructor) or websocket (NewWS), and the only uses I
found of the NewURI client constructor are in copies of our own test code.

This does not change the functionalitiy of the server, so curl and other
URL-based clients in other languages will still function as before.
pull/7477/head
M. J. Fromberger 2 years ago
committed by GitHub
parent
commit
cea8bcc9bb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1 additions and 200 deletions
  1. +1
    -0
      CHANGELOG_PENDING.md
  2. +0
    -39
      rpc/jsonrpc/client/args_test.go
  3. +0
    -46
      rpc/jsonrpc/client/encode.go
  4. +0
    -85
      rpc/jsonrpc/client/http_uri_client.go
  5. +0
    -30
      rpc/jsonrpc/jsonrpc_test.go

+ 1
- 0
CHANGELOG_PENDING.md View File

@ -27,6 +27,7 @@ Special thanks to external contributors on this release:
- Go API
- [rpc] \#7474 Remove the "URI" RPC client. (@creachadair)
- [libs/pubsub] \#7451 Internalize the pubsub packages. (@creachadair)
- [libs/sync] \#7450 Internalize and remove the library. (@creachadair)
- [libs/async] \#7449 Move library to internal. (@creachadair)


+ 0
- 39
rpc/jsonrpc/client/args_test.go View File

@ -1,39 +0,0 @@
package client
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type Tx []byte
type Foo struct {
Bar int
Baz string
}
func TestArgToJSON(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
cases := []struct {
input interface{}
expected string
}{
{[]byte("1234"), "0x31323334"},
{Tx("654"), "0x363534"},
{Foo{7, "hello"}, `{"Bar":"7","Baz":"hello"}`},
}
for i, tc := range cases {
args := map[string]interface{}{"data": tc.input}
err := argsToJSON(args)
require.Nil(err, "%d: %+v", i, err)
require.Equal(1, len(args), "%d", i)
data, ok := args["data"].(string)
require.True(ok, "%d: %#v", i, args["data"])
assert.Equal(tc.expected, data, "%d", i)
}
}

+ 0
- 46
rpc/jsonrpc/client/encode.go View File

@ -1,46 +0,0 @@
package client
import (
"fmt"
"net/url"
"reflect"
tmjson "github.com/tendermint/tendermint/libs/json"
)
func argsToURLValues(args map[string]interface{}) (url.Values, error) {
values := make(url.Values)
if len(args) == 0 {
return values, nil
}
err := argsToJSON(args)
if err != nil {
return nil, err
}
for key, val := range args {
values.Set(key, val.(string))
}
return values, nil
}
func argsToJSON(args map[string]interface{}) error {
for k, v := range args {
rt := reflect.TypeOf(v)
isByteSlice := rt.Kind() == reflect.Slice && rt.Elem().Kind() == reflect.Uint8
if isByteSlice {
bytes := reflect.ValueOf(v).Bytes()
args[k] = fmt.Sprintf("0x%X", bytes)
continue
}
data, err := tmjson.Marshal(v)
if err != nil {
return err
}
args[k] = string(data)
}
return nil
}

+ 0
- 85
rpc/jsonrpc/client/http_uri_client.go View File

@ -1,85 +0,0 @@
package client
import (
"context"
"fmt"
"io"
"net/http"
"strings"
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
const (
// URIClientRequestID in a request ID used by URIClient
URIClientRequestID = rpctypes.JSONRPCIntID(-1)
)
// URIClient is a JSON-RPC client, which sends POST form HTTP requests to the
// remote server.
//
// URIClient is safe for concurrent use by multiple goroutines.
type URIClient struct {
address string
client *http.Client
}
var _ HTTPClient = (*URIClient)(nil)
// NewURI returns a new client.
// An error is returned on invalid remote.
// The function panics when remote is nil.
func NewURI(remote string) (*URIClient, error) {
parsedURL, err := newParsedURL(remote)
if err != nil {
return nil, err
}
httpClient, err := DefaultHTTPClient(remote)
if err != nil {
return nil, err
}
parsedURL.SetDefaultSchemeHTTP()
uriClient := &URIClient{
address: parsedURL.GetTrimmedURL(),
client: httpClient,
}
return uriClient, nil
}
// Call issues a POST form HTTP request.
func (c *URIClient) Call(ctx context.Context, method string,
params map[string]interface{}, result interface{}) (interface{}, error) {
values, err := argsToURLValues(params)
if err != nil {
return nil, fmt.Errorf("failed to encode params: %w", err)
}
req, err := http.NewRequestWithContext(
ctx,
http.MethodPost,
c.address+"/"+method,
strings.NewReader(values.Encode()),
)
if err != nil {
return nil, fmt.Errorf("new request: %w", err)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := c.client.Do(req)
if err != nil {
return nil, fmt.Errorf("post: %w", err)
}
defer resp.Body.Close()
responseBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response body: %w", err)
}
return unmarshalResponseBytes(responseBytes, URIClientRequestID, result)
}

+ 0
- 30
rpc/jsonrpc/jsonrpc_test.go View File

@ -273,11 +273,6 @@ func TestServersAndClientsBasic(t *testing.T) {
ctx, cancel := context.WithCancel(bctx)
defer cancel()
cl1, err := client.NewURI(addr)
require.Nil(t, err)
fmt.Printf("=== testing server on %s using URI client", addr)
testWithHTTPClient(ctx, t, cl1)
cl2, err := client.New(addr)
require.Nil(t, err)
fmt.Printf("=== testing server on %s using JSONRPC client", addr)
@ -295,31 +290,6 @@ func TestServersAndClientsBasic(t *testing.T) {
}
}
func TestHexStringArg(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
cl, err := client.NewURI(tcpAddr)
require.Nil(t, err)
// should NOT be handled as hex
val := "0xabc"
got, err := echoViaHTTP(ctx, cl, val)
require.Nil(t, err)
assert.Equal(t, got, val)
}
func TestQuotedStringArg(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
cl, err := client.NewURI(tcpAddr)
require.Nil(t, err)
// should NOT be unquoted
val := "\"abc\""
got, err := echoViaHTTP(ctx, cl, val)
require.Nil(t, err)
assert.Equal(t, got, val)
}
func TestWSNewWSRPCFunc(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()


Loading…
Cancel
Save