mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
Compare commits
5 Commits
v2.1.10-rc
...
v2.1.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c8e77246 | ||
|
|
6f6e95cfdb | ||
|
|
c806a0c172 | ||
|
|
c136b878ce | ||
|
|
d4a81916d5 |
@@ -4,6 +4,8 @@
|
||||
[](https://goreportcard.com/report/github.com/silenceper/wechat/v2)
|
||||
[](https://pkg.go.dev/github.com/silenceper/wechat/v2?tab=doc)
|
||||

|
||||

|
||||
|
||||
|
||||
使用Golang开发的微信SDK,简单、易用。
|
||||
|
||||
|
||||
@@ -556,7 +556,7 @@ type SubscribeMsgSentEvent struct {
|
||||
type SubscribeMsgSentList struct {
|
||||
TemplateID string `xml:"TemplateId" json:"TemplateId"`
|
||||
MsgID string `xml:"MsgID" json:"MsgID"`
|
||||
ErrorCode int `xml:"ErrorCode" json:"ErrorCode"`
|
||||
ErrorCode string `xml:"ErrorCode" json:"ErrorCode"`
|
||||
ErrorStatus string `xml:"ErrorStatus" json:"ErrorStatus"`
|
||||
}
|
||||
|
||||
|
||||
@@ -68,3 +68,18 @@ func DecodeWithError(response []byte, obj interface{}, apiName string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleFileResponse 通用处理微信等接口返回:有时 JSON 错误,有时文件内容
|
||||
func HandleFileResponse(response []byte, apiName string) ([]byte, error) {
|
||||
var commErr CommonError
|
||||
if err := json.Unmarshal(response, &commErr); err == nil {
|
||||
// 能解析成 JSON,判断是否为错误
|
||||
if commErr.ErrCode != 0 {
|
||||
commErr.apiName = apiName
|
||||
return nil, &commErr
|
||||
}
|
||||
// 能解析成 JSON 且没错误码,极少情况(比如微信返回的业务数据是 JSON 但无 errcode 字段),可根据需要调整
|
||||
}
|
||||
// 不能解析成 JSON,或没错误码,直接返回原始内容
|
||||
return response, nil
|
||||
}
|
||||
|
||||
16
util/http.go
16
util/http.go
@@ -292,13 +292,19 @@ func httpWithTLS(rootCa, key string) (*http.Client, error) {
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
var baseTransport http.RoundTripper
|
||||
// 安全地获取 *http.Transport
|
||||
var trans *http.Transport
|
||||
// 尝试从 DefaultHTTPClient 获取 Transport,如果失败则使用默认值
|
||||
if DefaultHTTPClient.Transport != nil {
|
||||
baseTransport = DefaultHTTPClient.Transport
|
||||
} else {
|
||||
baseTransport = http.DefaultTransport
|
||||
if t, ok := DefaultHTTPClient.Transport.(*http.Transport); ok {
|
||||
trans = t.Clone()
|
||||
}
|
||||
}
|
||||
trans := baseTransport.(*http.Transport).Clone()
|
||||
// 如果无法获取有效的 Transport,使用默认值
|
||||
if trans == nil {
|
||||
trans = http.DefaultTransport.(*http.Transport).Clone()
|
||||
}
|
||||
|
||||
trans.TLSClientConfig = config
|
||||
trans.DisableCompression = true
|
||||
client = &http.Client{Transport: trans}
|
||||
|
||||
81
util/http_test.go
Normal file
81
util/http_test.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestHttpWithTLS_NilTransport tests the scenario where DefaultHTTPClient.Transport is nil
|
||||
func TestHttpWithTLS_NilTransport(t *testing.T) {
|
||||
// Save original transport
|
||||
originalTransport := DefaultHTTPClient.Transport
|
||||
defer func() {
|
||||
DefaultHTTPClient.Transport = originalTransport
|
||||
}()
|
||||
|
||||
// Set Transport to nil to simulate the bug scenario
|
||||
DefaultHTTPClient.Transport = nil
|
||||
|
||||
// This should not panic after the fix
|
||||
// Note: This will fail due to invalid cert path, but shouldn't panic on type assertion
|
||||
_, err := httpWithTLS("./testdata/invalid_cert.p12", "password")
|
||||
|
||||
// We expect an error (cert file not found), but NOT a panic
|
||||
if err == nil {
|
||||
t.Error("Expected error due to invalid cert path, but got nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestHttpWithTLS_CustomTransport tests the scenario where DefaultHTTPClient has a custom Transport
|
||||
func TestHttpWithTLS_CustomTransport(t *testing.T) {
|
||||
// Save original transport
|
||||
originalTransport := DefaultHTTPClient.Transport
|
||||
defer func() {
|
||||
DefaultHTTPClient.Transport = originalTransport
|
||||
}()
|
||||
|
||||
// Set a custom http.Transport
|
||||
customTransport := &http.Transport{
|
||||
MaxIdleConns: 100,
|
||||
}
|
||||
DefaultHTTPClient.Transport = customTransport
|
||||
|
||||
// This should not panic
|
||||
_, err := httpWithTLS("./testdata/invalid_cert.p12", "password")
|
||||
|
||||
// We expect an error (cert file not found), but NOT a panic
|
||||
if err == nil {
|
||||
t.Error("Expected error due to invalid cert path, but got nil")
|
||||
}
|
||||
}
|
||||
|
||||
// CustomRoundTripper is a custom implementation of http.RoundTripper
|
||||
type CustomRoundTripper struct{}
|
||||
|
||||
func (c *CustomRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return http.DefaultTransport.RoundTrip(req)
|
||||
}
|
||||
|
||||
// TestHttpWithTLS_CustomRoundTripper tests the edge case where DefaultHTTPClient has a custom RoundTripper
|
||||
// that is NOT *http.Transport
|
||||
func TestHttpWithTLS_CustomRoundTripper(t *testing.T) {
|
||||
// Save original transport
|
||||
originalTransport := DefaultHTTPClient.Transport
|
||||
defer func() {
|
||||
DefaultHTTPClient.Transport = originalTransport
|
||||
}()
|
||||
|
||||
// Set a custom RoundTripper that is NOT *http.Transport
|
||||
customRoundTripper := &CustomRoundTripper{}
|
||||
DefaultHTTPClient.Transport = customRoundTripper
|
||||
|
||||
// Create a recovery handler to catch potential panic
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("httpWithTLS panicked with custom RoundTripper: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
// This might panic if the code doesn't handle non-*http.Transport RoundTripper properly
|
||||
_, _ = httpWithTLS("./testdata/invalid_cert.p12", "password")
|
||||
}
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
// SignatureOptions 微信服务器验证参数
|
||||
type SignatureOptions struct {
|
||||
Signature string `form:"msg_signature"`
|
||||
TimeStamp string `form:"timestamp"`
|
||||
Nonce string `form:"nonce"`
|
||||
EchoStr string `form:"echostr"`
|
||||
Signature string `form:"msg_signature" json:"msg_signature"`
|
||||
TimeStamp string `form:"timestamp" json:"timestamp"`
|
||||
Nonce string `form:"nonce" json:"nonce"`
|
||||
EchoStr string `form:"echostr" json:"echostr"`
|
||||
}
|
||||
|
||||
// VerifyURL 验证请求参数是否合法并返回解密后的消息内容
|
||||
|
||||
@@ -191,12 +191,6 @@ func (r *Client) GetTempFile(mediaID string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查响应是否为错误信息
|
||||
err = util.DecodeWithCommonError(response, "GetTempFile")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 如果不是错误响应,则返回原始数据
|
||||
return response, nil
|
||||
// 检查响应是否为错误信息,如果不是错误响应,则返回原始数据
|
||||
return util.HandleFileResponse(response, "GetTempFile")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user