Skip to content

Commit d4e4051

Browse files
committed
fix: Do not duplicate headers when configured via builder.
1 parent f556fd4 commit d4e4051

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

src/main/java/io/github/nstdio/http/ext/HeadersAddingInterceptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ private HttpRequest apply(HttpRequest request) {
5252
private Map<String, List<String>> addHeaders(HttpHeaders h) {
5353
var headersBuilder = new HttpHeadersBuilder(h);
5454

55-
headers.forEach(headersBuilder::add);
56-
resolvableHeaders.forEach((name, valueSupplier) -> headersBuilder.add(name, valueSupplier.get()));
55+
headers.forEach(headersBuilder::addIfNotExist);
56+
resolvableHeaders.forEach((name, valueSupplier) -> headersBuilder.addIfNotExist(name, valueSupplier.get()));
5757

5858
return headersBuilder.map();
5959
}

src/main/java/io/github/nstdio/http/ext/HttpHeadersBuilder.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,31 @@ private void copyTo(HttpHeadersBuilder builder, Map<String, List<String>> source
4444
}
4545
}
4646

47+
private List<String> values(String name, int capacity) {
48+
return headersMap.computeIfAbsent(name, k -> new ArrayList<>(capacity));
49+
}
50+
51+
private List<String> values(String name) {
52+
return values(name, 1);
53+
}
54+
4755
HttpHeadersBuilder add(String name, String value) {
48-
headersMap.computeIfAbsent(name, k -> new ArrayList<>(1))
49-
.add(value);
56+
values(name).add(value);
57+
return this;
58+
}
59+
60+
HttpHeadersBuilder addIfNotExist(String name, String value) {
61+
List<String> existing = values(name);
62+
if (!existing.contains(value)) {
63+
existing.add(value);
64+
}
65+
5066
return this;
5167
}
5268

5369
HttpHeadersBuilder add(String name, List<String> values) {
5470
if (!values.isEmpty()) {
55-
headersMap.computeIfAbsent(name, k -> new ArrayList<>(values.size()))
56-
.addAll(values);
71+
values(name, values.size()).addAll(values);
5772
}
5873
return this;
5974
}

src/test/kotlin/io/github/nstdio/http/ext/HeadersAddingInterceptorTest.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,31 @@ class HeadersAddingInterceptorTest {
5656
}
5757
}
5858

59+
@Test
60+
fun `Should not duplicate headers`() {
61+
//given
62+
val interceptor = HeadersAddingInterceptor(
63+
mapOf("a" to "1", "b" to "3"),
64+
mapOf("b" to Supplier { "2" }),
65+
)
66+
67+
val request = HttpRequest.newBuilder("https://example.com".toUri())
68+
.header("a", "1")
69+
.header("b", "2")
70+
.header("b", "3")
71+
.build()
72+
val chain = Chain.of<Any>(RequestContext.of(request, bodyHandler))
73+
74+
//when
75+
val actual = interceptor.intercept(chain).request().headers()
76+
77+
//then
78+
actual.map().should {
79+
it.shouldContain("a", listOf("1"))
80+
it.shouldContain("b", listOf("2", "3"))
81+
}
82+
}
83+
5984
@Test
6085
fun `Should not add headers to the chain when response is present`() {
6186
//given

0 commit comments

Comments
 (0)