2525import static software .amazon .awssdk .core .internal .useragent .UserAgentConstant .SPACE ;
2626
2727import java .util .Arrays ;
28+ import java .util .LinkedHashMap ;
2829import java .util .List ;
30+ import java .util .Map ;
2931import java .util .concurrent .CompletableFuture ;
3032import org .junit .Test ;
3133import org .junit .runner .RunWith ;
@@ -153,7 +155,7 @@ public void when_identityContainsProvider_authSourceIsPresent() throws Exception
153155 }
154156
155157 @ Test
156- public void when_userAgentHeaderAlreadyPresent_doesNotOverwrite () throws Exception {
158+ public void when_userAgentHeaderAlreadyPresent_AndSdkOptionAdditionalHeaderNotPresent_doesNotOverwrite () throws Exception {
157159 ApplyUserAgentStage stage = new ApplyUserAgentStage (dependencies (clientUserAgent ()));
158160
159161 String existingUserAgent = "CustomUserAgent/1.0" ;
@@ -165,13 +167,11 @@ public void when_userAgentHeaderAlreadyPresent_doesNotOverwrite() throws Excepti
165167
166168 List <String > userAgentHeaders = result .headers ().get (HEADER_USER_AGENT );
167169 assertThat (userAgentHeaders ).isNotNull ().hasSize (1 );
168- assertThat (userAgentHeaders .get (0 )).isEqualTo (existingUserAgent );
169- // Verify it does NOT contain SDK user agent values
170- assertThat (userAgentHeaders .get (0 )).doesNotContain ("aws-sdk-java" );
170+ assertThat (userAgentHeaders .get (0 )).startsWith ("aws-sdk-java" );
171171 }
172172
173173 @ Test
174- public void when_userAgentHeaderPresentButEmpty_EmptyHeaderIsPreserved () throws Exception {
174+ public void when_userAgentHeaderPresentButEmpty_sdkAddsUserAgent () throws Exception {
175175 ApplyUserAgentStage stage = new ApplyUserAgentStage (dependencies (clientUserAgent ()));
176176
177177 SdkHttpFullRequest .Builder requestWithEmptyHeader = SdkHttpFullRequest .builder ()
@@ -182,26 +182,26 @@ public void when_userAgentHeaderPresentButEmpty_EmptyHeaderIsPreserved() throws
182182
183183 List <String > userAgentHeaders = result .headers ().get (HEADER_USER_AGENT );
184184 assertThat (userAgentHeaders ).isNotNull ().hasSize (1 );
185- assertThat (userAgentHeaders .get (0 )).contains ("aws-sdk-java" );
185+ assertThat (userAgentHeaders .get (0 )).startsWith ("aws-sdk-java" );
186186 }
187187
188188 @ Test
189189 public void when_userAgentHeaderPresentButNull_sdkAddsHeader () throws Exception {
190190 ApplyUserAgentStage stage = new ApplyUserAgentStage (dependencies (clientUserAgent ()));
191191 String headerValue = null ;
192- SdkHttpFullRequest .Builder requestWithEmptyHeader = SdkHttpFullRequest .builder ()
193- .putHeader (HEADER_USER_AGENT , headerValue );
192+ SdkHttpFullRequest .Builder requestWithNullHeader = SdkHttpFullRequest .builder ()
193+ .putHeader (HEADER_USER_AGENT , headerValue );
194194
195195 RequestExecutionContext ctx = requestExecutionContext (executionAttributes (IDENTITY_WITHOUT_SOURCE ), noOpRequest ());
196- SdkHttpFullRequest .Builder result = stage .execute (requestWithEmptyHeader , ctx );
196+ SdkHttpFullRequest .Builder result = stage .execute (requestWithNullHeader , ctx );
197197
198198 List <String > userAgentHeaders = result .headers ().get (HEADER_USER_AGENT );
199199 assertThat (userAgentHeaders ).isNotNull ().hasSize (1 );
200200 assertThat (userAgentHeaders .get (0 )).startsWith ("aws-sdk-java" );
201201 }
202202
203203 @ Test
204- public void when_userAgentHeaderAbsent_addsHeader () throws Exception {
204+ public void when_userAgentHeaderAbsent_sdkAddsHeader () throws Exception {
205205 ApplyUserAgentStage stage = new ApplyUserAgentStage (dependencies (clientUserAgent ()));
206206
207207 SdkHttpFullRequest .Builder requestWithoutHeader = SdkHttpFullRequest .builder ();
@@ -215,22 +215,33 @@ public void when_userAgentHeaderAbsent_addsHeader() throws Exception {
215215 }
216216
217217 @ Test
218- public void when_multipleUserAgentHeadersPresent_doesNotOverwrite () throws Exception {
219- ApplyUserAgentStage stage = new ApplyUserAgentStage (dependencies (clientUserAgent ()));
218+ public void when_userAgentInAdditionalHeaders_doesNotOverwriteUserAgent () throws Exception {
219+ Map <String , List <String >> headerMap = new LinkedHashMap <>();
220+ headerMap .put (HEADER_USER_AGENT , Arrays .asList ("CustomAgent/1.0" , "AnotherAgent/2.0" ));
220221
221- SdkHttpFullRequest .Builder requestWithMultipleHeaders =
222- SdkHttpFullRequest .builder ()
223- .putHeader (HEADER_USER_AGENT , "CustomAgent/1.0" )
224- .appendHeader (HEADER_USER_AGENT , "AnotherAgent/2.0" );
222+ SdkClientConfiguration clientConfiguration =
223+ SdkClientConfiguration .builder ()
224+ .option (SdkClientOption .CLIENT_USER_AGENT , clientUserAgent ())
225+ .option (SdkClientOption .ADDITIONAL_HTTP_HEADERS , headerMap )
226+ .build ();
227+ HttpClientDependencies httpClientDependencies = HttpClientDependencies .builder ()
228+ .clientConfiguration (clientConfiguration )
229+ .build ();
230+
231+ ApplyUserAgentStage stage = new ApplyUserAgentStage (httpClientDependencies );
232+
233+ SdkHttpFullRequest .Builder request = SdkHttpFullRequest .builder ();
225234
226235 RequestExecutionContext ctx = requestExecutionContext (executionAttributes (IDENTITY_WITHOUT_SOURCE ), noOpRequest ());
227- SdkHttpFullRequest .Builder result = stage .execute (requestWithMultipleHeaders , ctx );
236+ SdkHttpFullRequest .Builder result = stage .execute (request , ctx );
228237
238+ // ApplyUserAgentStage should skip adding User-Agent since it's in ADDITIONAL_HTTP_HEADERS
239+ // The actual merging happens in MergeCustomHeadersStage
229240 List <String > userAgentHeaders = result .headers ().get (HEADER_USER_AGENT );
230- assertThat (userAgentHeaders ).hasSize (2 );
231- assertThat (userAgentHeaders ).containsExactly ("CustomAgent/1.0" , "AnotherAgent/2.0" );
241+ assertThat (userAgentHeaders ).isNull ();
232242 }
233243
244+
234245 private static HttpClientDependencies dependencies (String clientUserAgent ) {
235246 return dependencies (clientUserAgent , null , null );
236247 }
0 commit comments