Skip to content

Commit

Permalink
[api] Separate Server and Server Handler (iotexproject#3485)
Browse files Browse the repository at this point in the history
  • Loading branch information
Liuhaai authored Jul 1, 2022
1 parent a4b1098 commit 5ee6a4f
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 179 deletions.
96 changes: 53 additions & 43 deletions api/grpcserver.go

Large diffs are not rendered by default.

188 changes: 112 additions & 76 deletions api/grpcserver_integrity_test.go

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions api/grpcserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/iotexproject/iotex-core/pkg/version"
"github.com/iotexproject/iotex-core/test/identityset"
"github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice"
"github.com/iotexproject/iotex-core/testutil"
)

func TestGrpcServer_GetAccount(t *testing.T) {
Expand Down Expand Up @@ -64,7 +63,7 @@ func TestGrpcServer_SendAction(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
core := mock_apicoreservice.NewMockCoreService(ctrl)
grpcSvr := NewGRPCServer(core, testutil.RandomPort())
grpcSvr := newGRPCHandler(core)

for _, test := range _sendActionTests {
core.EXPECT().EVMNetworkID().Return(uint32(1))
Expand Down Expand Up @@ -97,7 +96,7 @@ func TestGrpcServer_SuggestGasPrice(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
core := mock_apicoreservice.NewMockCoreService(ctrl)
grpcSvr := NewGRPCServer(core, testutil.RandomPort())
grpcSvr := newGRPCHandler(core)

core.EXPECT().SuggestGasPrice().Return(uint64(1), nil)
res, err := grpcSvr.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{})
Expand All @@ -114,7 +113,7 @@ func TestGrpcServer_EstimateGasForAction(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
core := mock_apicoreservice.NewMockCoreService(ctrl)
grpcSvr := NewGRPCServer(core, testutil.RandomPort())
grpcSvr := newGRPCHandler(core)

core.EXPECT().EstimateGasForAction(gomock.Any(), gomock.Any()).Return(uint64(10000), nil)
resp, err := grpcSvr.EstimateGasForAction(context.Background(), &iotexapi.EstimateGasForActionRequest{Action: getAction()})
Expand Down
33 changes: 22 additions & 11 deletions api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ import (
"github.com/iotexproject/iotex-core/pkg/log"
)

// HTTPServer handles requests from http protocol
type HTTPServer struct {
svr *http.Server
msgHandler Web3Handler
}
type (
// HTTPServer crates a http server
HTTPServer struct {
svr *http.Server
}

// hTTPHandler handles requests from http protocol
hTTPHandler struct {
msgHandler Web3Handler
}
)

// NewHTTPServer creates a new http server
// TODO: move timeout into config
func NewHTTPServer(route string, port int, handler Web3Handler) *HTTPServer {
func NewHTTPServer(route string, port int, handler http.Handler) *HTTPServer {
if port == 0 {
return nil
}
Expand All @@ -30,11 +36,9 @@ func NewHTTPServer(route string, port int, handler Web3Handler) *HTTPServer {
Addr: ":" + strconv.Itoa(port),
WriteTimeout: 30 * time.Second,
},
msgHandler: handler,
}

mux := http.NewServeMux()
mux.Handle("/"+route, svr)
mux.Handle("/"+route, handler)
svr.svr.Handler = mux
return svr
}
Expand All @@ -54,13 +58,20 @@ func (hSvr *HTTPServer) Stop(ctx context.Context) error {
return hSvr.svr.Shutdown(ctx)
}

func (hSvr *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// newHTTPHandler creates a new http handler
func newHTTPHandler(web3Handler Web3Handler) *hTTPHandler {
return &hTTPHandler{
msgHandler: web3Handler,
}
}

func (handler *hTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}

if err := hSvr.msgHandler.HandlePOSTReq(req.Body,
if err := handler.msgHandler.HandlePOSTReq(req.Body,
apitypes.NewResponseWriter(
func(resp interface{}) error {
w.Header().Set("Access-Control-Allow-Origin", "*")
Expand Down
4 changes: 2 additions & 2 deletions api/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestServeHTTP(t *testing.T) {
defer ctrl.Finish()
handler := mock_web3server.NewMockWeb3Handler(ctrl)
handler.EXPECT().HandlePOSTReq(gomock.Any(), gomock.Any()).Return(nil)
svr := NewHTTPServer("", testutil.RandomPort(), handler)
svr := newHTTPHandler(handler)

t.Run("WrongHTTPMethod", func(t *testing.T) {
req, _ := http.NewRequest(http.MethodGet, "http://url.com", nil)
Expand All @@ -45,7 +45,7 @@ func TestServerStartStop(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock_web3server.NewMockWeb3Handler(ctrl)
svr := NewHTTPServer("", testutil.RandomPort(), handler)
svr := NewHTTPServer("", testutil.RandomPort(), newHTTPHandler(handler))

err := svr.Start(context.Background())
require.NoError(err)
Expand Down
7 changes: 4 additions & 3 deletions api/serverV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ServerV2 struct {
core CoreService
grpcServer *GRPCServer
httpSvr *HTTPServer
websocketSvr *WebsocketServer
websocketSvr *HTTPServer
tracer *tracesdk.TracerProvider
}

Expand Down Expand Up @@ -61,11 +61,12 @@ func NewServerV2(
if err != nil {
return nil, errors.Wrapf(err, "cannot config tracer provider")
}

return &ServerV2{
core: coreAPI,
grpcServer: NewGRPCServer(coreAPI, cfg.GRPCPort),
httpSvr: NewHTTPServer("", cfg.HTTPPort, web3Handler),
websocketSvr: NewWebSocketServer("", cfg.WebSocketPort, web3Handler),
httpSvr: NewHTTPServer("", cfg.HTTPPort, newHTTPHandler(web3Handler)),
websocketSvr: NewHTTPServer("", cfg.WebSocketPort, NewWebsocketHandler(web3Handler)),
tracer: tp,
}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions api/serverV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func TestServerV2(t *testing.T) {
svr := &ServerV2{
core: core,
grpcServer: NewGRPCServer(core, testutil.RandomPort()),
httpSvr: NewHTTPServer("", testutil.RandomPort(), web3Handler),
websocketSvr: NewWebSocketServer("", testutil.RandomPort(), web3Handler),
httpSvr: NewHTTPServer("", testutil.RandomPort(), newHTTPHandler(web3Handler)),
websocketSvr: NewHTTPServer("", testutil.RandomPort(), NewWebsocketHandler(web3Handler)),
}
ctx := context.Background()

Expand Down
5 changes: 2 additions & 3 deletions api/web3server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/tidwall/gjson"

"github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice"
"github.com/iotexproject/iotex-core/testutil"
)

func TestGetWeb3Reqs(t *testing.T) {
Expand Down Expand Up @@ -73,8 +72,8 @@ func TestHandlePost(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
core := mock_apicoreservice.NewMockCoreService(ctrl)
svr := NewHTTPServer("", testutil.RandomPort(), NewWeb3Handler(core, ""))
getServerResp := func(svr *HTTPServer, req *http.Request) *httptest.ResponseRecorder {
svr := newHTTPHandler(NewWeb3Handler(core, ""))
getServerResp := func(svr *hTTPHandler, req *http.Request) *httptest.ResponseRecorder {
req.Header.Set("Content-Type", "application/json")
resp := httptest.NewRecorder()
svr.ServeHTTP(resp, req)
Expand Down
43 changes: 8 additions & 35 deletions api/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package api
import (
"context"
"net/http"
"strconv"
"time"

"github.com/gorilla/websocket"
Expand All @@ -27,9 +26,8 @@ const (
maxMessageSize = 15 * 1024 * 1024
)

// WebsocketServer handles requests from websocket protocol
type WebsocketServer struct {
svr *http.Server
// WebsocketHandler handles requests from websocket protocol
type WebsocketHandler struct {
msgHandler Web3Handler
}

Expand All @@ -38,39 +36,14 @@ var upgrader = websocket.Upgrader{
WriteBufferSize: 1024,
}

// NewWebSocketServer creates a new websocket server
func NewWebSocketServer(route string, port int, handler Web3Handler) *WebsocketServer {
if port == 0 {
return nil
}
svr := &WebsocketServer{
svr: &http.Server{
Addr: ":" + strconv.Itoa(port),
},
msgHandler: handler,
// NewWebsocketHandler creates a new websocket handler
func NewWebsocketHandler(web3Handler Web3Handler) *WebsocketHandler {
return &WebsocketHandler{
msgHandler: web3Handler,
}
mux := http.NewServeMux()
mux.Handle("/"+route, svr)
svr.svr.Handler = mux
return svr
}

// Start starts the websocket server
func (wsSvr *WebsocketServer) Start(_ context.Context) error {
go func() {
if err := wsSvr.svr.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.L().Fatal("Node failed to serve.", zap.Error(err))
}
}()
return nil
}

// Stop stops the websocket server
func (wsSvr *WebsocketServer) Stop(ctx context.Context) error {
return wsSvr.svr.Shutdown(ctx)
}

func (wsSvr *WebsocketServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
func (wsSvr *WebsocketHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
upgrader.CheckOrigin = func(_ *http.Request) bool { return true }

// upgrade this connection to a WebSocket connection
Expand All @@ -83,7 +56,7 @@ func (wsSvr *WebsocketServer) ServeHTTP(w http.ResponseWriter, req *http.Request
wsSvr.handleConnection(ws)
}

func (wsSvr *WebsocketServer) handleConnection(ws *websocket.Conn) {
func (wsSvr *WebsocketHandler) handleConnection(ws *websocket.Conn) {
defer ws.Close()
ws.SetReadDeadline(time.Now().Add(pongWait))
ws.SetReadLimit(maxMessageSize)
Expand Down

0 comments on commit 5ee6a4f

Please sign in to comment.