endpoints.go 4.3 KB

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