Example #1
0
// jsonRPCRead is the RPC wrapper around the jsonRead function to handle reading
// and responding to RPC messages.
func jsonRPCRead(w http.ResponseWriter, r *http.Request, s *rpcServer) {
	if atomic.LoadInt32(&s.shutdown) != 0 {
		return
	}
	body, err := btcjson.GetRaw(r.Body)
	if err != nil {
		rpcsLog.Errorf("Error getting json message: %v", err)
		return
	}

	var reply btcjson.Reply
	cmd, jsonErr := parseCmd(body)
	if cmd != nil {
		// Unmarshaling at least a valid JSON-RPC message succeeded.
		// Use the provided id for errors.
		id := cmd.Id()
		reply.Id = &id
	}
	if jsonErr != nil {
		reply.Error = jsonErr
	} else {
		reply = standardCmdReply(cmd, s)
	}

	rpcsLog.Tracef("reply: %v", reply)

	msg, err := btcjson.MarshallAndSend(reply, w)
	if err != nil {
		rpcsLog.Errorf(msg)
		return
	}
	rpcsLog.Debugf(msg)
}
Example #2
0
// websocketJSONHandler parses and handles a marshalled json message,
// sending the marshalled reply to a wallet notification channel.
func (s *rpcServer) websocketJSONHandler(wallet walletChan, msg []byte) {
	s.wg.Add(1)
	defer s.wg.Done()

	cmd, jsonErr := parseCmd(msg)
	if jsonErr != nil {
		var reply btcjson.Reply
		if cmd != nil {
			// Unmarshaling at least a valid JSON-RPC message succeeded.
			// Use the provided id for errors.
			id := cmd.Id()
			reply.Id = &id
		}
		reply.Error = jsonErr
		mreply, _ := json.Marshal(reply)
		wallet <- mreply
		return
	}

	respondToAnyCmd(cmd, s, wallet)
}
Example #3
0
// websocketJSONHandler parses and handles a marshalled json message,
// sending the marshalled reply to a wallet notification channel.
func (s *rpcServer) websocketJSONHandler(r chan *btcjson.Reply, c handlerChans, msg string) error {
	var resp *btcjson.Reply

	cmd, jsonErr := parseCmd([]byte(msg))
	if jsonErr != nil {
		resp = &btcjson.Reply{}
		if cmd != nil {
			// Unmarshaling at least a valid JSON-RPC message succeeded.
			// Use the provided id for errors.  Requests with no IDs
			// should be ignored.
			id := cmd.Id()
			if id == nil {
				return nil
			}
			resp.Id = &id
		}
		resp.Error = jsonErr
	} else {
		// The first command must be the "authenticate" command if the
		// connection is not already authenticated.
		s.ws.Lock()
		rc := s.ws.connections[c.n]
		if _, ok := cmd.(*btcws.AuthenticateCmd); ok {
			// Validate the provided credentials.
			err := websocketAuthenticate(cmd, rc, s.authsha[:])
			if err != nil {
				s.ws.Unlock()
				return err
			}

			// Generate an empty response to send for the successful
			// authentication.
			id := cmd.Id()
			resp = &btcjson.Reply{
				Id:     &id,
				Result: nil,
				Error:  nil,
			}
		} else if !rc.authenticated {
			rpcsLog.Warnf("Unauthenticated websocket message " +
				"received")
			s.ws.Unlock()
			return ErrBadAuth
		}

		s.ws.Unlock()
	}

	// Find and run handler in new goroutine.
	go func() {
		if resp == nil {
			resp = respondToAnyCmd(cmd, s, c)
		}
		select {
		case <-c.disconnected:
			return

		default:
			r <- resp
		}
	}()

	return nil
}