diff --git a/server/http.go b/server/http.go index 3d6f521..2aca120 100644 --- a/server/http.go +++ b/server/http.go @@ -236,17 +236,26 @@ func (c *HTTPClient) onBotPushEvent(e *coolq.Event) { } client := http.Client{Timeout: time.Second * time.Duration(c.timeout)} - req, _ := http.NewRequest("POST", c.addr, bytes.NewReader(e.JSONBytes())) - req.Header.Set("X-Self-ID", strconv.FormatInt(c.bot.Client.Uin, 10)) - req.Header.Set("User-Agent", "CQHttp/4.15.0") - req.Header.Set("Content-Type", "application/json") - if c.secret != "" { - mac := hmac.New(sha1.New, []byte(c.secret)) - _, _ = mac.Write(e.JSONBytes()) - req.Header.Set("X-Signature", "sha1="+hex.EncodeToString(mac.Sum(nil))) - } - if c.apiPort != 0 { - req.Header.Set("X-API-Port", strconv.FormatInt(int64(c.apiPort), 10)) + + // see https://stackoverflow.com/questions/31337891/net-http-http-contentlength-222-with-body-length-0 + // we should create a new request for every single post trial + createRequest := func() (*http.Request, error) { + req, err := http.NewRequest("POST", c.addr, bytes.NewReader(e.JSONBytes())) + if err != nil { + return nil, err + } + req.Header.Set("X-Self-ID", strconv.FormatInt(c.bot.Client.Uin, 10)) + req.Header.Set("User-Agent", "CQHttp/4.15.0") + req.Header.Set("Content-Type", "application/json") + if c.secret != "" { + mac := hmac.New(sha1.New, []byte(c.secret)) + _, _ = mac.Write(e.JSONBytes()) + req.Header.Set("X-Signature", "sha1="+hex.EncodeToString(mac.Sum(nil))) + } + if c.apiPort != 0 { + req.Header.Set("X-API-Port", strconv.FormatInt(int64(c.apiPort), 10)) + } + return req, nil } var res *http.Response @@ -254,6 +263,12 @@ func (c *HTTPClient) onBotPushEvent(e *coolq.Event) { const maxAttemptTimes = 5 for i := 0; i <= maxAttemptTimes; i++ { + req, err := createRequest() + if err != nil { + log.Warnf("上报 Event 数据到 %v 时创建请求失败: %v", c.addr, err) + return + } + res, err = client.Do(req) if err == nil { //goland:noinspection GoDeferInLoop