Skip to content

Commit

Permalink
rename and validation (Azure#45160)
Browse files Browse the repository at this point in the history
* rename and validation

* fix
  • Loading branch information
jaschrep-msft committed Aug 13, 2024
1 parent 212d8a4 commit 00a59a3
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 15 deletions.
4 changes: 2 additions & 2 deletions sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,7 @@ ValueTask<Response<BlobDownloadStreamingResult>> Factory(long offset, bool force
return StructuredMessageDecodingStream.WrapStream(result.Value.Content, result.Value.Details.ContentLength);
}
Stream stream;
if (response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader))
if (response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
(Stream decodingStream, StructuredMessageDecodingStream.DecodedData decodedData) = StructuredMessageDecodingStream.WrapStream(
response.Value.Content, response.Value.Details.ContentLength);
Expand Down Expand Up @@ -1600,7 +1600,7 @@ ValueTask<Response<BlobDownloadStreamingResult>> Factory(long offset, bool force
validationOptions.ChecksumAlgorithm != StorageChecksumAlgorithm.None &&
validationOptions.AutoValidateChecksum &&
// structured message decoding does the validation for us
!response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader))
!response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
// safe-buffer; transactional hash download limit well below maxInt
var readDestStream = new MemoryStream((int)response.Value.Details.ContentLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ private async Task CopyToInternal(
{
CancellationHelper.ThrowIfCancellationRequested(cancellationToken);
// if structured message, this crc is validated in the decoding process. don't decode it here.
using IHasher hasher = response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader)
using IHasher hasher = response.GetRawResponse().Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader)
? null
: ContentHasher.GetHasherFromAlgorithmId(_validationAlgorithm);
using Stream rawSource = response.Value.Content;
Expand Down
4 changes: 2 additions & 2 deletions sdk/storage/Azure.Storage.Common/src/Shared/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,8 @@ internal static class AccountResources

internal static class StructuredMessage
{
public const string CrcStructuredMessageHeader = "x-ms-structured-body";
public const string CrcStructuredContentLength = "x-ms-structured-content-length";
public const string StructuredMessageHeader = "x-ms-structured-body";
public const string StructuredContentLength = "x-ms-structured-content-length";
public const string CrcStructuredMessage = "XSM/1.0; properties=crc64";
public const int DefaultSegmentContentLength = 4 * MB;
public const int MaxDownloadCrcWithHeader = 4 * MB;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,17 @@ public static ArgumentException VersionNotSupported(string paramName)
public static RequestFailedException ClientRequestIdMismatch(Response response, string echo, string original)
=> new RequestFailedException(response.Status, $"Response x-ms-client-request-id '{echo}' does not match the original expected request id, '{original}'.", null);

public static InvalidDataException StructuredMessageNotAcknowledgedGET(Response response)
=> new InvalidDataException($"Response does not acknowledge structured message was requested. Unknown data structure in response body.");

public static InvalidDataException StructuredMessageNotAcknowledgedPUT(Response response)
=> new InvalidDataException($"Response does not acknowledge structured message was sent. Unexpected data may have been persisted to storage.");

public static ArgumentException TransactionalHashingNotSupportedWithClientSideEncryption()
=> new ArgumentException("Client-side encryption and transactional hashing are not supported at the same time.");

public static InvalidDataException ExpectedStructuredMessage()
=> new InvalidDataException($"Expected {Constants.StructuredMessage.CrcStructuredMessageHeader} in response, but found none.");
=> new InvalidDataException($"Expected {Constants.StructuredMessage.StructuredMessageHeader} in response, but found none.");

public static void VerifyHttpsTokenAuth(Uri uri)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,35 @@ public override void OnReceivedResponse(HttpMessage message)
{
throw Errors.ClientRequestIdMismatch(message.Response, echo.First(), original);
}

if (message.Request.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader) &&
message.Request.Headers.Contains(Constants.StructuredMessage.StructuredContentLength))
{
AssertStructuredMessageAcknowledgedPUT(message);
}
else if (message.Request.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
AssertStructuredMessageAcknowledgedGET(message);
}
}

private static void AssertStructuredMessageAcknowledgedPUT(HttpMessage message)
{
if (!message.Response.IsError &&
!message.Response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
throw Errors.StructuredMessageNotAcknowledgedPUT(message.Response);
}
}

