From 227c19036d741f1bc2546fa06946eae9c081d7e4 Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:01:49 +0100 Subject: [PATCH 1/2] feat: expose immutable header map view --- .../src/main/kotlin/com/openai/core/http/Headers.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openai-java-core/src/main/kotlin/com/openai/core/http/Headers.kt b/openai-java-core/src/main/kotlin/com/openai/core/http/Headers.kt index 5af3c3387..439e20109 100644 --- a/openai-java-core/src/main/kotlin/com/openai/core/http/Headers.kt +++ b/openai-java-core/src/main/kotlin/com/openai/core/http/Headers.kt @@ -21,8 +21,21 @@ private constructor( fun names(): Set = map.keys + /** + * Returns all values associated with [name], or an empty list when the header is absent. + * + * Names returned by [names] always have at least one value. + */ fun values(name: String): List = map[name].orEmpty() + /** + * Returns the immutable, case-insensitive mapping of header names to their values. + * + * The returned map and its value lists are the same immutable representation used by this + * [Headers] instance; mutating the returned data is not supported. + */ + fun asMap(): Map> = map + fun toBuilder(): Builder = Builder().putAll(map) companion object { From ebb9d8372b77b3ab020c54df9da3d5ec1e8137bf Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:02:23 +0100 Subject: [PATCH 2/2] test: cover immutable header map view --- .../openai/core/http/HeadersMapViewTest.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 openai-java-core/src/test/kotlin/com/openai/core/http/HeadersMapViewTest.kt diff --git a/openai-java-core/src/test/kotlin/com/openai/core/http/HeadersMapViewTest.kt b/openai-java-core/src/test/kotlin/com/openai/core/http/HeadersMapViewTest.kt new file mode 100644 index 000000000..5b8e53202 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/core/http/HeadersMapViewTest.kt @@ -0,0 +1,46 @@ +package com.openai.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test + +internal class HeadersMapViewTest { + + @Test + fun asMapReturnsCaseInsensitiveImmutableHeaderMapping() { + val headers = + Headers.builder() + .put("X-Test", "one") + .put("x-test", "two") + .put("Other", "value") + .build() + + val map = headers.asMap() + + assertThat(map["X-TEST"]).containsExactly("one", "two") + assertThat(map["other"]).containsExactly("value") + assertThat(map).hasSize(2) + } + + @Test + fun asMapDoesNotAllowMapMutation() { + val map = Headers.builder().put("X-Test", "value").build().asMap() + + assertThatThrownBy { + @Suppress("UNCHECKED_CAST") + (map as MutableMap>)["Other"] = listOf("value") + } + .isInstanceOf(UnsupportedOperationException::class.java) + } + + @Test + fun asMapDoesNotAllowValueListMutation() { + val values = Headers.builder().put("X-Test", "value").build().asMap()["X-Test"]!! + + assertThatThrownBy { + @Suppress("UNCHECKED_CAST") + (values as MutableList).add("other") + } + .isInstanceOf(UnsupportedOperationException::class.java) + } +}