最近工作需要,写了一个简单的 web 程序,程序主体 main.go:
package main
import (
"context"
"encoding/base64"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"github.com/gin-gonic/gin"
"github.com/leffss/token/pkg/setting"
)
func init() {
setting.Setup()
}
func serverName(v string) gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("server", v)
c.Next()
}
}
func ipWhiteList() gin.HandlerFunc {
whitelist := make(map[string]bool)
for _, ip := range setting.ServerSetting.IpWhiteLists {
whitelist[ip] = true
}
return func(c *gin.Context) {
if !whitelist[c.ClientIP()] && !whitelist["0.0.0.0"] {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"status": http.StatusForbidden,
"message": "Permission denied",
})
return
}
}
}
func token(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"secret": base64.StdEncoding.EncodeToString([]byte(setting.ServerSetting.Token)),
})
}
func main() {
// gin.SetMode("debug")
gin.SetMode("release")
gin.DisableConsoleColor()
router := gin.Default()
router.Use(serverName("nginx"))
router.Use(ipWhiteList())
router.GET("/", token)
endPoint := fmt.Sprintf("%s:%d", setting.ServerSetting.Host, setting.ServerSetting.Port)
server := &http.Server{
Addr: endPoint,
Handler: router,
ReadTimeout: 15,
WriteTimeout: 15,
MaxHeaderBytes: 1048576,
}
log.Printf("[info] start http server listen on %s", endPoint)
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("[error] Server Start Error: %s\n", err)
}
}()
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 15)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatal("[error] Server Shutdown Error: ", err)
}
log.Println("[info] Server Shutdown")
}
现象:windows 下正常运行并返回结果,但是 linux 正常监听端口后,curl 访问提示:
curl: (56) Recv failure: Connection reset by peer
使用 tcpdump 抓包:
tcpdump -i lo -w 10080.cap
使用 wareshark 查看,可以看到TCP三次握手是正常的,已经到了 get 请求阶段,但是最终返回 RST, ACK
包
网上查了下资料,可能原因有:
-
端口未打开
-
请求超时
-
提前关闭
-
在一个已关闭的socket上收到数据
-
异常终止一个连接
再看了下代码发现设置了超时参数:
ReadTimeout: 15,
WriteTimeout: 15,
大意了,这两个参数类型应该是 time.Duration 类型,这里设置了错误的读写超时时间,使用 //
注释掉或者设置正确的超时时间:
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
标签:reset,http,排错,15,setting,func,router,peer,gin
From: https://www.cnblogs.com/leffss/p/16860315.html