mirror of https://github.com/grpc/grpc-java.git
core: Emit bin-headers with unpadded encoding
Following the [grpc PROTOCOL-HTTP2 spec](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) "Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. "
This commit is contained in:
parent
cab5966415
commit
bff008fbc8
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.grpc.Metadata.AsciiMarshaller;
|
||||
import io.grpc.Metadata.Key;
|
||||
import java.nio.charset.Charset;
|
||||
|
|
@ -43,6 +44,13 @@ public final class InternalMetadata {
|
|||
@Internal
|
||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
|
||||
/**
|
||||
* An instance of base64 encoder that omits padding.
|
||||
*/
|
||||
@Internal
|
||||
public static final BaseEncoding BASE64_ENCODING_OMIT_PADDING
|
||||
= Metadata.BASE64_ENCODING_OMIT_PADDING;
|
||||
|
||||
@Internal
|
||||
public static <T> Key<T> keyOf(String name, TrustedAsciiMarshaller<T> marshaller) {
|
||||
boolean isPseudo = name != null && !name.isEmpty() && name.charAt(0) == ':';
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ public final class Metadata {
|
|||
}
|
||||
};
|
||||
|
||||
static final BaseEncoding BASE64_ENCODING_OMIT_PADDING = BaseEncoding.base64().omitPadding();
|
||||
|
||||
/**
|
||||
* Constructor called by the transport layer when it receives binary metadata. Metadata will
|
||||
* mutate the passed in array.
|
||||
|
|
@ -466,7 +468,7 @@ public final class Metadata {
|
|||
String headerName = new String(name(i), US_ASCII);
|
||||
sb.append(headerName).append('=');
|
||||
if (headerName.endsWith(BINARY_HEADER_SUFFIX)) {
|
||||
sb.append(BaseEncoding.base64().encode(value(i)));
|
||||
sb.append(BASE64_ENCODING_OMIT_PADDING.encode(value(i)));
|
||||
} else {
|
||||
String headerValue = new String(value(i), US_ASCII);
|
||||
sb.append(headerValue);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ public final class TransportFrameUtil {
|
|||
if (endsWith(key, binaryHeaderSuffixBytes)) {
|
||||
// Binary header.
|
||||
serializedHeaders[k] = key;
|
||||
serializedHeaders[k + 1] = BaseEncoding.base64().encode(value).getBytes(US_ASCII);
|
||||
serializedHeaders[k + 1]
|
||||
= InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(value).getBytes(US_ASCII);
|
||||
k += 2;
|
||||
} else {
|
||||
// Non-binary header.
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public class TransportFrameUtilTest {
|
|||
}
|
||||
|
||||
private static byte[] base64Encode(byte[] input) {
|
||||
return BaseEncoding.base64().encode(input).getBytes(US_ASCII);
|
||||
return InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(input).getBytes(US_ASCII);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@
|
|||
|
||||
package io.grpc.netty;
|
||||
|
||||
import static io.grpc.InternalMetadata.BASE64_ENCODING_OMIT_PADDING;
|
||||
import static io.netty.util.AsciiString.of;
|
||||
import static junit.framework.TestCase.assertNotSame;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.grpc.netty.GrpcHttp2HeadersUtils.GrpcHttp2InboundHeaders;
|
||||
import io.grpc.netty.GrpcHttp2HeadersUtils.GrpcHttp2RequestHeaders;
|
||||
import io.grpc.netty.GrpcHttp2HeadersUtils.GrpcHttp2ResponseHeaders;
|
||||
|
|
@ -69,7 +69,7 @@ public class GrpcHttp2InboundHeadersTest {
|
|||
|
||||
byte[] data = new byte[100];
|
||||
new Random().nextBytes(data);
|
||||
headers.add(of("foo-bin"), of(BaseEncoding.base64().encode(data)));
|
||||
headers.add(of("foo-bin"), of(BASE64_ENCODING_OMIT_PADDING.encode(data)));
|
||||
|
||||
assertEquals(1, headers.size());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue