From fd764d4ff7bd7e75dfdd7f733f50dd3805d4b3f2 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 16 Jun 2015 13:07:13 +0200 Subject: added comms http --- rpc/comms/http.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 rpc/comms/http.go (limited to 'rpc/comms/http.go') diff --git a/rpc/comms/http.go b/rpc/comms/http.go new file mode 100644 index 000000000..1fea8dc1d --- /dev/null +++ b/rpc/comms/http.go @@ -0,0 +1,65 @@ +package comms + +import ( + "fmt" + "net/http" + "strings" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/rpc/api" + "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/rs/cors" +) + +var ( + // main HTTP rpc listener + httpListener *stoppableTCPListener + listenerStoppedError = fmt.Errorf("Listener has stopped") +) + +type HttpConfig struct { + ListenAddress string + ListenPort uint + CorsDomain string +} + +func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error { + if httpListener != nil { + if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() { + return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String()) + } + return nil // RPC service already running on given host/port + } + + l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort)) + if err != nil { + glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", cfg.ListenAddress, cfg.ListenPort, err) + return err + } + httpListener = l + + api := api.Merge(apis...) + var handler http.Handler + if len(cfg.CorsDomain) > 0 { + var opts cors.Options + opts.AllowedMethods = []string{"POST"} + opts.AllowedOrigins = strings.Split(cfg.CorsDomain, " ") + + c := cors.New(opts) + handler = newStoppableHandler(c.Handler(gethHttpHandler(codec, api)), l.stop) + } else { + handler = newStoppableHandler(gethHttpHandler(codec, api), l.stop) + } + + go http.Serve(l, handler) + + return nil +} + +func StopHttp() { + if httpListener != nil { + httpListener.Stop() + httpListener = nil + } +} -- cgit v1.2.3 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/http.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'rpc/comms/http.go') 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 -- cgit v1.2.3 From f20256377731097c9478ede750efffd46d83b494 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 18 Jun 2015 18:23:13 +0200 Subject: added attach over ipc command --- rpc/comms/http.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'rpc/comms/http.go') diff --git a/rpc/comms/http.go b/rpc/comms/http.go index c0ea2cc78..04630d937 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -64,7 +64,6 @@ func StopHttp() { } } - type httpClient struct { codec codec.ApiCoder } @@ -86,4 +85,4 @@ func (self *httpClient) Send(req interface{}) error { func (self *httpClient) Recv() (interface{}, error) { return nil, nil -} \ No newline at end of file +} -- cgit v1.2.3 From ce5c94e4719586bbf81906cb90104babf79af0fe Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Fri, 19 Jun 2015 12:32:40 +0200 Subject: added attach over http/rpc support --- rpc/comms/http.go | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 5 deletions(-) (limited to 'rpc/comms/http.go') diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 04630d937..6a543c0ed 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -5,10 +5,14 @@ import ( "net/http" "strings" + "bytes" + "io/ioutil" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" + "github.com/ethereum/go-ethereum/rpc/shared" "github.com/rs/cors" ) @@ -65,13 +69,19 @@ func StopHttp() { } type httpClient struct { - codec codec.ApiCoder + address string + port uint + codec codec.ApiCoder + lastRes interface{} + lastErr error } // Create a new in process client -func NewHttpClient(cfg HttpConfig, codec codec.Codec) *httpClient { +func NewHttpClient(cfg HttpConfig, c codec.Codec) *httpClient { return &httpClient{ - codec: codec.New(nil), + address: cfg.ListenAddress, + port: cfg.ListenPort, + codec: c.New(nil), } } @@ -80,9 +90,103 @@ func (self *httpClient) Close() { } func (self *httpClient) Send(req interface{}) error { - return nil + var body []byte + var err error + + self.lastRes = nil + self.lastErr = nil + + if body, err = self.codec.Encode(req); err != nil { + return err + } + + httpReq, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body)) + if err != nil { + return err + } + httpReq.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(httpReq) + if err != nil { + return err + } + + defer resp.Body.Close() + + if resp.Status == "200 OK" { + reply, _ := ioutil.ReadAll(resp.Body) + var rpcSuccessResponse shared.SuccessResponse + if err = self.codec.Decode(reply, &rpcSuccessResponse); err == nil { + self.lastRes = rpcSuccessResponse.Result + self.lastErr = err + return nil + } else { + var rpcErrorResponse shared.ErrorResponse + if err = self.codec.Decode(reply, &rpcErrorResponse); err == nil { + self.lastRes = rpcErrorResponse.Error + self.lastErr = err + return nil + } else { + return err + } + } + } + + return fmt.Errorf("Not implemented") } func (self *httpClient) Recv() (interface{}, error) { - return nil, nil + return self.lastRes, self.lastErr +} + +func (self *httpClient) SupportedModules() (map[string]string, error) { + var body []byte + var err error + + payload := shared.Request{ + Id: 1, + Jsonrpc: "2.0", + Method: "modules", + } + + if body, err = self.codec.Encode(payload); err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", fmt.Sprintf("%s:%d", self.address, self.port), bytes.NewBuffer(body)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + if resp.Status == "200 OK" { + reply, _ := ioutil.ReadAll(resp.Body) + var rpcRes shared.SuccessResponse + if err = self.codec.Decode(reply, &rpcRes); err != nil { + return nil, err + } + + result := make(map[string]string) + if modules, ok := rpcRes.Result.(map[string]interface{}); ok { + for a, v := range modules { + result[a] = fmt.Sprintf("%s", v) + } + return result, nil + } + err = fmt.Errorf("Unable to parse module response - %v", rpcRes.Result) + } else { + fmt.Printf("resp.Status = %s\n", resp.Status) + fmt.Printf("err = %v\n", err) + } + + return nil, err } -- cgit v1.2.3 From 2e0b56a72b3eafc89938003da29c06496ac9ad4e Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 22 Jun 2015 12:47:32 +0200 Subject: added RPC start/stop support --- rpc/comms/http.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'rpc/comms/http.go') diff --git a/rpc/comms/http.go b/rpc/comms/http.go index 6a543c0ed..ebee791bd 100644 --- a/rpc/comms/http.go +++ b/rpc/comms/http.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/api" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/shared" "github.com/rs/cors" @@ -28,7 +27,7 @@ type HttpConfig struct { CorsDomain string } -func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error { +func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error { if httpListener != nil { if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() { return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String()) @@ -43,7 +42,6 @@ func StartHttp(cfg HttpConfig, codec codec.Codec, apis ...api.EthereumApi) error } httpListener = l - api := api.Merge(apis...) var handler http.Handler if len(cfg.CorsDomain) > 0 { var opts cors.Options -- cgit v1.2.3