fix: Repeater 直连拨号改由请求超时控制,补充 DNS 重绑定与 HTTP/2 测试(Codex gpt-6.1-sol)(#42)

This commit is contained in:
RuoJi6 committed 2026-10-24 23:42:30 +08:00
1 parent 5e908e9f39
commit 91d2fe456c
2 files changed
+48 -2

No files matched your search

+3 -2
View File
@@ -241,9 +241,10 @@ func (s *Server) repeaterTransport(useRecordingProxy, insecure bool) http.RoundT
transport.DialTLSContext = nil
transport.DialTLS = nil
transport.Dial = nil
// Let the request context enforce timeout_ms for the entire dial.
transport.DialContext = (&net.Dialer{
Timeout: 15 * time.Second, KeepAlive: 30 * time.Second,
Control: repeaterBlockSensitiveDial,
KeepAlive: 30 * time.Second,
Control: repeaterBlockSensitiveDial,
}).DialContext
}
if insecure {
+45
View File
@@ -2,6 +2,8 @@ package server
import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
@@ -14,6 +16,7 @@ import (
"os"
"strings"
"testing"
"time"
"github.com/Autumn-27/artex/traffic"
)
@@ -119,6 +122,45 @@ func TestRepeaterBlockSensitiveDial(t *testing.T) {
}
}
func TestRepeaterTransportBlocksSensitiveDial(t *testing.T) {
t.Setenv(repeaterAllowLocalEnv, "")
tr := (&Server{}).repeaterTransport(false, false).(*http.Transport)
defer tr.CloseIdleConnections()
if tr.DialContext == nil {
t.Fatal("direct transport has no guarded DialContext")
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
conn, err := tr.DialContext(ctx, "tcp", "127.0.0.1:1")
if conn != nil {
conn.Close()
}
if err == nil || !strings.Contains(err.Error(), "拒绝访问本机/链路本地地址 127.0.0.1") {
t.Fatalf("dial should fail at the sensitive-address guard, got %v", err)
}
}
func TestRepeaterDirectHTTP2(t *testing.T) {
t.Setenv(repeaterAllowLocalEnv, "1")
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ProtoMajor != 2 {
t.Errorf("request protocol=%s, want HTTP/2", r.Proto)
}
_, _ = io.WriteString(w, "h2 response")
}))
srv.EnableHTTP2 = true
srv.TLS = &tls.Config{NextProtos: []string{"h2"}}
srv.StartTLS()
defer srv.Close()
code, out, raw := repeaterTestSend(t, &Server{}, map[string]any{
"url": srv.URL, "use_recording_proxy": false, "insecure_skip_verify": true,
})
if code != http.StatusOK || out.Error != "" || out.Status != http.StatusOK || out.Proto != "HTTP/2.0" || out.Body != "h2 response" {
t.Fatalf("HTTP/2 response status=%d raw=%s", code, raw)
}
}
func TestRepeaterRoundTripHeadersAndBody(t *testing.T) {
t.Setenv(repeaterAllowLocalEnv, "1")
var got http.Request
@@ -264,6 +306,9 @@ func TestRepeaterProxyTransportConstruction(t *testing.T) {
if tr.TLSClientConfig == nil || tr.TLSClientConfig.RootCAs == nil || !tr.TLSClientConfig.RootCAs.Equal(wantRoots) {
t.Fatal("recording proxy CA was not loaded into transport RootCAs")
}
if s.repeaterTransport(true, false).(*http.Transport).ForceAttemptHTTP2 {
t.Fatal("recording proxy transport must not force HTTP/2")
}
}
func TestRepeaterRedactProxyCredentials(t *testing.T) {