io.grpc.InternalMetadata Java Examples
The following examples show how to use
io.grpc.InternalMetadata.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CronetClientStream.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
private void reportHeaders(List<Map.Entry<String, String>> headers, boolean endOfStream) { // TODO(ericgribkoff): create new utility methods to eliminate all these conversions List<String> headerList = new ArrayList<>(); for (Map.Entry<String, String> entry : headers) { headerList.add(entry.getKey()); headerList.add(entry.getValue()); } byte[][] headerValues = new byte[headerList.size()][]; for (int i = 0; i < headerList.size(); i += 2) { headerValues[i] = headerList.get(i).getBytes(Charset.forName("UTF-8")); headerValues[i + 1] = headerList.get(i + 1).getBytes(Charset.forName("UTF-8")); } Metadata metadata = InternalMetadata.newMetadata(TransportFrameUtil.toRawSerializedHeaders(headerValues)); synchronized (state.lock) { // There's no pending onReadCompleted callback so we can report trailers now. state.transportHeadersReceived(metadata, endOfStream); } }
Example #2
Source File: TransportFrameUtilTest.java From grpc-java with Apache License 2.0 | 6 votes |
@Test public void dupBinHeadersWithComma() { byte[][] http2Headers = new byte[][] { BINARY_BYTES.name().getBytes(US_ASCII), "BaS,e6,,4+,padding==".getBytes(US_ASCII), BINARY_BYTES.name().getBytes(US_ASCII), "more".getBytes(US_ASCII), BINARY_BYTES.name().getBytes(US_ASCII), "".getBytes(US_ASCII)}; byte[][] rawSerialized = TransportFrameUtil.toRawSerializedHeaders(http2Headers); Metadata recoveredHeaders = InternalMetadata.newMetadata(rawSerialized); byte[][] values = Iterables.toArray(recoveredHeaders.getAll(BINARY_BYTES), byte[].class); assertTrue(Arrays.deepEquals( new byte[][] { BaseEncoding.base64().decode("BaS"), BaseEncoding.base64().decode("e6"), BaseEncoding.base64().decode(""), BaseEncoding.base64().decode("4+"), BaseEncoding.base64().decode("padding"), BaseEncoding.base64().decode("more"), BaseEncoding.base64().decode("")}, values)); }
Example #3
Source File: NettyServerHandler.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
private void respondWithHttpError( ChannelHandlerContext ctx, int streamId, int code, Status.Code statusCode, String msg) { Metadata metadata = new Metadata(); metadata.put(InternalStatus.CODE_KEY, statusCode.toStatus()); metadata.put(InternalStatus.MESSAGE_KEY, msg); byte[][] serialized = InternalMetadata.serialize(metadata); Http2Headers headers = new DefaultHttp2Headers(true, serialized.length / 2) .status("" + code) .set(CONTENT_TYPE_HEADER, "text/plain; encoding=utf-8"); for (int i = 0; i < serialized.length; i += 2) { headers.add(new AsciiString(serialized[i], false), new AsciiString(serialized[i + 1], false)); } encoder().writeHeaders(ctx, streamId, headers, 0, false, ctx.newPromise()); ByteBuf msgBuf = ByteBufUtil.writeUtf8(ctx.alloc(), msg); encoder().writeData(ctx, streamId, msgBuf, 0, true, ctx.newPromise()); }
Example #4
Source File: NettyServerHandler.java From grpc-java with Apache License 2.0 | 6 votes |
private void respondWithHttpError( ChannelHandlerContext ctx, int streamId, int code, Status.Code statusCode, String msg) { Metadata metadata = new Metadata(); metadata.put(InternalStatus.CODE_KEY, statusCode.toStatus()); metadata.put(InternalStatus.MESSAGE_KEY, msg); byte[][] serialized = InternalMetadata.serialize(metadata); Http2Headers headers = new DefaultHttp2Headers(true, serialized.length / 2) .status("" + code) .set(CONTENT_TYPE_HEADER, "text/plain; encoding=utf-8"); for (int i = 0; i < serialized.length; i += 2) { headers.add(new AsciiString(serialized[i], false), new AsciiString(serialized[i + 1], false)); } encoder().writeHeaders(ctx, streamId, headers, 0, false, ctx.newPromise()); ByteBuf msgBuf = ByteBufUtil.writeUtf8(ctx.alloc(), msg); encoder().writeData(ctx, streamId, msgBuf, 0, true, ctx.newPromise()); }
Example #5
Source File: CronetClientStream.java From grpc-java with Apache License 2.0 | 6 votes |
private void reportHeaders(List<Map.Entry<String, String>> headers, boolean endOfStream) { // TODO(ericgribkoff): create new utility methods to eliminate all these conversions List<String> headerList = new ArrayList<>(); for (Map.Entry<String, String> entry : headers) { headerList.add(entry.getKey()); headerList.add(entry.getValue()); } byte[][] headerValues = new byte[headerList.size()][]; for (int i = 0; i < headerList.size(); i += 2) { headerValues[i] = headerList.get(i).getBytes(Charset.forName("UTF-8")); headerValues[i + 1] = headerList.get(i + 1).getBytes(Charset.forName("UTF-8")); } Metadata metadata = InternalMetadata.newMetadata(TransportFrameUtil.toRawSerializedHeaders(headerValues)); synchronized (state.lock) { // There's no pending onReadCompleted callback so we can report trailers now. state.transportHeadersReceived(metadata, endOfStream); } }
Example #6
Source File: TransportFrameUtilTest.java From grpc-nebula-java with Apache License 2.0 | 6 votes |
@Test public void dupBinHeadersWithComma() { byte[][] http2Headers = new byte[][] { BINARY_BYTES.name().getBytes(US_ASCII), "BaS,e6,,4+,padding==".getBytes(US_ASCII), BINARY_BYTES.name().getBytes(US_ASCII), "more".getBytes(US_ASCII), BINARY_BYTES.name().getBytes(US_ASCII), "".getBytes(US_ASCII)}; byte[][] rawSerialized = TransportFrameUtil.toRawSerializedHeaders(http2Headers); Metadata recoveredHeaders = InternalMetadata.newMetadata(rawSerialized); byte[][] values = Iterables.toArray(recoveredHeaders.getAll(BINARY_BYTES), byte[].class); assertTrue(Arrays.deepEquals( new byte[][] { BaseEncoding.base64().decode("BaS"), BaseEncoding.base64().decode("e6"), BaseEncoding.base64().decode(""), BaseEncoding.base64().decode("4+"), BaseEncoding.base64().decode("padding"), BaseEncoding.base64().decode("more"), BaseEncoding.base64().decode("")}, values)); }
Example #7
Source File: Utils.java From grpc-java with Apache License 2.0 | 5 votes |
public static Metadata convertTrailers(Http2Headers http2Headers) { if (http2Headers instanceof GrpcHttp2InboundHeaders) { GrpcHttp2InboundHeaders h = (GrpcHttp2InboundHeaders) http2Headers; return InternalMetadata.newMetadata(h.numHeaders(), h.namesAndValues()); } return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #8
Source File: Utils.java From grpc-java with Apache License 2.0 | 5 votes |
public static Metadata convertHeaders(Http2Headers http2Headers) { if (http2Headers instanceof GrpcHttp2InboundHeaders) { GrpcHttp2InboundHeaders h = (GrpcHttp2InboundHeaders) http2Headers; return InternalMetadata.newMetadata(h.numHeaders(), h.namesAndValues()); } return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #9
Source File: BinlogHelper.java From grpc-java with Apache License 2.0 | 5 votes |
@VisibleForTesting static MaybeTruncated<io.grpc.binarylog.v1.Metadata.Builder> createMetadataProto( Metadata metadata, int maxHeaderBytes) { checkNotNull(metadata, "metadata"); checkArgument(maxHeaderBytes >= 0, "maxHeaderBytes must be non negative"); io.grpc.binarylog.v1.Metadata.Builder metaBuilder = io.grpc.binarylog.v1.Metadata.newBuilder(); // This code is tightly coupled with Metadata's implementation byte[][] serialized = InternalMetadata.serialize(metadata); boolean truncated = false; if (serialized != null) { int curBytes = 0; for (int i = 0; i < serialized.length; i += 2) { String key = new String(serialized[i], Charsets.UTF_8); byte[] value = serialized[i + 1]; if (NEVER_INCLUDED_METADATA.contains(key)) { continue; } boolean forceInclude = ALWAYS_INCLUDED_METADATA.contains(key); int bytesAfterAdd = curBytes + key.length() + value.length; if (!forceInclude && bytesAfterAdd > maxHeaderBytes) { truncated = true; continue; } metaBuilder.addEntryBuilder() .setKey(key) .setValue(ByteString.copyFrom(value)); if (!forceInclude) { // force included keys do not count towards the size limit curBytes = bytesAfterAdd; } } } return new MaybeTruncated<>(metaBuilder, truncated); }
Example #10
Source File: InProcessTransport.java From grpc-java with Apache License 2.0 | 5 votes |
private static int metadataSize(Metadata metadata) { byte[][] serialized = InternalMetadata.serialize(metadata); if (serialized == null) { return 0; } // Calculate based on SETTINGS_MAX_HEADER_LIST_SIZE in RFC 7540 §6.5.2. We could use something // different, but it's "sane." long size = 0; for (int i = 0; i < serialized.length; i += 2) { size += 32 + serialized[i].length + serialized[i + 1].length; } size = Math.min(size, Integer.MAX_VALUE); return (int) size; }
Example #11
Source File: Http2ClientStreamTransportState.java From grpc-java with Apache License 2.0 | 5 votes |
/** * RFC 7231 says status codes are 3 digits long. * * @see <a href="https://tools.ietf.org/html/rfc7231#section-6">RFC 7231</a> */ @Override public Integer parseAsciiString(byte[] serialized) { if (serialized.length >= 3) { return (serialized[0] - '0') * 100 + (serialized[1] - '0') * 10 + (serialized[2] - '0'); } throw new NumberFormatException( "Malformed status code " + new String(serialized, InternalMetadata.US_ASCII)); }
Example #12
Source File: ArmeriaServerCall.java From armeria with Apache License 2.0 | 5 votes |
private void doSendHeaders(Metadata metadata) { checkState(!sendHeadersCalled, "sendHeaders already called"); checkState(!closeCalled, "call is closed"); if (compressor == null || !messageCompression || clientAcceptEncoding == null) { compressor = Codec.Identity.NONE; } else { final List<String> acceptedEncodingsList = ACCEPT_ENCODING_SPLITTER.splitToList(clientAcceptEncoding); if (!acceptedEncodingsList.contains(compressor.getMessageEncoding())) { // resort to using no compression. compressor = Codec.Identity.NONE; } } messageFramer.setCompressor(ForwardingCompressor.forGrpc(compressor)); ResponseHeaders headers = defaultHeaders; if (compressor != Codec.Identity.NONE || InternalMetadata.headerCount(metadata) > 0) { headers = headers.withMutations(builder -> { if (compressor != Codec.Identity.NONE) { builder.set(GrpcHeaderNames.GRPC_ENCODING, compressor.getMessageEncoding()); } MetadataUtil.fillHeaders(metadata, builder); }); } sendHeadersCalled = true; res.write(headers); }
Example #13
Source File: TransportFrameUtil.java From grpc-java with Apache License 2.0 | 5 votes |
/** * Transform the given headers to a format where only spec-compliant ASCII characters are allowed. * Binary header values are encoded by Base64 in the result. It is safe to modify the returned * array, but not to modify any of the underlying byte arrays. * * @return the interleaved keys and values. */ public static byte[][] toHttp2Headers(Metadata headers) { byte[][] serializedHeaders = InternalMetadata.serialize(headers); // TODO(carl-mastrangelo): eventually remove this once all callers are updated. if (serializedHeaders == null) { return new byte[][]{}; } int k = 0; for (int i = 0; i < serializedHeaders.length; i += 2) { byte[] key = serializedHeaders[i]; byte[] value = serializedHeaders[i + 1]; if (endsWith(key, binaryHeaderSuffixBytes)) { // Binary header. serializedHeaders[k] = key; serializedHeaders[k + 1] = InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(value).getBytes(US_ASCII); k += 2; } else { // Non-binary header. // Filter out headers that contain non-spec-compliant ASCII characters. // TODO(zhangkun83): only do such check in development mode since it's expensive if (isSpecCompliantAscii(value)) { serializedHeaders[k] = key; serializedHeaders[k + 1] = value; k += 2; } else { String keyString = new String(key, US_ASCII); logger.warning("Metadata key=" + keyString + ", value=" + Arrays.toString(value) + " contains invalid ASCII characters"); } } } // Fast path, everything worked out fine. if (k == serializedHeaders.length) { return serializedHeaders; } return Arrays.copyOfRange(serializedHeaders, 0, k); }
Example #14
Source File: TransportFrameUtilTest.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
@Test public void testToAndFromHttp2Headers() { Metadata headers = new Metadata(); headers.put(PLAIN_STRING, COMPLIANT_ASCII_STRING); headers.put(BINARY_STRING, NONCOMPLIANT_ASCII_STRING); headers.put(BINARY_STRING_WITHOUT_SUFFIX, NONCOMPLIANT_ASCII_STRING); byte[][] http2Headers = TransportFrameUtil.toHttp2Headers(headers); byte[][] rawSerialized = TransportFrameUtil.toRawSerializedHeaders(http2Headers); Metadata recoveredHeaders = InternalMetadata.newMetadata(rawSerialized); assertEquals(COMPLIANT_ASCII_STRING, recoveredHeaders.get(PLAIN_STRING)); assertEquals(NONCOMPLIANT_ASCII_STRING, recoveredHeaders.get(BINARY_STRING)); assertNull(recoveredHeaders.get(BINARY_STRING_WITHOUT_SUFFIX)); }
Example #15
Source File: TransportFrameUtil.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
/** * Transform the given headers to a format where only spec-compliant ASCII characters are allowed. * Binary header values are encoded by Base64 in the result. It is safe to modify the returned * array, but not to modify any of the underlying byte arrays. * * @return the interleaved keys and values. */ @SuppressWarnings("BetaApi") // BaseEncoding is stable in Guava 20.0 public static byte[][] toHttp2Headers(Metadata headers) { byte[][] serializedHeaders = InternalMetadata.serialize(headers); // TODO(carl-mastrangelo): eventually remove this once all callers are updated. if (serializedHeaders == null) { return new byte[][]{}; } int k = 0; for (int i = 0; i < serializedHeaders.length; i += 2) { byte[] key = serializedHeaders[i]; byte[] value = serializedHeaders[i + 1]; if (endsWith(key, binaryHeaderSuffixBytes)) { // Binary header. serializedHeaders[k] = key; serializedHeaders[k + 1] = InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(value).getBytes(US_ASCII); k += 2; } else { // Non-binary header. // Filter out headers that contain non-spec-compliant ASCII characters. // TODO(zhangkun83): only do such check in development mode since it's expensive if (isSpecCompliantAscii(value)) { serializedHeaders[k] = key; serializedHeaders[k + 1] = value; k += 2; } else { String keyString = new String(key, US_ASCII); logger.warning("Metadata key=" + keyString + ", value=" + Arrays.toString(value) + " contains invalid ASCII characters"); } } } // Fast path, everything worked out fine. if (k == serializedHeaders.length) { return serializedHeaders; } return Arrays.copyOfRange(serializedHeaders, 0, k); }
Example #16
Source File: Http2ClientStreamTransportState.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
/** * RFC 7231 says status codes are 3 digits long. * * @see <a href="https://tools.ietf.org/html/rfc7231#section-6">RFC 7231</a> */ @Override public Integer parseAsciiString(byte[] serialized) { if (serialized.length >= 3) { return (serialized[0] - '0') * 100 + (serialized[1] - '0') * 10 + (serialized[2] - '0'); } throw new NumberFormatException( "Malformed status code " + new String(serialized, InternalMetadata.US_ASCII)); }
Example #17
Source File: InProcessTransport.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
private static int metadataSize(Metadata metadata) { byte[][] serialized = InternalMetadata.serialize(metadata); if (serialized == null) { return 0; } // Calculate based on SETTINGS_MAX_HEADER_LIST_SIZE in RFC 7540 §6.5.2. We could use something // different, but it's "sane." long size = 0; for (int i = 0; i < serialized.length; i += 2) { size += 32 + serialized[i].length + serialized[i + 1].length; } size = Math.min(size, Integer.MAX_VALUE); return (int) size; }
Example #18
Source File: BinlogHelper.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
@VisibleForTesting static MaybeTruncated<io.grpc.binarylog.v1.Metadata.Builder> createMetadataProto( Metadata metadata, int maxHeaderBytes) { checkNotNull(metadata, "metadata"); checkArgument(maxHeaderBytes >= 0, "maxHeaderBytes must be non negative"); io.grpc.binarylog.v1.Metadata.Builder metaBuilder = io.grpc.binarylog.v1.Metadata.newBuilder(); // This code is tightly coupled with Metadata's implementation byte[][] serialized = InternalMetadata.serialize(metadata); boolean truncated = false; if (serialized != null) { int curBytes = 0; for (int i = 0; i < serialized.length; i += 2) { String key = new String(serialized[i], Charsets.UTF_8); byte[] value = serialized[i + 1]; if (NEVER_INCLUDED_METADATA.contains(key)) { continue; } boolean forceInclude = ALWAYS_INCLUDED_METADATA.contains(key); int bytesAfterAdd = curBytes + key.length() + value.length; if (!forceInclude && bytesAfterAdd > maxHeaderBytes) { truncated = true; continue; } metaBuilder.addEntryBuilder() .setKey(key) .setValue(ByteString.copyFrom(value)); if (!forceInclude) { // force included keys do not count towards the size limit curBytes = bytesAfterAdd; } } } return new MaybeTruncated<io.grpc.binarylog.v1.Metadata.Builder>(metaBuilder, truncated); }
Example #19
Source File: Utils.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
public static Metadata convertTrailers(Http2Headers http2Headers) { if (http2Headers instanceof GrpcHttp2InboundHeaders) { GrpcHttp2InboundHeaders h = (GrpcHttp2InboundHeaders) http2Headers; return InternalMetadata.newMetadata(h.numHeaders(), h.namesAndValues()); } return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #20
Source File: Utils.java From grpc-nebula-java with Apache License 2.0 | 5 votes |
public static Metadata convertHeaders(Http2Headers http2Headers) { if (http2Headers instanceof GrpcHttp2InboundHeaders) { GrpcHttp2InboundHeaders h = (GrpcHttp2InboundHeaders) http2Headers; return InternalMetadata.newMetadata(h.numHeaders(), h.namesAndValues()); } return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #21
Source File: TransportFrameUtilTest.java From grpc-java with Apache License 2.0 | 5 votes |
@Test public void testToAndFromHttp2Headers() { Metadata headers = new Metadata(); headers.put(PLAIN_STRING, COMPLIANT_ASCII_STRING); headers.put(BINARY_STRING, NONCOMPLIANT_ASCII_STRING); headers.put(BINARY_STRING_WITHOUT_SUFFIX, NONCOMPLIANT_ASCII_STRING); byte[][] http2Headers = TransportFrameUtil.toHttp2Headers(headers); byte[][] rawSerialized = TransportFrameUtil.toRawSerializedHeaders(http2Headers); Metadata recoveredHeaders = InternalMetadata.newMetadata(rawSerialized); assertEquals(COMPLIANT_ASCII_STRING, recoveredHeaders.get(PLAIN_STRING)); assertEquals(NONCOMPLIANT_ASCII_STRING, recoveredHeaders.get(BINARY_STRING)); assertNull(recoveredHeaders.get(BINARY_STRING_WITHOUT_SUFFIX)); }
Example #22
Source File: TransportFrameUtilTest.java From grpc-java with Apache License 2.0 | 4 votes |
private static byte[] base64Encode(byte[] input) { return InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(input).getBytes(US_ASCII); }
Example #23
Source File: Utils.java From grpc-java with Apache License 2.0 | 4 votes |
public static Metadata convertTrailers(List<Header> http2Headers) { return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #24
Source File: Utils.java From grpc-java with Apache License 2.0 | 4 votes |
public static Metadata convertHeaders(List<Header> http2Headers) { return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #25
Source File: Headers.java From grpc-java with Apache License 2.0 | 4 votes |
/** * Serializes the given headers and creates a list of OkHttp {@link Header}s to be used when * creating a stream. Since this serializes the headers, this method should be called in the * application thread context. */ public static List<Header> createRequestHeaders( Metadata headers, String defaultPath, String authority, String userAgent, boolean useGet, boolean usePlaintext) { Preconditions.checkNotNull(headers, "headers"); Preconditions.checkNotNull(defaultPath, "defaultPath"); Preconditions.checkNotNull(authority, "authority"); // Discard any application supplied duplicates of the reserved headers headers.discardAll(GrpcUtil.CONTENT_TYPE_KEY); headers.discardAll(GrpcUtil.TE_HEADER); headers.discardAll(GrpcUtil.USER_AGENT_KEY); // 7 is the number of explicit add calls below. List<Header> okhttpHeaders = new ArrayList<>(7 + InternalMetadata.headerCount(headers)); // Set GRPC-specific headers. if (usePlaintext) { okhttpHeaders.add(HTTP_SCHEME_HEADER); } else { okhttpHeaders.add(HTTPS_SCHEME_HEADER); } if (useGet) { okhttpHeaders.add(METHOD_GET_HEADER); } else { okhttpHeaders.add(METHOD_HEADER); } okhttpHeaders.add(new Header(Header.TARGET_AUTHORITY, authority)); String path = defaultPath; okhttpHeaders.add(new Header(Header.TARGET_PATH, path)); okhttpHeaders.add(new Header(GrpcUtil.USER_AGENT_KEY.name(), userAgent)); // All non-pseudo headers must come after pseudo headers. okhttpHeaders.add(CONTENT_TYPE_HEADER); okhttpHeaders.add(TE_HEADER); // Now add any application-provided headers. byte[][] serializedHeaders = TransportFrameUtil.toHttp2Headers(headers); for (int i = 0; i < serializedHeaders.length; i += 2) { ByteString key = ByteString.of(serializedHeaders[i]); String keyString = key.utf8(); if (isApplicationHeader(keyString)) { ByteString value = ByteString.of(serializedHeaders[i + 1]); okhttpHeaders.add(new Header(key, value)); } } return okhttpHeaders; }
Example #26
Source File: TransportFrameUtilTest.java From grpc-nebula-java with Apache License 2.0 | 4 votes |
private static byte[] base64Encode(byte[] input) { return InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(input).getBytes(US_ASCII); }
Example #27
Source File: Utils.java From grpc-nebula-java with Apache License 2.0 | 4 votes |
public static Metadata convertTrailers(List<Header> http2Headers) { return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #28
Source File: Utils.java From grpc-nebula-java with Apache License 2.0 | 4 votes |
public static Metadata convertHeaders(List<Header> http2Headers) { return InternalMetadata.newMetadata(convertHeadersToArray(http2Headers)); }
Example #29
Source File: Headers.java From grpc-nebula-java with Apache License 2.0 | 4 votes |
/** * Serializes the given headers and creates a list of OkHttp {@link Header}s to be used when * creating a stream. Since this serializes the headers, this method should be called in the * application thread context. */ public static List<Header> createRequestHeaders( Metadata headers, String defaultPath, String authority, String userAgent, boolean useGet) { Preconditions.checkNotNull(headers, "headers"); Preconditions.checkNotNull(defaultPath, "defaultPath"); Preconditions.checkNotNull(authority, "authority"); // Discard any application supplied duplicates of the reserved headers headers.discardAll(GrpcUtil.CONTENT_TYPE_KEY); headers.discardAll(GrpcUtil.TE_HEADER); headers.discardAll(GrpcUtil.USER_AGENT_KEY); // 7 is the number of explicit add calls below. List<Header> okhttpHeaders = new ArrayList<>(7 + InternalMetadata.headerCount(headers)); // Set GRPC-specific headers. okhttpHeaders.add(SCHEME_HEADER); if (useGet) { okhttpHeaders.add(METHOD_GET_HEADER); } else { okhttpHeaders.add(METHOD_HEADER); } okhttpHeaders.add(new Header(Header.TARGET_AUTHORITY, authority)); String path = defaultPath; okhttpHeaders.add(new Header(Header.TARGET_PATH, path)); okhttpHeaders.add(new Header(GrpcUtil.USER_AGENT_KEY.name(), userAgent)); // All non-pseudo headers must come after pseudo headers. okhttpHeaders.add(CONTENT_TYPE_HEADER); okhttpHeaders.add(TE_HEADER); // Now add any application-provided headers. byte[][] serializedHeaders = TransportFrameUtil.toHttp2Headers(headers); for (int i = 0; i < serializedHeaders.length; i += 2) { ByteString key = ByteString.of(serializedHeaders[i]); String keyString = key.utf8(); if (isApplicationHeader(keyString)) { ByteString value = ByteString.of(serializedHeaders[i + 1]); okhttpHeaders.add(new Header(key, value)); } } return okhttpHeaders; }