json.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package rpc
  17. import (
  18. "bytes"
  19. "context"
  20. "encoding/json"
  21. "errors"
  22. "fmt"
  23. "io"
  24. "reflect"
  25. "strings"
  26. "sync"
  27. "time"
  28. )
  29. const (
  30. vsn = "2.0"
  31. serviceMethodSeparator = "_"
  32. subscribeMethodSuffix = "_subscribe"
  33. unsubscribeMethodSuffix = "_unsubscribe"
  34. notificationMethodSuffix = "_subscription"
  35. defaultWriteTimeout = 10 * time.Second // used if context has no deadline
  36. )
  37. var null = json.RawMessage("null")
  38. type subscriptionResult struct {
  39. ID string `json:"subscription"`
  40. Result json.RawMessage `json:"result,omitempty"`
  41. }
  42. // A value of this type can a JSON-RPC request, notification, successful response or
  43. // error response. Which one it is depends on the fields.
  44. type jsonrpcMessage struct {
  45. Version string `json:"jsonrpc,omitempty"`
  46. ID json.RawMessage `json:"id,omitempty"`
  47. Method string `json:"method,omitempty"`
  48. Params json.RawMessage `json:"params,omitempty"`
  49. Error *jsonError `json:"error,omitempty"`
  50. Result json.RawMessage `json:"result,omitempty"`
  51. }
  52. func (msg *jsonrpcMessage) isNotification() bool {
  53. return msg.ID == nil && msg.Method != ""
  54. }
  55. func (msg *jsonrpcMessage) isCall() bool {
  56. return msg.hasValidID() && msg.Method != ""
  57. }
  58. func (msg *jsonrpcMessage) isResponse() bool {
  59. return msg.hasValidID() && msg.Method == "" && msg.Params == nil && (msg.Result != nil || msg.Error != nil)
  60. }
  61. func (msg *jsonrpcMessage) hasValidID() bool {
  62. return len(msg.ID) > 0 && msg.ID[0] != '{' && msg.ID[0] != '['
  63. }
  64. func (msg *jsonrpcMessage) isSubscribe() bool {
  65. return strings.HasSuffix(msg.Method, subscribeMethodSuffix)
  66. }
  67. func (msg *jsonrpcMessage) isUnsubscribe() bool {
  68. return strings.HasSuffix(msg.Method, unsubscribeMethodSuffix)
  69. }
  70. func (msg *jsonrpcMessage) namespace() string {
  71. elem := strings.SplitN(msg.Method, serviceMethodSeparator, 2)
  72. return elem[0]
  73. }
  74. func (msg *jsonrpcMessage) String() string {
  75. b, _ := json.Marshal(msg)
  76. return string(b)
  77. }
  78. func (msg *jsonrpcMessage) errorResponse(err error) *jsonrpcMessage {
  79. resp := errorMessage(err)
  80. resp.ID = msg.ID
  81. return resp
  82. }
  83. func (msg *jsonrpcMessage) response(result interface{}) *jsonrpcMessage {
  84. enc, err := json.Marshal(result)
  85. if err != nil {
  86. // TODO: wrap with 'internal server error'
  87. return msg.errorResponse(err)
  88. }
  89. return &jsonrpcMessage{Version: vsn, ID: msg.ID, Result: enc}
  90. }
  91. func errorMessage(err error) *jsonrpcMessage {
  92. msg := &jsonrpcMessage{Version: vsn, ID: null, Error: &jsonError{
  93. Code: defaultErrorCode,
  94. Message: err.Error(),
  95. }}
  96. ec, ok := err.(Error)
  97. if ok {
  98. msg.Error.Code = ec.ErrorCode()
  99. }
  100. de, ok := err.(DataError)
  101. if ok {
  102. msg.Error.Data = de.ErrorData()
  103. }
  104. return msg
  105. }
  106. type jsonError struct {
  107. Code int `json:"code"`
  108. Message string `json:"message"`
  109. Data interface{} `json:"data,omitempty"`
  110. }
  111. func (err *jsonError) Error() string {
  112. if err.Message == "" {
  113. return fmt.Sprintf("json-rpc error %d", err.Code)
  114. }
  115. return err.Message
  116. }
  117. func (err *jsonError) ErrorCode() int {
  118. return err.Code
  119. }
  120. func (err *jsonError) ErrorData() interface{} {
  121. return err.Data
  122. }
  123. // Conn is a subset of the methods of net.Conn which are sufficient for ServerCodec.
  124. type Conn interface {
  125. io.ReadWriteCloser
  126. SetWriteDeadline(time.Time) error
  127. }
  128. type deadlineCloser interface {
  129. io.Closer
  130. SetWriteDeadline(time.Time) error
  131. }
  132. // ConnRemoteAddr wraps the RemoteAddr operation, which returns a description
  133. // of the peer address of a connection. If a Conn also implements ConnRemoteAddr, this
  134. // description is used in log messages.
  135. type ConnRemoteAddr interface {
  136. RemoteAddr() string
  137. }
  138. // jsonCodec reads and writes JSON-RPC messages to the underlying connection. It also has
  139. // support for parsing arguments and serializing (result) objects.
  140. type jsonCodec struct {
  141. remote string
  142. closer sync.Once // close closed channel once
  143. closeCh chan interface{} // closed on Close
  144. decode func(v interface{}) error // decoder to allow multiple transports
  145. encMu sync.Mutex // guards the encoder
  146. encode func(v interface{}) error // encoder to allow multiple transports
  147. conn deadlineCloser
  148. }
  149. // NewFuncCodec creates a codec which uses the given functions to read and write. If conn
  150. // implements ConnRemoteAddr, log messages will use it to include the remote address of
  151. // the connection.
  152. func NewFuncCodec(conn deadlineCloser, encode, decode func(v interface{}) error) ServerCodec {
  153. codec := &jsonCodec{
  154. closeCh: make(chan interface{}),
  155. encode: encode,
  156. decode: decode,
  157. conn: conn,
  158. }
  159. if ra, ok := conn.(ConnRemoteAddr); ok {
  160. codec.remote = ra.RemoteAddr()
  161. }
  162. return codec
  163. }
  164. // NewCodec creates a codec on the given connection. If conn implements ConnRemoteAddr, log
  165. // messages will use it to include the remote address of the connection.
  166. func NewCodec(conn Conn) ServerCodec {
  167. enc := json.NewEncoder(conn)
  168. dec := json.NewDecoder(conn)
  169. dec.UseNumber()
  170. return NewFuncCodec(conn, enc.Encode, dec.Decode)
  171. }
  172. func (c *jsonCodec) peerInfo() PeerInfo {
  173. // This returns "ipc" because all other built-in transports have a separate codec type.
  174. return PeerInfo{Transport: "ipc", RemoteAddr: c.remote}
  175. }
  176. func (c *jsonCodec) remoteAddr() string {
  177. return c.remote
  178. }
  179. func (c *jsonCodec) readBatch() (messages []*jsonrpcMessage, batch bool, err error) {
  180. // Decode the next JSON object in the input stream.
  181. // This verifies basic syntax, etc.
  182. var rawmsg json.RawMessage
  183. if err := c.decode(&rawmsg); err != nil {
  184. return nil, false, err
  185. }
  186. messages, batch = parseMessage(rawmsg)
  187. for i, msg := range messages {
  188. if msg == nil {
  189. // Message is JSON 'null'. Replace with zero value so it
  190. // will be treated like any other invalid message.
  191. messages[i] = new(jsonrpcMessage)
  192. }
  193. }
  194. return messages, batch, nil
  195. }
  196. func (c *jsonCodec) writeJSON(ctx context.Context, v interface{}) error {
  197. c.encMu.Lock()
  198. defer c.encMu.Unlock()
  199. deadline, ok := ctx.Deadline()
  200. if !ok {
  201. deadline = time.Now().Add(defaultWriteTimeout)
  202. }
  203. c.conn.SetWriteDeadline(deadline)
  204. return c.encode(v)
  205. }
  206. func (c *jsonCodec) close() {
  207. c.closer.Do(func() {
  208. close(c.closeCh)
  209. c.conn.Close()
  210. })
  211. }
  212. // Closed returns a channel which will be closed when Close is called
  213. func (c *jsonCodec) closed() <-chan interface{} {
  214. return c.closeCh
  215. }
  216. // parseMessage parses raw bytes as a (batch of) JSON-RPC message(s). There are no error
  217. // checks in this function because the raw message has already been syntax-checked when it
  218. // is called. Any non-JSON-RPC messages in the input return the zero value of
  219. // jsonrpcMessage.
  220. func parseMessage(raw json.RawMessage) ([]*jsonrpcMessage, bool) {
  221. if !isBatch(raw) {
  222. msgs := []*jsonrpcMessage{{}}
  223. json.Unmarshal(raw, &msgs[0])
  224. return msgs, false
  225. }
  226. dec := json.NewDecoder(bytes.NewReader(raw))
  227. dec.Token() // skip '['
  228. var msgs []*jsonrpcMessage
  229. for dec.More() {
  230. msgs = append(msgs, new(jsonrpcMessage))
  231. dec.Decode(&msgs[len(msgs)-1])
  232. }
  233. return msgs, true
  234. }
  235. // isBatch returns true when the first non-whitespace characters is '['
  236. func isBatch(raw json.RawMessage) bool {
  237. for _, c := range raw {
  238. // skip insignificant whitespace (http://www.ietf.org/rfc/rfc4627.txt)
  239. if c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d {
  240. continue
  241. }
  242. return c == '['
  243. }
  244. return false
  245. }
  246. // parsePositionalArguments tries to parse the given args to an array of values with the
  247. // given types. It returns the parsed values or an error when the args could not be
  248. // parsed. Missing optional arguments are returned as reflect.Zero values.
  249. func parsePositionalArguments(rawArgs json.RawMessage, types []reflect.Type) ([]reflect.Value, error) {
  250. dec := json.NewDecoder(bytes.NewReader(rawArgs))
  251. var args []reflect.Value
  252. tok, err := dec.Token()
  253. switch {
  254. case err == io.EOF || tok == nil && err == nil:
  255. // "params" is optional and may be empty. Also allow "params":null even though it's
  256. // not in the spec because our own client used to send it.
  257. case err != nil:
  258. return nil, err
  259. case tok == json.Delim('['):
  260. // Read argument array.
  261. if args, err = parseArgumentArray(dec, types); err != nil {
  262. return nil, err
  263. }
  264. default:
  265. return nil, errors.New("non-array args")
  266. }
  267. // Set any missing args to nil.
  268. for i := len(args); i < len(types); i++ {
  269. if types[i].Kind() != reflect.Ptr {
  270. return nil, fmt.Errorf("missing value for required argument %d", i)
  271. }
  272. args = append(args, reflect.Zero(types[i]))
  273. }
  274. return args, nil
  275. }
  276. func parseArgumentArray(dec *json.Decoder, types []reflect.Type) ([]reflect.Value, error) {
  277. args := make([]reflect.Value, 0, len(types))
  278. for i := 0; dec.More(); i++ {
  279. if i >= len(types) {
  280. return args, fmt.Errorf("too many arguments, want at most %d", len(types))
  281. }
  282. argval := reflect.New(types[i])
  283. if err := dec.Decode(argval.Interface()); err != nil {
  284. return args, fmt.Errorf("invalid argument %d: %v", i, err)
  285. }
  286. if argval.IsNil() && types[i].Kind() != reflect.Ptr {
  287. return args, fmt.Errorf("missing value for required argument %d", i)
  288. }
  289. args = append(args, argval.Elem())
  290. }
  291. // Read end of args array.
  292. _, err := dec.Token()
  293. return args, err
  294. }
  295. // parseSubscriptionName extracts the subscription name from an encoded argument array.
  296. func parseSubscriptionName(rawArgs json.RawMessage) (string, error) {
  297. dec := json.NewDecoder(bytes.NewReader(rawArgs))
  298. if tok, _ := dec.Token(); tok != json.Delim('[') {
  299. return "", errors.New("non-array args")
  300. }
  301. v, _ := dec.Token()
  302. method, ok := v.(string)
  303. if !ok {
  304. return "", errors.New("expected subscription name as first argument")
  305. }
  306. return method, nil
  307. }