From a4a4e9fcf824189d8d06940492a01effe6e6cf92 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Wed, 17 Jun 2015 16:22:35 +0200 Subject: removed old rpc structure and added new inproc api client --- rpc/comms/comms.go | 18 ++++++++++++++++- rpc/comms/http.go | 24 +++++++++++++++++++++++ rpc/comms/http_net.go | 14 +++++++------- rpc/comms/inproc.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ rpc/comms/ipc.go | 8 ++++---- 5 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 rpc/comms/inproc.go (limited to 'rpc/comms') diff --git a/rpc/comms/comms.go b/rpc/comms/comms.go index 2af63e55d..050e7b4e2 100644 --- a/rpc/comms/comms.go +++ b/rpc/comms/comms.go @@ -9,16 +9,32 @@ import ( "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" + "strings" ) const ( - jsonrpcver = "2.0" maxHttpSizeReqLength = 1024 * 1024 // 1MB ) +var ( + // List with all API's which are offered over the in proc interface by default + DefaultInProcApis = api.AllApis + + // List with all API's which are offered over the IPC interface by default + DefaultIpcApis = api.AllApis + + // List with API's which are offered over thr HTTP/RPC interface by default + DefaultHttpRpcApis = strings.Join([]string{ + api.DbApiName, api.EthApiName, api.NetApiName, api.Web3ApiName, + }, ",") +) + type EthereumClient interface { + // Close underlaying connection Close() + // Send request Send(interface{}) error + // Receive response Recv() (interface{}, error) } diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 1fea8dc1d..c0ea2cc78 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -63,3 +63,27 @@ func StopHttp() { httpListener = nil } } + + +type httpClient struct { + codec codec.ApiCoder +} + +// Create a new in process client +func NewHttpClient(cfg HttpConfig, codec codec.Codec) *httpClient { + return &httpClient{ + codec: codec.New(nil), + } +} + +func (self *httpClient) Close() { + // do nothing +} + +func (self *httpClient) Send(req interface{}) error { + return nil +} + +func (self *httpClient) Recv() (interface{}, error) { + return nil, nil +} \ No newline at end of file diff --git a/rpc/comms/http_net.go b/rpc/comms/http_net.go index 8d1bacc06..f326f1a7e 100644 --- a/rpc/comms/http_net.go +++ b/rpc/comms/http_net.go @@ -90,7 +90,7 @@ func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { case <-stop: w.Header().Set("Content-Type", "application/json") err := fmt.Errorf("RPC service stopped") - response := shared.NewRpcResponse(-1, jsonrpcver, nil, err) + response := shared.NewRpcResponse(-1, api.JsonRpcVersion, nil, err) httpSend(w, response) default: h.ServeHTTP(w, r) @@ -110,14 +110,14 @@ func httpSend(writer io.Writer, v interface{}) (n int, err error) { return writer.Write(payload) } -func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { +func gethHttpHandler(codec codec.Codec, a api.EthereumApi) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") // Limit request size to resist DoS if req.ContentLength > maxHttpSizeReqLength { err := fmt.Errorf("Request too large") - response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -126,7 +126,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { payload, err := ioutil.ReadAll(req.Body) if err != nil { err := fmt.Errorf("Could not read request body") - response := shared.NewRpcErrorResponse(-1, jsonrpcver, -32700, err) + response := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32700, err) httpSend(w, &response) return } @@ -134,7 +134,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { c := codec.New(nil) var rpcReq shared.Request if err = c.Decode(payload, &rpcReq); err == nil { - reply, err := api.Execute(&rpcReq) + reply, err := a.Execute(&rpcReq) res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) httpSend(w, &res) return @@ -146,7 +146,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { resCount := 0 for i, rpcReq := range reqBatch { - reply, err := api.Execute(&rpcReq) + reply, err := a.Execute(&rpcReq) if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) resCount += 1 @@ -161,7 +161,7 @@ func gethHttpHandler(codec codec.Codec, api api.EthereumApi) http.Handler { // invalid request err = fmt.Errorf("Could not decode request") - res := shared.NewRpcErrorResponse(-1, jsonrpcver, -32600, err) + res := shared.NewRpcErrorResponse(-1, api.JsonRpcVersion, -32600, err) httpSend(w, res) }) } diff --git a/rpc/comms/inproc.go b/rpc/comms/inproc.go new file mode 100644 index 000000000..89cb93cdc --- /dev/null +++ b/rpc/comms/inproc.go @@ -0,0 +1,53 @@ +package comms + +import ( + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/shared" + "fmt" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/xeth" + "github.com/ethereum/go-ethereum/eth" +) + +type InProcClient struct { + api api.EthereumApi + codec codec.Codec + lastId interface{} + lastJsonrpc string + lastErr error + lastRes interface{} +} + +// Create a new in process client +func NewInProcClient(codec codec.Codec) *InProcClient { + return &InProcClient{ + codec: codec, + } +} + +func (self *InProcClient) Close() { + // do nothing +} + +// Need to setup api support +func (self *InProcClient) Initialize(xeth *xeth.XEth, eth *eth.Ethereum) { + if apis, err := api.ParseApiString(api.AllApis, self.codec, xeth, eth); err == nil { + self.api = api.Merge(apis...) + } +} + +func (self *InProcClient) Send(req interface{}) error { + if r, ok := req.(*shared.Request); ok { + self.lastId = r.Id + self.lastJsonrpc = r.Jsonrpc + self.lastRes, self.lastErr = self.api.Execute(r) + return self.lastErr + } + + return fmt.Errorf("Invalid request (%T)", req) +} + +func (self *InProcClient) Recv() (interface{}, error) { + return self.lastRes, self.lastErr + //return *shared.NewRpcResponse(self.lastId, self.lastJsonrpc, self.lastRes, self.lastErr), nil +} diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go index a75039d17..a07203803 100644 --- a/rpc/comms/ipc.go +++ b/rpc/comms/ipc.go @@ -10,19 +10,19 @@ type IpcConfig struct { } type ipcClient struct { - c codec.ApiCoder + codec codec.ApiCoder } func (self *ipcClient) Close() { - self.c.Close() + self.codec.Close() } func (self *ipcClient) Send(req interface{}) error { - return self.c.WriteResponse(req) + return self.codec.WriteResponse(req) } func (self *ipcClient) Recv() (interface{}, error) { - return self.c.ReadResponse() + return self.codec.ReadResponse() } // Create a new IPC client, UNIX domain socket on posix, named pipe on Windows -- cgit