Skip to content

Commit 79a0d64

Browse files
authored
fix(http-client): always provide a fallback URL in A2ACardResolver (a2aproject#1179)
When the user-provided base URL matched the computed card URL, no fallback was attempted on 404. Now falls back to cleanBase in that case, and to the original URL otherwise. This fixes a2aproject#1178 Signed-off-by: Emmanuel Hugonnet <ehugonne@redhat.com>
1 parent c257762 commit 79a0d64

2 files changed

Lines changed: 20 additions & 17 deletions

File tree

‎http-client/src/main/java/org/a2aproject/sdk/client/http/A2ACardResolver.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ private static ResolvedUrls resolveUrls(String cleanBase, String originalBase, @
269269
Utils.validateAbsoluteUrl(cleanBase);
270270
cardUrl = Utils.buildCardUrl(cleanBase, Utils.DEFAULT_AGENT_CARD_PATH);
271271
}
272-
String fallbackUrl = isSameUrl(cardUrl, originalBase) ? null : cleanBase;
272+
String fallbackUrl = isSameUrl(cardUrl, originalBase) ? cleanBase : originalBase;
273273
return new ResolvedUrls(cardUrl, fallbackUrl);
274274
}
275275

‎http-client/src/test/java/org/a2aproject/sdk/client/http/A2ACardResolverTest.java‎

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,16 @@ public void testTenantUrl_fullTenantCardUrlProvidedAsBase_withTrailingSlash_notD
337337
}
338338

339339
@Test
340-
public void testTenantUrl_fullTenantCardUrlProvidedAsBase_noFallback() throws Exception {
341-
// No fallback when the provided URL already IS the computed card URL.
340+
public void testTenantUrl_fullTenantCardUrlProvidedAsBase_fallsBackToCleanBase() throws Exception {
341+
// When the provided URL already IS the computed card URL, fall back to the clean base.
342342
TestHttpClient client = createTestClient();
343-
client.status = 404;
343+
client.statusSequence.add(404);
344+
client.statusSequence.add(200);
344345
String tenantCardUrl = "http://example.com/.well-known/acme/agent-card.json";
345-
A2ACardResolver resolver = A2ACardResolver.builder().httpClient(client).baseUrl(tenantCardUrl).tenant("acme").build();
346-
assertThrows(A2AClientHTTPError.class, resolver::getAgentCard);
347-
assertEquals(1, client.urlsCalled.size());
346+
A2ACardResolver.builder().httpClient(client).baseUrl(tenantCardUrl).tenant("acme").build().getAgentCard();
347+
assertEquals(2, client.urlsCalled.size());
348+
assertEquals("http://example.com/.well-known/acme/agent-card.json", client.urlsCalled.get(0));
349+
assertEquals("http://example.com", client.urlsCalled.get(1));
348350
}
349351

350352
@Test
@@ -371,16 +373,15 @@ public void testGetAgentCard_httpError_fallsBackToProvidedUrl() throws Exception
371373
}
372374

373375
@Test
374-
public void testGetAgentCard_doubleSlashBaseUrl_fallbackUrlNormalized() throws Exception {
375-
// A baseUrl with a double trailing slash must not produce a double-slash fallback URL.
376+
public void testGetAgentCard_doubleSlashBaseUrl_fallbackToOriginalUrl() throws Exception {
377+
// A baseUrl with a double trailing slash falls back to the originally provided URL.
376378
TestHttpClient client = createTestClient();
377379
client.statusSequence.add(404);
378380
client.statusSequence.add(200);
379381
A2ACardResolver.builder().httpClient(client).baseUrl("http://example.com//").build().getAgentCard();
380382
assertEquals(2, client.urlsCalled.size());
381383
assertEquals("http://example.com" + AGENT_CARD_PATH, client.urlsCalled.get(0));
382-
// cleanBase strips one trailing slash from "http://example.com//", yielding "http://example.com/"
383-
assertEquals("http://example.com/", client.urlsCalled.get(1));
384+
assertEquals("http://example.com//", client.urlsCalled.get(1));
384385
}
385386

386387
@Test
@@ -448,14 +449,16 @@ public void testGetAgentCard_nonNotFound_noFallback() throws Exception {
448449
}
449450

450451
@Test
451-
public void testGetAgentCard_noFallback_whenUrlAlreadyIsCardUrl() throws Exception {
452-
// When the provided URL already equals the computed card URL, no fallback.
452+
public void testGetAgentCard_fallbackToCleanBase_whenUrlAlreadyIsCardUrl() throws Exception {
453+
// When the provided URL already equals the computed card URL, fall back to the clean base.
453454
TestHttpClient client = createTestClient();
454-
client.status = 404;
455+
client.statusSequence.add(404);
456+
client.statusSequence.add(200);
455457
String fullCardUrl = "http://example.com" + AGENT_CARD_PATH;
456-
A2ACardResolver resolver = A2ACardResolver.builder().httpClient(client).baseUrl(fullCardUrl).build();
457-
assertThrows(A2AClientHTTPError.class, resolver::getAgentCard);
458-
assertEquals(1, client.urlsCalled.size());
458+
A2ACardResolver.builder().httpClient(client).baseUrl(fullCardUrl).build().getAgentCard();
459+
assertEquals(2, client.urlsCalled.size());
460+
assertEquals(fullCardUrl, client.urlsCalled.get(0));
461+
assertEquals("http://example.com", client.urlsCalled.get(1));
459462
}
460463

461464
@Test

0 commit comments

Comments
 (0)