Browse Source

feat: 合并冲突

SongZihuan 1 year ago
parent
commit
4b2d014bef
6 changed files with 68 additions and 13 deletions
  1. 3 3
      rest/engine.go
  2. 3 3
      rest/engine_test.go
  3. 16 1
      rest/httpx/requests.go
  4. 8 2
      rest/internal/starter.go
  5. 2 2
      rest/internal/starter_test.go
  6. 36 2
      rest/server.go

+ 3 - 3
rest/engine.go

@@ -302,7 +302,7 @@ func (ng *engine) signatureVerifier(signature signatureSetting) (func(chain.Chai
 	}, nil
 }
 
-func (ng *engine) start(router httpx.Router, opts ...StartOption) error {
+func (ng *engine) start(ch chan *http.Server, router httpx.Router, opts ...StartOption) error {
 	if err := ng.bindRoutes(router); err != nil {
 		return err
 	}
@@ -311,7 +311,7 @@ func (ng *engine) start(router httpx.Router, opts ...StartOption) error {
 	opts = append([]StartOption{ng.withTimeout()}, opts...)
 
 	if len(ng.conf.CertFile) == 0 && len(ng.conf.KeyFile) == 0 {
-		return internal.StartHttp(ng.conf.Host, ng.conf.Port, router, opts...)
+		return internal.StartHttp(ch, ng.conf.Host, ng.conf.Port, router, opts...)
 	}
 
 	// make sure user defined options overwrite default options
@@ -323,7 +323,7 @@ func (ng *engine) start(router httpx.Router, opts ...StartOption) error {
 		},
 	}, opts...)
 
-	return internal.StartHttps(ng.conf.Host, ng.conf.Port, ng.conf.CertFile,
+	return internal.StartHttps(ch, ng.conf.Host, ng.conf.Port, ng.conf.CertFile,
 		ng.conf.KeyFile, router, opts...)
 }
 

+ 3 - 3
rest/engine_test.go

@@ -224,7 +224,7 @@ Verbose: true
 					}
 				})
 
-				assert.NotNil(t, ng.start(mockedRouter{}, func(svr *http.Server) {
+				assert.NotNil(t, ng.start(nil, mockedRouter{}, func(svr *http.Server) {
 				}))
 
 				timeout := time.Second * 3
@@ -415,7 +415,7 @@ func TestEngine_start(t *testing.T) {
 			Host: "localhost",
 			Port: -1,
 		})
-		assert.Error(t, ng.start(router.NewRouter()))
+		assert.Error(t, ng.start(nil, router.NewRouter()))
 	})
 
 	t.Run("https", func(t *testing.T) {
@@ -426,7 +426,7 @@ func TestEngine_start(t *testing.T) {
 			KeyFile:  "bar",
 		})
 		ng.tlsConfig = &tls.Config{}
-		assert.Error(t, ng.start(router.NewRouter()))
+		assert.Error(t, ng.start(nil, router.NewRouter()))
 	})
 }
 

+ 16 - 1
rest/httpx/requests.go

