// MIT License // // Copyright (c) 2024 godoos.com // Email: xpbb@qq.com // GitHub: github.com/phpk/godoos // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package cmd import ( "context" "log" "net/http" "os" "os/signal" "sync" "syscall" "time" "github.com/gorilla/mux" ) func Serve(srv *http.Server) { var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Error starting server: %v\n", err) } }() // 监听退出信号 ctx, cancel := context.WithCancel(context.Background()) go func() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) <-c log.Println("Received signal, gracefully shutting down...") cancel() }() <-ctx.Done() shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second) defer shutdownCancel() if err := srv.Shutdown(shutdownCtx); err != nil { log.Printf("Error during server shutdown: %v\n", err) } wg.Wait() } type loggingMiddleware struct { } func (l loggingMiddleware) Middleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { startTime := time.Now() defer func() { log.Printf( "%s %s %s %v", r.Method, r.URL.Path, r.Proto, time.Since(startTime), ) }() next.ServeHTTP(w, r) }) } // CORS 中间件 func corsMiddleware() mux.MiddlewareFunc { allowHeaders := "Content-Type, Accept, Authorization, Origin,Pwd,Salt" allowMethods := "GET, POST, PUT, DELETE, OPTIONS" return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", allowMethods) w.Header().Set("Access-Control-Allow-Headers", allowHeaders) // 如果是预检请求(OPTIONS),直接返回 200 OK if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) } }