in Microsoft.Azure.Cosmos/src/GatewayStoreClient.cs [269:369]
internal async ValueTask<HttpRequestMessage> PrepareRequestMessageAsync(
DocumentServiceRequest request,
Uri physicalAddress)
{
HttpMethod httpMethod = HttpMethod.Head;
if (request.OperationType == OperationType.Create ||
request.OperationType == OperationType.Upsert ||
request.OperationType == OperationType.Query ||
request.OperationType == OperationType.SqlQuery ||
request.OperationType == OperationType.Batch ||
request.OperationType == OperationType.ExecuteJavaScript ||
request.OperationType == OperationType.QueryPlan ||
(request.ResourceType == ResourceType.PartitionKey && request.OperationType == OperationType.Delete))
{
httpMethod = HttpMethod.Post;
}
else if (ChangeFeedHelper.IsChangeFeedWithQueryRequest(request.OperationType, request.Body != null))
{
// ChangeFeed with payload is a CF with query support and will
// be a query POST request.
httpMethod = HttpMethod.Post;
}
else if (request.OperationType == OperationType.Read
|| request.OperationType == OperationType.ReadFeed)
{
httpMethod = HttpMethod.Get;
}
else if ((request.OperationType == OperationType.Replace)
|| (request.OperationType == OperationType.CollectionTruncate))
{
httpMethod = HttpMethod.Put;
}
else if (request.OperationType == OperationType.Delete)
{
httpMethod = HttpMethod.Delete;
}
else if (request.OperationType == OperationType.Patch)
{
// There isn't support for PATCH method in .NetStandard 2.0
httpMethod = httpPatchMethod;
}
else
{
throw new NotImplementedException();
}
HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, physicalAddress);
// The StreamContent created below will own and dispose its underlying stream, but we may need to reuse the stream on the
// DocumentServiceRequest for future requests. Hence we need to clone without incurring copy cost, so that when
// HttpRequestMessage -> StreamContent -> MemoryStream all get disposed, the original stream will be left open.
if (request.Body != null)
{
await request.EnsureBufferedBodyAsync();
MemoryStream clonedStream = new MemoryStream();
// WriteTo doesn't use and update Position of source stream. No point in setting/restoring it.
request.CloneableBody.WriteTo(clonedStream);
clonedStream.Position = 0;
requestMessage.Content = new StreamContent(clonedStream);
}
if (request.Headers != null)
{
foreach (string key in request.Headers)
{
if (GatewayStoreClient.IsAllowedRequestHeader(key))
{
if (key.Equals(HttpConstants.HttpHeaders.ContentType, StringComparison.OrdinalIgnoreCase))
{
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(request.Headers[key]);
}
else
{
requestMessage.Headers.TryAddWithoutValidation(key, request.Headers[key]);
}
}
}
}
if (request.Properties != null)
{
foreach (KeyValuePair<string, object> property in request.Properties)
{
requestMessage.Properties.Add(property);
}
}
// add activityId
Guid activityId = System.Diagnostics.Trace.CorrelationManager.ActivityId;
Debug.Assert(activityId != Guid.Empty);
requestMessage.Headers.Add(HttpConstants.HttpHeaders.ActivityId, activityId.ToString());
string regionName = request?.RequestContext?.RegionName;
if (regionName != null)
{
requestMessage.Properties.Add(ClientSideRequestStatisticsTraceDatum.HttpRequestRegionNameProperty, regionName);
}
return requestMessage;
}