Просмотр исходного кода

fix(fetcher): clone request builder before disabling redirects

The subscription finder holds a shared RequestBuilder whose methods mutate
in place. Disabling redirects while probing well-known feed URLs flipped
that flag on the shared builder permanently, leaking into the finder's
other requests instead of scoping to the probe.

Add a Clone method and derive an isolated builder for the probe so the
redirect setting no longer escapes the loop.
Frédéric Guillot 5 дней назад
Родитель
Сommit
8699a1d119

+ 9 - 0
internal/reader/fetcher/request_builder.go

@@ -53,6 +53,15 @@ func NewRequestBuilder() *RequestBuilder {
 	}
 }
 
+// Clone returns an independent copy of the builder. Mutating the copy (for
+// example to disable redirects for a single request) leaves the original
+// untouched.
+func (r *RequestBuilder) Clone() *RequestBuilder {
+	clone := *r
+	clone.headers = r.headers.Clone()
+	return &clone
+}
+
 func (r *RequestBuilder) WithHeader(key, value string) *RequestBuilder {
 	r.headers.Set(key, value)
 	return r

+ 23 - 0
internal/reader/fetcher/request_builder_test.go

@@ -267,6 +267,29 @@ func TestRequestBuilder_WithoutRedirects(t *testing.T) {
 	}
 }
 
+func TestRequestBuilder_Clone(t *testing.T) {
+	original := NewRequestBuilder().WithHeader("X-Shared", "value")
+
+	clone := original.Clone().WithoutRedirects()
+	clone.WithHeader("X-Clone-Only", "value")
+
+	if original.withoutRedirects {
+		t.Error("Mutating the clone should not disable redirects on the original")
+	}
+
+	if original.headers.Get("X-Clone-Only") != "" {
+		t.Error("Mutating the clone's headers should not affect the original")
+	}
+
+	if clone.headers.Get("X-Shared") != "value" {
+		t.Error("Expected the clone to inherit the original headers")
+	}
+
+	if clone.clientTimeout != original.clientTimeout {
+		t.Error("Expected the clone to inherit the original timeout")
+	}
+}
+
 func TestRequestBuilder_DisableHTTP2(t *testing.T) {
 	builder := NewRequestBuilder()
 	builder = builder.DisableHTTP2(true)

+ 4 - 1
internal/reader/subscription/finder.go

@@ -221,7 +221,10 @@ func (f *subscriptionFinder) findSubscriptionsFromWellKnownURLs(websiteURL strin
 			// Some websites redirects unknown URLs to the home page.
 			// As result, the list of known URLs is returned to the subscription list.
 			// We don't want the user to choose between invalid feed URLs.
-			requestBuilder := f.requestBuilder.WithoutRedirects()
+			//
+			// Probe each known URL on its own builder so disabling redirects
+			// here doesn't leak into the finder's other requests.
+			requestBuilder := f.requestBuilder.Clone().WithoutRedirects()
 
 			responseHandler := fetcher.NewResponseHandler(requestBuilder.ExecuteRequest(fullURL))
 			localizedError := responseHandler.LocalizedError()