Skip to content

Commit 05fcd27

Browse files
Consolidate validation logic and fix MD5/structured message coexistence
Co-authored-by: gunjansingh-msft <[email protected]>
1 parent 3fa74b0 commit 05fcd27

File tree

1 file changed

+49
-51
lines changed

1 file changed

+49
-51
lines changed

sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/specialized/BlobAsyncClientBase.java

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,10 +1254,7 @@ public Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange rang
12541254
public Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponse(DownloadRetryOptions options,
12551255
BlobRequestConditions requestConditions) {
12561256
try {
1257-
return withContext(context -> downloadStreamWithResponse(null, options, requestConditions, false, context)
1258-
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1259-
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1260-
data, r.getDeserializedHeaders()))));
1257+
return withContext(context -> downloadContentWithResponseHelper(options, requestConditions, null, context));
12611258
} catch (RuntimeException ex) {
12621259
return monoError(LOGGER, ex);
12631260
}
@@ -1296,24 +1293,35 @@ public Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponse(Downlo
12961293
public Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponse(DownloadRetryOptions options,
12971294
BlobRequestConditions requestConditions, DownloadContentValidationOptions contentValidationOptions) {
12981295
try {
1299-
return withContext(context -> {
1300-
if (contentValidationOptions != null && (contentValidationOptions.isStructuredMessageValidationEnabled() || contentValidationOptions.isMd5ValidationEnabled())) {
1301-
return downloadStreamWithResponse(null, options, requestConditions, false, contentValidationOptions, context)
1302-
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1303-
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1304-
data, r.getDeserializedHeaders())));
1305-
} else {
1306-
return downloadStreamWithResponse(null, options, requestConditions, false, context)
1307-
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1308-
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1309-
data, r.getDeserializedHeaders())));
1310-
}
1311-
});
1296+
return withContext(context -> downloadContentWithResponseHelper(options, requestConditions, contentValidationOptions, context));
13121297
} catch (RuntimeException ex) {
13131298
return monoError(LOGGER, ex);
13141299
}
13151300
}
13161301

