@@ -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