azure_storage/
clients.rs
1use crate::{
2 authorization::{AuthorizationPolicy, StorageCredentialsInner},
3 shared_access_signature::account_sas::{
4 AccountSasPermissions, AccountSasResource, AccountSasResourceType,
5 AccountSharedAccessSignature,
6 },
7 StorageCredentials,
8};
9use azure_core::{
10 date,
11 error::{Error, ErrorKind},
12 headers::*,
13 Body, ClientOptions, Method, Pipeline, Request, Url,
14};
15use std::{ops::Deref, sync::Arc};
16use time::OffsetDateTime;
17
18pub const EMULATOR_ACCOUNT: &str = "devstoreaccount1";
21
22pub const EMULATOR_ACCOUNT_KEY: &str =
25 "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
26
27const AZURE_VERSION: HeaderValue = HeaderValue::from_static("2022-11-02");
28
29#[derive(Debug, Clone, Copy)]
30pub enum ServiceType {
31 Blob,
32 Queue,
33 Table,
35 DataLake,
36}
37
38impl ServiceType {
39 pub fn subdomain(&self) -> &str {
40 match self {
41 ServiceType::Blob => "blob",
42 ServiceType::Queue => "queue",
43 ServiceType::Table => "table",
44 ServiceType::DataLake => "dfs",
45 }
46 }
47}
48
49pub async fn shared_access_signature(
50 storage_credentials: &StorageCredentials,
51 resource: AccountSasResource,
52 resource_type: AccountSasResourceType,
53 expiry: OffsetDateTime,
54 permissions: AccountSasPermissions,
55) -> Result<AccountSharedAccessSignature, Error> {
56 let creds = storage_credentials.0.read().await;
57 let StorageCredentialsInner::Key(account, key) = creds.deref() else {
58 return Err(Error::message(
59 ErrorKind::Credential,
60 "Shared access signature generation - SAS can be generated with access_key clients",
61 ));
62 };
63
64 Ok(AccountSharedAccessSignature::new(
65 account.clone(),
66 key.clone(),
67 resource,
68 resource_type,
69 expiry,
70 permissions,
71 ))
72}
73
74pub fn finalize_request(
75 url: Url,
76 method: Method,
77 headers: Headers,
78 request_body: Option<Body>,
79) -> Result<Request, Error> {
80 let dt = OffsetDateTime::now_utc();
81 let time = date::to_rfc1123(&dt);
82 let mut request = Request::new(url, method);
83 for (k, v) in headers {
84 request.insert_header(k, v);
85 }
86 match request_body {
88 Some(ref b) => request.insert_header(CONTENT_LENGTH, b.len().to_string()),
89 None => request.insert_header(CONTENT_LENGTH, "0"),
90 };
91 request.insert_header(MS_DATE, time);
92 request.insert_header(VERSION, AZURE_VERSION);
93 if let Some(request_body) = request_body {
94 request.set_body(request_body);
95 } else {
96 request.set_body(azure_core::EMPTY_BODY);
97 };
98 Ok(request)
99}
100
101pub fn new_pipeline_from_options(
103 options: ClientOptions,
104 credentials: StorageCredentials,
105) -> Pipeline {
106 let auth_policy: Arc<dyn azure_core::Policy> = Arc::new(AuthorizationPolicy::new(credentials));
107
108 let per_retry_policies = vec![
112 Arc::new(options.timeout.clone()) as Arc<dyn azure_core::Policy>,
113 auth_policy,
114 ];
115
116 Pipeline::new(
117 option_env!("CARGO_PKG_NAME"),
118 option_env!("CARGO_PKG_VERSION"),
119 options,
120 Vec::new(),
121 per_retry_policies,
122 )
123}