@@ -5,29 +5,44 @@ import (
55 "fmt"
66 "log"
77 "net"
8+ "net/http"
9+ "path"
810
11+ "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
912 "github.com/linuxsuren/api-testing/pkg/server"
13+ "github.com/linuxsuren/api-testing/pkg/testing"
1014 "github.com/spf13/cobra"
1115 "google.golang.org/grpc"
1216)
1317
14- func createServerCmd (gRPCServer gRPCServer ) (c * cobra.Command ) {
15- opt := & serverOption {gRPCServer : gRPCServer }
18+ func createServerCmd (gRPCServer gRPCServer , httpServer server.HTTPServer ) (c * cobra.Command ) {
19+ opt := & serverOption {
20+ gRPCServer : gRPCServer ,
21+ httpServer : httpServer ,
22+ }
1623 c = & cobra.Command {
1724 Use : "server" ,
1825 Short : "Run as a server mode" ,
1926 RunE : opt .runE ,
2027 }
2128 flags := c .Flags ()
2229 flags .IntVarP (& opt .port , "port" , "p" , 7070 , "The RPC server port" )
30+ flags .IntVarP (& opt .httpPort , "http-port" , "" , 8080 , "The HTTP server port" )
2331 flags .BoolVarP (& opt .printProto , "print-proto" , "" , false , "Print the proto content and exit" )
32+ flags .StringVarP (& opt .localStorage , "local-storage" , "" , "" , "The local storage path" )
33+ flags .StringVarP (& opt .consolePath , "console-path" , "" , "" , "The path of the console" )
2434 return
2535}
2636
2737type serverOption struct {
2838 gRPCServer gRPCServer
29- port int
30- printProto bool
39+ httpServer server.HTTPServer
40+
41+ port int
42+ httpPort int
43+ printProto bool
44+ localStorage string
45+ consolePath string
3146}
3247
3348func (o * serverOption ) runE (cmd * cobra.Command , args []string ) (err error ) {
@@ -38,19 +53,56 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
3853 return
3954 }
4055
41- var lis net.Listener
56+ var (
57+ lis net.Listener
58+ httplis net.Listener
59+ )
4260 lis , err = net .Listen ("tcp" , fmt .Sprintf (":%d" , o .port ))
4361 if err != nil {
4462 return
4563 }
64+ httplis , err = net .Listen ("tcp" , fmt .Sprintf (":%d" , o .httpPort ))
65+ if err != nil {
66+ return
67+ }
68+
69+ loader := testing .NewFileLoader ()
70+ if o .localStorage != "" {
71+ if err = loader .Put (o .localStorage ); err != nil {
72+ return
73+ }
74+ }
4675
76+ removeServer := server .NewRemoteServer (loader )
4777 s := o .gRPCServer
48- server .RegisterRunnerServer (s , server .NewRemoteServer ())
49- log .Printf ("server listening at %v" , lis .Addr ())
50- s .Serve (lis )
78+ go func () {
79+ server .RegisterRunnerServer (s , removeServer )
80+ log .Printf ("gRPC server listening at %v" , lis .Addr ())
81+ s .Serve (lis )
82+ }()
83+
84+ mux := runtime .NewServeMux ()
85+ err = server .RegisterRunnerHandlerServer (cmd .Context (), mux , removeServer )
86+ if err == nil {
87+ mux .HandlePath ("GET" , "/" , frontEndHandlerWithLocation (o .consolePath ))
88+ mux .HandlePath ("GET" , "/assets/{asset}" , frontEndHandlerWithLocation (o .consolePath ))
89+ o .httpServer .WithHandler (mux )
90+ err = o .httpServer .Serve (httplis )
91+ }
5192 return
5293}
5394
95+ func frontEndHandlerWithLocation (consolePath string ) func (w http.ResponseWriter , r * http.Request , pathParams map [string ]string ) {
96+ return func (w http.ResponseWriter , r * http.Request , pathParams map [string ]string ) {
97+ target := r .URL .Path
98+ if target == "/" {
99+ target = "/index.html"
100+ }
101+
102+ http .ServeFile (w , r , path .Join (consolePath , target ))
103+ }
104+ }
105+
54106type gRPCServer interface {
55107 Serve (lis net.Listener ) error
56108 grpc.ServiceRegistrar
0 commit comments