Bläddra i källkod

重构代码结构并初始化信号处理

将主函数中的信号处理、标志解析、HTTP服务器初始化等功能拆分到单独的模块中,提高了代码的可维护性和可读性。同时新增了多个处理器函数来处理不同的请求路径。
SongZihuan 3 månader sedan
förälder
incheckning
ccbf7c3215

+ 27 - 0
src/engine/engine.go

@@ -0,0 +1,27 @@
+package engine
+
+import (
+	"github.com/SongZihuan/Http-Demo/src/handler"
+	"github.com/gin-gonic/gin"
+)
+
+var Engine *gin.Engine = nil
+
+func InitEngine() error {
+	gin.SetMode(gin.ReleaseMode)
+
+	Engine = gin.New()
+	Engine.Use(gin.Logger(), gin.Recovery())
+
+	Engine.GET("/", handler.HandlerMessage)
+	Engine.GET("/ip", handler.HandlerRemoteIP)
+	Engine.GET("/client/ip", handler.HandlerClientIP)
+	Engine.GET("/timestamp", handler.HandlerTimestamp)
+	Engine.GET("/datetime", handler.HandlerDatetime)
+	Engine.GET("/hello", handler.HandlerHelloWorld)
+	Engine.GET("/empty", handler.HandlerEmpty)
+	Engine.NoRoute(handler.HandlerMethodNotFound)
+	Engine.NoMethod(handler.HandlerMethodNotAllowed)
+
+	return nil
+}

+ 3 - 0
src/flagparser/data.go

@@ -0,0 +1,3 @@
+package flagparser
+
+var HttpAddress string = ":3366"

+ 26 - 0
src/flagparser/flag.go

@@ -0,0 +1,26 @@
+package flagparser
+
+import (
+	"flag"
+	"fmt"
+)
+
+func InitFlag() (err error) {
+	defer func() {
+		e := recover()
+		if e != nil {
+			err = fmt.Errorf("%v", e)
+			return
+		}
+	}()
+
+	flag.StringVar(&HttpAddress, "address", HttpAddress, "http server address")
+	flag.StringVar(&HttpAddress, "a", HttpAddress, "http server address")
+
+	flag.StringVar(&HttpAddress, "http-address", HttpAddress, "http server address")
+	flag.StringVar(&HttpAddress, "h", HttpAddress, "http server address")
+
+	flag.Parse()
+
+	return nil
+}

+ 15 - 0
src/handler/clientip.go

