func gethHttpHandler(codec codec.Codec, a shared.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, shared.JsonRpcVersion, -32700, err) httpSend(w, &response) return } defer req.Body.Close() payload, err := ioutil.ReadAll(req.Body) if err != nil { err := fmt.Errorf("Could not read request body") response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err) httpSend(w, &response) return } c := codec.New(nil) var rpcReq shared.Request if err = c.Decode(payload, &rpcReq); err == nil { reply, err := a.Execute(&rpcReq) res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err) httpSend(w, &res) return } var reqBatch []shared.Request if err = c.Decode(payload, &reqBatch); err == nil { resBatch := make([]*interface{}, len(reqBatch)) resCount := 0 for i, rpcReq := range reqBatch { 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 } } // make response omitting nil entries resBatch = resBatch[:resCount] httpSend(w, resBatch) return } // invalid request err = fmt.Errorf("Could not decode request") res := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32600, err) httpSend(w, res) }) }
func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) { m := shared.NewRpcErrorResponse(id, shared.JsonRpcVersion, code, fmt.Errorf(msg)) errObj, _ := json.Marshal(m.Error) errRes, _ := json.Marshal(m) call.Otto.Run("ret_error = " + string(errObj)) res, _ := call.Otto.Run("ret_response = " + string(errRes)) return res }