private static void AssertStructuredMessageAcknowledgedGET(HttpMessage message)
{
if (!message.Response.IsError &&
!(message.Response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader) &&
message.Response.Headers.Contains(Constants.StructuredMessage.StructuredContentLength)))
{
throw Errors.StructuredMessageNotAcknowledgedGET(message.Response);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static string AssertHeaderPresent(this Request request, string headerName
{
if (request.Headers.TryGetValue(headerName, out string value))
{
return headerName == Constants.StructuredMessage.CrcStructuredMessageHeader ? null : value;
return headerName == Constants.StructuredMessage.StructuredMessageHeader ? null : value;
}
StringBuilder sb = new StringBuilder()
.AppendLine($"`{headerName}` expected on request but was not found.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void AssertChecksum(Request req, string headerName)
AssertChecksum(request, "Content-MD5");
break;
case StorageChecksumAlgorithm.StorageCrc64:
AssertChecksum(request, Constants.StructuredMessage.CrcStructuredMessageHeader);
AssertChecksum(request, Constants.StructuredMessage.StructuredMessageHeader);
break;
default:
throw new Exception($"Bad {nameof(StorageChecksumAlgorithm)} provided to {nameof(GetRequestChecksumHeaderAssertion)}.");
Expand Down Expand Up @@ -302,7 +302,7 @@ void AssertChecksum(ResponseHeaders headers, string headerName)
AssertChecksum(response.Headers, "Content-MD5");
break;
case StorageChecksumAlgorithm.StorageCrc64:
AssertChecksum(response.Headers, Constants.StructuredMessage.CrcStructuredMessageHeader);
AssertChecksum(response.Headers, Constants.StructuredMessage.StructuredMessageHeader);
break;
default:
throw new Exception($"Bad {nameof(StorageChecksumAlgorithm)} provided to {nameof(GetRequestChecksumHeaderAssertion)}.");
Expand Down Expand Up @@ -1744,7 +1744,7 @@ public virtual async Task DownloadSuccessfulHashVerification(StorageChecksumAlgo
Assert.True(response.Headers.Contains("Content-MD5"));
break;
case StorageChecksumAlgorithm.StorageCrc64:
Assert.True(response.Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader));
Assert.True(response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader));
break;
default:
Assert.Fail("Test can't validate given algorithm type.");
Expand Down Expand Up @@ -1908,7 +1908,7 @@ public virtual async Task DownloadUsesDefaultClientValidationOptions(
Assert.True(response.Headers.Contains("Content-MD5"));
break;
case StorageChecksumAlgorithm.StorageCrc64:
Assert.True(response.Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader));
Assert.True(response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader));
break;
default:
Assert.Fail("Test can't validate given algorithm type.");
Expand Down Expand Up @@ -1968,7 +1968,7 @@ public virtual async Task DownloadOverwritesDefaultClientValidationOptions(
Assert.True(response.Headers.Contains("Content-MD5"));
break;
case StorageChecksumAlgorithm.StorageCrc64:
Assert.True(response.Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader));
Assert.True(response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader));
break;
default:
Assert.Fail("Test can't validate given algorithm type.");
Expand Down Expand Up @@ -2072,7 +2072,7 @@ public virtual async Task DownloadRecoversFromInterruptWithValidation(
Assert.True(response.Headers.Contains("Content-MD5"));
break;
case StorageChecksumAlgorithm.StorageCrc64:
Assert.True(response.Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader));
Assert.True(response.Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader));
break;
default:
Assert.Fail("Test can't validate given algorithm type.");
Expand Down
4 changes: 2 additions & 2 deletions sdk/storage/Azure.Storage.Files.Shares/src/ShareFileClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2409,7 +2409,7 @@ async ValueTask<Response<ShareFileDownloadInfo>> Factory(long offset, bool async
return StructuredMessageDecodingStream.WrapStream(result.Value.Content, result.Value.ContentLength);
}

if (initialResponse.GetRawResponse().Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader))
if (initialResponse.GetRawResponse().Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
(Stream decodingStream, StructuredMessageDecodingStream.DecodedData decodedData) = StructuredMessageDecodingStream.WrapStream(
initialResponse.Value.Content, initialResponse.Value.ContentLength);
Expand Down Expand Up @@ -2443,7 +2443,7 @@ async ValueTask<Response<ShareFileDownloadInfo>> Factory(long offset, bool async
validationOptions.ChecksumAlgorithm != StorageChecksumAlgorithm.None &&
validationOptions.AutoValidateChecksum &&
// structured message decoding does the validation for us
!initialResponse.GetRawResponse().Headers.Contains(Constants.StructuredMessage.CrcStructuredMessageHeader))
!initialResponse.GetRawResponse().Headers.Contains(Constants.StructuredMessage.StructuredMessageHeader))
{
// safe-buffer; transactional hash download limit well below maxInt
var readDestStream = new MemoryStream((int)initialResponse.Value.ContentLength);
Expand Down

0 comments on commit 00a59a3

Please sign in to comment.