mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-01 19:12:14 +00:00
72aead5466
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
303 lines
9.8 KiB
Rust
303 lines
9.8 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
#![allow(unused_imports)]
|
|
#![allow(unused_variables)]
|
|
#![allow(unused_mut)]
|
|
#![allow(unused_assignments)]
|
|
#![allow(unused_must_use)]
|
|
#![allow(clippy::all)]
|
|
|
|
use bytes::Bytes;
|
|
use http::{HeaderMap, StatusCode};
|
|
use std::collections::HashMap;
|
|
|
|
use crate::client::{
|
|
api_error_response::http_resp_to_error_response,
|
|
api_s3_datatypes::{
|
|
ListBucketResult, ListBucketV2Result, ListMultipartUploadsResult, ListObjectPartsResult, ListVersionsResult, ObjectPart,
|
|
},
|
|
credentials,
|
|
transition_api::{ReaderImpl, RequestMetadata, TransitionClient},
|
|
};
|
|
use crate::store_api::BucketInfo;
|
|
use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH;
|
|
|
|
impl TransitionClient {
|
|
pub fn list_buckets(&self) -> Result<Vec<BucketInfo>, std::io::Error> {
|
|
todo!();
|
|
}
|
|
|
|
pub async fn list_objects_v2_query(
|
|
&self,
|
|
bucket_name: &str,
|
|
object_prefix: &str,
|
|
continuation_token: &str,
|
|
fetch_owner: bool,
|
|
metadata: bool,
|
|
delimiter: &str,
|
|
start_after: &str,
|
|
max_keys: i64,
|
|
headers: HeaderMap,
|
|
) -> Result<ListBucketV2Result, std::io::Error> {
|
|
let mut url_values = HashMap::new();
|
|
|
|
url_values.insert("list-type".to_string(), "2".to_string());
|
|
if metadata {
|
|
url_values.insert("metadata".to_string(), "true".to_string());
|
|
}
|
|
if start_after != "" {
|
|
url_values.insert("start-after".to_string(), start_after.to_string());
|
|
}
|
|
url_values.insert("encoding-type".to_string(), "url".to_string());
|
|
url_values.insert("prefix".to_string(), object_prefix.to_string());
|
|
url_values.insert("delimiter".to_string(), delimiter.to_string());
|
|
|
|
if continuation_token != "" {
|
|
url_values.insert("continuation-token".to_string(), continuation_token.to_string());
|
|
}
|
|
|
|
if fetch_owner {
|
|
url_values.insert("fetch-owner".to_string(), "true".to_string());
|
|
}
|
|
|
|
if max_keys > 0 {
|
|
url_values.insert("max-keys".to_string(), max_keys.to_string());
|
|
}
|
|
|
|
let mut resp = self
|
|
.execute_method(
|
|
http::Method::GET,
|
|
&mut RequestMetadata {
|
|
bucket_name: bucket_name.to_string(),
|
|
object_name: "".to_string(),
|
|
query_values: url_values,
|
|
content_sha256_hex: EMPTY_STRING_SHA256_HASH.to_string(),
|
|
custom_header: headers,
|
|
content_body: ReaderImpl::Body(Bytes::new()),
|
|
content_length: 0,
|
|
content_md5_base64: "".to_string(),
|
|
stream_sha256: false,
|
|
trailer: HeaderMap::new(),
|
|
pre_sign_url: Default::default(),
|
|
add_crc: Default::default(),
|
|
extra_pre_sign_header: Default::default(),
|
|
bucket_location: Default::default(),
|
|
expires: Default::default(),
|
|
},
|
|
)
|
|
.await?;
|
|
if resp.status() != StatusCode::OK {
|
|
return Err(std::io::Error::other(http_resp_to_error_response(resp, vec![], bucket_name, "")));
|
|
}
|
|
|
|
//let mut list_bucket_result = ListBucketV2Result::default();
|
|
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec();
|
|
let mut list_bucket_result = match serde_xml_rs::from_str::<ListBucketV2Result>(&String::from_utf8(b).unwrap()) {
|
|
Ok(result) => result,
|
|
Err(err) => {
|
|
return Err(std::io::Error::other(err.to_string()));
|
|
}
|
|
};
|
|
//println!("list_bucket_result: {:?}", list_bucket_result);
|
|
|
|
if list_bucket_result.is_truncated && list_bucket_result.next_continuation_token == "" {
|
|
return Err(std::io::Error::other(credentials::ErrorResponse {
|
|
sts_error: credentials::STSError {
|
|
r#type: "".to_string(),
|
|
code: "NotImplemented".to_string(),
|
|
message: "Truncated response should have continuation token set".to_string(),
|
|
},
|
|
request_id: "".to_string(),
|
|
}));
|
|
}
|
|
|
|
for (i, obj) in list_bucket_result.contents.iter_mut().enumerate() {
|
|
obj.name = decode_s3_name(&obj.name, &list_bucket_result.encoding_type)?;
|
|
//list_bucket_result.contents[i].mod_time = list_bucket_result.contents[i].mod_time.Truncate(time.Millisecond);
|
|
}
|
|
|
|
for (i, obj) in list_bucket_result.common_prefixes.iter_mut().enumerate() {
|
|
obj.prefix = decode_s3_name(&obj.prefix, &list_bucket_result.encoding_type)?;
|
|
}
|
|
|
|
Ok(list_bucket_result)
|
|
}
|
|
|
|
pub fn list_object_versions_query(
|
|
&self,
|
|
bucket_name: &str,
|
|
opts: &ListObjectsOptions,
|
|
key_marker: &str,
|
|
version_id_marker: &str,
|
|
delimiter: &str,
|
|
) -> Result<ListVersionsResult, std::io::Error> {
|
|
/*if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
|
return ListVersionsResult{}, err
|
|
}
|
|
if err := s3utils.CheckValidObjectNamePrefix(opts.Prefix); err != nil {
|
|
return ListVersionsResult{}, err
|
|
}
|
|
urlValues := make(url.Values)
|
|
|
|
urlValues.Set("versions", "")
|
|
|
|
urlValues.Set("prefix", opts.Prefix)
|
|
|
|
urlValues.Set("delimiter", delimiter)
|
|
|
|
if keyMarker != "" {
|
|
urlValues.Set("key-marker", keyMarker)
|
|
}
|
|
|
|
if opts.max_keys > 0 {
|
|
urlValues.Set("max-keys", fmt.Sprintf("%d", opts.max_keys))
|
|
}
|
|
|
|
if versionIDMarker != "" {
|
|
urlValues.Set("version-id-marker", versionIDMarker)
|
|
}
|
|
|
|
if opts.WithMetadata {
|
|
urlValues.Set("metadata", "true")
|
|
}
|
|
|
|
urlValues.Set("encoding-type", "url")
|
|
|
|
let resp = self.executeMethod(http::Method::GET, &mut RequestMetadata{
|
|
bucketName: bucketName,
|
|
queryValues: urlValues,
|
|
contentSHA256Hex: emptySHA256Hex,
|
|
customHeader: opts.headers,
|
|
}).await?;
|
|
defer closeResponse(resp)
|
|
if err != nil {
|
|
return ListVersionsResult{}, err
|
|
}
|
|
if resp != nil {
|
|
if resp.StatusCode != http.StatusOK {
|
|
return ListVersionsResult{}, httpRespToErrorResponse(resp, bucketName, "")
|
|
}
|
|
}
|
|
|
|
listObjectVersionsOutput := ListVersionsResult{}
|
|
err = xml_decoder(resp.Body, &listObjectVersionsOutput)
|
|
if err != nil {
|
|
return ListVersionsResult{}, err
|
|
}
|
|
|
|
for i, obj := range listObjectVersionsOutput.Versions {
|
|
listObjectVersionsOutput.Versions[i].Key, err = decode_s3_name(obj.Key, listObjectVersionsOutput.EncodingType)
|
|
if err != nil {
|
|
return listObjectVersionsOutput, err
|
|
}
|
|
}
|
|
|
|
for i, obj := range listObjectVersionsOutput.CommonPrefixes {
|
|
listObjectVersionsOutput.CommonPrefixes[i].Prefix, err = decode_s3_name(obj.Prefix, listObjectVersionsOutput.EncodingType)
|
|
if err != nil {
|
|
return listObjectVersionsOutput, err
|
|
}
|
|
}
|
|
|
|
if listObjectVersionsOutput.NextKeyMarker != "" {
|
|
listObjectVersionsOutput.NextKeyMarker, err = decode_s3_name(listObjectVersionsOutput.NextKeyMarker, listObjectVersionsOutput.EncodingType)
|
|
if err != nil {
|
|
return listObjectVersionsOutput, err
|
|
}
|
|
}
|
|
|
|
Ok(listObjectVersionsOutput)*/
|
|
todo!();
|
|
}
|
|
|
|
pub fn list_objects_query(
|
|
&self,
|
|
bucket_name: &str,
|
|
object_prefix: &str,
|
|
object_marker: &str,
|
|
delimiter: &str,
|
|
max_keys: i64,
|
|
headers: HeaderMap,
|
|
) -> Result<ListBucketResult, std::io::Error> {
|
|
todo!();
|
|
}
|
|
|
|
pub fn list_multipart_uploads_query(
|
|
&self,
|
|
bucket_name: &str,
|
|
key_marker: &str,
|
|
upload_id_marker: &str,
|
|
prefix: &str,
|
|
delimiter: &str,
|
|
max_uploads: i64,
|
|
) -> Result<ListMultipartUploadsResult, std::io::Error> {
|
|
todo!();
|
|
}
|
|
|
|
pub fn list_object_parts(
|
|
&self,
|
|
bucket_name: &str,
|
|
object_name: &str,
|
|
upload_id: &str,
|
|
) -> Result<HashMap<i64, ObjectPart>, std::io::Error> {
|
|
todo!();
|
|
}
|
|
|
|
pub fn find_upload_ids(&self, bucket_name: &str, object_name: &str) -> Result<Vec<String>, std::io::Error> {
|
|
todo!();
|
|
}
|
|
|
|
pub async fn list_object_parts_query(
|
|
&self,
|
|
bucket_name: &str,
|
|
object_name: &str,
|
|
upload_id: &str,
|
|
part_number_marker: i64,
|
|
max_parts: i64,
|
|
) -> Result<ListObjectPartsResult, std::io::Error> {
|
|
todo!();
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub struct ListObjectsOptions {
|
|
reverse_versions: bool,
|
|
with_versions: bool,
|
|
with_metadata: bool,
|
|
prefix: String,
|
|
recursive: bool,
|
|
max_keys: i64,
|
|
start_after: String,
|
|
use_v1: bool,
|
|
headers: HeaderMap,
|
|
}
|
|
|
|
impl ListObjectsOptions {
|
|
pub fn set(&mut self, key: &str, value: &str) {
|
|
todo!();
|
|
}
|
|
}
|
|
|
|
fn decode_s3_name(name: &str, encoding_type: &str) -> Result<String, std::io::Error> {
|
|
match encoding_type {
|
|
"url" => {
|
|
//return url::QueryUnescape(name);
|
|
return Ok(name.to_string());
|
|
}
|
|
_ => {
|
|
return Ok(name.to_string());
|
|
}
|
|
}
|
|
}
|