@@ -1,6 +1,7 @@
 package httpx
 
 import (
+	"fmt"
 	"io"
 	"net/http"
 	"strings"
@@ -35,7 +36,21 @@ type Validator interface {
 }
 
 // Parse parses the request.
-func Parse(r *http.Request, v any) error {
+func Parse(r *http.Request, v any) (err error) {
+	defer func() {
+		r := recover()
+		if r == nil {
+			return
+		}
+
+		tmp, ok := r.(error)
+		if ok {
+			err = tmp
+		} else {
+			err = fmt.Errorf("panic error: %v", r)
+		}
+	}()
+
 	if err := ParsePath(r, v); err != nil {
 		return err
 	}

+ 8 - 2
rest/internal/starter.go

@@ -17,16 +17,22 @@ const probeNamePrefix = "rest"
 type StartOption func(svr *http.Server)
 
 // StartHttp starts a http server.
-func StartHttp(host string, port int, handler http.Handler, opts ...StartOption) error {
+func StartHttp(ch chan *http.Server, host string, port int, handler http.Handler, opts ...StartOption) error {
 	return start(host, port, handler, func(svr *http.Server) error {
+		if ch != nil {
+			ch <- svr
+		}
 		return svr.ListenAndServe()
 	}, opts...)
 }
 
 // StartHttps starts a https server.
-func StartHttps(host string, port int, certFile, keyFile string, handler http.Handler,
+func StartHttps(ch chan *http.Server, host string, port int, certFile, keyFile string, handler http.Handler,
 	opts ...StartOption) error {
 	return start(host, port, handler, func(svr *http.Server) error {
+		if ch != nil {
+			ch <- svr
+		}
 		// certFile and keyFile are set in buildHttpsServer
 		return svr.ListenAndServeTLS(certFile, keyFile)
 	}, opts...)

+ 2 - 2
rest/internal/starter_test.go

@@ -16,7 +16,7 @@ func TestStartHttp(t *testing.T) {
 	fields := strings.Split(svr.Listener.Addr().String(), ":")
 	port, err := strconv.Atoi(fields[1])
 	assert.Nil(t, err)
-	err = StartHttp(fields[0], port, http.NotFoundHandler(), func(svr *http.Server) {
+	err = StartHttp(nil, fields[0], port, http.NotFoundHandler(), func(svr *http.Server) {
 		svr.IdleTimeout = 0
 	})
 	assert.NotNil(t, err)
@@ -28,7 +28,7 @@ func TestStartHttps(t *testing.T) {
 	fields := strings.Split(svr.Listener.Addr().String(), ":")
 	port, err := strconv.Atoi(fields[1])
 	assert.Nil(t, err)
-	err = StartHttps(fields[0], port, "", "", http.NotFoundHandler(), func(svr *http.Server) {
+	err = StartHttps(nil, fields[0], port, "", "", http.NotFoundHandler(), func(svr *http.Server) {
 		svr.IdleTimeout = 0
 	})
 	assert.NotNil(t, err)

+ 36 - 2
rest/server.go

@@ -117,14 +117,36 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 // Graceful shutdown is enabled by default.
 // Use proc.SetTimeToForceQuit to customize the graceful shutdown period.
 func (s *Server) Start() {
-	handleError(s.ngin.start(s.router))
+	handleError(s.ngin.start(nil, s.router))
+}
+
+func (s *Server) StartAsGoRoutine() *http.Server {
+	ch := make(chan *http.Server, 1)
+	go func() {
+		defer func() {
+			recover()
+		}()
+		handleError(s.ngin.start(ch, s.router))
+	}()
+	return <-ch
 }
 
 // StartWithOpts starts the Server.
 // Graceful shutdown is enabled by default.
 // Use proc.SetTimeToForceQuit to customize the graceful shutdown period.
 func (s *Server) StartWithOpts(opts ...StartOption) {
-	handleError(s.ngin.start(s.router, opts...))
+	handleError(s.ngin.start(nil, s.router, opts...))
+}
+
+func (s *Server) StartAsGoRoutineWithOpts(opts ...StartOption) *http.Server {
+	ch := make(chan *http.Server, 1)
+	go func() {
+		defer func() {
+			recover()
+		}()
+		handleError(s.ngin.start(ch, s.router, opts...))
+	}()
+	return <-ch
 }
 
 // Stop stops the Server.
@@ -238,6 +260,18 @@ func WithNotAllowedHandler(handler http.Handler) RunOption {
 	}
 }
 
+func WithOptionsHandler(handler http.Handler) RunOption {
+	return func(server *Server) {
+		server.router.SetOptionsHandler(handler)
+	}
+}
+
+func WithGlobalMiddleware(middleware httpx.MiddlewareFunc) RunOption {
+	return func(server *Server) {
+		server.router.SetMiddleware(middleware)
+	}
+}
+
 // WithPrefix adds group as a prefix to the route paths.
 func WithPrefix(group string) RouteOption {
 	return func(r *featuredRoutes) {