mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-03 23:06:36 +08:00
feat(framework): 回灌 OpenFlare 分层、安全与运行时改进
将平台域持久化收敛为 repository 唯一入口,model 去掉 IO。 邮件头写入前清除 CR/LF,防止 header 注入。 httppool 支持可配置 Transport;batchwriter 增加 MinBatchSize/Stats,flush 失败交回批次;任务 PermanentError 作为 SkipRetry 终态。 设置与推送页的确认改为 AlertDialog;axios 去尾斜杠并按 Gin 数组序列化查询参数。 升级共享 Go 依赖(Gin、Asynq、OTel、GORM、Redis 等)。
This commit is contained in:
@@ -4,6 +4,12 @@
|
||||
package httppool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -35,3 +41,60 @@ func TestNewClient(t *testing.T) {
|
||||
t.Error("NewClient() is not configured with the default transport")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewTransportUsesConfiguredDirectDialer(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
|
||||
_, _ = writer.Write([]byte("ok"))
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
var dialedAddress string
|
||||
dialer := &net.Dialer{}
|
||||
transport := NewTransport(TransportOptions{
|
||||
Proxy: nil,
|
||||
DialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
dialedAddress = address
|
||||
return dialer.DialContext(ctx, network, server.Listener.Addr().String())
|
||||
},
|
||||
})
|
||||
client := &http.Client{Transport: transport}
|
||||
t.Cleanup(client.CloseIdleConnections)
|
||||
|
||||
request, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://artifact.example/site.zip", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewRequestWithContext() error = %v", err)
|
||||
}
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
t.Fatalf("client.Do() error = %v", err)
|
||||
}
|
||||
defer func() { _ = response.Body.Close() }()
|
||||
if _, err := io.ReadAll(response.Body); err != nil {
|
||||
t.Fatalf("ReadAll() error = %v", err)
|
||||
}
|
||||
if dialedAddress != "artifact.example:80" {
|
||||
t.Fatalf("DialContext address = %q, want direct target", dialedAddress)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewTransportClonesTLSConfig(t *testing.T) {
|
||||
server := httptest.NewTLSServer(http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
|
||||
writer.WriteHeader(http.StatusNoContent)
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
tlsConfig := &tls.Config{InsecureSkipVerify: true} //nolint:gosec // test-only self-signed server
|
||||
client := &http.Client{Transport: NewTransport(TransportOptions{TLSClientConfig: tlsConfig})}
|
||||
t.Cleanup(client.CloseIdleConnections)
|
||||
tlsConfig.InsecureSkipVerify = false
|
||||
|
||||
request, err := http.NewRequestWithContext(t.Context(), http.MethodGet, server.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewRequestWithContext() error = %v", err)
|
||||
}
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
t.Fatalf("client.Do() error = %v", err)
|
||||
}
|
||||
_ = response.Body.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user