1use crate::generated::models::{
7 BlockBlobClientCommitBlockListOptions, BlockBlobClientCommitBlockListResult,
8 BlockBlobClientGetBlockListOptions, BlockBlobClientStageBlockFromUrlOptions,
9 BlockBlobClientStageBlockFromUrlResult, BlockBlobClientStageBlockOptions,
10 BlockBlobClientStageBlockResult, BlockBlobClientUploadBlobFromUrlOptions,
11 BlockBlobClientUploadBlobFromUrlResult, BlockBlobClientUploadInternalOptions,
12 BlockBlobClientUploadInternalResult, BlockList, BlockListType, BlockLookupList,
13};
14use azure_core::{
15 base64,
16 error::CheckSuccessOptions,
17 fmt::SafeDebug,
18 http::{
19 ClientOptions, Method, NoFormat, Pipeline, PipelineSendOptions, Request, RequestContent,
20 Response, Url, UrlExt, XmlFormat,
21 },
22 time::to_rfc7231,
23 tracing, Bytes, Result,
24};
25
26#[tracing::client]
27pub struct BlockBlobClient {
28 pub(crate) endpoint: Url,
29 pub(crate) pipeline: Pipeline,
30 pub(crate) version: String,
31}
32
33#[derive(Clone, SafeDebug)]
35pub struct BlockBlobClientOptions {
36 pub client_options: ClientOptions,
38 pub version: String,
40}
41
42impl BlockBlobClient {
43 #[tracing::function("Storage.Blob.BlockBlobClient.commitBlockList")]
86 pub async fn commit_block_list(
87 &self,
88 blocks: RequestContent<BlockLookupList, XmlFormat>,
89 options: Option<BlockBlobClientCommitBlockListOptions<'_>>,
90 ) -> Result<Response<BlockBlobClientCommitBlockListResult, NoFormat>> {
91 let options = options.unwrap_or_default();
92 let ctx = options.method_options.context.to_borrowed();
93 let mut url = self.endpoint.clone();
94 let mut query_builder = url.query_builder();
95 query_builder.append_pair("comp", "blocklist");
96 if let Some(timeout) = options.timeout {
97 query_builder.set_pair("timeout", timeout.to_string());
98 }
99 query_builder.build();
100 let mut request = Request::new(url, Method::Put);
101 if let Some(transactional_content_md5) = options.transactional_content_md5 {
102 request.insert_header("content-md5", base64::encode(transactional_content_md5));
103 }
104 request.insert_header("content-type", "application/xml");
105 if let Some(if_match) = options.if_match.as_ref() {
106 request.insert_header("if-match", if_match.to_string());
107 }
108 if let Some(if_modified_since) = options.if_modified_since {
109 request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
110 }
111 if let Some(if_none_match) = options.if_none_match.as_ref() {
112 request.insert_header("if-none-match", if_none_match.to_string());
113 }
114 if let Some(if_unmodified_since) = options.if_unmodified_since {
115 request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
116 }
117 if let Some(tier) = options.tier.as_ref() {
118 request.insert_header("x-ms-access-tier", tier.to_string());
119 }
120 if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
121 request.insert_header("x-ms-blob-cache-control", blob_cache_control);
122 }
123 if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
124 request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
125 }
126 if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
127 request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
128 }
129 if let Some(blob_content_language) = options.blob_content_language.as_ref() {
130 request.insert_header("x-ms-blob-content-language", blob_content_language);
131 }
132 if let Some(blob_content_md5) = options.blob_content_md5 {
133 request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
134 }
135 if let Some(blob_content_type) = options.blob_content_type.as_ref() {
136 request.insert_header("x-ms-blob-content-type", blob_content_type);
137 }
138 if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
139 request.insert_header(
140 "x-ms-content-crc64",
141 base64::encode(transactional_content_crc64),
142 );
143 }
144 if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
145 request.insert_header(
146 "x-ms-encryption-algorithm",
147 encryption_algorithm.to_string(),
148 );
149 }
150 if let Some(encryption_key) = options.encryption_key.as_ref() {
151 request.insert_header("x-ms-encryption-key", encryption_key);
152 }
153 if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
154 request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
155 }
156 if let Some(encryption_scope) = options.encryption_scope.as_ref() {
157 request.insert_header("x-ms-encryption-scope", encryption_scope);
158 }
159 if let Some(if_tags) = options.if_tags.as_ref() {
160 request.insert_header("x-ms-if-tags", if_tags);
161 }
162 if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
163 request.insert_header(
164 "x-ms-immutability-policy-mode",
165 immutability_policy_mode.to_string(),
166 );
167 }
168 if let Some(immutability_policy_expiry) = options.immutability_policy_expiry {
169 request.insert_header(
170 "x-ms-immutability-policy-until-date",
171 to_rfc7231(&immutability_policy_expiry),
172 );
173 }
174 if let Some(lease_id) = options.lease_id.as_ref() {
175 request.insert_header("x-ms-lease-id", lease_id);
176 }
177 if let Some(legal_hold) = options.legal_hold {
178 request.insert_header("x-ms-legal-hold", legal_hold.to_string());
179 }
180 if let Some(metadata) = options.metadata.as_ref() {
181 for (k, v) in metadata {
182 request.insert_header(format!("x-ms-meta-{k}"), v);
183 }
184 }
185 if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
186 request.insert_header("x-ms-tags", blob_tags_string);
187 }
188 request.insert_header("x-ms-version", &self.version);
189 request.set_body(blocks);
190 let rsp = self
191 .pipeline
192 .send(
193 &ctx,
194 &mut request,
195 Some(PipelineSendOptions {
196 check_success: CheckSuccessOptions {
197 success_codes: &[201],
198 },
199 ..Default::default()
200 }),
201 )
202 .await?;
203 Ok(rsp.into())
204 }
205
206 #[tracing::function("Storage.Blob.BlockBlobClient.getBlockList")]
245 pub async fn get_block_list(
246 &self,
247 list_type: BlockListType,
248 options: Option<BlockBlobClientGetBlockListOptions<'_>>,
249 ) -> Result<Response<BlockList, XmlFormat>> {
250 let options = options.unwrap_or_default();
251 let ctx = options.method_options.context.to_borrowed();
252 let mut url = self.endpoint.clone();
253 let mut query_builder = url.query_builder();
254 query_builder.append_pair("comp", "blocklist");
255 query_builder.set_pair("blocklisttype", list_type.as_ref());
256 if let Some(snapshot) = options.snapshot.as_ref() {
257 query_builder.set_pair("snapshot", snapshot);
258 }
259 if let Some(timeout) = options.timeout {
260 query_builder.set_pair("timeout", timeout.to_string());
261 }
262 query_builder.build();
263 let mut request = Request::new(url, Method::Get);
264 request.insert_header("accept", "application/xml");
265 if let Some(if_tags) = options.if_tags.as_ref() {
266 request.insert_header("x-ms-if-tags", if_tags);
267 }
268 if let Some(lease_id) = options.lease_id.as_ref() {
269 request.insert_header("x-ms-lease-id", lease_id);
270 }
271 request.insert_header("x-ms-version", &self.version);
272 let rsp = self
273 .pipeline
274 .send(
275 &ctx,
276 &mut request,
277 Some(PipelineSendOptions {
278 check_success: CheckSuccessOptions {
279 success_codes: &[200],
280 },
281 ..Default::default()
282 }),
283 )
284 .await?;
285 Ok(rsp.into())
286 }
287
288 #[tracing::function("Storage.Blob.BlockBlobClient.stageBlock")]
332 pub async fn stage_block(
333 &self,
334 block_id: &[u8],
335 content_length: u64,
336 body: RequestContent<Bytes, NoFormat>,
337 options: Option<BlockBlobClientStageBlockOptions<'_>>,
338 ) -> Result<Response<BlockBlobClientStageBlockResult, NoFormat>> {
339 let options = options.unwrap_or_default();
340 let ctx = options.method_options.context.to_borrowed();
341 let mut url = self.endpoint.clone();
342 let mut query_builder = url.query_builder();
343 query_builder.append_pair("comp", "block");
344 query_builder.set_pair("blockid", base64::encode(block_id));
345 if let Some(timeout) = options.timeout {
346 query_builder.set_pair("timeout", timeout.to_string());
347 }
348 query_builder.build();
349 let mut request = Request::new(url, Method::Put);
350 request.insert_header("content-length", content_length.to_string());
351 if let Some(transactional_content_md5) = options.transactional_content_md5 {
352 request.insert_header("content-md5", base64::encode(transactional_content_md5));
353 }
354 request.insert_header("content-type", "application/octet-stream");
355 if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
356 request.insert_header(
357 "x-ms-content-crc64",
358 base64::encode(transactional_content_crc64),
359 );
360 }
361 if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
362 request.insert_header(
363 "x-ms-encryption-algorithm",
364 encryption_algorithm.to_string(),
365 );
366 }
367 if let Some(encryption_key) = options.encryption_key.as_ref() {
368 request.insert_header("x-ms-encryption-key", encryption_key);
369 }
370 if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
371 request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
372 }
373 if let Some(encryption_scope) = options.encryption_scope.as_ref() {
374 request.insert_header("x-ms-encryption-scope", encryption_scope);
375 }
376 if let Some(lease_id) = options.lease_id.as_ref() {
377 request.insert_header("x-ms-lease-id", lease_id);
378 }
379 request.insert_header("x-ms-version", &self.version);
380 request.set_body(body);
381 let rsp = self
382 .pipeline
383 .send(
384 &ctx,
385 &mut request,
386 Some(PipelineSendOptions {
387 check_success: CheckSuccessOptions {
388 success_codes: &[201],
389 },
390 ..Default::default()
391 }),
392 )
393 .await?;
394 Ok(rsp.into())
395 }
396
397 #[tracing::function("Storage.Blob.BlockBlobClient.stageBlockFromUrl")]
441 pub async fn stage_block_from_url(
442 &self,
443 block_id: &[u8],
444 content_length: u64,
445 source_url: String,
446 options: Option<BlockBlobClientStageBlockFromUrlOptions<'_>>,
447 ) -> Result<Response<BlockBlobClientStageBlockFromUrlResult, NoFormat>> {
448 let options = options.unwrap_or_default();
449 let ctx = options.method_options.context.to_borrowed();
450 let mut url = self.endpoint.clone();
451 let mut query_builder = url.query_builder();
452 query_builder.append_pair("comp", "block");
453 query_builder.set_pair("blockid", base64::encode(block_id));
454 if let Some(timeout) = options.timeout {
455 query_builder.set_pair("timeout", timeout.to_string());
456 }
457 query_builder.build();
458 let mut request = Request::new(url, Method::Put);
459 request.insert_header("content-length", content_length.to_string());
460 request.insert_header("x-ms-copy-source", source_url);
461 if let Some(copy_source_authorization) = options.copy_source_authorization.as_ref() {
462 request.insert_header("x-ms-copy-source-authorization", copy_source_authorization);
463 }
464 if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
465 request.insert_header(
466 "x-ms-encryption-algorithm",
467 encryption_algorithm.to_string(),
468 );
469 }
470 if let Some(encryption_key) = options.encryption_key.as_ref() {
471 request.insert_header("x-ms-encryption-key", encryption_key);
472 }
473 if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
474 request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
475 }
476 if let Some(encryption_scope) = options.encryption_scope.as_ref() {
477 request.insert_header("x-ms-encryption-scope", encryption_scope);
478 }
479 if let Some(file_request_intent) = options.file_request_intent.as_ref() {
480 request.insert_header("x-ms-file-request-intent", file_request_intent.to_string());
481 }
482 if let Some(lease_id) = options.lease_id.as_ref() {
483 request.insert_header("x-ms-lease-id", lease_id);
484 }
485 if let Some(source_content_crc64) = options.source_content_crc64 {
486 request.insert_header(
487 "x-ms-source-content-crc64",
488 base64::encode(source_content_crc64),
489 );
490 }
491 if let Some(source_content_md5) = options.source_content_md5 {
492 request.insert_header(
493 "x-ms-source-content-md5",
494 base64::encode(source_content_md5),
495 );
496 }
497 if let Some(source_encryption_algorithm) = options.source_encryption_algorithm.as_ref() {
498 request.insert_header(
499 "x-ms-source-encryption-algorithm",
500 source_encryption_algorithm.to_string(),
501 );
502 }
503 if let Some(source_encryption_key) = options.source_encryption_key.as_ref() {
504 request.insert_header("x-ms-source-encryption-key", source_encryption_key);
505 }
506 if let Some(source_encryption_key_sha256) = options.source_encryption_key_sha256.as_ref() {
507 request.insert_header(
508 "x-ms-source-encryption-key-sha256",
509 source_encryption_key_sha256,
510 );
511 }
512 if let Some(source_if_match) = options.source_if_match.as_ref() {
513 request.insert_header("x-ms-source-if-match", source_if_match.to_string());
514 }
515 if let Some(source_if_modified_since) = options.source_if_modified_since {
516 request.insert_header(
517 "x-ms-source-if-modified-since",
518 to_rfc7231(&source_if_modified_since),
519 );
520 }
521 if let Some(source_if_none_match) = options.source_if_none_match.as_ref() {
522 request.insert_header(
523 "x-ms-source-if-none-match",
524 source_if_none_match.to_string(),
525 );
526 }
527 if let Some(source_if_unmodified_since) = options.source_if_unmodified_since {
528 request.insert_header(
529 "x-ms-source-if-unmodified-since",
530 to_rfc7231(&source_if_unmodified_since),
531 );
532 }
533 if let Some(source_range) = options.source_range.as_ref() {
534 request.insert_header("x-ms-source-range", source_range.to_string());
535 }
536 request.insert_header("x-ms-version", &self.version);
537 let rsp = self
538 .pipeline
539 .send(
540 &ctx,
541 &mut request,
542 Some(PipelineSendOptions {
543 check_success: CheckSuccessOptions {
544 success_codes: &[201],
545 },
546 ..Default::default()
547 }),
548 )
549 .await?;
550 Ok(rsp.into())
551 }
552
553 #[tracing::function("Storage.Blob.BlockBlobClient.uploadBlobFromUrl")]
597 pub async fn upload_blob_from_url(
598 &self,
599 copy_source: String,
600 options: Option<BlockBlobClientUploadBlobFromUrlOptions<'_>>,
601 ) -> Result<Response<BlockBlobClientUploadBlobFromUrlResult, NoFormat>> {
602 let options = options.unwrap_or_default();
603 let ctx = options.method_options.context.to_borrowed();
604 let mut url = self.endpoint.clone();
605 let mut query_builder = url.query_builder();
606 if let Some(timeout) = options.timeout {
607 query_builder.set_pair("timeout", timeout.to_string());
608 }
609 query_builder.build();
610 let mut request = Request::new(url, Method::Put);
611 request.insert_header("content-length", "0");
612 if let Some(transactional_content_md5) = options.transactional_content_md5 {
613 request.insert_header("content-md5", base64::encode(transactional_content_md5));
614 }
615 if let Some(if_match) = options.if_match.as_ref() {
616 request.insert_header("if-match", if_match.to_string());
617 }
618 if let Some(if_modified_since) = options.if_modified_since {
619 request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
620 }
621 if let Some(if_none_match) = options.if_none_match.as_ref() {
622 request.insert_header("if-none-match", if_none_match.to_string());
623 }
624 if let Some(if_unmodified_since) = options.if_unmodified_since {
625 request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
626 }
627 if let Some(tier) = options.tier.as_ref() {
628 request.insert_header("x-ms-access-tier", tier.to_string());
629 }
630 if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
631 request.insert_header("x-ms-blob-cache-control", blob_cache_control);
632 }
633 if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
634 request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
635 }
636 if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
637 request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
638 }
639 if let Some(blob_content_language) = options.blob_content_language.as_ref() {
640 request.insert_header("x-ms-blob-content-language", blob_content_language);
641 }
642 if let Some(blob_content_md5) = options.blob_content_md5 {
643 request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
644 }
645 if let Some(blob_content_type) = options.blob_content_type.as_ref() {
646 request.insert_header("x-ms-blob-content-type", blob_content_type);
647 }
648 request.insert_header("x-ms-blob-type", "BlockBlob");
649 request.insert_header("x-ms-copy-source", copy_source);
650 if let Some(copy_source_authorization) = options.copy_source_authorization.as_ref() {
651 request.insert_header("x-ms-copy-source-authorization", copy_source_authorization);
652 }
653 if let Some(copy_source_blob_properties) = options.copy_source_blob_properties {
654 request.insert_header(
655 "x-ms-copy-source-blob-properties",
656 copy_source_blob_properties.to_string(),
657 );
658 }
659 if let Some(copy_source_tags) = options.copy_source_tags.as_ref() {
660 request.insert_header("x-ms-copy-source-tag-option", copy_source_tags.to_string());
661 }
662 if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
663 request.insert_header(
664 "x-ms-encryption-algorithm",
665 encryption_algorithm.to_string(),
666 );
667 }
668 if let Some(encryption_key) = options.encryption_key.as_ref() {
669 request.insert_header("x-ms-encryption-key", encryption_key);
670 }
671 if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
672 request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
673 }
674 if let Some(encryption_scope) = options.encryption_scope.as_ref() {
675 request.insert_header("x-ms-encryption-scope", encryption_scope);
676 }
677 if let Some(file_request_intent) = options.file_request_intent.as_ref() {
678 request.insert_header("x-ms-file-request-intent", file_request_intent.to_string());
679 }
680 if let Some(if_tags) = options.if_tags.as_ref() {
681 request.insert_header("x-ms-if-tags", if_tags);
682 }
683 if let Some(lease_id) = options.lease_id.as_ref() {
684 request.insert_header("x-ms-lease-id", lease_id);
685 }
686 if let Some(metadata) = options.metadata.as_ref() {
687 for (k, v) in metadata {
688 request.insert_header(format!("x-ms-meta-{k}"), v);
689 }
690 }
691 if let Some(source_content_md5) = options.source_content_md5 {
692 request.insert_header(
693 "x-ms-source-content-md5",
694 base64::encode(source_content_md5),
695 );
696 }
697 if let Some(source_encryption_algorithm) = options.source_encryption_algorithm.as_ref() {
698 request.insert_header(
699 "x-ms-source-encryption-algorithm",
700 source_encryption_algorithm.to_string(),
701 );
702 }
703 if let Some(source_encryption_key) = options.source_encryption_key.as_ref() {
704 request.insert_header("x-ms-source-encryption-key", source_encryption_key);
705 }
706 if let Some(source_encryption_key_sha256) = options.source_encryption_key_sha256.as_ref() {
707 request.insert_header(
708 "x-ms-source-encryption-key-sha256",
709 source_encryption_key_sha256,
710 );
711 }
712 if let Some(source_if_match) = options.source_if_match.as_ref() {
713 request.insert_header("x-ms-source-if-match", source_if_match.to_string());
714 }
715 if let Some(source_if_modified_since) = options.source_if_modified_since {
716 request.insert_header(
717 "x-ms-source-if-modified-since",
718 to_rfc7231(&source_if_modified_since),
719 );
720 }
721 if let Some(source_if_none_match) = options.source_if_none_match.as_ref() {
722 request.insert_header(
723 "x-ms-source-if-none-match",
724 source_if_none_match.to_string(),
725 );
726 }
727 if let Some(source_if_tags) = options.source_if_tags.as_ref() {
728 request.insert_header("x-ms-source-if-tags", source_if_tags);
729 }
730 if let Some(source_if_unmodified_since) = options.source_if_unmodified_since {
731 request.insert_header(
732 "x-ms-source-if-unmodified-since",
733 to_rfc7231(&source_if_unmodified_since),
734 );
735 }
736 if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
737 request.insert_header("x-ms-tags", blob_tags_string);
738 }
739 request.insert_header("x-ms-version", &self.version);
740 let rsp = self
741 .pipeline
742 .send(
743 &ctx,
744 &mut request,
745 Some(PipelineSendOptions {
746 check_success: CheckSuccessOptions {
747 success_codes: &[201],
748 },
749 ..Default::default()
750 }),
751 )
752 .await?;
753 Ok(rsp.into())
754 }
755
756 #[tracing::function("Storage.Blob.BlockBlobClient.upload")]
801 pub(crate) async fn upload_internal(
802 &self,
803 body: RequestContent<Bytes, NoFormat>,
804 content_length: u64,
805 options: Option<BlockBlobClientUploadInternalOptions<'_>>,
806 ) -> Result<Response<BlockBlobClientUploadInternalResult, NoFormat>> {
807 let options = options.unwrap_or_default();
808 let ctx = options.method_options.context.to_borrowed();
809 let mut url = self.endpoint.clone();
810 let mut query_builder = url.query_builder();
811 if let Some(timeout) = options.timeout {
812 query_builder.set_pair("timeout", timeout.to_string());
813 }
814 query_builder.build();
815 let mut request = Request::new(url, Method::Put);
816 request.insert_header("content-length", content_length.to_string());
817 if let Some(transactional_content_md5) = options.transactional_content_md5 {
818 request.insert_header("content-md5", base64::encode(transactional_content_md5));
819 }
820 request.insert_header("content-type", "application/octet-stream");
821 if let Some(if_match) = options.if_match.as_ref() {
822 request.insert_header("if-match", if_match.to_string());
823 }
824 if let Some(if_modified_since) = options.if_modified_since {
825 request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
826 }
827 if let Some(if_none_match) = options.if_none_match.as_ref() {
828 request.insert_header("if-none-match", if_none_match.to_string());
829 }
830 if let Some(if_unmodified_since) = options.if_unmodified_since {
831 request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
832 }
833 if let Some(tier) = options.tier.as_ref() {
834 request.insert_header("x-ms-access-tier", tier.to_string());
835 }
836 if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
837 request.insert_header("x-ms-blob-cache-control", blob_cache_control);
838 }
839 if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
840 request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
841 }
842 if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
843 request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
844 }
845 if let Some(blob_content_language) = options.blob_content_language.as_ref() {
846 request.insert_header("x-ms-blob-content-language", blob_content_language);
847 }
848 if let Some(blob_content_md5) = options.blob_content_md5 {
849 request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
850 }
851 if let Some(blob_content_type) = options.blob_content_type.as_ref() {
852 request.insert_header("x-ms-blob-content-type", blob_content_type);
853 }
854 request.insert_header("x-ms-blob-type", "BlockBlob");
855 if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
856 request.insert_header(
857 "x-ms-content-crc64",
858 base64::encode(transactional_content_crc64),
859 );
860 }
861 if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
862 request.insert_header(
863 "x-ms-encryption-algorithm",
864 encryption_algorithm.to_string(),
865 );
866 }
867 if let Some(encryption_key) = options.encryption_key.as_ref() {
868 request.insert_header("x-ms-encryption-key", encryption_key);
869 }
870 if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
871 request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
872 }
873 if let Some(encryption_scope) = options.encryption_scope.as_ref() {
874 request.insert_header("x-ms-encryption-scope", encryption_scope);
875 }
876 if let Some(if_tags) = options.if_tags.as_ref() {
877 request.insert_header("x-ms-if-tags", if_tags);
878 }
879 if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
880 request.insert_header(
881 "x-ms-immutability-policy-mode",
882 immutability_policy_mode.to_string(),
883 );
884 }
885 if let Some(immutability_policy_expiry) = options.immutability_policy_expiry {
886 request.insert_header(
887 "x-ms-immutability-policy-until-date",
888 to_rfc7231(&immutability_policy_expiry),
889 );
890 }
891 if let Some(lease_id) = options.lease_id.as_ref() {
892 request.insert_header("x-ms-lease-id", lease_id);
893 }
894 if let Some(legal_hold) = options.legal_hold {
895 request.insert_header("x-ms-legal-hold", legal_hold.to_string());
896 }
897 if let Some(metadata) = options.metadata.as_ref() {
898 for (k, v) in metadata {
899 request.insert_header(format!("x-ms-meta-{k}"), v);
900 }
901 }
902 if let Some(structured_body_type) = options.structured_body_type.as_ref() {
903 request.insert_header("x-ms-structured-body", structured_body_type);
904 }
905 if let Some(structured_content_length) = options.structured_content_length {
906 request.insert_header(
907 "x-ms-structured-content-length",
908 structured_content_length.to_string(),
909 );
910 }
911 if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
912 request.insert_header("x-ms-tags", blob_tags_string);
913 }
914 request.insert_header("x-ms-version", &self.version);
915 request.set_body(body);
916 let rsp = self
917 .pipeline
918 .send(
919 &ctx,
920 &mut request,
921 Some(PipelineSendOptions {
922 check_success: CheckSuccessOptions {
923 success_codes: &[201],
924 },
925 ..Default::default()
926 }),
927 )
928 .await?;
929 Ok(rsp.into())
930 }
931}
932
933pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
935
936impl Default for BlockBlobClientOptions {
937 fn default() -> Self {
938 Self {
939 client_options: ClientOptions::default(),
940 version: String::from(DEFAULT_VERSION),
941 }
942 }
943}