mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 23:36:52 +08:00
Parse XML Errors. (#11)
This commit is contained in:
parent
db45f6865f
commit
91ad6401c3
@ -15,9 +15,12 @@ pretty_env_logger = "0.3.0"
|
||||
ring = "0.14.6"
|
||||
roxmltree = "0.6.0"
|
||||
serde = "1.0.92"
|
||||
serde_derive = "1.0.91"
|
||||
serde_derive = "1.0.124"
|
||||
serde_json = "1.0.39"
|
||||
time = "0.1.42"
|
||||
tokio = "0.1.21"
|
||||
xml-rs = "0.8.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
xml-rs = "0.8.3"
|
||||
quick-xml = { version = "0.22", features = [ "serialize" ] }
|
||||
thiserror = "1.0.24"
|
||||
|
||||
|
||||
|
||||
16
src/lib.rs
16
src/lib.rs
@ -23,7 +23,6 @@ mod tests {
|
||||
use hyper::rt;
|
||||
use log::debug;
|
||||
|
||||
use minio::BucketInfo;
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -39,17 +38,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_lib_functions() {
|
||||
println!("test func");
|
||||
rt::run(rt::lazy(|| {
|
||||
let c = minio::Client::get_play_client();
|
||||
let bucket = "aaaa";
|
||||
let bucket_name = "aaaa";
|
||||
|
||||
c.put_object_req(bucket, "hhhhhhhhhh", vec![], "object content".as_bytes().to_vec())
|
||||
c.put_object_req(bucket_name, "hhhhhhhhhh", vec![], "object content".as_bytes().to_vec())
|
||||
.and_then(|g| {
|
||||
debug!("object: {} {} {:?}", g.object_size, g.etag, g.content_type);
|
||||
print!("object: {} {} {:?}", g.object_size, g.etag, g.content_type);
|
||||
g.get_object_stream().concat2()
|
||||
})
|
||||
.map(|c| debug!("get obj res: {:?}", c))
|
||||
.map_err(|c| debug!("err res: {:?}", c))
|
||||
.map(|c| {
|
||||
println!("{:?}", c);
|
||||
})
|
||||
.map_err(|c| {
|
||||
println!("{:?}", c);
|
||||
})
|
||||
.map(|_| {})
|
||||
}));
|
||||
|
||||
|
||||
23
src/minio.rs
23
src/minio.rs
@ -15,22 +15,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
use std::env;
|
||||
use std::str;
|
||||
use std::string::String;
|
||||
|
||||
use futures::future::{self, Future};
|
||||
use futures::Stream;
|
||||
use http;
|
||||
use hyper::header::{HeaderName, HeaderValue};
|
||||
use hyper::{body::Body, client, header, header::HeaderMap, Method, Request, Response, Uri};
|
||||
use hyper::header::{HeaderName, HeaderValue};
|
||||
use hyper_tls::HttpsConnector;
|
||||
use log::debug;
|
||||
use time;
|
||||
use time::Tm;
|
||||
|
||||
pub use types::BucketInfo;
|
||||
use types::{Err, GetObjectResp, ListObjectsResp, Region};
|
||||
pub use types::BucketInfo;
|
||||
|
||||
|
||||
use crate::minio::net::{Values, ValuesAccess};
|
||||
use crate::minio::xml::{parse_s3_error, S3GenericError};
|
||||
use bytes::Buf;
|
||||
|
||||
mod api;
|
||||
mod api_notification;
|
||||
@ -38,7 +44,6 @@ mod net;
|
||||
mod sign;
|
||||
mod types;
|
||||
mod xml;
|
||||
use log::debug;
|
||||
mod woxml;
|
||||
|
||||
pub const SPACE_BYTE: &[u8; 1] = b" ";
|
||||
@ -205,7 +210,16 @@ impl Client {
|
||||
.concat2()
|
||||
.map_err(|err| Err::HyperErr(err))
|
||||
.and_then(move |chunk| {
|
||||
match st.as_str() {
|
||||
"404" => {
|
||||
let x = str::from_utf8(&chunk.bytes());
|
||||
let s3_err = parse_s3_error(x.unwrap());
|
||||
Err(Err::S3Error(s3_err))
|
||||
}
|
||||
_ => {
|
||||
Err(Err::FailStatusCodeErr(st, chunk.into_bytes()))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -486,9 +500,10 @@ impl S3Req {
|
||||
|
||||
#[cfg(test)]
|
||||
mod minio_tests {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_query_parameters() {
|
||||
let mut query_params: HashMap<String, Vec<Option<String>>> = HashMap::new();
|
||||
|
||||
@ -26,6 +26,7 @@ use roxmltree;
|
||||
use std::collections::HashMap;
|
||||
use std::string;
|
||||
use time::{strptime, Tm};
|
||||
use crate::minio::xml::S3GenericError;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Region(String);
|
||||
@ -60,6 +61,7 @@ pub enum Err {
|
||||
MissingRequiredParams,
|
||||
RawSvcErr(hyper::StatusCode, Response<Body>),
|
||||
XmlWriteErr(String),
|
||||
S3Error(S3GenericError),
|
||||
}
|
||||
|
||||
pub struct GetObjectResp {
|
||||
|
||||
@ -15,11 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
extern crate quick_xml;
|
||||
extern crate serde;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use std::str;
|
||||
|
||||
use hyper::body::Body;
|
||||
use roxmltree;
|
||||
use serde_derive::Deserialize;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::minio::types::{BucketInfo, Err, ListObjectsResp, ObjectInfo, Region};
|
||||
use crate::minio::woxml;
|
||||
@ -39,6 +45,80 @@ pub fn parse_bucket_location(s: String) -> Result<Region, Err> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Debug, Deserialize, PartialEq)]
|
||||
pub struct Error {
|
||||
Param: Option<String>,
|
||||
Code: String,
|
||||
Message: String,
|
||||
BucketName: String,
|
||||
Key: Option<String>,
|
||||
RequestId: String,
|
||||
HostId: String,
|
||||
// Region where the bucket is located. This header is returned
|
||||
// only in HEAD bucket and ListObjects response.
|
||||
Region: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum S3GenericError {
|
||||
#[error("no such bucket: {error:?}")]
|
||||
NoSuchBucket {
|
||||
error: Error,
|
||||
},
|
||||
#[error("unknown error: {error:?}")]
|
||||
Unknown {
|
||||
error: Error,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn parse_s3_error(response_xml: &str) -> S3GenericError {
|
||||
println!("{}",response_xml);
|
||||
let doc: Error = quick_xml::de::from_str(response_xml).unwrap();
|
||||
match doc.Code.as_str() {
|
||||
"NoSuchBucket" => {
|
||||
return S3GenericError::NoSuchBucket {
|
||||
error: doc,
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
return S3GenericError::Unknown {
|
||||
error: doc,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod xml_tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_xml_error() {
|
||||
let response_xml = r#"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>NoSuchBucket</Code>
|
||||
<Message>The specified bucket does not exist</Message>
|
||||
<Key>hhhhhhhhhh</Key>
|
||||
<BucketName>aaaa</BucketName>
|
||||
<Resource>/aaaa/hhhhhhhhhh</Resource>
|
||||
<RequestId>166B5E4E3A406CC6</RequestId>
|
||||
<HostId>129c19c9-4cf6-44ff-9f2d-4cb7611be894</HostId>
|
||||
</Error>
|
||||
"#;
|
||||
|
||||
let s3_error = parse_s3_error(response_xml);
|
||||
|
||||
print!("test! {:?}", s3_error);
|
||||
assert!(matches!(s3_error, S3GenericError::NoSuchBucket {cerror} ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn parse_bucket_list(s: String) -> Result<Vec<BucketInfo>, Err> {
|
||||
let res = roxmltree::Document::parse(&s);
|
||||
match res {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user