Skip to content

Commit bb0e6a7

Browse files
authored
Merge pull request #153 from iankurrathi/issues-152
(fix) add support for binary headers
2 parents 3169d8d + f940b47 commit bb0e6a7

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

src/main/java/org/wiremock/grpc/internal/HeaderCopyingServerInterceptor.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2024 Thomas Akehurst
2+
* Copyright (C) 2024-2025 Thomas Akehurst
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,12 @@
1616
package org.wiremock.grpc.internal;
1717

1818
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
19+
import static io.grpc.Metadata.BINARY_BYTE_MARSHALLER;
1920

2021
import com.github.tomakehurst.wiremock.http.HttpHeader;
2122
import com.github.tomakehurst.wiremock.http.HttpHeaders;
2223
import io.grpc.*;
24+
import java.util.Arrays;
2325
import java.util.List;
2426
import java.util.stream.Collectors;
2527

@@ -40,9 +42,19 @@ private static HttpHeaders buildHttpHeaders(Metadata metadata) {
4042
final List<HttpHeader> httpHeaderList =
4143
metadata.keys().stream()
4244
.map(
43-
key ->
44-
new HttpHeader(
45-
key, metadata.get(Metadata.Key.of(key, ASCII_STRING_MARSHALLER))))
45+
key -> {
46+
if (key.endsWith("-bin")) {
47+
// Use the binary marshaller for binary headers
48+
return new HttpHeader(
49+
key,
50+
Arrays.toString(
51+
metadata.get(Metadata.Key.of(key, BINARY_BYTE_MARSHALLER))));
52+
} else {
53+
// Use ASCII marshaller for normal headers
54+
return new HttpHeader(
55+
key, metadata.get(Metadata.Key.of(key, ASCII_STRING_MARSHALLER)));
56+
}
57+
})
4658
.collect(Collectors.toList());
4759
return new HttpHeaders(httpHeaderList);
4860
}

src/test/java/org/wiremock/grpc/RequestHeadersAcceptanceTest.java

+41-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2023-2024 Thomas Akehurst
2+
* Copyright (C) 2023-2025 Thomas Akehurst
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
import com.github.tomakehurst.wiremock.client.WireMock;
2525
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
2626
import io.grpc.*;
27+
import java.util.Arrays;
2728
import org.junit.jupiter.api.AfterEach;
2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.Test;
@@ -34,6 +35,7 @@
3435
public class RequestHeadersAcceptanceTest {
3536

3637
public static final String X_MY_HEADER = "x-my-Header";
38+
public static final String X_MY_HEADER_BINARY = "x-my-Header-bin";
3739
WireMockGrpcService mockGreetingService;
3840
ManagedChannel managedChannel;
3941
Channel channel;
@@ -58,8 +60,6 @@ void init() {
5860

5961
managedChannel =
6062
ManagedChannelBuilder.forAddress("localhost", wm.getPort()).usePlaintext().build();
61-
channel = ClientInterceptors.intercept(managedChannel, new HeaderAdditionInterceptor());
62-
greetingsClient = new GreetingsClient(channel);
6363
}
6464

6565
@AfterEach
@@ -69,6 +69,8 @@ void tearDown() {
6969

7070
@Test
7171
void arbitraryRequestHeaderCanBeUsedWhenMatchingAndTemplating() {
72+
channel = ClientInterceptors.intercept(managedChannel, new HeaderAdditionInterceptor());
73+
greetingsClient = new GreetingsClient(channel);
7274
wm.stubFor(
7375
post(urlPathEqualTo("/com.example.grpc.GreetingService/greeting"))
7476
.withHeader(X_MY_HEADER, equalTo("match me"))
@@ -84,6 +86,22 @@ void arbitraryRequestHeaderCanBeUsedWhenMatchingAndTemplating() {
8486
assertThat(greeting, is("The header value was: match me"));
8587
}
8688

89+
@Test
90+
void binaryRequestHeaderCanBeUsed() {
91+
channel = ClientInterceptors.intercept(managedChannel, new BinaryHeaderAdditionInterceptor());
92+
greetingsClient = new GreetingsClient(channel);
93+
wm.stubFor(
94+
post(urlPathEqualTo("/com.example.grpc.GreetingService/greeting"))
95+
.withHeader(X_MY_HEADER_BINARY, equalTo(Arrays.toString("binary match me".getBytes())))
96+
.willReturn(
97+
okJson("{\n" + " \"greeting\": \"{{request.headers.x-my-Header-bin}}\"\n" + "}")
98+
.withTransformers("response-template")));
99+
100+
String greeting = greetingsClient.greet("Whatever");
101+
102+
assertThat(greeting, is(Arrays.toString("binary match me".getBytes())));
103+
}
104+
87105
public static class HeaderAdditionInterceptor implements ClientInterceptor {
88106

89107
static final Metadata.Key<String> CUSTOM_HEADER_KEY =
@@ -103,4 +121,24 @@ public void start(Listener<RespT> responseListener, Metadata headers) {
103121
};
104122
}
105123
}
124+
125+
public static class BinaryHeaderAdditionInterceptor implements ClientInterceptor {
126+
127+
static final Metadata.Key<byte[]> CUSTOM_HEADER_KEY =
128+
Metadata.Key.of(X_MY_HEADER_BINARY, Metadata.BINARY_BYTE_MARSHALLER);
129+
130+
@Override
131+
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
132+
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
133+
return new ForwardingClientCall.SimpleForwardingClientCall<>(
134+
next.newCall(method, callOptions)) {
135+
136+
@Override
137+
public void start(Listener<RespT> responseListener, Metadata headers) {
138+
headers.put(CUSTOM_HEADER_KEY, "binary match me".getBytes());
139+
super.start(responseListener, headers);
140+
}
141+
};
142+
}
143+
}
106144
}

0 commit comments

Comments
 (0)