private void ValidateHeaders() { Log.ResponseHeadersReceived(Logger); if (HttpResponse.StatusCode != HttpStatusCode.OK) { _headerValidationError = "Bad gRPC response. Expected HTTP status code 200. Got status code: " + (int)HttpResponse.StatusCode; } else if (HttpResponse.Content.Headers.ContentType == null) { _headerValidationError = "Bad gRPC response. Response did not have a content-type header."; } else { var grpcEncoding = HttpResponse.Content.Headers.ContentType.ToString(); if (!GrpcProtocolHelpers.IsGrpcContentType(grpcEncoding)) { _headerValidationError = "Bad gRPC response. Invalid content-type value: " + grpcEncoding; } } if (_headerValidationError != null) { // Response is not valid gRPC // Clean up/cancel any pending operations DisposeCore(); throw new InvalidOperationException(_headerValidationError); } // Success! }
private HttpRequestMessage CreateHttpRequestMessage() { var message = new HttpRequestMessage(HttpMethod.Post, _uri); message.Version = new Version(2, 0); // User agent is optional but recommended message.Headers.UserAgent.Add(GrpcProtocolConstants.UserAgentHeader); // TE is required by some servers, e.g. C Core // A missing TE header results in servers aborting the gRPC call message.Headers.TE.Add(GrpcProtocolConstants.TEHeader); if (Options.Headers != null && Options.Headers.Count > 0) { foreach (var entry in Options.Headers) { // Deadline is set via CallOptions.Deadline if (entry.Key == GrpcProtocolConstants.TimeoutHeader) { continue; } var value = entry.IsBinary ? Convert.ToBase64String(entry.ValueBytes) : entry.Value; message.Headers.Add(entry.Key, value); } } if (_timeout != null) { message.Headers.Add(GrpcProtocolConstants.TimeoutHeader, GrpcProtocolHelpers.EncodeTimeout(Convert.ToInt64(_timeout.Value.TotalMilliseconds))); } return(message); }
public static Metadata BuildMetadata(HttpResponseHeaders responseHeaders) { var headers = new Metadata(); foreach (var header in responseHeaders) { // ASP.NET Core includes pseudo headers in the set of request headers // whereas, they are not in gRPC implementations. We will filter them // out when we construct the list of headers on the context. if (header.Key.StartsWith(":", StringComparison.Ordinal)) { continue; } else if (header.Key.EndsWith(Metadata.BinaryHeaderSuffix, StringComparison.OrdinalIgnoreCase)) { headers.Add(header.Key, GrpcProtocolHelpers.ParseBinaryHeader(string.Join(",", header.Value))); } else { headers.Add(header.Key, string.Join(",", header.Value)); } } return(headers); }
private HttpRequestMessage CreateHttpRequestMessage() { var message = new HttpRequestMessage(HttpMethod.Post, Method.FullName); message.Version = new Version(2, 0); message.Headers.UserAgent.Add(GrpcProtocolConstants.UserAgentHeader); if (Options.Headers != null && Options.Headers.Count > 0) { foreach (var entry in Options.Headers) { // Deadline is set via CallOptions.Deadline if (entry.Key == GrpcProtocolConstants.TimeoutHeader) { continue; } var value = entry.IsBinary ? Convert.ToBase64String(entry.ValueBytes) : entry.Value; message.Headers.Add(entry.Key, value); } } if (_timeout != null) { message.Headers.Add(GrpcProtocolConstants.TimeoutHeader, GrpcProtocolHelpers.EncodeTimeout(Convert.ToInt64(_timeout.Value.TotalMilliseconds))); } return(message); }
public Metadata GetTrailers() { if (_trailers == null) { ValidateTrailersAvailable(); _trailers = GrpcProtocolHelpers.BuildMetadata(HttpResponse.TrailingHeaders); } return(_trailers); }
public async Task <Metadata> GetResponseHeadersAsync() { try { await SendTask.ConfigureAwait(false); // The task of this method is cached so there is no need to cache the headers here return(GrpcProtocolHelpers.BuildMetadata(HttpResponse.Headers)); } catch (OperationCanceledException) { EnsureNotDisposed(); throw CreateCanceledStatusException(); } }
public Metadata GetTrailers() { using (StartScope()) { if (_trailers == null) { ValidateTrailersAvailable(); Debug.Assert(HttpResponse != null); _trailers = GrpcProtocolHelpers.BuildMetadata(HttpResponse.TrailingHeaders); } return(_trailers); } }