endpoints.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2018 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. "fmt"
  19. "net"
  20. "github.com/ethereum/go-ethereum/log"
  21. )
  22. // checkModuleAvailability check that all names given in modules are actually
  23. // available API services.
  24. func checkModuleAvailability(modules []string, apis []API) error {
  25. available := make(map[string]struct{})
  26. var availableNames string
  27. for i, api := range apis {
  28. if _, ok := available[api.Namespace]; !ok {
  29. available[api.Namespace] = struct{}{}
  30. if i > 0 {
  31. availableNames += ", "
  32. }
  33. availableNames += api.Namespace
  34. }
  35. }
  36. for _, name := range modules {
  37. if _, ok := available[name]; !ok {
  38. return fmt.Errorf("invalid API %q in whitelist (available: %s)", name, availableNames)
  39. }
  40. }
  41. return nil
  42. }
  43. // StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules.
  44. func StartHTTPEndpoint(endpoint string, apis []API, modules []string, cors []string, vhosts []string, timeouts HTTPTimeouts) (net.Listener, *Server, error) {
  45. if err := checkModuleAvailability(modules, apis); err != nil {
  46. return nil, nil, err
  47. }
  48. // Generate the whitelist based on the allowed modules
  49. whitelist := make(map[string]bool)
  50. for _, module := range modules {
  51. whitelist[module] = true
  52. }
  53. // Register all the APIs exposed by the services
  54. handler := NewServer()
  55. for _, api := range apis {
  56. if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
  57. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  58. return nil, nil, err
  59. }
  60. log.Debug("HTTP registered", "namespace", api.Namespace)
  61. }
  62. }
  63. // All APIs registered, start the HTTP listener
  64. var (
  65. listener net.Listener
  66. err error
  67. )
  68. if listener, err = net.Listen("tcp", endpoint); err != nil {
  69. return nil, nil, err
  70. }
  71. go NewHTTPServer(cors, vhosts, timeouts, handler).Serve(listener)
  72. return listener, handler, err
  73. }
  74. // StartWSEndpoint starts a websocket endpoint.
  75. func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []string, exposeAll bool) (net.Listener, *Server, error) {
  76. if err := checkModuleAvailability(modules, apis); err != nil {
  77. return nil, nil, err
  78. }
  79. // Generate the whitelist based on the allowed modules
  80. whitelist := make(map[string]bool)
  81. for _, module := range modules {
  82. whitelist[module] = true
  83. }
  84. // Register all the APIs exposed by the services
  85. handler := NewServer()
  86. for _, api := range apis {
  87. if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
  88. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  89. return nil, nil, err
  90. }
  91. log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace)
  92. }
  93. }
  94. // All APIs registered, start the HTTP listener
  95. var (
  96. listener net.Listener
  97. err error
  98. )
  99. if listener, err = net.Listen("tcp", endpoint); err != nil {
  100. return nil, nil, err
  101. }
  102. go NewWSServer(wsOrigins, handler).Serve(listener)
  103. return listener, handler, err
  104. }
  105. // StartIPCEndpoint starts an IPC endpoint.
  106. func StartIPCEndpoint(ipcEndpoint string, apis []API) (net.Listener, *Server, error) {
  107. // Register all the APIs exposed by the services.
  108. handler := NewServer()
  109. for _, api := range apis {
  110. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  111. return nil, nil, err
  112. }
  113. log.Debug("IPC registered", "namespace", api.Namespace)
  114. }
  115. // All APIs registered, start the IPC listener.
  116. listener, err := ipcListen(ipcEndpoint)
  117. if err != nil {
  118. return nil, nil, err
  119. }
  120. go handler.ServeListener(listener)
  121. return listener, handler, nil
  122. }