Skip to content

Commit db5ae86

Browse files
committed
fix: Add Content-Type header to push notification requests
Set `Content-Type: application/json` header when sending push notifications to prevent `415 Unsupported Media Type` errors. The request was previously defaulting to `application/octet-stream`. Updates tests to verify that the `Content-Type` header is always present in push notification requests, regardless of whether authentication token is included. Fixes: #486 Signed-off-by: Jeff Mesnil <[email protected]>
1 parent fcc02ec commit db5ae86

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

server-common/src/main/java/io/a2a/server/tasks/BasePushNotificationSender.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ private boolean dispatchNotification(Task task, PushNotificationConfig pushInfo)
9090
try {
9191
postBuilder
9292
.url(url)
93+
.addHeader("Content-Type", "application/json")
9394
.body(body)
9495
.post();
9596
} catch (IOException | InterruptedException e) {

server-common/src/test/java/io/a2a/server/tasks/InMemoryPushNotificationConfigStoreTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public void setUp() {
5050
private void setupBasicMockHttpResponse() throws Exception {
5151
when(mockHttpClient.createPost()).thenReturn(mockPostBuilder);
5252
when(mockPostBuilder.url(any(String.class))).thenReturn(mockPostBuilder);
53+
when(mockPostBuilder.addHeader("Content-Type", "application/json")).thenReturn(mockPostBuilder);
5354
when(mockPostBuilder.body(any(String.class))).thenReturn(mockPostBuilder);
5455
when(mockPostBuilder.post()).thenReturn(mockHttpResponse);
5556
when(mockHttpResponse.success()).thenReturn(true);
@@ -233,6 +234,7 @@ public void testSendNotificationSuccess() throws Exception {
233234
when(mockHttpClient.createPost()).thenReturn(mockPostBuilder);
234235
when(mockPostBuilder.url(any(String.class))).thenReturn(mockPostBuilder);
235236
when(mockPostBuilder.body(any(String.class))).thenReturn(mockPostBuilder);
237+
when(mockPostBuilder.addHeader("Content-Type", "application/json")).thenReturn(mockPostBuilder);
236238
when(mockPostBuilder.post()).thenReturn(mockHttpResponse);
237239
when(mockHttpResponse.success()).thenReturn(true);
238240

server-common/src/test/java/io/a2a/server/tasks/PushNotificationSenderTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.a2a.server.tasks;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
45
import static org.junit.jupiter.api.Assertions.assertTrue;
56

67
import java.io.IOException;
@@ -158,7 +159,11 @@ private void testSendNotificationWithInvalidToken(String token, String testName)
158159
// Verify that no authentication header was sent (invalid token should not add header)
159160
assertEquals(1, testHttpClient.headers.size());
160161
Map<String, String> sentHeaders = testHttpClient.headers.get(0);
161-
assertTrue(sentHeaders.isEmpty(), "No headers should be sent when token is invalid");
162+
assertFalse(sentHeaders.containsKey(A2AHeaders.X_A2A_NOTIFICATION_TOKEN),
163+
"X-A2A-Notification-Token header should not be sent when token is invalid");
164+
// Content-Type header should always be present
165+
assertTrue(sentHeaders.containsKey("Content-Type"), "Content-Type header should be present");
166+
assertEquals("application/json", sentHeaders.get("Content-Type"));
162167
}
163168

164169
private Task createSampleTask(String taskId, TaskState state) {
@@ -229,6 +234,10 @@ public void testSendNotificationWithTokenSuccess() throws InterruptedException {
229234
Map<String, String> sentHeaders = testHttpClient.headers.get(0);
230235
assertTrue(sentHeaders.containsKey(A2AHeaders.X_A2A_NOTIFICATION_TOKEN));
231236
assertEquals(config.token(), sentHeaders.get(A2AHeaders.X_A2A_NOTIFICATION_TOKEN));
237+
// Content-Type header should always be present
238+
assertTrue(sentHeaders.containsKey("Content-Type"), "Content-Type header should be present");
239+
assertEquals("application/json", sentHeaders.get("Content-Type"));
240+
232241
}
233242

234243
@Test
@@ -290,10 +299,10 @@ public void testSendNotificationHttpError() {
290299
String taskId = "task_send_http_err";
291300
Task taskData = createSampleTask(taskId, TaskState.COMPLETED);
292301
PushNotificationConfig config = createSamplePushConfig("http://notify.me/http_error", "cfg1", null);
293-
302+
294303
// Set up the configuration in the store
295304
configStore.setInfo(taskId, config);
296-
305+
297306
// Configure the test client to throw an exception
298307
testHttpClient.shouldThrowException = true;
299308

0 commit comments

Comments
 (0)