@@ -0,0 +1,15 @@
+package handler
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerClientIP(c *gin.Context) {
+	str := c.ClientIP()
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 16 - 0
src/handler/datatime.go

@@ -0,0 +1,16 @@
+package handler
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"time"
+)
+
+func HandlerDatetime(c *gin.Context) {
+	str := time.Now().Format("2006-01-15 15:04:05")
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 12 - 0
src/handler/empty.go

@@ -0,0 +1,12 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerEmpty(c *gin.Context) {
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", "0")
+	c.Status(http.StatusNoContent)
+}

+ 10 - 0
src/handler/header.go

@@ -0,0 +1,10 @@
+package handler
+
+const (
+	RequestsForwarded       = "Forwarded"
+	RequestsXForwardedFor   = "X-Forwarded-For"
+	RequestsXForwardedHost  = "X-Forwarded-Host"
+	RequestsXForwardedProto = "X-Forwarded-Proto"
+	RequestsXMessage        = "X-Message"
+	RequestsXVia            = "Via"
+)

+ 15 - 0
src/handler/hello.go

@@ -0,0 +1,15 @@
+package handler
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerHelloWorld(c *gin.Context) {
+	str := "Hello, world!"
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 48 - 0
src/handler/message.go

@@ -0,0 +1,48 @@
+package handler
+
+import (
+	"fmt"
+	resource "github.com/SongZihuan/Http-Demo"
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"strings"
+	"time"
+)
+
+func HandlerMessage(c *gin.Context) {
+	nowTime := time.Now()
+
+	var res strings.Builder
+
+	res.WriteString(fmt.Sprintf("Hello, this is HTTP-DEMO %s\n", resource.Version))
+	res.WriteString(fmt.Sprintf("Date: %s\n", nowTime.Format("2006-01-02 15:04:05")))
+	res.WriteString(fmt.Sprintf("Timestamp(Unix Second): %d\n", nowTime.Unix()))
+	res.WriteString(fmt.Sprintf("Host: %s\n", c.Request.Host))
+	res.WriteString(fmt.Sprintf("Proto: %s\n", c.Request.Proto))
+	if c.Request.TLS == nil {
+		res.WriteString(fmt.Sprintf("Https/TLS: %s\n", "No"))
+		res.WriteString(fmt.Sprintf("Http/TLS: %s\n", "Yes"))
+		res.WriteString(fmt.Sprintf("Scheme: %s\n", "HTTP"))
+	} else {
+		res.WriteString(fmt.Sprintf("Https/TLS: %s\n", "Yes"))
+		res.WriteString(fmt.Sprintf("Http/TLS: %s\n", "No"))
+		res.WriteString(fmt.Sprintf("Scheme: %s\n", "HTTPS"))
+	}
+	res.WriteString(fmt.Sprintf("Path: %s\n", c.Request.URL.Path))
+	res.WriteString(fmt.Sprintf("Query: %s\n", c.Request.URL.RawQuery))
+	res.WriteString(fmt.Sprintf("ClientIP: %s\n", c.ClientIP()))
+	res.WriteString(fmt.Sprintf("RemoteIP: %s\n", c.RemoteIP()))
+	res.WriteString(fmt.Sprintf("Via: %s\n", c.Request.Header.Get(RequestsXVia)))
+	res.WriteString(fmt.Sprintf("Forwarded: %s\n", c.Request.Header.Get(RequestsForwarded)))
+	res.WriteString(fmt.Sprintf("X-Forwarded-For: %s\n", c.Request.Header.Get(RequestsXForwardedFor)))
+	res.WriteString(fmt.Sprintf("X-Forwarded-Proto: %s\n", c.Request.Header.Get(RequestsXForwardedProto)))
+	res.WriteString(fmt.Sprintf("X-Forwarded-Host: %s\n", c.Request.Header.Get(RequestsXForwardedHost)))
+	res.WriteString(fmt.Sprintf("X-Forwarded-Host: %s\n", c.Request.Header.Get(RequestsXForwardedHost)))
+	res.WriteString(fmt.Sprintf("X-Message: %s\n", strings.Join(c.Request.Header.Values(RequestsXMessage), " ")))
+
+	str := res.String()
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 10 - 0
src/handler/notmethod.go

@@ -0,0 +1,10 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerMethodNotAllowed(c *gin.Context) {
+	c.AbortWithStatus(http.StatusMethodNotAllowed)
+}

+ 10 - 0
src/handler/notrouter.go

@@ -0,0 +1,10 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerMethodNotFound(c *gin.Context) {
+	c.AbortWithStatus(http.StatusNotFound)
+}

+ 15 - 0
src/handler/remoteip.go

@@ -0,0 +1,15 @@
+package handler
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func HandlerRemoteIP(c *gin.Context) {
+	str := c.RemoteIP()
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 16 - 0
src/handler/timestamp.go

@@ -0,0 +1,16 @@
+package handler
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"time"
+)
+
+func HandlerTimestamp(c *gin.Context) {
+	str := fmt.Sprintf("%d", time.Now().Unix())
+	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
+	_, _ = c.Writer.WriteString(str)
+	c.Status(http.StatusOK)
+}

+ 34 - 0
src/httpserver/server.go

@@ -0,0 +1,34 @@
+package httpserver
+
+import (
+	"errors"
+	"fmt"
+	"github.com/SongZihuan/Http-Demo/src/engine"
+	"github.com/SongZihuan/Http-Demo/src/flagparser"
+	"net/http"
+)
+
+var HttpServer *http.Server = nil
+var HttpAddress string
+
+var ErrStop = fmt.Errorf("http server error")
+
+func InitHttpServer() error {
+	HttpAddress = flagparser.HttpAddress
+
+	HttpServer = &http.Server{
+		Addr:    HttpAddress,
+		Handler: engine.Engine,
+	}
+
+	return nil
+}
+
+func RunServer() error {
+	fmt.Printf("http server start at %s\n", HttpAddress)
+	err := HttpServer.ListenAndServe()
+	if err != nil && errors.Is(err, http.ErrServerClosed) {
+		return ErrStop
+	}
+	return err
+}

+ 24 - 169
src/mainfunc/v1.go

@@ -2,90 +2,48 @@ package mainfunc
 
 import (
 	"errors"
-	"flag"
 	"fmt"
-	resource "github.com/SongZihuan/Http-Demo"
-	"github.com/gin-gonic/gin"
-	"net/http"
-	"os"
-	"os/signal"
-	"strings"
-	"syscall"
-	"time"
+	"github.com/SongZihuan/Http-Demo/src/engine"
+	"github.com/SongZihuan/Http-Demo/src/flagparser"
+	"github.com/SongZihuan/Http-Demo/src/httpserver"
+	"github.com/SongZihuan/Http-Demo/src/signalchan"
 )
 
-const (
-	RequestsForwarded       = "Forwarded"
-	RequestsXForwardedFor   = "X-Forwarded-For"
-	RequestsXForwardedHost  = "X-Forwarded-Host"
-	RequestsXForwardedProto = "X-Forwarded-Proto"
-	RequestsXMessage        = "X-Message"
-	RequestsXVia            = "Via"
-)
-
-var address string
-var engine *gin.Engine = nil
-var server *http.Server = nil
-
 func MainV1() (exitcode int) {
-	func() {
-		defer func() {
-			err := recover()
-			if err != nil {
-				fmt.Println("option parse error")
-				exitcode = 1
-				return
-			}
-		}()
-
-		flag.StringVar(&address, "address", ":3366", "http server address")
-		flag.StringVar(&address, "a", ":3366", "http server address")
-		flag.Parse()
-	}()
-
-	gin.SetMode(gin.ReleaseMode)
-
-	engine = gin.New()
-	engine.Use(gin.Logger(), gin.Recovery())
-
-	engine.GET("/", Handler)
-	engine.GET("/ip", HandlerRemoteIP)
-	engine.GET("/client/ip", HandlerClientIP)
-	engine.GET("/timestamp", HandlerTimestamp)
-	engine.GET("/datetime", HandlerDatetime)
-	engine.GET("/hello", HandlerHelloWorld)
-	engine.GET("/empty", HandlerEmpty)
-	engine.NoRoute(HandlerMethodNotFound)
-	engine.NoMethod(HandlerMethodNotAllowed)
+	err := flagparser.InitFlag()
+	if err != nil {
+		fmt.Printf("init flag fail: %s\n", err.Error())
+		return 1
+	}
 
-	server = &http.Server{
-		Addr:    address,
-		Handler: engine,
+	err = engine.InitEngine()
+	if err != nil {
+		fmt.Printf("init engine fail: %s\n", err.Error())
+		return 1
 	}
 
-	var sigchan = make(chan os.Signal)
-	var stopchan = make(chan error)
+	err = httpserver.InitHttpServer()
+	if err != nil {
+		return 1
+	}
 
-	err := initSignal(sigchan)
+	err = signalchan.InitSignal()
 	if err != nil {
-		fmt.Printf("Listen signal fail: %s\n", err.Error())
+		fmt.Printf("init http server fail: %s\n", err.Error())
 		return 1
 	}
 
+	var httpchan = make(chan error)
 	go func() {
-		fmt.Printf("server start at %s\n", address)
-		err := server.ListenAndServe()
-		if err != nil {
-			stopchan <- err
-		}
+		httpchan <- httpserver.RunServer()
 	}()
 
 	select {
-	case <-sigchan:
+	case <-signalchan.SignalChan:
 		fmt.Printf("Server closed: safe\n")
 		return 0
-	case err := <-stopchan:
-		if errors.Is(err, http.ErrServerClosed) {
+	case err := <-httpchan:
+		if errors.Is(err, httpserver.ErrStop) {
 			fmt.Printf("Server closed: safe\n")
 			return 0
 		}
@@ -93,106 +51,3 @@ func MainV1() (exitcode int) {
 		return 1
 	}
 }
-
-func initSignal(sigchan chan os.Signal) (err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			err = fmt.Errorf("init signal error: %v", r)
-		}
-	}()
-
-	signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM)
-	return nil
-}
-
-func Handler(c *gin.Context) {
-	nowTime := time.Now()
-
-	var res strings.Builder
-
-	res.WriteString(fmt.Sprintf("Hello, this is HTTP-DEMO %s\n", resource.Version))
-	res.WriteString(fmt.Sprintf("Date: %s\n", nowTime.Format("2006-01-02 15:04:05")))
-	res.WriteString(fmt.Sprintf("Timestamp(Unix Second): %d\n", nowTime.Unix()))
-	res.WriteString(fmt.Sprintf("Host: %s\n", c.Request.Host))
-	res.WriteString(fmt.Sprintf("Proto: %s\n", c.Request.Proto))
-	if c.Request.TLS == nil {
-		res.WriteString(fmt.Sprintf("Https/TLS: %s\n", "No"))
-		res.WriteString(fmt.Sprintf("Http/TLS: %s\n", "Yes"))
-		res.WriteString(fmt.Sprintf("Scheme: %s\n", "HTTP"))
-	} else {
-		res.WriteString(fmt.Sprintf("Https/TLS: %s\n", "Yes"))
-		res.WriteString(fmt.Sprintf("Http/TLS: %s\n", "No"))
-		res.WriteString(fmt.Sprintf("Scheme: %s\n", "HTTPS"))
-	}
-	res.WriteString(fmt.Sprintf("Path: %s\n", c.Request.URL.Path))
-	res.WriteString(fmt.Sprintf("Query: %s\n", c.Request.URL.RawQuery))
-	res.WriteString(fmt.Sprintf("ClientIP: %s\n", c.ClientIP()))
-	res.WriteString(fmt.Sprintf("RemoteIP: %s\n", c.RemoteIP()))
-	res.WriteString(fmt.Sprintf("Via: %s\n", c.Request.Header.Get(RequestsXVia)))
-	res.WriteString(fmt.Sprintf("Forwarded: %s\n", c.Request.Header.Get(RequestsForwarded)))
-	res.WriteString(fmt.Sprintf("X-Forwarded-For: %s\n", c.Request.Header.Get(RequestsXForwardedFor)))
-	res.WriteString(fmt.Sprintf("X-Forwarded-Proto: %s\n", c.Request.Header.Get(RequestsXForwardedProto)))
-	res.WriteString(fmt.Sprintf("X-Forwarded-Host: %s\n", c.Request.Header.Get(RequestsXForwardedHost)))
-	res.WriteString(fmt.Sprintf("X-Forwarded-Host: %s\n", c.Request.Header.Get(RequestsXForwardedHost)))
-	res.WriteString(fmt.Sprintf("X-Message: %s\n", strings.Join(c.Request.Header.Values(RequestsXMessage), " ")))
-
-	str := res.String()
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerRemoteIP(c *gin.Context) {
-	str := c.RemoteIP()
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerClientIP(c *gin.Context) {
-	str := c.ClientIP()
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerTimestamp(c *gin.Context) {
-	str := fmt.Sprintf("%d", time.Now().Unix())
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerDatetime(c *gin.Context) {
-	str := time.Now().Format("2006-01-15 15:04:05")
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerHelloWorld(c *gin.Context) {
-	str := "Hello, world!"
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", len(str)))
-	_, _ = c.Writer.WriteString(str)
-	c.Status(http.StatusOK)
-}
-
-func HandlerEmpty(c *gin.Context) {
-	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	c.Writer.Header().Set("Content-Length", "0")
-	c.Status(http.StatusNoContent)
-}
-
-func HandlerMethodNotFound(c *gin.Context) {
-	c.AbortWithStatus(http.StatusNotFound)
-}
-
-func HandlerMethodNotAllowed(c *gin.Context) {
-	c.AbortWithStatus(http.StatusMethodNotAllowed)
-}

+ 22 - 0
src/signalchan/signal.go

@@ -0,0 +1,22 @@
+package signalchan
+
+import (
+	"fmt"
+	"os"
+	"os/signal"
+	"syscall"
+)
+
+var SignalChan = make(chan os.Signal)
+
+func InitSignal() (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("init signal error: %v", r)
+			return
+		}
+	}()
+
+	signal.Notify(SignalChan, syscall.SIGINT, syscall.SIGTERM)
+	return nil
+}