|
|
@ -2,6 +2,7 @@ package rpc |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"encoding/json" |
|
|
|
"encoding/json" |
|
|
|
|
|
|
|
"io" |
|
|
|
"io/ioutil" |
|
|
|
"io/ioutil" |
|
|
|
"net/http" |
|
|
|
"net/http" |
|
|
|
|
|
|
|
|
|
|
@ -18,7 +19,6 @@ const ( |
|
|
|
|
|
|
|
|
|
|
|
// JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
|
|
|
|
// JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
|
|
|
|
func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { |
|
|
|
func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { |
|
|
|
var jsw JsonWrapper |
|
|
|
|
|
|
|
api := NewEthereumApi(pipe, dataDir) |
|
|
|
api := NewEthereumApi(pipe, dataDir) |
|
|
|
|
|
|
|
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { |
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { |
|
|
@ -28,22 +28,23 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { |
|
|
|
// Limit request size to resist DoS
|
|
|
|
// Limit request size to resist DoS
|
|
|
|
if req.ContentLength > maxSizeReqLength { |
|
|
|
if req.ContentLength > maxSizeReqLength { |
|
|
|
jsonerr := &RpcErrorObject{-32700, "Request too large"} |
|
|
|
jsonerr := &RpcErrorObject{-32700, "Request too large"} |
|
|
|
jsw.Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Read request body
|
|
|
|
defer req.Body.Close() |
|
|
|
defer req.Body.Close() |
|
|
|
body, err := ioutil.ReadAll(req.Body) |
|
|
|
body, err := ioutil.ReadAll(req.Body) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
jsonerr := &RpcErrorObject{-32700, "Could not read request body"} |
|
|
|
jsonerr := &RpcErrorObject{-32700, "Could not read request body"} |
|
|
|
jsw.Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Try to parse the request as a single
|
|
|
|
// Try to parse the request as a single
|
|
|
|
var reqSingle RpcRequest |
|
|
|
var reqSingle RpcRequest |
|
|
|
if err := json.Unmarshal(body, &reqSingle); err == nil { |
|
|
|
if err := json.Unmarshal(body, &reqSingle); err == nil { |
|
|
|
response := RpcResponse(api, &reqSingle) |
|
|
|
response := RpcResponse(api, &reqSingle) |
|
|
|
jsw.Send(w, &response) |
|
|
|
Send(w, &response) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -56,13 +57,13 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { |
|
|
|
response := RpcResponse(api, &request) |
|
|
|
response := RpcResponse(api, &request) |
|
|
|
resBatch[i] = response |
|
|
|
resBatch[i] = response |
|
|
|
} |
|
|
|
} |
|
|
|
jsw.Send(w, resBatch) |
|
|
|
Send(w, resBatch) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Not a batch or single request, error
|
|
|
|
// Not a batch or single request, error
|
|
|
|
jsonerr := &RpcErrorObject{-32600, "Could not decode request"} |
|
|
|
jsonerr := &RpcErrorObject{-32600, "Could not decode request"} |
|
|
|
jsw.Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
Send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -86,3 +87,15 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} { |
|
|
|
rpchttplogger.DebugDetailf("Generated response: %T %s", response, response) |
|
|
|
rpchttplogger.DebugDetailf("Generated response: %T %s", response, response) |
|
|
|
return &response |
|
|
|
return &response |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func Send(writer io.Writer, v interface{}) (n int, err error) { |
|
|
|
|
|
|
|
var payload []byte |
|
|
|
|
|
|
|
payload, err = json.MarshalIndent(v, "", "\t") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
rpclogger.Fatalln("Error marshalling JSON", err) |
|
|
|
|
|
|
|
return 0, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
rpclogger.DebugDetailf("Sending payload: %s", payload) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return writer.Write(payload) |
|
|
|
|
|
|
|
} |
|
|
|