1302+
/**
1303+
* Helper method to consolidate downloadContentWithResponse logic for both overloads.
1304+
*/
1305+
private Mono<BlobDownloadContentAsyncResponse> downloadContentWithResponseHelper(DownloadRetryOptions options,
1306+
BlobRequestConditions requestConditions, DownloadContentValidationOptions contentValidationOptions, Context context) {
1307+
1308+
// Determine if content validation is needed
1309+
boolean hasContentValidation = contentValidationOptions != null &&
1310+
(contentValidationOptions.isStructuredMessageValidationEnabled() || contentValidationOptions.isMd5ValidationEnabled());
1311+
1312+
if (hasContentValidation) {
1313+
return downloadStreamWithResponse(null, options, requestConditions, false, contentValidationOptions, context)
1314+
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1315+
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1316+
data, r.getDeserializedHeaders())));
1317+
} else {
1318+
return downloadStreamWithResponse(null, options, requestConditions, false, context)
1319+
.flatMap(r -> BinaryData.fromFlux(r.getValue())
1320+
.map(data -> new BlobDownloadContentAsyncResponse(r.getRequest(), r.getStatusCode(), r.getHeaders(),
1321+
data, r.getDeserializedHeaders())));
1322+
}
1323+
}
1324+
13171325
Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, DownloadRetryOptions options,
13181326
BlobRequestConditions requestConditions, boolean getRangeContentMd5, Context context) {
13191327
BlobRange finalRange = range == null ? new BlobRange(0) : range;
@@ -1383,13 +1391,27 @@ Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, Down
13831391

13841392
Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, DownloadRetryOptions options,
13851393
BlobRequestConditions requestConditions, boolean getRangeContentMd5, DownloadContentValidationOptions contentValidationOptions, Context context) {
1394+
1395+
// Consolidate validation logic - check if any content validation is needed
1396+
boolean hasContentValidation = contentValidationOptions != null &&
1397+
(contentValidationOptions.isStructuredMessageValidationEnabled() || contentValidationOptions.isMd5ValidationEnabled());
1398+
13861399
// For backward compatibility, if no content validation options are provided, use the original method
1387-
if (contentValidationOptions == null || (!contentValidationOptions.isStructuredMessageValidationEnabled() && !contentValidationOptions.isMd5ValidationEnabled())) {
1400+
if (!hasContentValidation) {
13881401
return downloadStreamWithResponse(range, options, requestConditions, getRangeContentMd5, context);
13891402
}
13901403

13911404
BlobRange finalRange = range == null ? new BlobRange(0) : range;
1392-
Boolean getMD5 = getRangeContentMd5 || (contentValidationOptions != null && contentValidationOptions.isMd5ValidationEnabled()) ? true : null;
1405+
1406+
// Determine MD5 validation: properly consider both getRangeContentMd5 parameter and validation options
1407+
// MD5 validation is enabled if:
1408+
// 1. getRangeContentMd5 is explicitly true, OR
1409+
// 2. contentValidationOptions.isMd5ValidationEnabled() is true
1410+
Boolean getMD5 = null;
1411+
if (getRangeContentMd5 || (contentValidationOptions != null && contentValidationOptions.isMd5ValidationEnabled())) {
1412+
getMD5 = true;
1413+
}
1414+
13931415
BlobRequestConditions finalRequestConditions
13941416
= requestConditions == null ? new BlobRequestConditions() : requestConditions;
13951417
DownloadRetryOptions finalOptions = (options == null) ? new DownloadRetryOptions() : options;
@@ -1419,12 +1441,12 @@ Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, Down
14191441
finalCount = finalRange.getCount();
14201442
}
14211443

1422-
// Apply structured message decoding if enabled
1423-
Flux<ByteBuffer> decodedStream = response.getValue();
1444+
// Apply structured message decoding if enabled - this allows both MD5 and structured message to coexist
1445+
Flux<ByteBuffer> processedStream = response.getValue();
14241446
if (contentValidationOptions != null && contentValidationOptions.isStructuredMessageValidationEnabled()) {
14251447
// Use the content length from headers to determine expected length for structured message decoding
14261448
Long contentLength = blobDownloadHeaders.getContentLength();
1427-
decodedStream = StructuredMessageDecodingStream.wrapStreamIfNeeded(response.getValue(), contentLength, contentValidationOptions);
1449+
processedStream = StructuredMessageDecodingStream.wrapStreamIfNeeded(response.getValue(), contentLength, contentValidationOptions);
14281450
}
14291451

14301452
// The resume function takes throwable and offset at the destination.
@@ -1457,35 +1479,11 @@ Mono<BlobDownloadAsyncResponse> downloadStreamWithResponse(BlobRange range, Down
14571479
}
14581480
};
14591481

1460-
// Create a new response with the decoded stream
1461-
StreamResponse decodedResponse = new StreamResponse() {
1462-
@Override
1463-
public int getStatusCode() {
1464-
return response.getStatusCode();
1465-
}
1466-
1467-
@Override
1468-
public HttpHeaders getHeaders() {
1469-
return response.getHeaders();
1470-
}
1471-
1472-
@Override
1473-
public Flux<ByteBuffer> getValue() {
1474-
return decodedStream;
1475-
}
1476-
1477-
@Override
1478-
public HttpRequest getRequest() {
1479-
return response.getRequest();
1480-
}
1481-
1482-
@Override
1483-
public void close() {
1484-
response.close();
1485-
}
1486-
};
1487-
1488-
return BlobDownloadAsyncResponseConstructorProxy.create(decodedResponse, onDownloadErrorResume, finalOptions);
1482+
// Create a new response with the processed stream (which may include structured message decoding)
1483+
// Use the same approach as the original method to maintain consistency
1484+
return BlobDownloadAsyncResponseConstructorProxy.create(
1485+
new ResponseBase<>(response.getRequest(), response.getStatusCode(), response.getHeaders(),
1486+
processedStream, blobDownloadHeaders), onDownloadErrorResume, finalOptions);
14891487
});
14901488
}
14911489

0 commit comments

Comments
 (0)