Added support for Azure storage emulator
This commit is contained in:
Родитель
1e5be2a780
Коммит
2218a66f78
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "azure_sdk_for_rust"
|
name = "azure_sdk_for_rust"
|
||||||
version = "0.10.0"
|
version = "0.10.1"
|
||||||
description = "Rust wrappers around Microsoft Azure REST APIs"
|
description = "Rust wrappers around Microsoft Azure REST APIs"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = ["Francesco Cogno <francesco.cogno@outlook.com>", "Max Gortman <mgortman@microsoft.com>", "Dong Liu <doliu@microsoft.com>"]
|
authors = ["Francesco Cogno <francesco.cogno@outlook.com>", "Max Gortman <mgortman@microsoft.com>", "Dong Liu <doliu@microsoft.com>"]
|
||||||
|
@ -41,3 +41,4 @@ tokio-core = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test_e2e = []
|
test_e2e = []
|
||||||
|
emulator = []
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
extern crate azure_sdk_for_rust;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate env_logger;
|
||||||
|
extern crate futures;
|
||||||
|
extern crate hyper;
|
||||||
|
extern crate hyper_tls;
|
||||||
|
extern crate log;
|
||||||
|
extern crate md5;
|
||||||
|
extern crate tokio_core;
|
||||||
|
|
||||||
|
use azure_sdk_for_rust::prelude::*;
|
||||||
|
use azure_sdk_for_rust::storage::container::PublicAccess;
|
||||||
|
use futures::future::*;
|
||||||
|
use std::error::Error;
|
||||||
|
use tokio_core::reactor::Core;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
env_logger::init();
|
||||||
|
code().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We run a separate method to use the elegant quotation mark operator.
|
||||||
|
// A series of unwrap(), unwrap() would have achieved the same result.
|
||||||
|
fn code() -> Result<(), Box<Error>> {
|
||||||
|
let mut core = Core::new()?;
|
||||||
|
|
||||||
|
// this will only work with the emulator
|
||||||
|
let client = Client::new("", "")?;
|
||||||
|
|
||||||
|
// create container
|
||||||
|
let future = client
|
||||||
|
.create_container()
|
||||||
|
.with_container_name("emulcont")
|
||||||
|
.with_public_access(PublicAccess::None)
|
||||||
|
.finalize();
|
||||||
|
core.run(future.map(|res| println!("{:?}", res)))?;
|
||||||
|
|
||||||
|
//let data = b"something";
|
||||||
|
|
||||||
|
//// this is not mandatory but it helps preventing
|
||||||
|
//// spurious data to be uploaded.
|
||||||
|
//let digest = md5::compute(&data[..]);
|
||||||
|
|
||||||
|
//let future = client
|
||||||
|
// .put_block_blob()
|
||||||
|
// .with_container_name(&container_name)
|
||||||
|
// .with_blob_name("blob0.txt")
|
||||||
|
// .with_content_type("text/plain")
|
||||||
|
// .with_body(&data[..])
|
||||||
|
// .with_content_md5(&digest[..])
|
||||||
|
// .finalize();
|
||||||
|
//core.run(future.map(|res| println!("{:?}", res)))?;
|
||||||
|
|
||||||
|
//let future = client
|
||||||
|
// .put_block_blob()
|
||||||
|
// .with_container_name(&container_name)
|
||||||
|
// .with_blob_name("blob1.txt")
|
||||||
|
// .with_content_type("text/plain")
|
||||||
|
// .with_body(&data[..])
|
||||||
|
// .with_content_md5(&digest[..])
|
||||||
|
// .finalize();
|
||||||
|
//core.run(future.map(|res| println!("{:?}", res)))?;
|
||||||
|
|
||||||
|
//let future = client
|
||||||
|
// .put_block_blob()
|
||||||
|
// .with_container_name(&container_name)
|
||||||
|
// .with_blob_name("blob2.txt")
|
||||||
|
// .with_content_type("text/plain")
|
||||||
|
// .with_body(&data[..])
|
||||||
|
// .with_content_md5(&digest[..])
|
||||||
|
// .finalize();
|
||||||
|
//core.run(future.map(|res| println!("{:?}", res)))?;
|
||||||
|
|
||||||
|
//let future = client
|
||||||
|
// .list_blobs()
|
||||||
|
// .with_container_name(&container_name)
|
||||||
|
// .with_include_metadata()
|
||||||
|
// .finalize();
|
||||||
|
//core.run(future.map(|res| println!("{:?}", res)))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -119,10 +119,12 @@ pub fn find_subnodes<'a>(node: &'a Element, subnode: &str) -> Vec<&'a Element> {
|
||||||
.filter(|x| match **x {
|
.filter(|x| match **x {
|
||||||
ElementNode(ref mynode) => mynode.name == subnode,
|
ElementNode(ref mynode) => mynode.name == subnode,
|
||||||
_ => false,
|
_ => false,
|
||||||
}).map(|x| match *x {
|
})
|
||||||
|
.map(|x| match *x {
|
||||||
ElementNode(ref mynode) => mynode,
|
ElementNode(ref mynode) => mynode,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}).collect::<Vec<_>>()
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -224,7 +224,8 @@ impl Blob {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
static CL: header::HeaderName = header::CONTENT_LENGTH;
|
static CL: header::HeaderName = header::CONTENT_LENGTH;
|
||||||
AzureError::HeaderNotFound(CL.as_str().to_owned())
|
AzureError::HeaderNotFound(CL.as_str().to_owned())
|
||||||
})?.to_str()?
|
})?
|
||||||
|
.to_str()?
|
||||||
.parse::<u64>()?;
|
.parse::<u64>()?;
|
||||||
trace!("content_length == {:?}", content_length);
|
trace!("content_length == {:?}", content_length);
|
||||||
|
|
||||||
|
@ -370,15 +371,15 @@ where
|
||||||
{
|
{
|
||||||
match params {
|
match params {
|
||||||
Some(ref params) => format!(
|
Some(ref params) => format!(
|
||||||
"https://{}.blob.core.windows.net/{}/{}?{}",
|
"{}/{}/{}?{}",
|
||||||
t.client().account(),
|
t.client().blob_uri(),
|
||||||
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
||||||
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET),
|
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET),
|
||||||
params
|
params
|
||||||
),
|
),
|
||||||
None => format!(
|
None => format!(
|
||||||
"https://{}.blob.core.windows.net/{}/{}",
|
"{}/{}/{}",
|
||||||
t.client().account(),
|
t.client().blob_uri(),
|
||||||
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
||||||
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET)
|
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET)
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,10 +6,6 @@ use hyper::{self, Method};
|
||||||
use hyper_tls;
|
use hyper_tls;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
// Can be variant for different cloud environment
|
|
||||||
const SERVICE_SUFFIX_BLOB: &str = ".blob.core.windows.net";
|
|
||||||
const SERVICE_SUFFIX_TABLE: &str = ".table.core.windows.net";
|
|
||||||
|
|
||||||
pub trait Blob {
|
pub trait Blob {
|
||||||
fn list_blobs<'a>(&'a self) -> blob::requests::ListBlobBuilder<'a, No>;
|
fn list_blobs<'a>(&'a self) -> blob::requests::ListBlobBuilder<'a, No>;
|
||||||
fn get_blob<'a>(&'a self) -> blob::requests::GetBlobBuilder<'a, No, No>;
|
fn get_blob<'a>(&'a self) -> blob::requests::GetBlobBuilder<'a, No, No>;
|
||||||
|
@ -50,6 +46,8 @@ pub struct Client {
|
||||||
account: String,
|
account: String,
|
||||||
key: String,
|
key: String,
|
||||||
hc: hyper::Client<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>,
|
hc: hyper::Client<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>,
|
||||||
|
blob_uri: String,
|
||||||
|
table_uri: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Blob for Client {
|
impl Blob for Client {
|
||||||
|
@ -178,11 +176,23 @@ impl Client {
|
||||||
|
|
||||||
let client = hyper::Client::builder().build(hyper_tls::HttpsConnector::new(4)?);
|
let client = hyper::Client::builder().build(hyper_tls::HttpsConnector::new(4)?);
|
||||||
|
|
||||||
Ok(Client {
|
if cfg!(feature = "emulator") {
|
||||||
account: account.to_owned(),
|
Ok(Client {
|
||||||
key: key.to_owned(),
|
account: "devstoreaccount1".to_owned(),
|
||||||
hc: client,
|
key: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==".to_owned(),
|
||||||
})
|
hc: client,
|
||||||
|
blob_uri: "http://127.0.0.1:10000/devstoreaccount1".to_owned(),
|
||||||
|
table_uri: "http://127.0.0.1:10002/devstoreaccount1".to_owned(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(Client {
|
||||||
|
account: account.to_owned(),
|
||||||
|
key: key.to_owned(),
|
||||||
|
hc: client,
|
||||||
|
blob_uri: format!("https://{}.blob.core.windows.net", account),
|
||||||
|
table_uri: format!("https://{}.table.core.windows.net", account),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn account(&self) -> &str {
|
pub fn account(&self) -> &str {
|
||||||
|
@ -193,6 +203,16 @@ impl Client {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn blob_uri(&self) -> &str {
|
||||||
|
&self.blob_uri
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn table_uri(&self) -> &str {
|
||||||
|
&self.table_uri
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn perform_request<F>(
|
pub(crate) fn perform_request<F>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
|
@ -230,12 +250,9 @@ impl Client {
|
||||||
|
|
||||||
/// Uri scheme + authority e.g. http://myaccount.table.core.windows.net/
|
/// Uri scheme + authority e.g. http://myaccount.table.core.windows.net/
|
||||||
pub(crate) fn get_uri_prefix(&self, service_type: ServiceType) -> String {
|
pub(crate) fn get_uri_prefix(&self, service_type: ServiceType) -> String {
|
||||||
"https://".to_owned()
|
match service_type {
|
||||||
+ self.account()
|
ServiceType::Blob => format!("{}/", self.blob_uri()),
|
||||||
+ match service_type {
|
ServiceType::Table => format!("{}/", self.table_uri()),
|
||||||
ServiceType::Blob => SERVICE_SUFFIX_BLOB,
|
}
|
||||||
ServiceType::Table => SERVICE_SUFFIX_TABLE,
|
|
||||||
}
|
|
||||||
+ "/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
pub struct CreateRequest<N> {
|
|
||||||
name: String,
|
|
||||||
timeout: Option<u64>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateRequest
|
|
|
@ -229,14 +229,14 @@ where
|
||||||
{
|
{
|
||||||
match params {
|
match params {
|
||||||
Some(ref params) => format!(
|
Some(ref params) => format!(
|
||||||
"https://{}.blob.core.windows.net/{}?{}",
|
"{}/{}?{}",
|
||||||
t.client().account(),
|
t.client().blob_uri(),
|
||||||
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
||||||
params
|
params
|
||||||
),
|
),
|
||||||
None => format!(
|
None => format!(
|
||||||
"https://{}.blob.core.windows.net/{}",
|
"{}/{}",
|
||||||
t.client().account(),
|
t.client().blob_uri(),
|
||||||
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,13 +250,14 @@ impl<'a, ContainerNameSet, LeaseDurationSet> AcquireLeaseBuilder<'a, ContainerNa
|
||||||
where
|
where
|
||||||
ContainerNameSet: ToAssign,
|
ContainerNameSet: ToAssign,
|
||||||
LeaseDurationSet: ToAssign,
|
LeaseDurationSet: ToAssign,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> AcquireLeaseBuilder<'a, Yes, Yes> {
|
impl<'a> AcquireLeaseBuilder<'a, Yes, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = AcquireLeaseResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = AcquireLeaseResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!(
|
||||||
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
|
"{}/{}?comp=lease&restype=container",
|
||||||
self.client().account(),
|
self.client().blob_uri(),
|
||||||
self.container_name()
|
self.container_name()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -192,8 +192,8 @@ impl<'a, ContainerNameSet> BreakLeaseBuilder<'a, ContainerNameSet> where Contain
|
||||||
impl<'a> BreakLeaseBuilder<'a, Yes> {
|
impl<'a> BreakLeaseBuilder<'a, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = BreakLeaseResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = BreakLeaseResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!(
|
||||||
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
|
"{}/{}?comp=lease&restype=container",
|
||||||
self.client().account(),
|
self.client().blob_uri(),
|
||||||
self.container_name()
|
self.container_name()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,8 @@ impl<'a, ContainerNameSet, PublicAccessSet> CreateBuilder<'a, ContainerNameSet,
|
||||||
where
|
where
|
||||||
ContainerNameSet: ToAssign,
|
ContainerNameSet: ToAssign,
|
||||||
PublicAccessSet: ToAssign,
|
PublicAccessSet: ToAssign,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, ContainerNameSet, PublicAccessSet> ContainerNameSupport<'a> for CreateBuilder<'a, ContainerNameSet, PublicAccessSet>
|
impl<'a, ContainerNameSet, PublicAccessSet> ContainerNameSupport<'a> for CreateBuilder<'a, ContainerNameSet, PublicAccessSet>
|
||||||
where
|
where
|
||||||
|
@ -214,11 +215,8 @@ impl<'a> CreateBuilder<'a, No, No> {
|
||||||
|
|
||||||
impl<'a> CreateBuilder<'a, Yes, Yes> {
|
impl<'a> CreateBuilder<'a, Yes, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = (), Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = (), Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}/{}?restype=container", self.client().blob_uri(), self.container_name());
|
||||||
"https://{}.blob.core.windows.net/{}?restype=container",
|
println!("{}", uri);
|
||||||
self.client().account(),
|
|
||||||
self.container_name()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
||||||
uri = format!("{}&{}", uri, nm);
|
uri = format!("{}&{}", uri, nm);
|
||||||
|
|
|
@ -146,11 +146,7 @@ impl<'a> DeleteBuilder<'a, No> {
|
||||||
|
|
||||||
impl<'a> DeleteBuilder<'a, Yes> {
|
impl<'a> DeleteBuilder<'a, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = (), Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = (), Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}/{}?restype=container", self.client().blob_uri(), self.container_name());
|
||||||
"https://{}.blob.core.windows.net/{}?restype=container",
|
|
||||||
self.client().account(),
|
|
||||||
self.container_name()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
||||||
uri = format!("{}&{}", uri, nm);
|
uri = format!("{}&{}", uri, nm);
|
||||||
|
|
|
@ -72,11 +72,7 @@ where
|
||||||
|
|
||||||
impl<'a> GetACLBuilder<'a, Yes> {
|
impl<'a> GetACLBuilder<'a, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = GetACLResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = GetACLResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}/{}?restype=container&comp=acl", self.client().blob_uri(), self.container_name());
|
||||||
"https://{}.blob.core.windows.net/{}?restype=container&comp=acl",
|
|
||||||
self.client().account(),
|
|
||||||
self.container_name()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
||||||
uri = format!("{}&{}", uri, nm);
|
uri = format!("{}&{}", uri, nm);
|
||||||
|
|
|
@ -72,11 +72,7 @@ where
|
||||||
|
|
||||||
impl<'a> GetPropertiesBuilder<'a, Yes> {
|
impl<'a> GetPropertiesBuilder<'a, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = GetPropertiesResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = GetPropertiesResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}/{}?restype=container", self.client().blob_uri(), self.container_name());
|
||||||
"https://{}.blob.core.windows.net/{}?restype=container",
|
|
||||||
self.client().account(),
|
|
||||||
self.container_name()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
||||||
uri = format!("{}&{}", uri, nm);
|
uri = format!("{}&{}", uri, nm);
|
||||||
|
|
|
@ -78,11 +78,7 @@ impl<'a> ListBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finalize(self) -> impl Future<Item = ListContainersResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = ListContainersResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}?comp=list&maxresults={}", self.client().blob_uri(), self.max_results());
|
||||||
"https://{}.blob.core.windows.net?comp=list&maxresults={}",
|
|
||||||
self.client().account(),
|
|
||||||
self.max_results()
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.is_metadata_included() {
|
if self.is_metadata_included() {
|
||||||
uri = format!("{}&include=metadata", uri);
|
uri = format!("{}&include=metadata", uri);
|
||||||
|
|
|
@ -174,13 +174,14 @@ impl<'a, ContainerNameSet, LeaseIdSet> ReleaseLeaseBuilder<'a, ContainerNameSet,
|
||||||
where
|
where
|
||||||
ContainerNameSet: ToAssign,
|
ContainerNameSet: ToAssign,
|
||||||
LeaseIdSet: ToAssign,
|
LeaseIdSet: ToAssign,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ReleaseLeaseBuilder<'a, Yes, Yes> {
|
impl<'a> ReleaseLeaseBuilder<'a, Yes, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = ReleaseLeaseResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = ReleaseLeaseResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!(
|
||||||
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
|
"{}/{}?comp=lease&restype=container",
|
||||||
self.client().account(),
|
self.client().blob_uri(),
|
||||||
self.container_name()
|
self.container_name()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -174,13 +174,14 @@ impl<'a, ContainerNameSet, LeaseIdSet> RenewLeaseBuilder<'a, ContainerNameSet, L
|
||||||
where
|
where
|
||||||
ContainerNameSet: ToAssign,
|
ContainerNameSet: ToAssign,
|
||||||
LeaseIdSet: ToAssign,
|
LeaseIdSet: ToAssign,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> RenewLeaseBuilder<'a, Yes, Yes> {
|
impl<'a> RenewLeaseBuilder<'a, Yes, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = RenewLeaseResponse, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = RenewLeaseResponse, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!(
|
||||||
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
|
"{}/{}?comp=lease&restype=container",
|
||||||
self.client().account(),
|
self.client().blob_uri(),
|
||||||
self.container_name()
|
self.container_name()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -112,11 +112,7 @@ where
|
||||||
|
|
||||||
impl<'a> SetACLBuilder<'a, Yes, Yes> {
|
impl<'a> SetACLBuilder<'a, Yes, Yes> {
|
||||||
pub fn finalize(self) -> impl Future<Item = PublicAccess, Error = AzureError> {
|
pub fn finalize(self) -> impl Future<Item = PublicAccess, Error = AzureError> {
|
||||||
let mut uri = format!(
|
let mut uri = format!("{}/{}?restype=container&comp=acl", self.client().blob_uri(), self.container_name());
|
||||||
"https://{}.blob.core.windows.net/{}?restype=container&comp=acl",
|
|
||||||
self.client().account(),
|
|
||||||
self.container_name()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
|
||||||
uri = format!("{}&{}", uri, nm);
|
uri = format!("{}&{}", uri, nm);
|
||||||
|
|
|
@ -67,7 +67,8 @@ fn string_to_sign(h: &HeaderMap, u: &url::Url, method: &Method, service_type: Se
|
||||||
add_if_exists(h, header::CONTENT_TYPE),
|
add_if_exists(h, header::CONTENT_TYPE),
|
||||||
add_if_exists(h, HEADER_DATE),
|
add_if_exists(h, HEADER_DATE),
|
||||||
canonicalized_resource_table(u)
|
canonicalized_resource_table(u)
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -95,7 +96,8 @@ fn string_to_sign(h: &HeaderMap, u: &url::Url, method: &Method, service_type: Se
|
||||||
add_if_exists(h, header::RANGE),
|
add_if_exists(h, header::RANGE),
|
||||||
canonicalize_header(h),
|
canonicalize_header(h),
|
||||||
canonicalized_resource(u)
|
canonicalized_resource(u)
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,13 +141,17 @@ fn canonicalize_header(h: &HeaderMap) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_account(u: &url::Url) -> String {
|
fn get_account(u: &url::Url) -> &str {
|
||||||
match u.host().unwrap().clone() {
|
match u.host().unwrap().clone() {
|
||||||
url::Host::Domain(dm) => {
|
url::Host::Domain(dm) => {
|
||||||
// debug!("dom == {:?}", dm);
|
// debug!("dom == {:?}", dm);
|
||||||
|
|
||||||
let first_dot = dm.find('.').unwrap();
|
let first_dot = dm.find('.').unwrap();
|
||||||
String::from(&dm[0..first_dot])
|
&dm[0..first_dot]
|
||||||
|
}
|
||||||
|
url::Host::Ipv4(_) => {
|
||||||
|
// this must be the emulator
|
||||||
|
"devstoreaccount1"
|
||||||
}
|
}
|
||||||
_ => panic!("only Domains are supported in canonicalized_resource"),
|
_ => panic!("only Domains are supported in canonicalized_resource"),
|
||||||
}
|
}
|
||||||
|
@ -341,7 +347,8 @@ Wed, 03 May 2017 14:04:56 GMT
|
||||||
let url = url::Url::parse(
|
let url = url::Url::parse(
|
||||||
"http://myaccount.blob.core.windows.\
|
"http://myaccount.blob.core.windows.\
|
||||||
net/mycontainer?restype=container&comp=metadata",
|
net/mycontainer?restype=container&comp=metadata",
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::canonicalized_resource(&url),
|
super::canonicalized_resource(&url),
|
||||||
"/myaccount/mycontainer\ncomp:metadata\nrestype:container"
|
"/myaccount/mycontainer\ncomp:metadata\nrestype:container"
|
||||||
|
@ -354,7 +361,8 @@ Wed, 03 May 2017 14:04:56 GMT
|
||||||
"http://myaccount.blob.core.windows.\
|
"http://myaccount.blob.core.windows.\
|
||||||
net/mycontainer?restype=container&comp=list&include=snapshots&\
|
net/mycontainer?restype=container&comp=list&include=snapshots&\
|
||||||
include=metadata&include=uncommittedblobs",
|
include=metadata&include=uncommittedblobs",
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::canonicalized_resource(&url),
|
super::canonicalized_resource(&url),
|
||||||
"/myaccount/mycontainer\ncomp:list\ninclude:metadata,snapshots,\
|
"/myaccount/mycontainer\ncomp:list\ninclude:metadata,snapshots,\
|
||||||
|
@ -367,7 +375,8 @@ Wed, 03 May 2017 14:04:56 GMT
|
||||||
let url = url::Url::parse(
|
let url = url::Url::parse(
|
||||||
"https://myaccount-secondary.blob.core.windows.\
|
"https://myaccount-secondary.blob.core.windows.\
|
||||||
net/mycontainer/myblob",
|
net/mycontainer/myblob",
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(super::canonicalized_resource(&url), "/myaccount-secondary/mycontainer/myblob");
|
assert_eq!(super::canonicalized_resource(&url), "/myaccount-secondary/mycontainer/myblob");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче