1use crate::bucket::is_non_positive;
18use crate::common::{DataTransferListener, DataTransferStatus, Grant, ListedCommonPrefix, Meta, Owner, RateLimiter, RequestInfo, RequestInfoTrait, TagSet, TempCopyResult};
19use crate::common::{GenericInput, UserMeta};
20use crate::config::ConfigHolder;
21use crate::constant::{DEFAULT_READ_BUFFER_SIZE, HEADER_CACHE_CONTROL, HEADER_CALLBACK, HEADER_CONTENT_DISPOSITION, HEADER_CONTENT_ENCODING, HEADER_CONTENT_LANGUAGE, HEADER_CONTENT_LENGTH, HEADER_CONTENT_MD5, HEADER_CONTENT_RANGE, HEADER_CONTENT_SHA256, HEADER_CONTENT_TYPE, HEADER_COPY_SOURCE_VERSION_ID, HEADER_DELETE_MARKER, HEADER_DIRECTORY, HEADER_ETAG, HEADER_EXPIRATION, HEADER_EXPIRES, HEADER_FETCH_DETECT_MIME_TYPE, HEADER_FORBID_OVERWRITE, HEADER_HASH_CRC64ECMA, HEADER_IF_NONE_MATCH, HEADER_LAST_MODIFIED, HEADER_LAST_MODIFIED_NS, HEADER_METADATA_DIRECTIVE, HEADER_MODIFY_TIMESTAMP, HEADER_MODIFY_TIMESTAMP_NS, HEADER_NEXT_APPEND_OFFSET, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, HEADER_OBJECT_EXPIRES, HEADER_OBJECT_TYPE, HEADER_PREFIX_META, HEADER_RANGE, HEADER_RECURSIVE_MKDIR, HEADER_REPLICATION_STATUS, HEADER_RESTORE, HEADER_RESTORE_EXPIRY_DAYS, HEADER_RESTORE_REQUEST_DATE, HEADER_RESTORE_TIER, HEADER_SERVER_SIDE_ENCRYPTION, HEADER_SERVER_SIDE_ENCRYPTION_KMS_KEY_ID, HEADER_SSEC_ALGORITHM, HEADER_SSEC_KEY_MD5, HEADER_STORAGE_CLASS, HEADER_SYMLINK_BUCKET, HEADER_SYMLINK_TARGET, HEADER_SYMLINK_TARGET_SIZE, HEADER_TAGGING, HEADER_TAGGING_COUNT, HEADER_TAGGING_DIRECTIVE, HEADER_TRAFFIC_LIMIT, HEADER_TRANSFER_ENCODING_LOWER, HEADER_VERSION_ID, HEADER_WEBSITE_REDIRECT_LOCATION, HEADER_X_IF_MATCH, QUERY_CONTINUATION_TOKEN, QUERY_FETCH_META, QUERY_FETCH_OWNER, QUERY_KEY_MARKER, QUERY_MARKER, QUERY_MAX_KEYS, QUERY_OFFSET, QUERY_PROCESS, QUERY_RECURSIVE, QUERY_SKIP_TRASH, QUERY_START_AFTER, QUERY_TASK_ID, QUERY_VERSION_ID, QUERY_VERSION_ID_MARKER, TRUE, UUID_NODE};
22use crate::enumeration::HttpMethodType::{HttpMethodDelete, HttpMethodGet, HttpMethodHead, HttpMethodPost, HttpMethodPut};
23use crate::enumeration::{ACLType, DocPreviewDstType, DocPreviewSrcType, HttpMethodType, MetadataDirectiveType, ObjectLockModeType, ReplicationStatusType, StorageClassType, TaggingDirectiveType, TierType};
24use crate::error::{ErrorResponse, GenericError, TosError};
25use crate::http::{HttpRequest, HttpResponse, RequestContext};
26use crate::internal::{base64_md5, get_header_value_ref, map_insert, parse_json_by_buf, parse_response_string_by_buf, read_response, set_acl_header, set_copy_source_header, set_copy_source_if_condition_header, set_copy_source_ssec_header, set_data_process_query, set_http_basic_header, set_http_basic_header_for_fetch, set_if_match_header, set_misc_header, set_misc_header_for_fetch, set_object_lock_header, set_rewrite_response_query, set_sse_header, trans_meta, url_encode_with_safe};
27use crate::internal::{get_header_value, get_header_value_from_str, get_header_value_str, get_header_value_url_decoded, get_map_value_str, parse_date_time_iso8601, parse_date_time_rfc1123, parse_json, set_callback_header, set_if_condition_header, set_list_common_query, set_ssec_header, InputDescriptor, InputTranslator, OutputParser};
28use crate::reader::{BuildBufferReader, BuildFileReader, BuildMultiBufferReader, MultiBytes, MultifunctionalReader};
29use bytes::Bytes;
30use chrono::{DateTime, Utc};
31use futures_core::Stream;
32use reqwest::header::HeaderMap;
33use serde::{Deserialize, Serialize};
34use std::cell::{Ref, RefCell};
35use std::collections::{HashMap, LinkedList};
36use std::fmt::{Debug, Formatter};
37use std::fs;
38use std::fs::File;
39use std::io::{ErrorKind, Read, Write};
40use std::ops::Add;
41use std::path::Path;
42use std::sync::atomic::AtomicU64;
43use std::sync::mpsc::Sender;
44use std::sync::Arc;
45use std::time::Duration;
46use uuid::Uuid;
47use ve_tos_generic::{AclHeader, CallbackHeader, CopySourceHeader, CopySourceIfConditionHeader, CopySourceSSecHeader, DataProcessQuery, GenericInput, HttpBasicHeader, IfConditionHeader, IfMatch, ListCommonQuery, MiscHeader, ObjectLock, RequestInfo, RewriteResponseQuery, SseHeader, SsecHeader};
48
49pub trait ObjectAPI {
50 fn copy_object(&self, input: &CopyObjectInput) -> Result<CopyObjectOutput, TosError>;
51 fn delete_object(&self, input: &DeleteObjectInput) -> Result<DeleteObjectOutput, TosError>;
52 fn delete_multi_objects(&self, input: &DeleteMultiObjectsInput) -> Result<DeleteMultiObjectsOutput, TosError>;
53 fn get_object(&self, input: &GetObjectInput) -> Result<GetObjectOutput, TosError>;
54 fn get_object_to_file(&self, input: &GetObjectToFileInput) -> Result<GetObjectToFileOutput, TosError>;
55 fn get_object_acl(&self, input: &GetObjectACLInput) -> Result<GetObjectACLOutput, TosError>;
56 fn head_object(&self, input: &HeadObjectInput) -> Result<HeadObjectOutput, TosError>;
57 fn append_object<B>(&self, input: &AppendObjectInput<B>) -> Result<AppendObjectOutput, TosError>
58 where
59 B: Read + Send + 'static;
60 fn append_object_from_buffer(&self, input: &AppendObjectFromBufferInput) -> Result<AppendObjectOutput, TosError>;
61 #[deprecated]
62 fn list_objects(&self, input: &ListObjectsInput) -> Result<ListObjectsOutput, TosError>;
63 fn list_objects_type2(&self, input: &ListObjectsType2Input) -> Result<ListObjectsType2Output, TosError>;
64 fn list_object_versions(&self, input: &ListObjectVersionsInput) -> Result<ListObjectVersionsOutput, TosError>;
65 fn put_object<B>(&self, input: &PutObjectInput<B>) -> Result<PutObjectOutput, TosError>
66 where
67 B: Read + Send + 'static;
68 fn put_object_from_buffer(&self, input: &PutObjectFromBufferInput) -> Result<PutObjectOutput, TosError>;
69 fn put_object_from_file(&self, input: &PutObjectFromFileInput) -> Result<PutObjectOutput, TosError>;
70 fn put_object_acl(&self, input: &PutObjectACLInput) -> Result<PutObjectACLOutput, TosError>;
71 fn set_object_meta(&self, input: &SetObjectMetaInput) -> Result<SetObjectMetaOutput, TosError>;
72}
73
74pub trait ObjectContent {
75 type Content: ?Sized;
76
77 fn content(&mut self) -> Option<&mut Self::Content>;
78
79 fn read_all(&mut self) -> Result<Vec<u8>, TosError>;
80}
81
82#[derive(
83 Debug,
84 Clone,
85 PartialEq,
86 Default,
87 HttpBasicHeader,
88 AclHeader,
89 MiscHeader,
90 SseHeader,
91 SsecHeader,
92 CopySourceHeader,
93 CopySourceSSecHeader,
94 CopySourceIfConditionHeader,
95 GenericInput
96)]
97pub struct CopyObjectInput {
98 pub(crate) generic_input: GenericInput,
99 pub(crate) bucket: String,
100 pub(crate) key: String,
101
102 pub(crate) src_bucket: String,
103 pub(crate) src_key: String,
104 pub(crate) src_version_id: String,
105
106 pub(crate) content_length: i64,
107 pub(crate) cache_control: String,
108 pub(crate) content_disposition: String,
109 pub(crate) content_encoding: String,
110 pub(crate) content_language: String,
111 pub(crate) content_type: String,
112 pub(crate) expires: Option<DateTime<Utc>>,
113
114 pub(crate) copy_source_if_match: String,
115 pub(crate) copy_source_if_modified_since: Option<DateTime<Utc>>,
116 pub(crate) copy_source_if_none_match: String,
117 pub(crate) copy_source_if_unmodified_since: Option<DateTime<Utc>>,
118
119 pub(crate) copy_source_ssec_algorithm: String,
120 pub(crate) copy_source_ssec_key: String,
121 pub(crate) copy_source_ssec_key_md5: String,
122 pub(crate) ssec_algorithm: String,
123 pub(crate) ssec_key: String,
124 pub(crate) ssec_key_md5: String,
125 pub(crate) server_side_encryption: String,
126 pub(crate) server_side_encryption_key_id: String,
127
128 pub(crate) acl: Option<ACLType>,
129 pub(crate) grant_full_control: String,
130 pub(crate) grant_read: String,
131 pub(crate) grant_read_acp: String,
132 pub(crate) grant_write: String,
133 pub(crate) grant_write_acp: String,
134
135 pub(crate) metadata_directive: Option<MetadataDirectiveType>,
136 pub(crate) meta: HashMap<String, String>,
137 pub(crate) website_redirect_location: String,
138 pub(crate) storage_class: Option<StorageClassType>,
139 pub(crate) traffic_limit: i64,
140 pub(crate) forbid_overwrite: bool,
141 pub(crate) if_match: String,
142 pub(crate) if_none_match: String,
143
144 pub(crate) tagging: String,
145 pub(crate) tagging_directive: Option<TaggingDirectiveType>,
146 pub(crate) object_expires: i64,
147}
148
149impl CopyObjectInput {
150 pub fn new(bucket: impl Into<String>, key: impl Into<String>,
151 src_bucket: impl Into<String>, src_key: impl Into<String>) -> Self {
152 let mut input = Self::default();
153 input.bucket = bucket.into();
154 input.key = key.into();
155 input.src_bucket = src_bucket.into();
156 input.src_key = src_key.into();
157 input.content_length = -1;
158 input.object_expires = -1;
159 input
160 }
161
162 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>,
163 src_bucket: impl Into<String>, src_key: impl Into<String>, src_version_id: impl Into<String>) -> Self {
164 let mut input = Self::default();
165 input.bucket = bucket.into();
166 input.key = key.into();
167 input.src_bucket = src_bucket.into();
168 input.src_key = src_key.into();
169 input.content_length = -1;
170 input.src_version_id = src_version_id.into();
171 input.object_expires = -1;
172 input
173 }
174
175 pub fn bucket(&self) -> &str {
176 &self.bucket
177 }
178
179 pub fn key(&self) -> &str {
180 &self.key
181 }
182
183 pub fn metadata_directive(&self) -> &Option<MetadataDirectiveType> {
184 &self.metadata_directive
185 }
186 pub fn meta(&self) -> &HashMap<String, String> {
187 &self.meta
188 }
189 pub fn traffic_limit(&self) -> i64 {
190 self.traffic_limit
191 }
192 pub fn forbid_overwrite(&self) -> bool {
193 self.forbid_overwrite
194 }
195 pub fn if_match(&self) -> &str {
196 &self.if_match
197 }
198 pub fn if_none_match(&self) -> &str {
199 &self.if_none_match
200 }
201 pub fn tagging(&self) -> &str {
202 &self.tagging
203 }
204
205 pub fn tagging_directive(&self) -> &Option<TaggingDirectiveType> {
206 &self.tagging_directive
207 }
208 pub fn object_expires(&self) -> i64 {
209 self.object_expires
210 }
211 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
212 self.bucket = bucket.into();
213 }
214 pub fn set_key(&mut self, key: impl Into<String>) {
215 self.key = key.into();
216 }
217 pub fn set_metadata_directive(&mut self, metadata_directive: impl Into<MetadataDirectiveType>) {
218 self.metadata_directive = Some(metadata_directive.into());
219 }
220 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
221 self.meta = meta.into();
222 }
223 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
224 self.traffic_limit = traffic_limit;
225 }
226 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
227 self.forbid_overwrite = forbid_overwrite;
228 }
229 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
230 self.if_match = if_match.into();
231 }
232 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
233 self.if_none_match = if_none_match.into();
234 }
235 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
236 self.tagging = tagging.into();
237 }
238 pub fn set_tagging_directive(&mut self, tagging_directive: impl Into<TaggingDirectiveType>) {
239 self.tagging_directive = Some(tagging_directive.into());
240 }
241 pub fn set_object_expires(&mut self, object_expires: i64) {
242 self.object_expires = object_expires;
243 }
244}
245
246impl InputDescriptor for CopyObjectInput {
247 fn operation(&self) -> &str {
248 "CopyObject"
249 }
250 fn bucket(&self) -> Result<&str, TosError> {
251 Ok(&self.bucket)
252 }
253 fn key(&self) -> Result<&str, TosError> {
254 Ok(&self.key)
255 }
256}
257
258impl<B> InputTranslator<B> for CopyObjectInput {
259 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
260 let mut request = self.trans_key()?;
261 request.method = HttpMethodPut;
262 let header = &mut request.header;
263 set_copy_source_header(header, self)?;
264 set_copy_source_if_condition_header(header, self);
265 set_http_basic_header(header, config_holder.disable_encoding_meta, self);
266 set_sse_header(header, self)?;
267 set_ssec_header(header, &self.server_side_encryption, self)?;
268 set_copy_source_ssec_header(header, self)?;
269 set_acl_header(header, self);
270 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
271 set_misc_header(header, self);
272 if let Some(metadata_directive) = &self.metadata_directive {
273 header.insert(HEADER_METADATA_DIRECTIVE, metadata_directive.as_str().to_string());
274 }
275 if self.forbid_overwrite {
276 header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
277 }
278 if self.traffic_limit > 0 {
279 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
280 }
281 map_insert(header, HEADER_X_IF_MATCH, &self.if_match);
282 map_insert(header, HEADER_IF_NONE_MATCH, &self.if_none_match);
283
284 if self.tagging != "" {
285 if let Some(tagging_directive) = &self.tagging_directive {
286 header.insert(HEADER_TAGGING_DIRECTIVE, tagging_directive.as_str().to_string());
287 }
288 header.insert(HEADER_TAGGING, self.tagging.clone());
289 }
290 if self.object_expires >= 0 {
291 header.insert(HEADER_OBJECT_EXPIRES, self.object_expires.to_string());
292 }
293
294 Ok(request)
295 }
296}
297
298#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
299pub struct CopyObjectOutput {
300 pub(crate) request_info: RequestInfo,
301 pub(crate) etag: String,
302 pub(crate) last_modified: Option<DateTime<Utc>>,
303 pub(crate) copy_source_version_id: String,
304 pub(crate) version_id: String,
305 pub(crate) ssec_algorithm: String,
306 pub(crate) ssec_key_md5: String,
307 pub(crate) server_side_encryption: String,
308 pub(crate) server_side_encryption_key_id: String,
309}
310
311impl CopyObjectOutput {
312 pub fn etag(&self) -> &str {
313 &self.etag
314 }
315 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
316 self.last_modified
317 }
318 pub fn copy_source_version_id(&self) -> &str {
319 &self.copy_source_version_id
320 }
321 pub fn version_id(&self) -> &str {
322 &self.version_id
323 }
324 pub fn ssec_algorithm(&self) -> &str {
325 &self.ssec_algorithm
326 }
327 pub fn ssec_key_md5(&self) -> &str {
328 &self.ssec_key_md5
329 }
330 pub fn server_side_encryption(&self) -> &str {
331 &self.server_side_encryption
332 }
333 pub fn server_side_encryption_key_id(&self) -> &str {
334 &self.server_side_encryption_key_id
335 }
336}
337
338impl OutputParser for CopyObjectOutput {
339 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
340 let temp_result = parse_json::<TempCopyResult>(response)?;
341 if temp_result.etag == "" {
342 return Err(TosError::server_error_with_code(temp_result.code, temp_result.ec, temp_result.key, temp_result.message,
343 temp_result.host_id, temp_result.resource, request_info));
344 }
345
346 let mut result = Self {
347 request_info: RequestInfo::default(),
348 etag: temp_result.etag,
349 last_modified: parse_date_time_iso8601(&temp_result.last_modified)?,
350 copy_source_version_id: get_header_value(response.headers(), HEADER_COPY_SOURCE_VERSION_ID),
351 version_id: get_header_value(response.headers(), HEADER_VERSION_ID),
352 ssec_algorithm: get_header_value(response.headers(), HEADER_SSEC_ALGORITHM),
353 ssec_key_md5: get_header_value(response.headers(), HEADER_SSEC_KEY_MD5),
354 server_side_encryption: get_header_value(response.headers(), HEADER_SERVER_SIDE_ENCRYPTION),
355 server_side_encryption_key_id: get_header_value(response.headers(), HEADER_SERVER_SIDE_ENCRYPTION_KMS_KEY_ID),
356 };
357
358 result.request_info = request_info;
359 Ok(result)
360 }
361}
362
363#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
364pub struct DeleteObjectInput {
365 pub(crate) generic_input: GenericInput,
366 pub(crate) bucket: String,
367 pub(crate) key: String,
368 pub(crate) version_id: String,
369 pub(crate) recursive: bool,
370 pub(crate) skip_trash: bool,
371 pub(crate) if_match: String,
372}
373
374impl DeleteObjectInput {
375 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
376 Self {
377 generic_input: Default::default(),
378 bucket: bucket.into(),
379 key: key.into(),
380 version_id: "".to_string(),
381 recursive: false,
382 skip_trash: false,
383 if_match: "".to_string(),
384 }
385 }
386 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
387 Self {
388 generic_input: Default::default(),
389 bucket: bucket.into(),
390 key: key.into(),
391 version_id: version_id.into(),
392 recursive: false,
393 skip_trash: false,
394 if_match: "".to_string(),
395 }
396 }
397 pub fn bucket(&self) -> &str {
398 &self.bucket
399 }
400 pub fn key(&self) -> &str {
401 &self.key
402 }
403 pub fn version_id(&self) -> &str {
404 &self.version_id
405 }
406 pub fn recursive(&self) -> bool {
407 self.recursive
408 }
409 pub fn if_match(&self) -> &str {
410 &self.if_match
411 }
412 pub fn skip_trash(&self) -> bool {
413 self.skip_trash
414 }
415 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
416 self.bucket = bucket.into();
417 }
418 pub fn set_key(&mut self, key: impl Into<String>) {
419 self.key = key.into();
420 }
421 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
422 self.version_id = version_id.into();
423 }
424 pub fn set_recursive(&mut self, recursive: bool) {
425 self.recursive = recursive;
426 }
427
428 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
429 self.if_match = if_match.into();
430 }
431 pub fn set_skip_trash(&mut self, skip_trash: bool) {
432 self.skip_trash = skip_trash;
433 }
434}
435
436impl InputDescriptor for DeleteObjectInput {
437 fn operation(&self) -> &str {
438 "DeleteObject"
439 }
440 fn bucket(&self) -> Result<&str, TosError> {
441 Ok(&self.bucket)
442 }
443 fn key(&self) -> Result<&str, TosError> {
444 Ok(&self.key)
445 }
446}
447
448impl<B> InputTranslator<B> for DeleteObjectInput {
449 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
450 let mut request = self.trans_key()?;
451 request.method = HttpMethodDelete;
452 map_insert(&mut request.header, HEADER_X_IF_MATCH, &self.if_match);
453 let mut query = HashMap::with_capacity(3);
454 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
455 if self.recursive {
456 query.insert(QUERY_RECURSIVE, self.recursive.to_string());
457 }
458 if self.skip_trash {
459 query.insert(QUERY_SKIP_TRASH, self.skip_trash.to_string());
460 }
461 request.query = Some(query);
462 Ok(request)
463 }
464}
465
466#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
467pub struct DeleteObjectOutput {
468 pub(crate) request_info: RequestInfo,
469 pub(crate) delete_marker: bool,
470 pub(crate) version_id: String,
471}
472
473impl DeleteObjectOutput {
474 pub fn delete_marker(&self) -> bool {
475 self.delete_marker
476 }
477 pub fn version_id(&self) -> &str {
478 &self.version_id
479 }
480}
481
482impl OutputParser for DeleteObjectOutput {
483 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
484 let version_id = get_header_value(response.headers(), HEADER_VERSION_ID);
485 let delete_marker = get_header_value_ref(response.headers(), HEADER_DELETE_MARKER) == TRUE;
486 Ok(Self {
487 request_info,
488 delete_marker,
489 version_id,
490 })
491 }
492}
493
494#[derive(Debug, Clone, PartialEq, Default, Serialize, GenericInput)]
495pub struct DeleteMultiObjectsInput {
496 #[serde(skip)]
497 pub(crate) generic_input: GenericInput,
498 #[serde(skip)]
499 pub(crate) bucket: String,
500 #[serde(rename = "Objects")]
501 pub(crate) objects: Vec<ObjectTobeDeleted>,
502 #[serde(rename = "Quiet")]
503 pub(crate) quiet: bool,
504 #[serde(skip)]
505 pub(crate) recursive: bool,
506 #[serde(skip)]
507 pub(crate) skip_trash: bool,
508}
509
510#[derive(Debug, Clone, PartialEq, Default, Serialize)]
511pub struct ObjectTobeDeleted {
512 #[serde(rename = "Key")]
513 pub(crate) key: String,
514 #[serde(rename = "VersionId")]
515 #[serde(skip_serializing_if = "String::is_empty")]
516 pub(crate) version_id: String,
517}
518
519impl ObjectTobeDeleted {
520 pub fn new(key: impl Into<String>) -> Self {
521 Self { key: key.into(), version_id: "".to_string() }
522 }
523 pub fn new_with_version_id(key: impl Into<String>, version_id: impl Into<String>) -> Self {
524 Self { key: key.into(), version_id: version_id.into() }
525 }
526 pub fn key(&self) -> &str {
527 &self.key
528 }
529 pub fn version_id(&self) -> &str {
530 &self.version_id
531 }
532 pub fn set_key(&mut self, key: impl Into<String>) {
533 self.key = key.into();
534 }
535 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
536 self.version_id = version_id.into();
537 }
538}
539
540
541impl DeleteMultiObjectsInput {
542 pub fn new(bucket: impl Into<String>) -> Self {
543 Self {
544 generic_input: Default::default(),
545 bucket: bucket.into(),
546 objects: vec![],
547 quiet: false,
548 recursive: false,
549 skip_trash: false,
550 }
551 }
552 pub fn new_with_objects(bucket: impl Into<String>, objects: impl Into<Vec<ObjectTobeDeleted>>) -> Self {
553 Self {
554 generic_input: Default::default(),
555 bucket: bucket.into(),
556 objects: objects.into(),
557 quiet: false,
558 recursive: false,
559 skip_trash: false,
560 }
561 }
562
563 pub fn add_object(&mut self, object: impl Into<ObjectTobeDeleted>) {
564 self.objects.push(object.into());
565 }
566
567 pub fn bucket(&self) -> &str {
568 &self.bucket
569 }
570 pub fn objects(&self) -> &Vec<ObjectTobeDeleted> {
571 &self.objects
572 }
573 pub fn quiet(&self) -> bool {
574 self.quiet
575 }
576 pub fn recursive(&self) -> bool {
577 self.recursive
578 }
579
580 pub fn skip_trash(&self) -> bool {
581 self.skip_trash
582 }
583 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
584 self.bucket = bucket.into();
585 }
586 pub fn set_objects(&mut self, objects: impl Into<Vec<ObjectTobeDeleted>>) {
587 self.objects = objects.into();
588 }
589 pub fn set_quiet(&mut self, quiet: bool) {
590 self.quiet = quiet;
591 }
592
593 pub fn set_recursive(&mut self, recursive: bool) {
594 self.recursive = recursive;
595 }
596
597 pub fn set_skip_trash(&mut self, skip_trash: bool) {
598 self.skip_trash = skip_trash;
599 }
600}
601
602impl InputDescriptor for DeleteMultiObjectsInput {
603 fn operation(&self) -> &str {
604 "DeleteMultiObjects"
605 }
606
607 fn bucket(&self) -> Result<&str, TosError> {
608 Ok(&self.bucket)
609 }
610}
611
612impl<B> InputTranslator<B> for DeleteMultiObjectsInput
613where
614 B: BuildBufferReader,
615{
616 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
617 if self.objects.len() == 0 {
618 return Err(TosError::client_error("empty objects for delete"));
619 }
620
621 match serde_json::to_string(self) {
622 Err(e) => Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
623 Ok(json) => {
624 let mut request = self.trans_bucket()?;
625 request.method = HttpMethodPost;
626 request.header.insert(HEADER_CONTENT_MD5, base64_md5(&json));
627 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
628 request.body = Some(body);
629 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
630
631 let mut query = HashMap::with_capacity(3);
632 if self.recursive {
633 query.insert(QUERY_RECURSIVE, self.recursive.to_string());
634 }
635 if self.skip_trash {
636 query.insert(QUERY_SKIP_TRASH, self.skip_trash.to_string());
637 }
638 query.insert("delete", "".to_string());
639 request.query = Some(query);
640 Ok(request)
641 }
642 }
643 }
644}
645
646
647#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
648pub struct DeleteMultiObjectsOutput {
649 #[serde(skip)]
650 pub(crate) request_info: RequestInfo,
651 #[serde(default)]
652 #[serde(rename = "Deleted")]
653 pub(crate) deleted: Vec<Deleted>,
654 #[serde(default)]
655 #[serde(rename = "Error")]
656 pub(crate) error: Vec<DeleteError>,
657}
658
659#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
660pub struct Deleted {
661 #[serde(default)]
662 #[serde(rename = "Key")]
663 pub(crate) key: String,
664 #[serde(default)]
665 #[serde(rename = "VersionId")]
666 pub(crate) version_id: String,
667 #[serde(default)]
668 #[serde(rename = "DeleteMarker")]
669 pub(crate) delete_marker: bool,
670 #[serde(default)]
671 #[serde(rename = "DeleteMarkerVersionId")]
672 pub(crate) delete_marker_version_id: String,
673}
674
675#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
676pub struct DeleteError {
677 #[serde(default)]
678 #[serde(rename = "Key")]
679 pub(crate) key: String,
680 #[serde(default)]
681 #[serde(rename = "VersionId")]
682 pub(crate) version_id: String,
683 #[serde(default)]
684 #[serde(rename = "Code")]
685 pub(crate) code: String,
686 #[serde(default)]
687 #[serde(rename = "Message")]
688 pub(crate) message: String,
689}
690
691impl Deleted {
692 pub fn key(&self) -> &str {
693 &self.key
694 }
695 pub fn version_id(&self) -> &str {
696 &self.version_id
697 }
698 pub fn delete_marker(&self) -> bool {
699 self.delete_marker
700 }
701 pub fn delete_marker_version_id(&self) -> &str {
702 &self.delete_marker_version_id
703 }
704}
705
706
707impl DeleteError {
708 pub fn key(&self) -> &str {
709 &self.key
710 }
711 pub fn version_id(&self) -> &str {
712 &self.version_id
713 }
714 pub fn code(&self) -> &str {
715 &self.code
716 }
717 pub fn message(&self) -> &str {
718 &self.message
719 }
720}
721
722impl DeleteMultiObjectsOutput {
723 pub fn deleted(&self) -> &Vec<Deleted> {
724 &self.deleted
725 }
726 pub fn error(&self) -> &Vec<DeleteError> {
727 &self.error
728 }
729}
730
731impl OutputParser for DeleteMultiObjectsOutput {
732 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
733 let mut result = parse_json::<Self>(response)?;
734 result.request_info = request_info;
735 Ok(result)
736 }
737}
738
739#[derive(
740 Debug,
741 Clone,
742 IfConditionHeader,
743 SsecHeader,
744 RewriteResponseQuery,
745 DataProcessQuery,
746 GenericInput
747)]
748pub struct GetObjectInput {
749 pub(crate) generic_input: GenericInput,
750 pub(crate) bucket: String,
751 pub(crate) key: String,
752 pub(crate) version_id: String,
753 pub(crate) if_match: String,
754 pub(crate) if_modified_since: Option<DateTime<Utc>>,
755 pub(crate) if_none_match: String,
756 pub(crate) if_unmodified_since: Option<DateTime<Utc>>,
757 pub(crate) ssec_algorithm: String,
758 pub(crate) ssec_key: String,
759 pub(crate) ssec_key_md5: String,
760
761 pub(crate) response_cache_control: String,
762 pub(crate) response_content_disposition: String,
763 pub(crate) response_content_encoding: String,
764 pub(crate) response_content_language: String,
765 pub(crate) response_content_type: String,
766 pub(crate) response_expires: Option<DateTime<Utc>>,
767
768 pub(crate) range_start: i64,
769 pub(crate) range_end: i64,
770
771 pub(crate) range: String,
772 pub(crate) traffic_limit: i64,
773
774 pub(crate) process: String,
775
776 pub(crate) doc_page: isize,
777 pub(crate) src_type: Option<DocPreviewSrcType>,
778 pub(crate) dst_type: Option<DocPreviewDstType>,
779
780 pub(crate) save_bucket: String,
781 pub(crate) save_object: String,
782 pub(crate) rate_limiter: Option<Arc<RateLimiter>>,
783 pub(crate) data_transfer_listener: Option<Sender<DataTransferStatus>>,
784 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
785}
786
787impl InputDescriptor for GetObjectInput {
788 fn operation(&self) -> &str {
789 "GetObject"
790 }
791 fn bucket(&self) -> Result<&str, TosError> {
792 Ok(&self.bucket)
793 }
794
795 fn key(&self) -> Result<&str, TosError> {
796 Ok(&self.key)
797 }
798}
799
800impl<B> InputTranslator<B> for GetObjectInput {
801 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
802 let mut request = self.trans_key()?;
803 request.method = HttpMethodGet;
804 if let Some(rl) = self.rate_limiter() {
805 let mut rc = RequestContext::default();
806 rc.rate_limiter = Some(rl.clone());
807 request.request_context = Some(rc);
808 }
809
810 if let Some(ref dts) = self.data_transfer_listener {
811 if request.request_context.is_some() {
812 request.request_context.as_mut().unwrap().data_transfer_listener = Some(dts.clone());
813 } else {
814 let mut rc = RequestContext::default();
815 rc.data_transfer_listener = Some(dts.clone());
816 request.request_context = Some(rc);
817 }
818 } else if let Some(ref adts) = self.async_data_transfer_listener {
819 if request.request_context.is_some() {
820 request.request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
821 } else {
822 let mut rc = RequestContext::default();
823 rc.async_data_transfer_listener = Some(adts.clone());
824 request.request_context = Some(rc);
825 }
826 }
827
828 let header = &mut request.header;
829 set_if_condition_header(header, self);
830 set_ssec_header(header, "", self)?;
831 if self.range != "" {
832 if !self.range.starts_with("bytes=") {
833 return Err(TosError::client_error("invalid range format"));
834 }
835 header.insert(HEADER_RANGE, self.range.clone());
836 } else if self.range_start >= 0 && self.range_end >= 0 && self.range_start <= self.range_end {
837 header.insert(HEADER_RANGE, format!("bytes={}-{}", self.range_start, self.range_end));
838 }
839 if self.traffic_limit > 0 {
840 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
841 }
842
843 let mut query = HashMap::with_capacity(16);
844 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
845 set_rewrite_response_query(&mut query, self);
846 set_data_process_query(&mut query, self);
847
848 request.query = Some(query);
849 Ok(request)
850 }
851}
852
853impl Default for GetObjectInput {
854 fn default() -> Self {
855 Self {
856 generic_input: Default::default(),
857 bucket: "".to_string(),
858 key: "".to_string(),
859 version_id: "".to_string(),
860 if_match: "".to_string(),
861 if_modified_since: None,
862 if_none_match: "".to_string(),
863 if_unmodified_since: None,
864 ssec_algorithm: "".to_string(),
865 ssec_key: "".to_string(),
866 ssec_key_md5: "".to_string(),
867 response_cache_control: "".to_string(),
868 response_content_disposition: "".to_string(),
869 response_content_encoding: "".to_string(),
870 response_content_language: "".to_string(),
871 response_content_type: "".to_string(),
872 response_expires: None,
873 range_start: -1,
874 range_end: -1,
875 range: "".to_string(),
876 traffic_limit: 0,
877 process: "".to_string(),
878 doc_page: 0,
879 src_type: None,
880 dst_type: None,
881 save_bucket: "".to_string(),
882 save_object: "".to_string(),
883 rate_limiter: None,
884 data_transfer_listener: None,
885 async_data_transfer_listener: None,
886 }
887 }
888}
889
890impl DataTransferListener for GetObjectInput {
891 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
892 &self.data_transfer_listener
893 }
894
895 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
896 self.data_transfer_listener = Some(listener.into());
897 }
898}
899
900impl GetObjectInput {
901 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
902 let mut input = Self::default();
903 input.bucket = bucket.into();
904 input.key = key.into();
905 input
906 }
907 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
908 let mut input = Self::default();
909 input.bucket = bucket.into();
910 input.key = key.into();
911 input.version_id = version_id.into();
912 input
913 }
914 pub fn bucket(&self) -> &str {
915 &self.bucket
916 }
917 pub fn key(&self) -> &str {
918 &self.key
919 }
920 pub fn version_id(&self) -> &str {
921 &self.version_id
922 }
923 pub fn range_start(&self) -> i64 {
924 self.range_start
925 }
926 pub fn range_end(&self) -> i64 {
927 self.range_end
928 }
929 pub fn range(&self) -> &str {
930 &self.range
931 }
932 pub fn traffic_limit(&self) -> i64 {
933 self.traffic_limit
934 }
935 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
936 &self.rate_limiter
937 }
938 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
939 self.bucket = bucket.into();
940 }
941 pub fn set_key(&mut self, key: impl Into<String>) {
942 self.key = key.into();
943 }
944 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
945 self.version_id = version_id.into();
946 }
947 pub fn set_range_start(&mut self, range_start: i64) {
948 self.range_start = range_start;
949 }
950 pub fn set_range_end(&mut self, range_end: i64) {
951 self.range_end = range_end;
952 }
953 pub fn set_range(&mut self, range: impl Into<String>) {
954 self.range = range.into();
955 }
956 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
957 self.traffic_limit = traffic_limit;
958 }
959 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
960 self.rate_limiter = Some(rate_limiter.into());
961 }
962}
963
964#[derive(Default)]
965pub struct GetObjectOutput {
966 pub(crate) content_range: String,
967 pub(crate) content: Option<MultifunctionalReader<HttpResponse>>,
968 pub(crate) async_content: Option<MultifunctionalReader<Box<dyn Stream<Item=Result<Bytes, crate::error::CommonError>> + Send + Unpin>>>,
969 pub(crate) head_object_output: HeadObjectOutput,
970}
971
972unsafe impl Sync for GetObjectOutput {}
973
974impl Debug for GetObjectOutput {
975 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
976 write!(f, "({:?}, {})", self.head_object_output, self.content_range)
977 }
978}
979
980impl OutputParser for GetObjectOutput {
981 fn parse_by_ref<B>(_: &HttpRequest<B>, _: &mut HttpResponse, _: RequestInfo, _: Meta) -> Result<Self, TosError> {
982 Err(TosError::client_error("unimplemented"))
983 }
984
985 fn parse<B>(request: HttpRequest<B>, response: HttpResponse, request_info: RequestInfo, meta: Meta) -> Result<Self, TosError> {
986 let transfer_encoding = request_info.header.get(HEADER_TRANSFER_ENCODING_LOWER).map(|x| x.to_string());
987 let head_object_output = HeadObjectOutput::parse_by_header(response.headers(), request_info, meta)?;
988 let content_range = get_header_value(response.headers(), HEADER_CONTENT_RANGE);
989 let mut target_crc64 = None;
990 if request.enable_crc && !request.header.contains_key(HEADER_RANGE) &&
991 (request.query.is_none() || !request.query.as_ref().unwrap().contains_key(QUERY_PROCESS)) {
992 if let Some(te) = transfer_encoding {
993 if te != "chunked" {
994 target_crc64 = Some(head_object_output.hash_crc64ecma);
995 }
996 } else {
997 target_crc64 = Some(head_object_output.hash_crc64ecma);
998 }
999 }
1000 let mut crc64 = None;
1001 if target_crc64.is_some() {
1002 crc64 = Some(Arc::new(AtomicU64::new(0)));
1003 }
1004 let mut reader = MultifunctionalReader::with_target_crc64(response, crc64, head_object_output.content_length,
1005 &request, target_crc64);
1006
1007 if let Some(ref rc) = request.request_context {
1008 if let Some(ref rl) = rc.rate_limiter {
1009 reader.set_rate_limiter(rl.clone());
1010 }
1011 if let Some(ref dts) = rc.data_transfer_listener {
1012 reader.set_data_transfer_listener(dts.clone());
1013 reader.inner.operation = request.operation.to_string();
1014 reader.inner.bucket = request.bucket.to_string();
1015 reader.inner.key = request.key.to_string();
1016 reader.inner.retry_count = request.retry_count;
1017 }
1018 }
1019
1020 Ok(Self {
1021 content_range,
1022 content: Some(reader),
1023 async_content: None,
1024 head_object_output,
1025 })
1026 }
1027}
1028
1029impl Read for GetObjectOutput {
1030 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
1031 match self.content.as_mut() {
1032 None => {
1033 Err(std::io::Error::new(ErrorKind::Other, "empty content"))
1034 }
1035 Some(content) => {
1036 content.read(buf)
1037 }
1038 }
1039 }
1040}
1041
1042impl ObjectContent for GetObjectOutput {
1043 type Content = dyn Read;
1044
1045 fn content(&mut self) -> Option<&mut Self::Content> {
1046 match self.content.as_mut() {
1047 None => None,
1048 Some(x) => Some(x as &mut dyn Read),
1049 }
1050 }
1051
1052 fn read_all(&mut self) -> Result<Vec<u8>, TosError> {
1053 let x = self.content_length();
1054 if x == 0 {
1055 return Ok(vec![]);
1056 }
1057 let mut buf;
1058 if x > 0 {
1059 buf = Vec::with_capacity(x as usize);
1060 } else {
1061 buf = Vec::new();
1062 }
1063 match self.content.as_mut() {
1064 None => Err(TosError::client_error("empty content")),
1065 Some(r) => {
1066 match r.read_to_end(&mut buf) {
1067 Err(e) => Err(TosError::client_error_with_cause("read error", GenericError::IoError(e.to_string()))),
1068 Ok(_) => Ok(buf),
1069 }
1070 }
1071 }
1072 }
1073}
1074
1075impl RequestInfoTrait for GetObjectOutput {
1076 fn request_id(&self) -> &str {
1077 &self.head_object_output.request_info.request_id
1078 }
1079
1080 fn id2(&self) -> &str {
1081 &self.head_object_output.request_info.id2
1082 }
1083
1084 fn status_code(&self) -> isize {
1085 self.head_object_output.request_info.status_code
1086 }
1087
1088 fn header(&self) -> &HashMap<String, String> {
1089 &self.head_object_output.request_info.header
1090 }
1091}
1092
1093impl GetObjectOutput {
1094 pub fn request_id(&self) -> &str {
1095 &self.head_object_output.request_info.request_id
1096 }
1097
1098 pub fn id2(&self) -> &str {
1099 &self.head_object_output.request_info.id2
1100 }
1101
1102 pub fn status_code(&self) -> isize {
1103 self.head_object_output.request_info.status_code
1104 }
1105
1106 pub fn header(&self) -> &HashMap<String, String> {
1107 &self.head_object_output.request_info.header
1108 }
1109 pub fn content_range(&self) -> &str {
1110 &self.content_range
1111 }
1112 pub fn etag(&self) -> &str {
1113 &self.head_object_output.etag
1114 }
1115 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
1116 self.head_object_output.last_modified
1117 }
1118 pub fn last_modified_timestamp(&self) -> Option<DateTime<Utc>> {
1119 self.head_object_output.last_modify_timestamp
1120 }
1121 pub fn delete_marker(&self) -> bool {
1122 self.head_object_output.delete_marker
1123 }
1124 pub fn ssec_algorithm(&self) -> &str {
1125 &self.head_object_output.ssec_algorithm
1126 }
1127 pub fn ssec_key_md5(&self) -> &str {
1128 &self.head_object_output.ssec_key_md5
1129 }
1130 pub fn version_id(&self) -> &str {
1131 &self.head_object_output.version_id
1132 }
1133 pub fn website_redirect_location(&self) -> &str {
1134 &self.head_object_output.website_redirect_location
1135 }
1136 pub fn object_type(&self) -> &str {
1137 &self.head_object_output.object_type
1138 }
1139 pub fn hash_crc64ecma(&self) -> u64 {
1140 self.head_object_output.hash_crc64ecma
1141 }
1142 pub fn storage_class(&self) -> &Option<StorageClassType> {
1143 &self.head_object_output.storage_class
1144 }
1145 pub fn meta(&self) -> &HashMap<String, String> {
1146 &self.head_object_output.meta
1147 }
1148 pub fn content_length(&self) -> i64 {
1149 self.head_object_output.content_length
1150 }
1151 pub fn cache_control(&self) -> &str {
1152 &self.head_object_output.cache_control
1153 }
1154 pub fn content_disposition(&self) -> &str {
1155 &self.head_object_output.content_disposition
1156 }
1157 pub fn content_encoding(&self) -> &str {
1158 &self.head_object_output.content_encoding
1159 }
1160 pub fn content_language(&self) -> &str {
1161 &self.head_object_output.content_language
1162 }
1163 pub fn content_type(&self) -> &str {
1164 &self.head_object_output.content_type
1165 }
1166 pub fn expires(&self) -> Option<DateTime<Utc>> {
1167 self.head_object_output.expires
1168 }
1169 pub fn restore_info(&self) -> &Option<RestoreInfo> {
1170 &self.head_object_output.restore_info
1171 }
1172 pub fn server_side_encryption(&self) -> &str {
1173 &self.head_object_output.server_side_encryption
1174 }
1175 pub fn server_side_encryption_key_id(&self) -> &str {
1176 &self.head_object_output.server_side_encryption_key_id
1177 }
1178 pub fn replication_status(&self) -> &Option<ReplicationStatusType> {
1179 &self.head_object_output.replication_status
1180 }
1181 pub fn tagging_count(&self) -> isize {
1182 self.head_object_output.tagging_count
1183 }
1184 pub fn expiration(&self) -> &str {
1185 &self.head_object_output.expiration
1186 }
1187 pub fn is_directory(&self) -> bool {
1188 self.head_object_output.is_directory
1189 }
1190}
1191
1192#[derive(
1193 Debug,
1194 Clone,
1195 IfConditionHeader,
1196 SsecHeader,
1197 RewriteResponseQuery,
1198 DataProcessQuery,
1199 GenericInput
1200)]
1201#[use_inner]
1202pub struct GetObjectToFileInput {
1203 pub(crate) inner: GetObjectInput,
1204 pub(crate) file_path: String,
1205}
1206
1207
1208impl InputDescriptor for GetObjectToFileInput {
1209 fn operation(&self) -> &str {
1210 "GetObjectToFile"
1211 }
1212 fn bucket(&self) -> Result<&str, TosError> {
1213 Ok(&self.inner.bucket)
1214 }
1215
1216 fn key(&self) -> Result<&str, TosError> {
1217 Ok(&self.inner.key)
1218 }
1219}
1220
1221impl<B> InputTranslator<B> for GetObjectToFileInput {
1222 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
1223 if self.file_path == "" {
1224 return Err(TosError::client_error("empty file path"));
1225 }
1226 let mut request = self.inner.trans(config_holder)?;
1227 if request.request_context.is_some() {
1228 request.request_context.as_mut().unwrap().file_path = &self.file_path
1229 } else {
1230 let mut rc = RequestContext::default();
1231 rc.file_path = &self.file_path;
1232 request.request_context = Some(rc);
1233 }
1234 Ok(request)
1235 }
1236}
1237
1238impl Default for GetObjectToFileInput {
1239 fn default() -> Self {
1240 Self {
1241 inner: Default::default(),
1242 file_path: "".to_string(),
1243 }
1244 }
1245}
1246
1247impl DataTransferListener for GetObjectToFileInput {
1248 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
1249 &self.inner.data_transfer_listener
1250 }
1251
1252 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
1253 self.inner.data_transfer_listener = Some(listener.into());
1254 }
1255}
1256
1257impl GetObjectToFileInput {
1258 pub fn new(bucket: impl Into<String>, key: impl Into<String>, file_path: impl Into<String>) -> Self {
1259 let mut input = Self::default();
1260 input.inner.bucket = bucket.into();
1261 input.inner.key = key.into();
1262 input.file_path = file_path.into();
1263 input
1264 }
1265 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>, file_path: impl Into<String>) -> Self {
1266 let mut input = Self::default();
1267 input.inner.bucket = bucket.into();
1268 input.inner.key = key.into();
1269 input.inner.version_id = version_id.into();
1270 input.file_path = file_path.into();
1271 input
1272 }
1273 pub fn bucket(&self) -> &str {
1274 &self.inner.bucket
1275 }
1276 pub fn key(&self) -> &str {
1277 &self.inner.key
1278 }
1279 pub fn version_id(&self) -> &str {
1280 &self.inner.version_id
1281 }
1282 pub fn range_start(&self) -> i64 {
1283 self.inner.range_start
1284 }
1285 pub fn range_end(&self) -> i64 {
1286 self.inner.range_end
1287 }
1288 pub fn range(&self) -> &str {
1289 &self.inner.range
1290 }
1291 pub fn traffic_limit(&self) -> i64 {
1292 self.inner.traffic_limit
1293 }
1294 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
1295 &self.inner.rate_limiter
1296 }
1297 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
1298 self.inner.bucket = bucket.into();
1299 }
1300 pub fn set_key(&mut self, key: impl Into<String>) {
1301 self.inner.key = key.into();
1302 }
1303 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
1304 self.inner.version_id = version_id.into();
1305 }
1306 pub fn set_range_start(&mut self, range_start: i64) {
1307 self.inner.range_start = range_start;
1308 }
1309 pub fn set_range_end(&mut self, range_end: i64) {
1310 self.inner.range_end = range_end;
1311 }
1312 pub fn set_range(&mut self, range: impl Into<String>) {
1313 self.inner.range = range.into();
1314 }
1315 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
1316 self.inner.traffic_limit = traffic_limit;
1317 }
1318 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
1319 self.inner.rate_limiter = Some(rate_limiter.into());
1320 }
1321}
1322#[derive(Default)]
1323pub struct GetObjectToFileOutput {
1324 pub(crate) content_range: String,
1325 pub(crate) head_object_output: HeadObjectOutput,
1326}
1327
1328impl Debug for GetObjectToFileOutput {
1329 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1330 write!(f, "({:?}, {})", self.head_object_output, self.content_range)
1331 }
1332}
1333
1334impl OutputParser for GetObjectToFileOutput {
1335 fn parse_by_ref<B>(request: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, meta: Meta) -> Result<Self, TosError> {
1336 let transfer_encoding = request_info.header.get(HEADER_TRANSFER_ENCODING_LOWER).map(|x| x.to_string());
1337 let head_object_output = HeadObjectOutput::parse_by_header(response.headers(), request_info, meta)?;
1338 let content_range = get_header_value(response.headers(), HEADER_CONTENT_RANGE);
1339 let mut target_crc64 = None;
1340 if request.enable_crc && !request.header.contains_key(HEADER_RANGE) &&
1341 (request.query.is_none() || !request.query.as_ref().unwrap().contains_key(QUERY_PROCESS)) {
1342 if let Some(te) = transfer_encoding {
1343 if te != "chunked" {
1344 target_crc64 = Some(head_object_output.hash_crc64ecma);
1345 }
1346 } else {
1347 target_crc64 = Some(head_object_output.hash_crc64ecma);
1348 }
1349 }
1350 let mut crc64 = None;
1351 if target_crc64.is_some() {
1352 crc64 = Some(Arc::new(AtomicU64::new(0)));
1353 }
1354 let mut reader = MultifunctionalReader::with_target_crc64(response, crc64, head_object_output.content_length,
1355 &request, target_crc64);
1356 if let Some(ref rc) = request.request_context {
1357 if let Some(ref rl) = rc.rate_limiter {
1358 reader.set_rate_limiter(rl.clone());
1359 }
1360 if let Some(ref dts) = rc.data_transfer_listener {
1361 reader.set_data_transfer_listener(dts.clone());
1362 reader.inner.operation = request.operation.to_string();
1363 reader.inner.bucket = request.bucket.to_string();
1364 reader.inner.key = request.key.to_string();
1365 reader.inner.retry_count = request.retry_count;
1366 }
1367 }
1368 let file_path = &request.request_context.as_ref().unwrap().file_path;
1369 let path = Path::new(file_path);
1370 match path.parent() {
1371 None => return Err(TosError::client_error(format!("cannot get parent for path {}", file_path))),
1372 Some(p) => {
1373 if !p.exists() {
1374 if let Err(e) = fs::create_dir_all(p) {
1375 return Err(TosError::client_error_with_cause(format!("create dir for parent {} error", p.display()),
1376 GenericError::IoError(e.to_string())));
1377 }
1378 }
1379 }
1380 }
1381 let final_file_path;
1382 if path.exists() && path.is_dir() {
1383 final_file_path = path.join(request.key);
1384 } else {
1385 final_file_path = path.to_path_buf();
1386 }
1387
1388 let temp_file_path = final_file_path.parent().unwrap().join(Uuid::now_v1(&UUID_NODE).to_string());
1389 match File::options().write(true).truncate(true).create(true).open(temp_file_path.clone()) {
1390 Err(e) => {
1391 return Err(TosError::client_error_with_cause("open file to write error", GenericError::IoError(e.to_string())))
1392 }
1393 Ok(mut fd) => {
1394 let mut data = [0u8; DEFAULT_READ_BUFFER_SIZE];
1395 loop {
1396 match reader.read(&mut data) {
1397 Err(re) => {
1398 if re.kind() == ErrorKind::Interrupted {
1399 continue;
1400 }
1401 let _ = fs::remove_file(temp_file_path);
1402 return Err(TosError::client_error_with_cause("read content to write error", GenericError::IoError(re.to_string())));
1403 }
1404 Ok(n) => {
1405 if n == 0 {
1406 break;
1407 }
1408 if let Err(we) = fd.write_all(&data[..n]) {
1409 let _ = fs::remove_file(temp_file_path);
1410 return Err(TosError::client_error_with_cause("write data to file error", GenericError::IoError(we.to_string())));
1411 }
1412 }
1413 }
1414 }
1415 }
1416 }
1417 if let Err(re) = fs::rename(temp_file_path.clone(), final_file_path) {
1418 let _ = fs::remove_file(temp_file_path);
1419 return Err(TosError::client_error_with_cause("rename file error", GenericError::IoError(re.to_string())));
1420 }
1421
1422 Ok(Self {
1423 content_range,
1424 head_object_output,
1425 })
1426 }
1427}
1428
1429impl RequestInfoTrait for GetObjectToFileOutput {
1430 fn request_id(&self) -> &str {
1431 &self.head_object_output.request_info.request_id
1432 }
1433
1434 fn id2(&self) -> &str {
1435 &self.head_object_output.request_info.id2
1436 }
1437
1438 fn status_code(&self) -> isize {
1439 self.head_object_output.request_info.status_code
1440 }
1441
1442 fn header(&self) -> &HashMap<String, String> {
1443 &self.head_object_output.request_info.header
1444 }
1445}
1446
1447impl GetObjectToFileOutput {
1448 pub fn request_id(&self) -> &str {
1449 &self.head_object_output.request_info.request_id
1450 }
1451
1452 pub fn id2(&self) -> &str {
1453 &self.head_object_output.request_info.id2
1454 }
1455
1456 pub fn status_code(&self) -> isize {
1457 self.head_object_output.request_info.status_code
1458 }
1459
1460 pub fn header(&self) -> &HashMap<String, String> {
1461 &self.head_object_output.request_info.header
1462 }
1463 pub fn content_range(&self) -> &str {
1464 &self.content_range
1465 }
1466 pub fn etag(&self) -> &str {
1467 &self.head_object_output.etag
1468 }
1469 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
1470 self.head_object_output.last_modified
1471 }
1472 pub fn last_modify_timestamp(&self) -> Option<DateTime<Utc>> {
1473 self.head_object_output.last_modify_timestamp
1474 }
1475 pub fn delete_marker(&self) -> bool {
1476 self.head_object_output.delete_marker
1477 }
1478 pub fn ssec_algorithm(&self) -> &str {
1479 &self.head_object_output.ssec_algorithm
1480 }
1481 pub fn ssec_key_md5(&self) -> &str {
1482 &self.head_object_output.ssec_key_md5
1483 }
1484 pub fn version_id(&self) -> &str {
1485 &self.head_object_output.version_id
1486 }
1487 pub fn website_redirect_location(&self) -> &str {
1488 &self.head_object_output.website_redirect_location
1489 }
1490 pub fn object_type(&self) -> &str {
1491 &self.head_object_output.object_type
1492 }
1493 pub fn hash_crc64ecma(&self) -> u64 {
1494 self.head_object_output.hash_crc64ecma
1495 }
1496 pub fn storage_class(&self) -> &Option<StorageClassType> {
1497 &self.head_object_output.storage_class
1498 }
1499 pub fn meta(&self) -> &HashMap<String, String> {
1500 &self.head_object_output.meta
1501 }
1502 pub fn content_length(&self) -> i64 {
1503 self.head_object_output.content_length
1504 }
1505 pub fn cache_control(&self) -> &str {
1506 &self.head_object_output.cache_control
1507 }
1508 pub fn content_disposition(&self) -> &str {
1509 &self.head_object_output.content_disposition
1510 }
1511 pub fn content_encoding(&self) -> &str {
1512 &self.head_object_output.content_encoding
1513 }
1514 pub fn content_language(&self) -> &str {
1515 &self.head_object_output.content_language
1516 }
1517 pub fn content_type(&self) -> &str {
1518 &self.head_object_output.content_type
1519 }
1520 pub fn expires(&self) -> Option<DateTime<Utc>> {
1521 self.head_object_output.expires
1522 }
1523 pub fn restore_info(&self) -> &Option<RestoreInfo> {
1524 &self.head_object_output.restore_info
1525 }
1526 pub fn server_side_encryption(&self) -> &str {
1527 &self.head_object_output.server_side_encryption
1528 }
1529 pub fn server_side_encryption_key_id(&self) -> &str {
1530 &self.head_object_output.server_side_encryption_key_id
1531 }
1532 pub fn replication_status(&self) -> &Option<ReplicationStatusType> {
1533 &self.head_object_output.replication_status
1534 }
1535 pub fn tagging_count(&self) -> isize {
1536 self.head_object_output.tagging_count
1537 }
1538}
1539
1540#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
1541pub struct GetObjectACLInput {
1542 pub(crate) generic_input: GenericInput,
1543 pub(crate) bucket: String,
1544 pub(crate) key: String,
1545 pub(crate) version_id: String,
1546}
1547
1548impl GetObjectACLInput {
1549 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
1550 Self {
1551 generic_input: Default::default(),
1552 bucket: bucket.into(),
1553 key: key.into(),
1554 version_id: "".to_string(),
1555 }
1556 }
1557 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
1558 Self {
1559 generic_input: Default::default(),
1560 bucket: bucket.into(),
1561 key: key.into(),
1562 version_id: version_id.into(),
1563 }
1564 }
1565 pub fn bucket(&self) -> &str {
1566 &self.bucket
1567 }
1568 pub fn key(&self) -> &str {
1569 &self.key
1570 }
1571 pub fn version_id(&self) -> &str {
1572 &self.version_id
1573 }
1574 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
1575 self.bucket = bucket.into();
1576 }
1577 pub fn set_key(&mut self, key: impl Into<String>) {
1578 self.key = key.into();
1579 }
1580 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
1581 self.version_id = version_id.into();
1582 }
1583}
1584
1585impl InputDescriptor for GetObjectACLInput {
1586 fn operation(&self) -> &str {
1587 "GetObjectACL"
1588 }
1589 fn bucket(&self) -> Result<&str, TosError> {
1590 Ok(&self.bucket)
1591 }
1592
1593 fn key(&self) -> Result<&str, TosError> {
1594 Ok(&self.key)
1595 }
1596}
1597
1598impl<B> InputTranslator<B> for GetObjectACLInput {
1599 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
1600 let mut request = self.trans_key()?;
1601 request.method = HttpMethodGet;
1602 let mut query = HashMap::with_capacity(2);
1603 query.insert("acl", "".to_string());
1604 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
1605 request.query = Some(query);
1606 Ok(request)
1607 }
1608}
1609
1610#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
1611pub struct GetObjectACLOutput {
1612 #[serde(skip)]
1613 pub(crate) request_info: RequestInfo,
1614 #[serde(skip)]
1615 pub(crate) version_id: String,
1616 #[serde(default)]
1617 #[serde(rename = "Owner")]
1618 pub(crate) owner: Owner,
1619 #[serde(default)]
1620 #[serde(rename = "Grants")]
1621 pub(crate) grants: Vec<Grant>,
1622 #[serde(default)]
1623 #[serde(rename = "BucketOwnerEntrusted")]
1624 pub(crate) bucket_owner_entrusted: bool,
1625 #[serde(default)]
1626 #[serde(rename = "IsDefault")]
1627 pub(crate) is_default: bool,
1628}
1629
1630impl GetObjectACLOutput {
1631 pub fn version_id(&self) -> &str {
1632 &self.version_id
1633 }
1634 pub fn owner(&self) -> &Owner {
1635 &self.owner
1636 }
1637 pub fn grants(&self) -> &Vec<Grant> {
1638 &self.grants
1639 }
1640 pub fn bucket_owner_entrusted(&self) -> bool {
1641 self.bucket_owner_entrusted
1642 }
1643
1644 pub fn is_default(&self) -> bool {
1645 self.is_default
1646 }
1647}
1648
1649impl OutputParser for GetObjectACLOutput {
1650 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
1651 let mut result = parse_json::<Self>(response)?;
1652 result.version_id = get_header_value(response.headers(), HEADER_VERSION_ID);
1653 result.request_info = request_info;
1654 Ok(result)
1655 }
1656}
1657
1658#[derive(Debug, Clone, PartialEq, Default, IfConditionHeader, SsecHeader, GenericInput)]
1659pub struct HeadObjectInput {
1660 pub(crate) generic_input: GenericInput,
1661 pub(crate) bucket: String,
1662 pub(crate) key: String,
1663 pub(crate) version_id: String,
1664 pub(crate) if_match: String,
1665 pub(crate) if_modified_since: Option<DateTime<Utc>>,
1666 pub(crate) if_none_match: String,
1667 pub(crate) if_unmodified_since: Option<DateTime<Utc>>,
1668 pub(crate) ssec_algorithm: String,
1669 pub(crate) ssec_key: String,
1670 pub(crate) ssec_key_md5: String,
1671}
1672
1673impl HeadObjectInput {
1674 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
1675 let mut input = Self::default();
1676 input.bucket = bucket.into();
1677 input.key = key.into();
1678 input
1679 }
1680 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
1681 let mut input = Self::default();
1682 input.bucket = bucket.into();
1683 input.key = key.into();
1684 input.version_id = version_id.into();
1685 input
1686 }
1687 pub fn bucket(&self) -> &str {
1688 &self.bucket
1689 }
1690 pub fn key(&self) -> &str {
1691 &self.key
1692 }
1693 pub fn version_id(&self) -> &str {
1694 &self.version_id
1695 }
1696 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
1697 self.bucket = bucket.into();
1698 }
1699 pub fn set_key(&mut self, key: impl Into<String>) {
1700 self.key = key.into();
1701 }
1702 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
1703 self.version_id = version_id.into();
1704 }
1705}
1706
1707impl InputDescriptor for HeadObjectInput {
1708 fn operation(&self) -> &str {
1709 "HeadObject"
1710 }
1711
1712 fn bucket(&self) -> Result<&str, TosError> {
1713 Ok(&self.bucket)
1714 }
1715
1716 fn key(&self) -> Result<&str, TosError> {
1717 Ok(&self.key)
1718 }
1719}
1720
1721impl<B> InputTranslator<B> for HeadObjectInput {
1722 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
1723 let mut request = self.trans_key()?;
1724 request.method = HttpMethodHead;
1725 if self.version_id != "" {
1726 request.query = Some(HashMap::from([(QUERY_VERSION_ID, self.version_id.clone())]));
1727 }
1728 let header = &mut request.header;
1729 set_if_condition_header(header, self);
1730 set_ssec_header(header, "", self)?;
1731 Ok(request)
1732 }
1733}
1734
1735#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
1736pub struct HeadObjectOutput {
1737 pub(crate) request_info: RequestInfo,
1738 pub(crate) etag: String,
1739 pub(crate) last_modified: Option<DateTime<Utc>>,
1740 pub(crate) last_modify_timestamp: Option<DateTime<Utc>>,
1741 pub(crate) delete_marker: bool,
1742 pub(crate) ssec_algorithm: String,
1743 pub(crate) ssec_key_md5: String,
1744 pub(crate) version_id: String,
1745 pub(crate) website_redirect_location: String,
1746 pub(crate) object_type: String,
1747 pub(crate) hash_crc64ecma: u64,
1748 pub(crate) storage_class: Option<StorageClassType>,
1749 pub(crate) meta: HashMap<String, String>,
1750
1751 pub(crate) content_length: i64,
1752 pub(crate) cache_control: String,
1753 pub(crate) content_disposition: String,
1754 pub(crate) content_encoding: String,
1755 pub(crate) content_language: String,
1756 pub(crate) content_type: String,
1757 pub(crate) expires: Option<DateTime<Utc>>,
1758 pub(crate) restore_info: Option<RestoreInfo>,
1759
1760 pub(crate) server_side_encryption: String,
1761 pub(crate) server_side_encryption_key_id: String,
1762 pub(crate) replication_status: Option<ReplicationStatusType>,
1763 pub(crate) tagging_count: isize,
1764 pub(crate) symlink_target_size: i64,
1765 pub(crate) expiration: String,
1766 pub(crate) is_directory: bool,
1767}
1768
1769impl OutputParser for HeadObjectOutput {
1770 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, meta: Meta) -> Result<Self, TosError> {
1771 Self::parse_by_header(response.headers(), request_info, meta)
1772 }
1773}
1774
1775impl HeadObjectOutput {
1776 pub fn etag(&self) -> &str {
1777 &self.etag
1778 }
1779 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
1780 self.last_modified
1781 }
1782 pub fn last_modify_timestamp(&self) -> Option<DateTime<Utc>> {
1783 self.last_modify_timestamp
1784 }
1785 pub fn delete_marker(&self) -> bool {
1786 self.delete_marker
1787 }
1788 pub fn ssec_algorithm(&self) -> &str {
1789 &self.ssec_algorithm
1790 }
1791 pub fn ssec_key_md5(&self) -> &str {
1792 &self.ssec_key_md5
1793 }
1794 pub fn version_id(&self) -> &str {
1795 &self.version_id
1796 }
1797 pub fn website_redirect_location(&self) -> &str {
1798 &self.website_redirect_location
1799 }
1800 pub fn object_type(&self) -> &str {
1801 &self.object_type
1802 }
1803 pub fn hash_crc64ecma(&self) -> u64 {
1804 self.hash_crc64ecma
1805 }
1806 pub fn storage_class(&self) -> &Option<StorageClassType> {
1807 &self.storage_class
1808 }
1809 pub fn meta(&self) -> &HashMap<String, String> {
1810 &self.meta
1811 }
1812 pub fn content_length(&self) -> i64 {
1813 self.content_length
1814 }
1815 pub fn cache_control(&self) -> &str {
1816 &self.cache_control
1817 }
1818 pub fn content_disposition(&self) -> &str {
1819 &self.content_disposition
1820 }
1821 pub fn content_encoding(&self) -> &str {
1822 &self.content_encoding
1823 }
1824 pub fn content_language(&self) -> &str {
1825 &self.content_language
1826 }
1827 pub fn content_type(&self) -> &str {
1828 &self.content_type
1829 }
1830 pub fn expires(&self) -> Option<DateTime<Utc>> {
1831 self.expires
1832 }
1833 pub fn restore_info(&self) -> &Option<RestoreInfo> {
1834 &self.restore_info
1835 }
1836 pub fn server_side_encryption(&self) -> &str {
1837 &self.server_side_encryption
1838 }
1839 pub fn server_side_encryption_key_id(&self) -> &str {
1840 &self.server_side_encryption_key_id
1841 }
1842 pub fn replication_status(&self) -> &Option<ReplicationStatusType> {
1843 &self.replication_status
1844 }
1845 pub fn tagging_count(&self) -> isize {
1846 self.tagging_count
1847 }
1848 pub fn symlink_target_size(&self) -> i64 {
1849 self.symlink_target_size
1850 }
1851 pub fn expiration(&self) -> &str {
1852 &self.expiration
1853 }
1854
1855 pub fn is_directory(&self) -> bool {
1856 self.is_directory
1857 }
1858 pub(crate) fn parse_by_header(header: &HeaderMap, request_info: RequestInfo, meta: Meta) -> Result<Self, TosError> {
1859 let mut result = Self::default();
1860 result.etag = get_header_value(header, HEADER_ETAG);
1861 result.last_modified = parse_date_time_rfc1123(&get_header_value(header, HEADER_LAST_MODIFIED))?;
1862
1863 let ns = get_header_value_from_str::<u64>(header, HEADER_LAST_MODIFIED_NS, 0)?;
1864 if ns > 0 {
1865 if let Some(last_modified) = &result.last_modified {
1866 result.last_modify_timestamp = Some(last_modified.add(Duration::from_nanos(ns)));
1867 }
1868 }
1869
1870 result.delete_marker = get_header_value_str(header, HEADER_DELETE_MARKER) == TRUE;
1871 result.ssec_algorithm = get_header_value(header, HEADER_SSEC_ALGORITHM);
1872 result.ssec_key_md5 = get_header_value(header, HEADER_SSEC_KEY_MD5);
1873 result.version_id = get_header_value(header, HEADER_VERSION_ID);
1874 result.website_redirect_location = get_header_value(header, HEADER_WEBSITE_REDIRECT_LOCATION);
1875 result.object_type = get_header_value(header, HEADER_OBJECT_TYPE);
1876 result.hash_crc64ecma = get_header_value_from_str::<u64>(header, HEADER_HASH_CRC64ECMA, 0)?;
1877 result.content_length = get_header_value_from_str::<i64>(header, HEADER_CONTENT_LENGTH, -1)?;
1878 result.cache_control = get_header_value(header, HEADER_CACHE_CONTROL);
1879 result.content_disposition = get_header_value_url_decoded(header, HEADER_CONTENT_DISPOSITION);
1880 result.content_encoding = get_header_value(header, HEADER_CONTENT_ENCODING);
1881 result.content_language = get_header_value(header, HEADER_CONTENT_LANGUAGE);
1882 result.content_type = get_header_value(header, HEADER_CONTENT_TYPE);
1883 result.expires = parse_date_time_rfc1123(&get_header_value(header, HEADER_EXPIRES))?;
1884 let restore = get_header_value(header, HEADER_RESTORE);
1885 let restore_trim = restore.trim();
1886 if restore_trim != "" {
1887 if restore_trim == "ongoing-request=\"true\"" {
1888 result.restore_info = Some(RestoreInfo {
1889 restore_status: RestoreStatus {
1890 ongoing_request: true,
1891 expiry_date: None,
1892 },
1893 restore_param: Some(RestoreParam {
1894 request_date: parse_date_time_rfc1123(&get_header_value(header, HEADER_RESTORE_REQUEST_DATE))?,
1895 expiry_days: get_header_value_from_str::<isize>(header, HEADER_RESTORE_EXPIRY_DAYS, 0)?,
1896 tier: TierType::from(get_header_value_str(header, HEADER_RESTORE_TIER)),
1897 }),
1898 });
1899 } else {
1900 let pattern = "ongoing-request=\"false\", expiry-date=\"";
1901 if let Some(idx) = restore_trim.find(pattern) {
1902 let mut expiry_date = &restore_trim[idx..];
1903 if expiry_date.len() > 0 && &expiry_date[expiry_date.len() - 1..] == "\"" {
1904 expiry_date = &expiry_date[..expiry_date.len() - 1];
1905 }
1906 result.restore_info = Some(RestoreInfo {
1907 restore_status: RestoreStatus {
1908 ongoing_request: false,
1909 expiry_date: parse_date_time_rfc1123(expiry_date)?,
1910 },
1911 restore_param: None,
1912 });
1913 }
1914 }
1915 }
1916 result.server_side_encryption = get_header_value(header, HEADER_SERVER_SIDE_ENCRYPTION);
1917 result.server_side_encryption_key_id = get_header_value(header, HEADER_SERVER_SIDE_ENCRYPTION_KMS_KEY_ID);
1918 result.storage_class = StorageClassType::from(get_header_value_str(header, HEADER_STORAGE_CLASS));
1919 result.replication_status = ReplicationStatusType::from(get_header_value_str(header, HEADER_REPLICATION_STATUS));
1920 result.tagging_count = get_header_value_from_str::<isize>(header, HEADER_TAGGING_COUNT, 0)?;
1921 result.symlink_target_size = get_header_value_from_str::<i64>(header, HEADER_SYMLINK_TARGET_SIZE, -1)?;
1922 result.expiration = get_header_value(header, HEADER_EXPIRATION);
1923 result.is_directory = get_header_value_str(header, HEADER_DIRECTORY) == TRUE;
1924 result.meta = meta;
1925 result.request_info = request_info;
1926 Ok(result)
1927 }
1928}
1929
1930#[derive(Debug, Clone, PartialEq, Default)]
1931pub struct RestoreInfo {
1932 pub(crate) restore_status: RestoreStatus,
1933 pub(crate) restore_param: Option<RestoreParam>,
1934}
1935
1936impl RestoreInfo {
1937 pub fn restore_status(&self) -> &RestoreStatus {
1938 &self.restore_status
1939 }
1940 pub fn restore_param(&self) -> &Option<RestoreParam> {
1941 &self.restore_param
1942 }
1943}
1944
1945#[derive(Debug, Clone, PartialEq, Default)]
1946pub struct RestoreStatus {
1947 pub(crate) ongoing_request: bool,
1948 pub(crate) expiry_date: Option<DateTime<Utc>>,
1949}
1950
1951impl RestoreStatus {
1952 pub fn ongoing_request(&self) -> bool {
1953 self.ongoing_request
1954 }
1955 pub fn expiry_date(&self) -> Option<DateTime<Utc>> {
1956 self.expiry_date
1957 }
1958}
1959
1960#[derive(Debug, Clone, PartialEq, Default)]
1961pub struct RestoreParam {
1962 pub(crate) request_date: Option<DateTime<Utc>>,
1963 pub(crate) expiry_days: isize,
1964 pub(crate) tier: Option<TierType>,
1965}
1966
1967impl RestoreParam {
1968 pub fn request_date(&self) -> Option<DateTime<Utc>> {
1969 self.request_date
1970 }
1971 pub fn expiry_days(&self) -> isize {
1972 self.expiry_days
1973 }
1974 pub fn tier(&self) -> &Option<TierType> {
1975 &self.tier
1976 }
1977}
1978
1979#[derive(Debug, Clone, HttpBasicHeader, AclHeader, MiscHeader, GenericInput)]
1980#[enable_content_length]
1981pub(crate) struct AppendObjectBasicInput {
1982 pub(crate) generic_input: GenericInput,
1983 pub(crate) bucket: String,
1984 pub(crate) key: String,
1985 pub(crate) offset: i64,
1986 pub(crate) content_length: i64,
1987 pub(crate) cache_control: String,
1988 pub(crate) content_disposition: String,
1989 pub(crate) content_encoding: String,
1990 pub(crate) content_language: String,
1991 pub(crate) content_type: String,
1992 pub(crate) expires: Option<DateTime<Utc>>,
1993 pub(crate) acl: Option<ACLType>,
1994 pub(crate) grant_full_control: String,
1995 pub(crate) grant_read: String,
1996 pub(crate) grant_read_acp: String,
1997 pub(crate) grant_write: String,
1998 pub(crate) grant_write_acp: String,
1999 pub(crate) meta: HashMap<String, String>,
2000 pub(crate) website_redirect_location: String,
2001 pub(crate) storage_class: Option<StorageClassType>,
2002 pub(crate) traffic_limit: i64,
2003 pub(crate) if_match: String,
2004 pub(crate) if_none_match: String,
2005 pub(crate) pre_hash_crc64ecma: u64,
2006 pub(crate) object_expires: i64,
2007 pub(crate) rate_limiter: Option<Arc<RateLimiter>>,
2008 pub(crate) data_transfer_listener: Option<Sender<DataTransferStatus>>,
2009 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
2010 pub(crate) notification_custom_parameters: String,
2011}
2012
2013
2014impl InputDescriptor for AppendObjectBasicInput {
2015 fn operation(&self) -> &str {
2016 "AppendObject"
2017 }
2018
2019 fn bucket(&self) -> Result<&str, TosError> {
2020 Ok(&self.bucket)
2021 }
2022
2023 fn key(&self) -> Result<&str, TosError> {
2024 Ok(&self.key)
2025 }
2026}
2027
2028impl<B> InputTranslator<B> for AppendObjectBasicInput {
2029 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
2030 if self.offset < 0
2031 {
2032 return Err(TosError::client_error("invalid offset for append object"));
2033 }
2034 let mut request = self.trans_key()?;
2035 request.method = HttpMethodPost;
2036 if let Some(ref rl) = self.rate_limiter {
2037 let mut rc = RequestContext::default();
2038 rc.rate_limiter = Some(rl.clone());
2039 request.request_context = Some(rc);
2040 }
2041
2042 if let Some(ref dts) = self.data_transfer_listener {
2043 if request.request_context.is_some() {
2044 request.request_context.as_mut().unwrap().data_transfer_listener = Some(dts.clone());
2045 } else {
2046 let mut rc = RequestContext::default();
2047 rc.data_transfer_listener = Some(dts.clone());
2048 request.request_context = Some(rc);
2049 }
2050 } else if let Some(ref adts) = self.async_data_transfer_listener {
2051 if request.request_context.is_some() {
2052 request.request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
2053 } else {
2054 let mut rc = RequestContext::default();
2055 rc.async_data_transfer_listener = Some(adts.clone());
2056 request.request_context = Some(rc);
2057 }
2058 }
2059
2060 if self.pre_hash_crc64ecma > 0 {
2061 if request.request_context.is_some() {
2062 request.request_context.as_mut().unwrap().init_crc64 = Some(self.pre_hash_crc64ecma);
2063 } else {
2064 let mut rc = RequestContext::default();
2065 rc.init_crc64 = Some(self.pre_hash_crc64ecma);
2066 request.request_context = Some(rc);
2067 }
2068 }
2069 let header = &mut request.header;
2070 set_http_basic_header(header, config_holder.disable_encoding_meta, self);
2071 set_acl_header(header, self);
2072 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
2073 set_misc_header(header, self);
2074 if self.traffic_limit > 0 {
2075 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
2076 }
2077 map_insert(header, HEADER_X_IF_MATCH, &self.if_match);
2078 map_insert(header, HEADER_IF_NONE_MATCH, &self.if_none_match);
2079 if self.object_expires >= 0 {
2080 header.insert(HEADER_OBJECT_EXPIRES, self.object_expires.to_string());
2081 }
2082 map_insert(header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
2083 let mut query = HashMap::with_capacity(2);
2084 query.insert("append", "".to_string());
2085 query.insert(QUERY_OFFSET, self.offset.to_string());
2086 request.query = Some(query);
2087 Ok(request)
2088 }
2089}
2090
2091impl Default for AppendObjectBasicInput {
2092 fn default() -> Self {
2093 Self {
2094 generic_input: Default::default(),
2095 bucket: "".to_string(),
2096 key: "".to_string(),
2097 offset: 0,
2098 content_length: -1,
2099 cache_control: "".to_string(),
2100 content_disposition: "".to_string(),
2101 content_encoding: "".to_string(),
2102 content_language: "".to_string(),
2103 content_type: "".to_string(),
2104 expires: None,
2105 acl: None,
2106 grant_full_control: "".to_string(),
2107 grant_read: "".to_string(),
2108 grant_read_acp: "".to_string(),
2109 grant_write: "".to_string(),
2110 grant_write_acp: "".to_string(),
2111 meta: Default::default(),
2112 website_redirect_location: "".to_string(),
2113 storage_class: None,
2114 traffic_limit: 0,
2115 if_match: "".to_string(),
2116 if_none_match: "".to_string(),
2117 pre_hash_crc64ecma: 0,
2118 object_expires: -1,
2119 rate_limiter: None,
2120 data_transfer_listener: None,
2121 async_data_transfer_listener: None,
2122 notification_custom_parameters: "".to_string(),
2123 }
2124 }
2125}
2126
2127#[derive(Debug, HttpBasicHeader, AclHeader, MiscHeader, GenericInput)]
2128#[enable_content_length]
2129#[handle_content]
2130#[use_inner]
2131pub struct AppendObjectInput<B>
2132{
2133 pub(crate) inner: AppendObjectBasicInput,
2134 pub(crate) content: Arc<RefCell<Option<B>>>,
2135}
2136
2137unsafe impl<B> Sync for AppendObjectInput<B> {}
2138unsafe impl<B> Send for AppendObjectInput<B> {}
2139
2140impl<B> InputDescriptor for AppendObjectInput<B>
2141{
2142 fn operation(&self) -> &str {
2143 "AppendObject"
2144 }
2145 fn bucket(&self) -> Result<&str, TosError> {
2146 Ok(&self.inner.bucket)
2147 }
2148
2149 fn key(&self) -> Result<&str, TosError> {
2150 Ok(&self.inner.key)
2151 }
2152}
2153
2154impl<B> InputTranslator<B> for AppendObjectInput<B>
2155{
2156 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
2157 let mut request = self.inner.trans(config_holder)?;
2158 request.operation = self.operation();
2159 request.body = self.content.take();
2160 Ok(request)
2161 }
2162}
2163
2164impl<B> AppendObjectInput<B>
2165{
2166 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
2167 let mut input = Self::default();
2168 input.inner.bucket = bucket.into();
2169 input.inner.key = key.into();
2170 input
2171 }
2172 pub fn new_with_offset(bucket: impl Into<String>, key: impl Into<String>, offset: i64) -> Self {
2173 let mut input = Self::default();
2174 input.inner.bucket = bucket.into();
2175 input.inner.key = key.into();
2176 input.inner.offset = offset;
2177 input
2178 }
2179 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl Into<B>) -> Self {
2180 let mut input = Self::default();
2181 input.inner.bucket = bucket.into();
2182 input.inner.key = key.into();
2183 input.set_content(content);
2184 input
2185 }
2186 pub fn new_with_offset_content(bucket: impl Into<String>, key: impl Into<String>, offset: i64, content: impl Into<B>) -> Self {
2187 let mut input = Self::default();
2188 input.inner.bucket = bucket.into();
2189 input.inner.key = key.into();
2190 input.inner.offset = offset;
2191 input.set_content(content);
2192 input
2193 }
2194 pub fn bucket(&self) -> &str {
2195 &self.inner.bucket
2196 }
2197 pub fn key(&self) -> &str {
2198 &self.inner.key
2199 }
2200 pub fn offset(&self) -> i64 {
2201 self.inner.offset
2202 }
2203 pub fn content(&self) -> Ref<Option<B>> {
2204 self.content.borrow()
2205 }
2206 pub fn meta(&self) -> &HashMap<String, String> {
2207 &self.inner.meta
2208 }
2209 pub fn traffic_limit(&self) -> i64 {
2210 self.inner.traffic_limit
2211 }
2212 pub fn if_match(&self) -> &str {
2213 &self.inner.if_match
2214 }
2215 pub fn if_none_match(&self) -> &str {
2216 &self.inner.if_none_match
2217 }
2218 pub fn pre_hash_crc64ecma(&self) -> u64 {
2219 self.inner.pre_hash_crc64ecma
2220 }
2221 pub fn object_expires(&self) -> i64 {
2222 self.inner.object_expires
2223 }
2224 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
2225 &self.inner.rate_limiter
2226 }
2227 pub fn notification_custom_parameters(&self) -> &str {
2228 &self.inner.notification_custom_parameters
2229 }
2230 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
2231 self.inner.bucket = bucket.into();
2232 }
2233 pub fn set_key(&mut self, key: impl Into<String>) {
2234 self.inner.key = key.into();
2235 }
2236 pub fn set_offset(&mut self, offset: i64) {
2237 self.inner.offset = offset;
2238 }
2239 pub fn set_content(&mut self, content: impl Into<B>) {
2240 self.content = Arc::new(RefCell::new(Some(content.into())));
2241 }
2242 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
2243 self.inner.meta = meta.into();
2244 }
2245 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
2246 self.inner.traffic_limit = traffic_limit;
2247 }
2248 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
2249 self.inner.if_match = if_match.into();
2250 }
2251 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
2252 self.inner.if_none_match = if_none_match.into();
2253 }
2254 pub fn set_pre_hash_crc64ecma(&mut self, pre_hash_crc64ecma: u64) {
2255 self.inner.pre_hash_crc64ecma = pre_hash_crc64ecma;
2256 }
2257 pub fn set_object_expires(&mut self, object_expires: i64) {
2258 self.inner.object_expires = object_expires;
2259 }
2260 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
2261 self.inner.rate_limiter = Some(rate_limiter.into());
2262 }
2263 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
2264 self.inner.notification_custom_parameters = notification_custom_parameters.into();
2265 }
2266}
2267
2268impl<B> Default for AppendObjectInput<B>
2269{
2270 fn default() -> Self {
2271 Self {
2272 inner: Default::default(),
2273 content: Arc::new(RefCell::new(None)),
2274 }
2275 }
2276}
2277
2278impl<B> DataTransferListener for AppendObjectInput<B> {
2279 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
2280 &self.inner.data_transfer_listener
2281 }
2282
2283 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
2284 self.inner.data_transfer_listener = Some(listener.into());
2285 }
2286}
2287
2288#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
2289pub struct AppendObjectOutput {
2290 pub(crate) request_info: RequestInfo,
2291 pub(crate) next_append_offset: i64,
2292 pub(crate) hash_crc64ecma: u64,
2293}
2294
2295impl OutputParser for AppendObjectOutput {
2296 fn parse_by_ref<B>(request: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
2297 let hash_crc64ecma = get_header_value_from_str::<u64>(response.headers(), HEADER_HASH_CRC64ECMA, 0)?;
2298 if let Some(ref rc) = request.request_context {
2299 if let Some(calc_hash_crc64ecma) = rc.crc64 {
2300 if calc_hash_crc64ecma != hash_crc64ecma {
2301 return Err(TosError::client_error(format!("expect crc64 {hash_crc64ecma}, actual crc64 {calc_hash_crc64ecma}")));
2302 }
2303 }
2304 }
2305 let mut result = Self::default();
2306 result.next_append_offset = get_header_value_from_str::<i64>(response.headers(), HEADER_NEXT_APPEND_OFFSET, 0)?;
2307 result.hash_crc64ecma = hash_crc64ecma;
2308 result.request_info = request_info;
2309 Ok(result)
2310 }
2311}
2312
2313impl AppendObjectOutput {
2314 pub fn next_append_offset(&self) -> i64 {
2315 self.next_append_offset
2316 }
2317 pub fn hash_crc64ecma(&self) -> u64 {
2318 self.hash_crc64ecma
2319 }
2320}
2321
2322#[derive(Debug, Default, HttpBasicHeader, AclHeader, MiscHeader, GenericInput)]
2323#[enable_content_length]
2324#[use_inner]
2325pub struct AppendObjectFromBufferInput {
2326 pub(crate) inner: AppendObjectBasicInput,
2327 pub(crate) content: Option<MultiBytes>,
2328}
2329
2330impl InputDescriptor for AppendObjectFromBufferInput {
2331 fn operation(&self) -> &str {
2332 "AppendObjectFromBuffer"
2333 }
2334 fn bucket(&self) -> Result<&str, TosError> {
2335 Ok(&self.inner.bucket)
2336 }
2337 fn key(&self) -> Result<&str, TosError> {
2338 Ok(&self.inner.key)
2339 }
2340}
2341
2342impl<B> InputTranslator<B> for AppendObjectFromBufferInput
2343where
2344 B: BuildMultiBufferReader,
2345{
2346 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
2347 let mut request = self.inner.trans(config_holder)?;
2348 request.operation = self.operation();
2349 if let Some(content) = &self.content {
2350 let (body, len) = B::new(content.clone())?;
2351 request.body = Some(body);
2352 if self.inner.content_length < 0 {
2353 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
2354 }
2355 }
2356 Ok(request)
2357 }
2358}
2359
2360impl DataTransferListener for AppendObjectFromBufferInput {
2361 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
2362 &self.inner.data_transfer_listener
2363 }
2364
2365 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
2366 self.inner.data_transfer_listener = Some(listener.into());
2367 }
2368}
2369
2370impl AppendObjectFromBufferInput {
2371 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
2372 let mut input = Self::default();
2373 input.inner.bucket = bucket.into();
2374 input.inner.key = key.into();
2375 input
2376 }
2377 pub fn new_with_offset(bucket: impl Into<String>, key: impl Into<String>, offset: i64) -> Self {
2378 let mut input = Self::default();
2379 input.inner.bucket = bucket.into();
2380 input.inner.key = key.into();
2381 input.inner.offset = offset;
2382 input
2383 }
2384 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl AsRef<[u8]>) -> Self {
2385 let mut input = Self::default();
2386 input.inner.bucket = bucket.into();
2387 input.inner.key = key.into();
2388 input.set_content(content);
2389 input
2390 }
2391 pub fn new_with_offset_content(bucket: impl Into<String>, key: impl Into<String>, offset: i64, content: impl AsRef<[u8]>) -> Self {
2392 let mut input = Self::default();
2393 input.inner.bucket = bucket.into();
2394 input.inner.key = key.into();
2395 input.inner.offset = offset;
2396 input.set_content(content);
2397 input
2398 }
2399 pub fn bucket(&self) -> &str {
2400 &self.inner.bucket
2401 }
2402 pub fn key(&self) -> &str {
2403 &self.inner.key
2404 }
2405 pub fn offset(&self) -> i64 {
2406 self.inner.offset
2407 }
2408 pub fn content(&self) -> Option<impl Iterator<Item=&Bytes>> {
2409 match &self.content {
2410 None => None,
2411 Some(x) => Some(x.inner.iter()),
2412 }
2413 }
2414 pub fn meta(&self) -> &HashMap<String, String> {
2415 &self.inner.meta
2416 }
2417 pub fn traffic_limit(&self) -> i64 {
2418 self.inner.traffic_limit
2419 }
2420 pub fn if_match(&self) -> &str {
2421 &self.inner.if_match
2422 }
2423 pub fn if_none_match(&self) -> &str {
2424 &self.inner.if_none_match
2425 }
2426 pub fn pre_hash_crc64ecma(&self) -> u64 {
2427 self.inner.pre_hash_crc64ecma
2428 }
2429 pub fn object_expires(&self) -> i64 {
2430 self.inner.object_expires
2431 }
2432 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
2433 &self.inner.rate_limiter
2434 }
2435 pub fn notification_custom_parameters(&self) -> &str {
2436 &self.inner.notification_custom_parameters
2437 }
2438 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
2439 self.inner.bucket = bucket.into();
2440 }
2441 pub fn set_key(&mut self, key: impl Into<String>) {
2442 self.inner.key = key.into();
2443 }
2444 pub fn set_offset(&mut self, offset: i64) {
2445 self.inner.offset = offset;
2446 }
2447 pub fn set_content_with_bytes_list(&mut self, bytes_list: impl Iterator<Item=impl Into<Bytes>>) {
2448 let mut list = LinkedList::new();
2449 let mut size = 0;
2450 for item in bytes_list {
2451 let item = item.into();
2452 size += item.len();
2453 list.push_back(item);
2454 }
2455 self.content = Some(MultiBytes::new(list, size));
2456 }
2457 pub fn set_content(&mut self, content: impl AsRef<[u8]>) {
2458 let item = content.as_ref().to_owned();
2459 let size = item.len();
2460 let mut list = LinkedList::new();
2461 list.push_back(Bytes::from(item));
2462 self.content = Some(MultiBytes::new(list, size));
2463 }
2464 pub fn append_content(&mut self, content: impl AsRef<[u8]>) {
2465 if let Some(contents) = &mut self.content {
2466 contents.push(Bytes::from(content.as_ref().to_owned()));
2467 } else {
2468 self.set_content(content);
2469 }
2470 }
2471 pub fn set_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
2472 let item = content.into();
2473 let size = item.len();
2474 let mut list = LinkedList::new();
2475 list.push_back(Bytes::from(item));
2476 self.content = Some(MultiBytes::new(list, size));
2477 }
2478 pub fn append_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
2479 if let Some(contents) = &mut self.content {
2480 contents.push(Bytes::from(content.into()));
2481 } else {
2482 self.set_content_nocopy(content);
2483 }
2484 }
2485 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
2486 self.inner.meta = meta.into();
2487 }
2488 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
2489 self.inner.traffic_limit = traffic_limit;
2490 }
2491 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
2492 self.inner.if_match = if_match.into();
2493 }
2494 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
2495 self.inner.if_none_match = if_none_match.into();
2496 }
2497 pub fn set_pre_hash_crc64ecma(&mut self, pre_hash_crc64ecma: u64) {
2498 self.inner.pre_hash_crc64ecma = pre_hash_crc64ecma;
2499 }
2500 pub fn set_object_expires(&mut self, object_expires: i64) {
2501 self.inner.object_expires = object_expires;
2502 }
2503 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
2504 self.inner.rate_limiter = Some(rate_limiter.into());
2505 }
2506 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
2507 self.inner.notification_custom_parameters = notification_custom_parameters.into();
2508 }
2509}
2510#[derive(Debug, HttpBasicHeader, AclHeader, MiscHeader, GenericInput)]
2511#[enable_content_length]
2512#[use_inner]
2513pub struct AppendObjectFromFileInput {
2514 pub(crate) inner: AppendObjectBasicInput,
2515 pub(crate) file_path: String,
2516}
2517
2518impl InputDescriptor for AppendObjectFromFileInput {
2519 fn operation(&self) -> &str {
2520 "AppendObjectFromFile"
2521 }
2522
2523 fn bucket(&self) -> Result<&str, TosError> {
2524 Ok(&self.inner.bucket)
2525 }
2526
2527 fn key(&self) -> Result<&str, TosError> {
2528 Ok(&self.inner.key)
2529 }
2530}
2531
2532impl<B> InputTranslator<B> for AppendObjectFromFileInput
2533where
2534 B: BuildFileReader,
2535{
2536 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
2537 let mut request = self.inner.trans(config_holder)?;
2538 request.operation = self.operation();
2539 if self.file_path != "" {
2540 let (body, len) = B::new(&self.file_path)?;
2541 request.body = Some(body);
2542 if let Some(l) = len {
2543 if self.inner.content_length < 0 {
2544 request.header.insert(HEADER_CONTENT_LENGTH, l.to_string());
2545 }
2546 }
2547 }
2548 Ok(request)
2549 }
2550}
2551
2552impl DataTransferListener for AppendObjectFromFileInput {
2553 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
2554 &self.inner.data_transfer_listener
2555 }
2556
2557 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
2558 self.inner.data_transfer_listener = Some(listener.into());
2559 }
2560}
2561
2562impl AppendObjectFromFileInput {
2563 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
2564 let mut input = Self::default();
2565 input.inner.bucket = bucket.into();
2566 input.inner.key = key.into();
2567 input
2568 }
2569 pub fn new_with_file_path(bucket: impl Into<String>, key: impl Into<String>, file_path: impl Into<String>) -> Self {
2570 let mut input = Self::default();
2571 input.inner.bucket = bucket.into();
2572 input.inner.key = key.into();
2573 input.file_path = file_path.into();
2574 input
2575 }
2576 pub fn new_with_offset(bucket: impl Into<String>, key: impl Into<String>, offset: i64) -> Self {
2577 let mut input = Self::default();
2578 input.inner.bucket = bucket.into();
2579 input.inner.key = key.into();
2580 input.inner.offset = offset;
2581 input
2582 }
2583 pub fn new_with_offset_file_path(bucket: impl Into<String>, key: impl Into<String>, offset: i64, file_path: impl Into<String>) -> Self {
2584 let mut input = Self::default();
2585 input.inner.bucket = bucket.into();
2586 input.inner.key = key.into();
2587 input.inner.offset = offset;
2588 input.file_path = file_path.into();
2589 input
2590 }
2591 pub fn bucket(&self) -> &str {
2592 &self.inner.bucket
2593 }
2594 pub fn key(&self) -> &str {
2595 &self.inner.key
2596 }
2597 pub fn file_path(&self) -> &str {
2598 &self.file_path
2599 }
2600 pub fn meta(&self) -> &HashMap<String, String> {
2601 &self.inner.meta
2602 }
2603 pub fn traffic_limit(&self) -> i64 {
2604 self.inner.traffic_limit
2605 }
2606 pub fn if_match(&self) -> &str {
2607 &self.inner.if_match
2608 }
2609 pub fn if_none_match(&self) -> &str {
2610 &self.inner.if_none_match
2611 }
2612 pub fn object_expires(&self) -> i64 {
2613 self.inner.object_expires
2614 }
2615 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
2616 &self.inner.rate_limiter
2617 }
2618 pub fn notification_custom_parameters(&self) -> &str {
2619 &self.inner.notification_custom_parameters
2620 }
2621 pub fn offset(&self) -> i64 {
2622 self.inner.offset
2623 }
2624 pub fn pre_hash_crc64ecma(&self) -> u64 {
2625 self.inner.pre_hash_crc64ecma
2626 }
2627 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
2628 self.inner.bucket = bucket.into();
2629 }
2630 pub fn set_key(&mut self, key: impl Into<String>) {
2631 self.inner.key = key.into();
2632 }
2633 pub fn set_file_path(&mut self, file_path: impl Into<String>) {
2634 self.file_path = file_path.into();
2635 }
2636 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
2637 self.inner.meta = meta.into();
2638 }
2639 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
2640 self.inner.traffic_limit = traffic_limit;
2641 }
2642 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
2643 self.inner.if_match = if_match.into();
2644 }
2645 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
2646 self.inner.if_none_match = if_none_match.into();
2647 }
2648 pub fn set_object_expires(&mut self, object_expires: i64) {
2649 self.inner.object_expires = object_expires;
2650 }
2651 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
2652 self.inner.rate_limiter = Some(rate_limiter.into());
2653 }
2654 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
2655 self.inner.notification_custom_parameters = notification_custom_parameters.into();
2656 }
2657 pub fn set_offset(&mut self, offset: i64) {
2658 self.inner.offset = offset;
2659 }
2660 pub fn set_pre_hash_crc64ecma(&mut self, pre_hash_crc64ecma: u64) {
2661 self.inner.pre_hash_crc64ecma = pre_hash_crc64ecma;
2662 }
2663}
2664
2665impl Default for AppendObjectFromFileInput {
2666 fn default() -> Self {
2667 Self {
2668 inner: Default::default(),
2669 file_path: "".to_string(),
2670 }
2671 }
2672}
2673
2674#[derive(Debug, Clone, PartialEq, ListCommonQuery, GenericInput)]
2675pub struct ListObjectsInput {
2676 pub(crate) generic_input: GenericInput,
2677 pub(crate) bucket: String,
2678 pub(crate) prefix: String,
2679 pub(crate) delimiter: String,
2680 pub(crate) marker: String,
2681 pub(crate) max_keys: isize,
2682 pub(crate) encoding_type: String,
2683 pub(crate) fetch_meta: bool,
2684}
2685
2686impl Default for ListObjectsInput {
2687 fn default() -> Self {
2688 Self {
2689 generic_input: Default::default(),
2690 bucket: "".to_string(),
2691 prefix: "".to_string(),
2692 delimiter: "".to_string(),
2693 marker: "".to_string(),
2694 max_keys: -1,
2695 encoding_type: "".to_string(),
2696 fetch_meta: false,
2697 }
2698 }
2699}
2700
2701impl ListObjectsInput {
2702 pub fn new(bucket: impl Into<String>) -> Self {
2703 let mut input = Self::default();
2704 input.bucket = bucket.into();
2705 input
2706 }
2707
2708 pub fn bucket(&self) -> &str {
2709 &self.bucket
2710 }
2711 pub fn marker(&self) -> &str {
2712 &self.marker
2713 }
2714 pub fn max_keys(&self) -> isize {
2715 self.max_keys
2716 }
2717 pub fn fetch_meta(&self) -> bool {
2718 self.fetch_meta
2719 }
2720 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
2721 self.bucket = bucket.into();
2722 }
2723 pub fn set_marker(&mut self, marker: impl Into<String>) {
2724 self.marker = marker.into();
2725 }
2726 pub fn set_max_keys(&mut self, max_keys: isize) {
2727 self.max_keys = max_keys;
2728 }
2729 pub fn set_fetch_meta(&mut self, fetch_meta: bool) {
2730 self.fetch_meta = fetch_meta;
2731 }
2732}
2733
2734impl InputDescriptor for ListObjectsInput {
2735 fn operation(&self) -> &str {
2736 "ListObjects"
2737 }
2738 fn bucket(&self) -> Result<&str, TosError> {
2739 Ok(&self.bucket)
2740 }
2741}
2742
2743impl<B> InputTranslator<B> for ListObjectsInput {
2744 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
2745 let mut request = self.trans_bucket()?;
2746 request.method = HttpMethodGet;
2747 let mut query = HashMap::with_capacity(6);
2748 set_list_common_query(&mut query, self);
2749 map_insert(&mut query, QUERY_MARKER, &self.marker);
2750 if self.max_keys >= 0 {
2751 query.insert(QUERY_MAX_KEYS, self.max_keys.to_string());
2752 }
2753 if self.fetch_meta {
2754 query.insert(QUERY_FETCH_META, self.fetch_meta.to_string());
2755 }
2756 request.query = Some(query);
2757 Ok(request)
2758 }
2759}
2760
2761#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
2762pub struct ListObjectsOutput {
2763 #[serde(skip)]
2764 pub(crate) request_info: RequestInfo,
2765 #[serde(default)]
2766 #[serde(rename = "Name")]
2767 pub(crate) name: String,
2768 #[serde(default)]
2769 #[serde(rename = "Prefix")]
2770 pub(crate) prefix: String,
2771 #[serde(default)]
2772 #[serde(rename = "Marker")]
2773 pub(crate) marker: String,
2774 #[serde(default)]
2775 #[serde(rename = "MaxKeys")]
2776 pub(crate) max_keys: isize,
2777 #[serde(default)]
2778 #[serde(rename = "Delimiter")]
2779 pub(crate) delimiter: String,
2780 #[serde(default)]
2781 #[serde(rename = "IsTruncated")]
2782 pub(crate) is_truncated: bool,
2783 #[serde(default)]
2784 #[serde(rename = "EncodingType")]
2785 pub(crate) encoding_type: String,
2786 #[serde(default)]
2787 #[serde(rename = "NextMarker")]
2788 pub(crate) next_marker: String,
2789 #[serde(default)]
2790 #[serde(rename = "CommonPrefixes")]
2791 pub(crate) common_prefixes: Vec<ListedCommonPrefix>,
2792 #[serde(default)]
2793 #[serde(rename = "Contents")]
2794 pub(crate) contents: Vec<ListedObject>,
2795}
2796
2797impl OutputParser for ListObjectsOutput {
2798 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
2799 let mut result = parse_json::<Self>(response)?;
2800 for content in &mut result.contents {
2801 if let Some(x) = content.last_modified_string.take() {
2802 content.last_modified = parse_date_time_iso8601(&x)?;
2803 }
2804
2805 if let Some(x) = content.user_meta.take() {
2806 let mut meta = HashMap::with_capacity(x.len());
2807 for item in x {
2808 if let Ok(dk) = urlencoding::decode(&item.key[HEADER_PREFIX_META.len()..]) {
2809 if let Ok(dv) = urlencoding::decode(item.value.as_str()) {
2810 meta.insert(dk.to_string(), dv.to_string());
2811 }
2812 }
2813 }
2814 content.meta = meta;
2815 }
2816 }
2817 for common_prefix in &mut result.common_prefixes {
2818 if let Some(x) = common_prefix.last_modified_string.take() {
2819 common_prefix.last_modified = parse_date_time_iso8601(&x)?;
2820 }
2821 }
2822 result.request_info = request_info;
2823 Ok(result)
2824 }
2825}
2826
2827impl ListObjectsOutput {
2828 pub fn name(&self) -> &str {
2829 &self.name
2830 }
2831 pub fn prefix(&self) -> &str {
2832 &self.prefix
2833 }
2834 pub fn marker(&self) -> &str {
2835 &self.marker
2836 }
2837 pub fn max_keys(&self) -> isize {
2838 self.max_keys
2839 }
2840 pub fn delimiter(&self) -> &str {
2841 &self.delimiter
2842 }
2843 pub fn is_truncated(&self) -> bool {
2844 self.is_truncated
2845 }
2846 pub fn encoding_type(&self) -> &str {
2847 &self.encoding_type
2848 }
2849 pub fn next_marker(&self) -> &str {
2850 &self.next_marker
2851 }
2852 pub fn common_prefixes(&self) -> &Vec<ListedCommonPrefix> {
2853 &self.common_prefixes
2854 }
2855 pub fn contents(&self) -> &Vec<ListedObject> {
2856 &self.contents
2857 }
2858}
2859
2860
2861#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
2862pub struct ListedObject {
2863 #[serde(default)]
2864 #[serde(rename = "Key")]
2865 pub(crate) key: String,
2866 #[serde(default)]
2867 #[serde(rename = "LastModified")]
2868 pub(crate) last_modified_string: Option<String>,
2869 #[serde(skip)]
2870 pub(crate) last_modified: Option<DateTime<Utc>>,
2871 #[serde(default)]
2872 #[serde(rename = "ETag")]
2873 pub(crate) etag: String,
2874 #[serde(default)]
2875 #[serde(rename = "Size")]
2876 pub(crate) size: i64,
2877 #[serde(default)]
2878 #[serde(rename = "Owner")]
2879 pub(crate) owner: Owner,
2880 #[serde(default)]
2881 #[serde(rename = "StorageClass")]
2882 pub(crate) storage_class: Option<StorageClassType>,
2883 #[serde(default)]
2884 #[serde(rename = "HashCrc64ecma")]
2885 pub(crate) hash_crc64ecma: String,
2886 #[serde(default)]
2887 #[serde(rename = "UserMeta")]
2888 pub(crate) user_meta: Option<Vec<MetaItem>>,
2889 #[serde(skip)]
2890 pub(crate) meta: HashMap<String, String>,
2891 #[serde(default)]
2892 #[serde(rename = "Type")]
2893 pub(crate) object_type: String,
2894 #[serde(default)]
2895 #[serde(rename = "HashCrc32c")]
2896 pub(crate) hash_crc32c: Option<String>,
2897}
2898
2899#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
2900pub(crate) struct MetaItem {
2901 #[serde(default)]
2902 #[serde(rename = "Key")]
2903 pub(crate) key: String,
2904 #[serde(default)]
2905 #[serde(rename = "Value")]
2906 pub(crate) value: String,
2907}
2908
2909
2910impl ListedObject {
2911 pub fn key(&self) -> &str {
2912 &self.key
2913 }
2914 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
2915 self.last_modified
2916 }
2917 pub fn etag(&self) -> &str {
2918 &self.etag
2919 }
2920 pub fn size(&self) -> i64 {
2921 self.size
2922 }
2923 pub fn owner(&self) -> &Owner {
2924 &self.owner
2925 }
2926 pub fn storage_class(&self) -> &Option<StorageClassType> {
2927 &self.storage_class
2928 }
2929 pub fn hash_crc64ecma(&self) -> u64 {
2930 self.hash_crc64ecma.parse::<u64>().unwrap_or_else(|_| 0)
2931 }
2932 pub fn meta(&self) -> &HashMap<String, String> {
2933 &self.meta
2934 }
2935
2936 pub fn object_type(&self) -> &str {
2937 &self.object_type
2938 }
2939
2940 pub fn hash_crc32c(&self) -> Option<u32> {
2941 match &self.hash_crc32c {
2942 None => None,
2943 Some(hash_crc32c) => Some(hash_crc32c.parse::<u32>().unwrap_or_else(|_| 0))
2944 }
2945 }
2946}
2947
2948#[derive(Debug, Clone, PartialEq, ListCommonQuery, GenericInput)]
2949pub struct ListObjectsType2Input {
2950 pub(crate) generic_input: GenericInput,
2951 pub(crate) bucket: String,
2952 pub(crate) prefix: String,
2953 pub(crate) delimiter: String,
2954 pub(crate) start_after: String,
2955 pub(crate) continuation_token: String,
2956 pub(crate) max_keys: isize,
2957 pub(crate) encoding_type: String,
2958 pub(crate) list_only_once: bool,
2959 pub(crate) fetch_meta: bool,
2960}
2961
2962impl Default for ListObjectsType2Input {
2963 fn default() -> Self {
2964 Self {
2965 generic_input: Default::default(),
2966 bucket: "".to_string(),
2967 prefix: "".to_string(),
2968 delimiter: "".to_string(),
2969 start_after: "".to_string(),
2970 continuation_token: "".to_string(),
2971 max_keys: -1,
2972 encoding_type: "".to_string(),
2973 list_only_once: false,
2974 fetch_meta: false,
2975 }
2976 }
2977}
2978
2979impl ListObjectsType2Input {
2980 pub fn new(bucket: impl Into<String>) -> Self {
2981 let mut input = Self::default();
2982 input.bucket = bucket.into();
2983 input
2984 }
2985 pub fn bucket(&self) -> &str {
2986 &self.bucket
2987 }
2988 pub fn start_after(&self) -> &str {
2989 &self.start_after
2990 }
2991 pub fn continuation_token(&self) -> &str {
2992 &self.continuation_token
2993 }
2994 pub fn max_keys(&self) -> isize {
2995 self.max_keys
2996 }
2997 pub fn list_only_once(&self) -> bool {
2998 self.list_only_once
2999 }
3000 pub fn fetch_meta(&self) -> bool {
3001 self.fetch_meta
3002 }
3003 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
3004 self.bucket = bucket.into();
3005 }
3006 pub fn set_start_after(&mut self, start_after: impl Into<String>) {
3007 self.start_after = start_after.into();
3008 }
3009 pub fn set_continuation_token(&mut self, continuation_token: impl Into<String>) {
3010 self.continuation_token = continuation_token.into();
3011 }
3012 pub fn set_max_keys(&mut self, max_keys: isize) {
3013 self.max_keys = max_keys;
3014 }
3015 pub fn set_list_only_once(&mut self, list_only_once: bool) {
3016 self.list_only_once = list_only_once;
3017 }
3018 pub fn set_fetch_meta(&mut self, fetch_meta: bool) {
3019 self.fetch_meta = fetch_meta;
3020 }
3021}
3022
3023impl InputDescriptor for ListObjectsType2Input {
3024 fn operation(&self) -> &str {
3025 "ListObjectsType2"
3026 }
3027 fn bucket(&self) -> Result<&str, TosError> {
3028 Ok(&self.bucket)
3029 }
3030}
3031
3032impl<B> InputTranslator<B> for ListObjectsType2Input {
3033 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
3034 let mut request = self.trans_bucket()?;
3035 request.method = HttpMethodGet;
3036 let mut query = HashMap::with_capacity(9);
3037 set_list_common_query(&mut query, self);
3038 map_insert(&mut query, QUERY_START_AFTER, &self.start_after);
3039 map_insert(&mut query, QUERY_CONTINUATION_TOKEN, &self.continuation_token);
3040 if self.max_keys >= 0 {
3041 query.insert(QUERY_MAX_KEYS, self.max_keys.to_string());
3042 }
3043 if self.fetch_meta {
3044 query.insert(QUERY_FETCH_META, self.fetch_meta.to_string());
3045 }
3046 query.insert("list-type", 2.to_string());
3047 query.insert(QUERY_FETCH_OWNER, true.to_string());
3048 request.query = Some(query);
3049 Ok(request)
3050 }
3051}
3052
3053
3054#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
3055pub struct ListObjectsType2Output {
3056 #[serde(skip)]
3057 pub(crate) request_info: RequestInfo,
3058 #[serde(default)]
3059 #[serde(rename = "Name")]
3060 pub(crate) name: String,
3061 #[serde(default)]
3062 #[serde(rename = "Prefix")]
3063 pub(crate) prefix: String,
3064 #[serde(default)]
3065 #[serde(rename = "StartAfter")]
3066 pub(crate) start_after: String,
3067 #[serde(default)]
3068 #[serde(rename = "ContinuationToken")]
3069 pub(crate) continuation_token: String,
3070 #[serde(default)]
3071 #[serde(rename = "MaxKeys")]
3072 pub(crate) max_keys: isize,
3073 #[serde(default)]
3074 #[serde(rename = "Delimiter")]
3075 pub(crate) delimiter: String,
3076 #[serde(default)]
3077 #[serde(rename = "IsTruncated")]
3078 pub(crate) is_truncated: bool,
3079 #[serde(default)]
3080 #[serde(rename = "EncodingType")]
3081 pub(crate) encoding_type: String,
3082 #[serde(default)]
3083 #[serde(rename = "KeyCount")]
3084 pub(crate) key_count: isize,
3085 #[serde(default)]
3086 #[serde(rename = "NextContinuationToken")]
3087 pub(crate) next_continuation_token: String,
3088 #[serde(default)]
3089 #[serde(rename = "CommonPrefixes")]
3090 pub(crate) common_prefixes: Vec<ListedCommonPrefix>,
3091 #[serde(default)]
3092 #[serde(rename = "Contents")]
3093 pub(crate) contents: Vec<ListedObject>,
3094}
3095
3096impl ListObjectsType2Output {
3097 pub fn name(&self) -> &str {
3098 &self.name
3099 }
3100 pub fn prefix(&self) -> &str {
3101 &self.prefix
3102 }
3103 pub fn start_after(&self) -> &str {
3104 &self.start_after
3105 }
3106 pub fn continuation_token(&self) -> &str {
3107 &self.continuation_token
3108 }
3109 pub fn max_keys(&self) -> isize {
3110 self.max_keys
3111 }
3112 pub fn delimiter(&self) -> &str {
3113 &self.delimiter
3114 }
3115 pub fn is_truncated(&self) -> bool {
3116 self.is_truncated
3117 }
3118 pub fn encoding_type(&self) -> &str {
3119 &self.encoding_type
3120 }
3121 pub fn key_count(&self) -> isize {
3122 self.key_count
3123 }
3124 pub fn next_continuation_token(&self) -> &str {
3125 &self.next_continuation_token
3126 }
3127 pub fn common_prefixes(&self) -> &Vec<ListedCommonPrefix> {
3128 &self.common_prefixes
3129 }
3130 pub fn contents(&self) -> &Vec<ListedObject> {
3131 &self.contents
3132 }
3133}
3134
3135impl OutputParser for ListObjectsType2Output {
3136 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
3137 let mut result = parse_json::<Self>(response)?;
3138 for content in &mut result.contents {
3139 if let Some(x) = content.last_modified_string.take() {
3140 content.last_modified = parse_date_time_iso8601(&x)?;
3141 }
3142
3143 if let Some(x) = content.user_meta.take() {
3144 let mut meta = HashMap::with_capacity(x.len());
3145 for item in x {
3146 if let Ok(dk) = urlencoding::decode(&item.key[HEADER_PREFIX_META.len()..]) {
3147 if let Ok(dv) = urlencoding::decode(item.value.as_str()) {
3148 meta.insert(dk.to_string(), dv.to_string());
3149 }
3150 }
3151 }
3152 content.meta = meta;
3153 }
3154 }
3155 for common_prefix in &mut result.common_prefixes {
3156 if let Some(x) = common_prefix.last_modified_string.take() {
3157 common_prefix.last_modified = parse_date_time_iso8601(&x)?;
3158 }
3159 }
3160 result.request_info = request_info;
3161 Ok(result)
3162 }
3163}
3164
3165#[derive(Debug, Clone, PartialEq, ListCommonQuery, GenericInput)]
3166pub struct ListObjectVersionsInput {
3167 pub(crate) generic_input: GenericInput,
3168 pub(crate) bucket: String,
3169 pub(crate) prefix: String,
3170 pub(crate) delimiter: String,
3171 pub(crate) key_marker: String,
3172 pub(crate) version_id_marker: String,
3173 pub(crate) max_keys: isize,
3174 pub(crate) encoding_type: String,
3175 pub(crate) fetch_meta: bool,
3176}
3177
3178impl Default for ListObjectVersionsInput {
3179 fn default() -> Self {
3180 Self {
3181 generic_input: Default::default(),
3182 bucket: "".to_string(),
3183 prefix: "".to_string(),
3184 delimiter: "".to_string(),
3185 key_marker: "".to_string(),
3186 version_id_marker: "".to_string(),
3187 max_keys: -1,
3188 encoding_type: "".to_string(),
3189 fetch_meta: false,
3190 }
3191 }
3192}
3193
3194impl ListObjectVersionsInput {
3195 pub fn new(bucket: impl Into<String>) -> Self {
3196 let mut input = Self::default();
3197 input.bucket = bucket.into();
3198 input
3199 }
3200 pub fn bucket(&self) -> &str {
3201 &self.bucket
3202 }
3203 pub fn key_marker(&self) -> &str {
3204 &self.key_marker
3205 }
3206 pub fn version_id_marker(&self) -> &str {
3207 &self.version_id_marker
3208 }
3209 pub fn max_keys(&self) -> isize {
3210 self.max_keys
3211 }
3212 pub fn fetch_meta(&self) -> bool {
3213 self.fetch_meta
3214 }
3215 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
3216 self.bucket = bucket.into();
3217 }
3218 pub fn set_key_marker(&mut self, key_marker: impl Into<String>) {
3219 self.key_marker = key_marker.into();
3220 }
3221 pub fn set_version_id_marker(&mut self, version_id_marker: impl Into<String>) {
3222 self.version_id_marker = version_id_marker.into();
3223 }
3224 pub fn set_max_keys(&mut self, max_keys: isize) {
3225 self.max_keys = max_keys;
3226 }
3227 pub fn set_fetch_meta(&mut self, fetch_meta: bool) {
3228 self.fetch_meta = fetch_meta;
3229 }
3230}
3231
3232impl InputDescriptor for ListObjectVersionsInput {
3233 fn operation(&self) -> &str {
3234 "ListObjectVersions"
3235 }
3236 fn bucket(&self) -> Result<&str, TosError> {
3237 Ok(&self.bucket)
3238 }
3239}
3240
3241impl<B> InputTranslator<B> for ListObjectVersionsInput {
3242 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
3243 let mut request = self.trans_bucket()?;
3244 request.method = HttpMethodGet;
3245 let mut query = HashMap::with_capacity(8);
3246 query.insert("versions", "".to_string());
3247 set_list_common_query(&mut query, self);
3248 map_insert(&mut query, QUERY_KEY_MARKER, &self.key_marker);
3249 map_insert(&mut query, QUERY_VERSION_ID_MARKER, &self.version_id_marker);
3250 if self.max_keys >= 0 {
3251 query.insert(QUERY_MAX_KEYS, self.max_keys.to_string());
3252 }
3253 if self.fetch_meta {
3254 query.insert(QUERY_FETCH_META, self.fetch_meta.to_string());
3255 }
3256 request.query = Some(query);
3257 Ok(request)
3258 }
3259}
3260
3261#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
3262pub struct ListObjectVersionsOutput {
3263 #[serde(skip)]
3264 pub(crate) request_info: RequestInfo,
3265 #[serde(default)]
3266 #[serde(rename = "Name")]
3267 pub(crate) name: String,
3268 #[serde(default)]
3269 #[serde(rename = "Prefix")]
3270 pub(crate) prefix: String,
3271 #[serde(default)]
3272 #[serde(rename = "KeyMarker")]
3273 pub(crate) key_marker: String,
3274 #[serde(default)]
3275 #[serde(rename = "VersionIdMarker")]
3276 pub(crate) version_id_marker: String,
3277 #[serde(default)]
3278 #[serde(rename = "MaxKeys")]
3279 pub(crate) max_keys: isize,
3280 #[serde(default)]
3281 #[serde(rename = "Delimiter")]
3282 pub(crate) delimiter: String,
3283 #[serde(default)]
3284 #[serde(rename = "IsTruncated")]
3285 pub(crate) is_truncated: bool,
3286 #[serde(default)]
3287 #[serde(rename = "EncodingType")]
3288 pub(crate) encoding_type: String,
3289 #[serde(default)]
3290 #[serde(rename = "NextKeyMarker")]
3291 pub(crate) next_key_marker: String,
3292 #[serde(default)]
3293 #[serde(rename = "NextVersionIdMarker")]
3294 pub(crate) next_version_id_marker: String,
3295 #[serde(default)]
3296 #[serde(rename = "CommonPrefixes")]
3297 pub(crate) common_prefixes: Vec<ListedCommonPrefix>,
3298 #[serde(default)]
3299 #[serde(rename = "Versions")]
3300 pub(crate) versions: Vec<ListedObjectVersion>,
3301 #[serde(default)]
3302 #[serde(rename = "DeleteMarkers")]
3303 pub(crate) delete_markers: Vec<ListedDeleteMarker>,
3304}
3305
3306impl ListObjectVersionsOutput {
3307 pub fn name(&self) -> &str {
3308 &self.name
3309 }
3310 pub fn prefix(&self) -> &str {
3311 &self.prefix
3312 }
3313 pub fn key_marker(&self) -> &str {
3314 &self.key_marker
3315 }
3316 pub fn version_id_marker(&self) -> &str {
3317 &self.version_id_marker
3318 }
3319 pub fn max_keys(&self) -> isize {
3320 self.max_keys
3321 }
3322 pub fn delimiter(&self) -> &str {
3323 &self.delimiter
3324 }
3325 pub fn is_truncated(&self) -> bool {
3326 self.is_truncated
3327 }
3328 pub fn encoding_type(&self) -> &str {
3329 &self.encoding_type
3330 }
3331 pub fn next_key_marker(&self) -> &str {
3332 &self.next_key_marker
3333 }
3334 pub fn next_version_id_marker(&self) -> &str {
3335 &self.next_version_id_marker
3336 }
3337 pub fn common_prefixes(&self) -> &Vec<ListedCommonPrefix> {
3338 &self.common_prefixes
3339 }
3340 pub fn versions(&self) -> &Vec<ListedObjectVersion> {
3341 &self.versions
3342 }
3343 pub fn delete_markers(&self) -> &Vec<ListedDeleteMarker> {
3344 &self.delete_markers
3345 }
3346}
3347
3348impl OutputParser for ListObjectVersionsOutput {
3349 fn parse_by_ref<B>(_: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
3350 let mut result = parse_json::<Self>(response)?;
3351 for version in &mut result.versions {
3352 if let Some(x) = version.last_modified_string.take() {
3353 version.last_modified = parse_date_time_iso8601(&x)?;
3354 }
3355
3356 if let Some(x) = version.user_meta.take() {
3357 let mut meta = HashMap::with_capacity(x.len());
3358 for item in x {
3359 if let Ok(dk) = urlencoding::decode(&item.key[HEADER_PREFIX_META.len()..]) {
3360 if let Ok(dv) = urlencoding::decode(item.value.as_str()) {
3361 meta.insert(dk.to_string(), dv.to_string());
3362 }
3363 }
3364 }
3365 version.meta = meta;
3366 }
3367 }
3368
3369 for delete_marker in &mut result.delete_markers {
3370 if let Some(x) = delete_marker.last_modified_string.take() {
3371 delete_marker.last_modified = parse_date_time_iso8601(&x)?;
3372 }
3373 }
3374
3375 result.request_info = request_info;
3376 Ok(result)
3377 }
3378}
3379
3380#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
3381pub struct ListedObjectVersion {
3382 #[serde(default)]
3383 #[serde(rename = "Key")]
3384 pub(crate) key: String,
3385 #[serde(default)]
3386 #[serde(rename = "LastModified")]
3387 pub(crate) last_modified_string: Option<String>,
3388 #[serde(skip)]
3389 pub(crate) last_modified: Option<DateTime<Utc>>,
3390 #[serde(default)]
3391 #[serde(rename = "ETag")]
3392 pub(crate) etag: String,
3393 #[serde(default)]
3394 #[serde(rename = "IsLatest")]
3395 pub(crate) is_latest: bool,
3396 #[serde(default)]
3397 #[serde(rename = "Size")]
3398 pub(crate) size: i64,
3399 #[serde(default)]
3400 #[serde(rename = "Owner")]
3401 pub(crate) owner: Owner,
3402 #[serde(default)]
3403 #[serde(rename = "StorageClass")]
3404 pub(crate) storage_class: Option<StorageClassType>,
3405 #[serde(default)]
3406 #[serde(rename = "VersionId")]
3407 pub(crate) version_id: String,
3408 #[serde(default)]
3409 #[serde(rename = "HashCrc64ecma")]
3410 pub(crate) hash_crc64ecma: String,
3411 #[serde(default)]
3412 #[serde(rename = "UserMeta")]
3413 pub(crate) user_meta: Option<Vec<MetaItem>>,
3414 #[serde(skip)]
3415 pub(crate) meta: HashMap<String, String>,
3416 #[serde(default)]
3417 #[serde(rename = "Type")]
3418 pub(crate) object_type: String,
3419}
3420
3421impl ListedObjectVersion {
3422 pub fn key(&self) -> &str {
3423 &self.key
3424 }
3425 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
3426 self.last_modified
3427 }
3428 pub fn etag(&self) -> &str {
3429 &self.etag
3430 }
3431 pub fn is_latest(&self) -> bool {
3432 self.is_latest
3433 }
3434 pub fn size(&self) -> i64 {
3435 self.size
3436 }
3437 pub fn owner(&self) -> &Owner {
3438 &self.owner
3439 }
3440 pub fn storage_class(&self) -> &Option<StorageClassType> {
3441 &self.storage_class
3442 }
3443 pub fn version_id(&self) -> &str {
3444 &self.version_id
3445 }
3446 pub fn hash_crc64ecma(&self) -> u64 {
3447 self.hash_crc64ecma.parse::<u64>().unwrap_or_else(|_| 0)
3448 }
3449 pub fn meta(&self) -> &HashMap<String, String> {
3450 &self.meta
3451 }
3452 pub fn object_type(&self) -> &str {
3453 &self.object_type
3454 }
3455}
3456
3457#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
3458pub struct ListedDeleteMarker {
3459 #[serde(default)]
3460 #[serde(rename = "Key")]
3461 pub(crate) key: String,
3462 #[serde(default)]
3463 #[serde(rename = "LastModified")]
3464 pub(crate) last_modified_string: Option<String>,
3465 #[serde(skip)]
3466 pub(crate) last_modified: Option<DateTime<Utc>>,
3467 #[serde(default)]
3468 #[serde(rename = "IsLatest")]
3469 pub(crate) is_latest: bool,
3470 #[serde(default)]
3471 #[serde(rename = "Owner")]
3472 pub(crate) owner: Owner,
3473 #[serde(default)]
3474 #[serde(rename = "VersionId")]
3475 pub(crate) version_id: String,
3476}
3477
3478impl ListedDeleteMarker {
3479 pub fn key(&self) -> &str {
3480 &self.key
3481 }
3482 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
3483 self.last_modified
3484 }
3485 pub fn is_latest(&self) -> bool {
3486 self.is_latest
3487 }
3488 pub fn owner(&self) -> &Owner {
3489 &self.owner
3490 }
3491 pub fn version_id(&self) -> &str {
3492 &self.version_id
3493 }
3494}
3495
3496#[derive(
3497 Debug,
3498 Clone,
3499 HttpBasicHeader,
3500 AclHeader,
3501 SseHeader,
3502 SsecHeader,
3503 MiscHeader,
3504 CallbackHeader,
3505 GenericInput
3506)]
3507#[enable_content_length]
3508pub(crate) struct PutObjectBasicInput {
3509 pub(crate) generic_input: GenericInput,
3510 pub(crate) bucket: String,
3511 pub(crate) key: String,
3512 pub(crate) content_md5: String,
3513 pub(crate) content_sha256: String,
3514 pub(crate) content_length: i64,
3515 pub(crate) cache_control: String,
3516 pub(crate) content_disposition: String,
3517 pub(crate) content_encoding: String,
3518 pub(crate) content_language: String,
3519 pub(crate) content_type: String,
3520 pub(crate) expires: Option<DateTime<Utc>>,
3521
3522 pub(crate) acl: Option<ACLType>,
3523 pub(crate) grant_full_control: String,
3524 pub(crate) grant_read: String,
3525 pub(crate) grant_read_acp: String,
3526 pub(crate) grant_write: String,
3527 pub(crate) grant_write_acp: String,
3528
3529 pub(crate) ssec_algorithm: String,
3530 pub(crate) ssec_key: String,
3531 pub(crate) ssec_key_md5: String,
3532 pub(crate) server_side_encryption: String,
3533 pub(crate) server_side_encryption_key_id: String,
3534
3535 pub(crate) meta: HashMap<String, String>,
3536 pub(crate) website_redirect_location: String,
3537 pub(crate) storage_class: Option<StorageClassType>,
3538 pub(crate) traffic_limit: i64,
3539 pub(crate) callback: String,
3540 pub(crate) callback_var: String,
3541 pub(crate) forbid_overwrite: bool,
3542 pub(crate) if_match: String,
3543 pub(crate) if_none_match: String,
3544
3545 pub(crate) tagging: String,
3546 pub(crate) object_expires: i64,
3547 pub(crate) rate_limiter: Option<Arc<RateLimiter>>,
3548 pub(crate) data_transfer_listener: Option<Sender<DataTransferStatus>>,
3549 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
3550 pub(crate) notification_custom_parameters: String,
3551}
3552
3553impl Default for PutObjectBasicInput {
3554 fn default() -> Self {
3555 Self {
3556 generic_input: Default::default(),
3557 bucket: "".to_string(),
3558 key: "".to_string(),
3559 content_md5: "".to_string(),
3560 content_sha256: "".to_string(),
3561 content_length: -1,
3562 cache_control: "".to_string(),
3563 content_disposition: "".to_string(),
3564 content_encoding: "".to_string(),
3565 content_language: "".to_string(),
3566 content_type: "".to_string(),
3567 expires: None,
3568 acl: None,
3569 grant_full_control: "".to_string(),
3570 grant_read: "".to_string(),
3571 grant_read_acp: "".to_string(),
3572 grant_write: "".to_string(),
3573 grant_write_acp: "".to_string(),
3574 ssec_algorithm: "".to_string(),
3575 ssec_key: "".to_string(),
3576 ssec_key_md5: "".to_string(),
3577 server_side_encryption: "".to_string(),
3578 server_side_encryption_key_id: "".to_string(),
3579 meta: Default::default(),
3580 website_redirect_location: "".to_string(),
3581 storage_class: None,
3582 traffic_limit: 0,
3583 callback: "".to_string(),
3584 callback_var: "".to_string(),
3585 forbid_overwrite: false,
3586 if_match: "".to_string(),
3587 if_none_match: "".to_string(),
3588 tagging: "".to_string(),
3589 object_expires: -1,
3590 rate_limiter: None,
3591 data_transfer_listener: None,
3592 async_data_transfer_listener: None,
3593 notification_custom_parameters: "".to_string(),
3594 }
3595 }
3596}
3597
3598impl InputDescriptor for PutObjectBasicInput {
3599 fn operation(&self) -> &str {
3600 "PutObject"
3601 }
3602 fn bucket(&self) -> Result<&str, TosError> {
3603 Ok(&self.bucket)
3604 }
3605
3606 fn key(&self) -> Result<&str, TosError> {
3607 Ok(&self.key)
3608 }
3609}
3610
3611impl<B> InputTranslator<B> for PutObjectBasicInput {
3612 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
3613 let mut request = self.trans_key()?;
3614 request.method = HttpMethodPut;
3615
3616 if let Some(ref rl) = self.rate_limiter {
3617 let mut rc = RequestContext::default();
3618 rc.rate_limiter = Some(rl.clone());
3619 request.request_context = Some(rc);
3620 }
3621
3622 if let Some(ref dts) = self.data_transfer_listener {
3623 if request.request_context.is_some() {
3624 request.request_context.as_mut().unwrap().data_transfer_listener = Some(dts.clone());
3625 } else {
3626 let mut rc = RequestContext::default();
3627 rc.data_transfer_listener = Some(dts.clone());
3628 request.request_context = Some(rc);
3629 }
3630 } else if let Some(ref adts) = self.async_data_transfer_listener {
3631 if request.request_context.is_some() {
3632 request.request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
3633 } else {
3634 let mut rc = RequestContext::default();
3635 rc.async_data_transfer_listener = Some(adts.clone());
3636 request.request_context = Some(rc);
3637 }
3638 }
3639
3640 let header = &mut request.header;
3641 set_http_basic_header(header, config_holder.disable_encoding_meta, self);
3642 set_acl_header(header, self);
3643 set_sse_header(header, self)?;
3644 set_ssec_header(header, &self.server_side_encryption, self)?;
3645 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
3646 set_misc_header(header, self);
3647 set_callback_header(header, self);
3648 map_insert(header, HEADER_CONTENT_MD5, &self.content_md5);
3649 map_insert(header, HEADER_CONTENT_SHA256, &self.content_sha256);
3650 if self.forbid_overwrite {
3651 header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
3652 }
3653 if self.traffic_limit > 0 {
3654 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
3655 }
3656 map_insert(header, HEADER_X_IF_MATCH, &self.if_match);
3657 map_insert(header, HEADER_IF_NONE_MATCH, &self.if_none_match);
3658
3659 if self.tagging != "" {
3660 header.insert(HEADER_TAGGING, self.tagging.clone());
3661 }
3662 if self.object_expires >= 0 {
3663 header.insert(HEADER_OBJECT_EXPIRES, self.object_expires.to_string());
3664 }
3665 map_insert(header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
3666 Ok(request)
3667 }
3668}
3669
3670#[derive(
3672 Debug,
3673 HttpBasicHeader,
3674 AclHeader,
3675 SseHeader,
3676 SsecHeader,
3677 MiscHeader,
3678 CallbackHeader,
3679 GenericInput
3680)]
3681#[enable_content_length]
3682#[handle_content]
3683#[use_inner]
3684pub struct PutObjectInput<B>
3685{
3686 pub(crate) inner: PutObjectBasicInput,
3687 pub(crate) content: Arc<RefCell<Option<B>>>,
3688}
3689
3690unsafe impl<B> Sync for PutObjectInput<B> {}
3691
3692unsafe impl<B> Send for PutObjectInput<B> {}
3693
3694impl<B> InputDescriptor for PutObjectInput<B>
3695{
3696 fn operation(&self) -> &str {
3697 "PutObject"
3698 }
3699 fn bucket(&self) -> Result<&str, TosError> {
3700 Ok(&self.inner.bucket)
3701 }
3702
3703 fn key(&self) -> Result<&str, TosError> {
3704 Ok(&self.inner.key)
3705 }
3706}
3707
3708impl<B> InputTranslator<B> for PutObjectInput<B>
3709{
3710 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
3711 let mut request = self.inner.trans(config_holder)?;
3712 request.operation = self.operation();
3713 request.body = self.content.take();
3714 Ok(request)
3715 }
3716}
3717
3718impl<B> Default for PutObjectInput<B>
3719{
3720 fn default() -> Self {
3721 Self {
3722 inner: Default::default(),
3723 content: Arc::new(RefCell::new(None)),
3724 }
3725 }
3726}
3727
3728impl<B> DataTransferListener for PutObjectInput<B> {
3729 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
3730 &self.inner.data_transfer_listener
3731 }
3732
3733 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
3734 self.inner.data_transfer_listener = Some(listener.into());
3735 }
3736}
3737
3738impl<B> PutObjectInput<B>
3739{
3740 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
3741 let mut input = Self::default();
3742 input.inner.bucket = bucket.into();
3743 input.inner.key = key.into();
3744 input
3745 }
3746 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl Into<B>) -> Self {
3747 let mut input = Self::default();
3748 input.inner.bucket = bucket.into();
3749 input.inner.key = key.into();
3750 input.set_content(content);
3751 input
3752 }
3753 pub fn bucket(&self) -> &str {
3754 &self.inner.bucket
3755 }
3756 pub fn key(&self) -> &str {
3757 &self.inner.key
3758 }
3759 pub fn content(&self) -> Ref<Option<B>> {
3760 self.content.borrow()
3761 }
3762 pub fn content_md5(&self) -> &str {
3763 &self.inner.content_md5
3764 }
3765 pub fn content_sha256(&self) -> &str {
3766 &self.inner.content_sha256
3767 }
3768 pub fn meta(&self) -> &HashMap<String, String> {
3769 &self.inner.meta
3770 }
3771 pub fn traffic_limit(&self) -> i64 {
3772 self.inner.traffic_limit
3773 }
3774 pub fn forbid_overwrite(&self) -> bool {
3775 self.inner.forbid_overwrite
3776 }
3777 pub fn if_match(&self) -> &str {
3778 &self.inner.if_match
3779 }
3780 pub fn if_none_match(&self) -> &str {
3781 &self.inner.if_none_match
3782 }
3783 pub fn tagging(&self) -> &str {
3784 &self.inner.tagging
3785 }
3786 pub fn object_expires(&self) -> i64 {
3787 self.inner.object_expires
3788 }
3789 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
3790 &self.inner.rate_limiter
3791 }
3792 pub fn notification_custom_parameters(&mut self) -> &str {
3793 &self.inner.notification_custom_parameters
3794 }
3795 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
3796 self.inner.bucket = bucket.into();
3797 }
3798 pub fn set_key(&mut self, key: impl Into<String>) {
3799 self.inner.key = key.into();
3800 }
3801 pub fn set_content(&mut self, content: impl Into<B>) {
3802 self.content = Arc::new(RefCell::new(Some(content.into())));
3803 }
3804 pub fn set_content_md5(&mut self, content_md5: impl Into<String>) {
3805 self.inner.content_md5 = content_md5.into();
3806 }
3807 pub fn set_content_sha256(&mut self, content_sha256: impl Into<String>) {
3808 self.inner.content_sha256 = content_sha256.into();
3809 }
3810 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
3811 self.inner.meta = meta.into();
3812 }
3813 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
3814 self.inner.traffic_limit = traffic_limit;
3815 }
3816 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
3817 self.inner.forbid_overwrite = forbid_overwrite;
3818 }
3819 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
3820 self.inner.if_match = if_match.into();
3821 }
3822 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
3823 self.inner.if_none_match = if_none_match.into();
3824 }
3825 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
3826 self.inner.tagging = tagging.into();
3827 }
3828 pub fn set_object_expires(&mut self, object_expires: i64) {
3829 self.inner.object_expires = object_expires;
3830 }
3831 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
3832 self.inner.rate_limiter = Some(rate_limiter.into());
3833 }
3834 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
3835 self.inner.notification_custom_parameters = notification_custom_parameters.into();
3836 }
3837}
3838
3839
3840#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
3841pub struct PutObjectOutput {
3842 pub(crate) request_info: RequestInfo,
3843 pub(crate) etag: String,
3844 pub(crate) version_id: String,
3845 pub(crate) ssec_algorithm: String,
3846 pub(crate) ssec_key_md5: String,
3847 pub(crate) hash_crc64ecma: u64,
3848 pub(crate) callback_result: String,
3849 pub(crate) server_side_encryption: String,
3850 pub(crate) server_side_encryption_key_id: String,
3851}
3852
3853impl OutputParser for PutObjectOutput {
3854 fn parse_by_ref<B>(request: &HttpRequest<B>, response: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
3855 let hash_crc64ecma = get_header_value_from_str::<u64>(response.headers(), HEADER_HASH_CRC64ECMA, 0)?;
3856 if let Some(ref rc) = request.request_context {
3857 if let Some(calc_hash_crc64ecma) = rc.crc64 {
3858 if calc_hash_crc64ecma != hash_crc64ecma {
3859 return Err(TosError::client_error(format!("expect crc64 {hash_crc64ecma}, actual crc64 {calc_hash_crc64ecma}")));
3860 }
3861 }
3862 }
3863
3864 let mut result = Self::default();
3865 if get_map_value_str(&request.header, HEADER_CALLBACK) != "" { let buf = read_response(response)?;
3867 if request_info.status_code == 203 {
3868 if let Ok(error_response) = parse_json_by_buf::<ErrorResponse>(buf.as_slice()) {
3869 return Err(TosError::server_error_with_code(error_response.code, error_response.ec, error_response.key, error_response.message,
3870 error_response.host_id, error_response.resource, request_info));
3871 }
3872 }
3873 result.callback_result = parse_response_string_by_buf(buf)?;
3874 }
3875 result.etag = get_header_value(response.headers(), HEADER_ETAG);
3876 result.version_id = get_header_value(response.headers(), HEADER_VERSION_ID);
3877 result.ssec_algorithm = get_header_value(response.headers(), HEADER_SSEC_ALGORITHM);
3878 result.ssec_key_md5 = get_header_value(response.headers(), HEADER_SSEC_KEY_MD5);
3879 result.hash_crc64ecma = hash_crc64ecma;
3880 result.server_side_encryption = get_header_value(response.headers(), HEADER_SERVER_SIDE_ENCRYPTION);
3881 result.server_side_encryption_key_id = get_header_value(response.headers(), HEADER_SERVER_SIDE_ENCRYPTION_KMS_KEY_ID);
3882 result.request_info = request_info;
3883 Ok(result)
3884 }
3885}
3886
3887impl PutObjectOutput {
3888 pub fn etag(&self) -> &str {
3889 &self.etag
3890 }
3891 pub fn version_id(&self) -> &str {
3892 &self.version_id
3893 }
3894 pub fn ssec_algorithm(&self) -> &str {
3895 &self.ssec_algorithm
3896 }
3897 pub fn ssec_key_md5(&self) -> &str {
3898 &self.ssec_key_md5
3899 }
3900 pub fn hash_crc64ecma(&self) -> u64 {
3901 self.hash_crc64ecma
3902 }
3903 pub fn callback_result(&self) -> &str {
3904 &self.callback_result
3905 }
3906 pub fn server_side_encryption(&self) -> &str {
3907 &self.server_side_encryption
3908 }
3909 pub fn server_side_encryption_key_id(&self) -> &str {
3910 &self.server_side_encryption_key_id
3911 }
3912}
3913
3914#[derive(
3915 Debug,
3916 HttpBasicHeader,
3917 AclHeader,
3918 SseHeader,
3919 SsecHeader,
3920 MiscHeader,
3921 CallbackHeader,
3922 GenericInput
3923)]
3924#[enable_content_length]
3925#[use_inner]
3926pub struct PutObjectFromBufferInput {
3927 pub(crate) inner: PutObjectBasicInput,
3928 pub(crate) content: Option<MultiBytes>,
3929}
3930
3931impl InputDescriptor for PutObjectFromBufferInput {
3932 fn operation(&self) -> &str {
3933 "PutObjectFromBuffer"
3934 }
3935 fn bucket(&self) -> Result<&str, TosError> {
3936 Ok(&self.inner.bucket)
3937 }
3938
3939 fn key(&self) -> Result<&str, TosError> {
3940 Ok(&self.inner.key)
3941 }
3942}
3943
3944impl<B> InputTranslator<B> for PutObjectFromBufferInput
3945where
3946 B: BuildMultiBufferReader,
3947{
3948 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
3949 let mut request = self.inner.trans(config_holder)?;
3950 request.operation = self.operation();
3951 if let Some(content) = &self.content {
3952 let (body, len) = B::new(content.clone())?;
3953 request.body = Some(body);
3954 if self.inner.content_length < 0 {
3955 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
3956 }
3957 }
3958 Ok(request)
3959 }
3960}
3961
3962impl PutObjectFromBufferInput {
3963 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
3964 let mut input = Self::default();
3965 input.inner.bucket = bucket.into();
3966 input.inner.key = key.into();
3967 input
3968 }
3969 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl AsRef<[u8]>) -> Self {
3970 let mut input = Self::default();
3971 input.inner.bucket = bucket.into();
3972 input.inner.key = key.into();
3973 input.set_content(content);
3974 input
3975 }
3976 pub fn bucket(&self) -> &str {
3977 &self.inner.bucket
3978 }
3979 pub fn key(&self) -> &str {
3980 &self.inner.key
3981 }
3982 pub fn content(&self) -> Option<impl Iterator<Item=&Bytes>> {
3983 match &self.content {
3984 None => None,
3985 Some(x) => Some(x.inner.iter()),
3986 }
3987 }
3988 pub fn content_md5(&self) -> &str {
3989 &self.inner.content_md5
3990 }
3991 pub fn content_sha256(&self) -> &str {
3992 &self.inner.content_sha256
3993 }
3994 pub fn meta(&self) -> &HashMap<String, String> {
3995 &self.inner.meta
3996 }
3997 pub fn traffic_limit(&self) -> i64 {
3998 self.inner.traffic_limit
3999 }
4000 pub fn forbid_overwrite(&self) -> bool {
4001 self.inner.forbid_overwrite
4002 }
4003 pub fn if_match(&self) -> &str {
4004 &self.inner.if_match
4005 }
4006 pub fn if_none_match(&self) -> &str {
4007 &self.inner.if_none_match
4008 }
4009 pub fn tagging(&self) -> &str {
4010 &self.inner.tagging
4011 }
4012 pub fn object_expires(&self) -> i64 {
4013 self.inner.object_expires
4014 }
4015 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
4016 &self.inner.rate_limiter
4017 }
4018 pub fn notification_custom_parameters(&mut self) -> &str {
4019 &self.inner.notification_custom_parameters
4020 }
4021 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4022 self.inner.bucket = bucket.into();
4023 }
4024 pub fn set_key(&mut self, key: impl Into<String>) {
4025 self.inner.key = key.into();
4026 }
4027 pub fn set_content_with_bytes_list(&mut self, bytes_list: impl Iterator<Item=impl Into<Bytes>>) {
4028 let mut list = LinkedList::new();
4029 let mut size = 0;
4030 for item in bytes_list {
4031 let item = item.into();
4032 size += item.len();
4033 list.push_back(item);
4034 }
4035 self.content = Some(MultiBytes::new(list, size));
4036 }
4037 pub fn set_content(&mut self, content: impl AsRef<[u8]>) {
4038 let item = content.as_ref().to_owned();
4039 let size = item.len();
4040 let mut list = LinkedList::new();
4041 list.push_back(Bytes::from(item));
4042 self.content = Some(MultiBytes::new(list, size));
4043 }
4044 pub fn append_content(&mut self, content: impl AsRef<[u8]>) {
4045 if let Some(contents) = &mut self.content {
4046 contents.push(Bytes::from(content.as_ref().to_owned()));
4047 } else {
4048 self.set_content(content);
4049 }
4050 }
4051 pub fn set_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
4052 let item = content.into();
4053 let size = item.len();
4054 let mut list = LinkedList::new();
4055 list.push_back(Bytes::from(item));
4056 self.content = Some(MultiBytes::new(list, size));
4057 }
4058
4059 pub fn append_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
4060 if let Some(contents) = &mut self.content {
4061 contents.push(Bytes::from(content.into()));
4062 } else {
4063 self.set_content_nocopy(content);
4064 }
4065 }
4066
4067 pub fn set_content_md5(&mut self, content_md5: impl Into<String>) {
4068 self.inner.content_md5 = content_md5.into();
4069 }
4070 pub fn set_content_sha256(&mut self, content_sha256: impl Into<String>) {
4071 self.inner.content_sha256 = content_sha256.into();
4072 }
4073 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
4074 self.inner.meta = meta.into();
4075 }
4076 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
4077 self.inner.traffic_limit = traffic_limit;
4078 }
4079 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
4080 self.inner.forbid_overwrite = forbid_overwrite;
4081 }
4082 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
4083 self.inner.if_match = if_match.into();
4084 }
4085 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
4086 self.inner.if_none_match = if_none_match.into();
4087 }
4088 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
4089 self.inner.tagging = tagging.into();
4090 }
4091 pub fn set_object_expires(&mut self, object_expires: i64) {
4092 self.inner.object_expires = object_expires;
4093 }
4094 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
4095 self.inner.rate_limiter = Some(rate_limiter.into());
4096 }
4097 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
4098 self.inner.notification_custom_parameters = notification_custom_parameters.into();
4099 }
4100}
4101
4102impl Default for PutObjectFromBufferInput {
4103 fn default() -> Self {
4104 Self {
4105 inner: Default::default(),
4106 content: None,
4107 }
4108 }
4109}
4110
4111impl DataTransferListener for PutObjectFromBufferInput {
4112 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
4113 &self.inner.data_transfer_listener
4114 }
4115
4116 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
4117 self.inner.data_transfer_listener = Some(listener.into());
4118 }
4119}
4120
4121#[derive(
4122 Debug,
4123 HttpBasicHeader,
4124 AclHeader,
4125 SseHeader,
4126 SsecHeader,
4127 MiscHeader,
4128 CallbackHeader,
4129 GenericInput
4130)]
4131#[enable_content_length]
4132#[use_inner]
4133pub struct PutObjectFromFileInput {
4134 pub(crate) inner: PutObjectBasicInput,
4135 pub(crate) file_path: String,
4136}
4137
4138impl InputDescriptor for PutObjectFromFileInput {
4139 fn operation(&self) -> &str {
4140 "PutObjectFromFile"
4141 }
4142
4143 fn bucket(&self) -> Result<&str, TosError> {
4144 Ok(&self.inner.bucket)
4145 }
4146
4147 fn key(&self) -> Result<&str, TosError> {
4148 Ok(&self.inner.key)
4149 }
4150}
4151
4152impl<B> InputTranslator<B> for PutObjectFromFileInput
4153where
4154 B: BuildFileReader,
4155{
4156 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4157 let mut request = self.inner.trans(config_holder)?;
4158 request.operation = self.operation();
4159 if self.file_path != "" {
4160 let (body, len) = B::new(&self.file_path)?;
4161 request.body = Some(body);
4162 if let Some(l) = len {
4163 if self.inner.content_length < 0 {
4164 request.header.insert(HEADER_CONTENT_LENGTH, l.to_string());
4165 }
4166 }
4167 }
4168 Ok(request)
4169 }
4170}
4171
4172impl DataTransferListener for PutObjectFromFileInput {
4173 fn data_transfer_listener(&self) -> &Option<Sender<DataTransferStatus>> {
4174 &self.inner.data_transfer_listener
4175 }
4176
4177 fn set_data_transfer_listener(&mut self, listener: impl Into<Sender<DataTransferStatus>>) {
4178 self.inner.data_transfer_listener = Some(listener.into());
4179 }
4180}
4181
4182impl PutObjectFromFileInput {
4183 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4184 let mut input = Self::default();
4185 input.inner.bucket = bucket.into();
4186 input.inner.key = key.into();
4187 input
4188 }
4189 pub fn new_with_file_path(bucket: impl Into<String>, key: impl Into<String>, file_path: impl Into<String>) -> Self {
4190 let mut input = Self::default();
4191 input.inner.bucket = bucket.into();
4192 input.inner.key = key.into();
4193 input.file_path = file_path.into();
4194 input
4195 }
4196 pub fn bucket(&self) -> &str {
4197 &self.inner.bucket
4198 }
4199 pub fn key(&self) -> &str {
4200 &self.inner.key
4201 }
4202 pub fn file_path(&self) -> &str {
4203 &self.file_path
4204 }
4205 pub fn content_md5(&self) -> &str {
4206 &self.inner.content_md5
4207 }
4208 pub fn content_sha256(&self) -> &str {
4209 &self.inner.content_sha256
4210 }
4211 pub fn meta(&self) -> &HashMap<String, String> {
4212 &self.inner.meta
4213 }
4214 pub fn traffic_limit(&self) -> i64 {
4215 self.inner.traffic_limit
4216 }
4217 pub fn forbid_overwrite(&self) -> bool {
4218 self.inner.forbid_overwrite
4219 }
4220 pub fn if_match(&self) -> &str {
4221 &self.inner.if_match
4222 }
4223 pub fn if_none_match(&self) -> &str {
4224 &self.inner.if_none_match
4225 }
4226 pub fn tagging(&self) -> &str {
4227 &self.inner.tagging
4228 }
4229 pub fn object_expires(&self) -> i64 {
4230 self.inner.object_expires
4231 }
4232 pub fn rate_limiter(&self) -> &Option<Arc<RateLimiter>> {
4233 &self.inner.rate_limiter
4234 }
4235 pub fn notification_custom_parameters(&mut self) -> &str {
4236 &self.inner.notification_custom_parameters
4237 }
4238 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4239 self.inner.bucket = bucket.into();
4240 }
4241 pub fn set_key(&mut self, key: impl Into<String>) {
4242 self.inner.key = key.into();
4243 }
4244 pub fn set_file_path(&mut self, file_path: impl Into<String>) {
4245 self.file_path = file_path.into();
4246 }
4247 pub fn set_content_md5(&mut self, content_md5: impl Into<String>) {
4248 self.inner.content_md5 = content_md5.into();
4249 }
4250 pub fn set_content_sha256(&mut self, content_sha256: impl Into<String>) {
4251 self.inner.content_sha256 = content_sha256.into();
4252 }
4253 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
4254 self.inner.meta = meta.into();
4255 }
4256 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
4257 self.inner.traffic_limit = traffic_limit;
4258 }
4259 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
4260 self.inner.forbid_overwrite = forbid_overwrite;
4261 }
4262 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
4263 self.inner.if_match = if_match.into();
4264 }
4265 pub fn set_if_none_match(&mut self, if_none_match: impl Into<String>) {
4266 self.inner.if_none_match = if_none_match.into();
4267 }
4268 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
4269 self.inner.tagging = tagging.into();
4270 }
4271 pub fn set_object_expires(&mut self, object_expires: i64) {
4272 self.inner.object_expires = object_expires;
4273 }
4274 pub fn set_rate_limiter(&mut self, rate_limiter: impl Into<Arc<RateLimiter>>) {
4275 self.inner.rate_limiter = Some(rate_limiter.into());
4276 }
4277 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
4278 self.inner.notification_custom_parameters = notification_custom_parameters.into();
4279 }
4280}
4281
4282impl Default for PutObjectFromFileInput {
4283 fn default() -> Self {
4284 Self {
4285 inner: Default::default(),
4286 file_path: "".to_string(),
4287 }
4288 }
4289}
4290
4291#[derive(Debug, Clone, PartialEq, Default, AclHeader, Serialize, GenericInput)]
4292pub struct PutObjectACLInput {
4293 #[serde(skip)]
4294 pub(crate) generic_input: GenericInput,
4295 #[serde(skip)]
4296 pub(crate) bucket: String,
4297 #[serde(skip)]
4298 pub(crate) key: String,
4299 #[serde(skip)]
4300 pub(crate) version_id: String,
4301 #[serde(skip)]
4302 pub(crate) acl: Option<ACLType>,
4303 #[serde(skip)]
4304 pub(crate) grant_full_control: String,
4305 #[serde(skip)]
4306 pub(crate) grant_read: String,
4307 #[serde(skip)]
4308 pub(crate) grant_read_acp: String,
4309 #[serde(skip)]
4310 pub(crate) grant_write: String,
4311 #[serde(skip)]
4312 pub(crate) grant_write_acp: String,
4313 #[serde(rename = "Owner")]
4314 pub(crate) owner: Owner,
4315 #[serde(rename = "Grants")]
4316 pub(crate) grants: Vec<Grant>,
4317 #[serde(rename = "BucketOwnerEntrusted")]
4318 #[serde(skip_serializing_if = "<&bool as std::ops::Not>::not")]
4319 pub(crate) bucket_owner_entrusted: bool,
4320 #[serde(rename = "IsDefault")]
4321 #[serde(skip_serializing_if = "<&bool as std::ops::Not>::not")]
4322 pub(crate) is_default: bool,
4323}
4324
4325impl InputDescriptor for PutObjectACLInput {
4326 fn operation(&self) -> &str {
4327 "PutObjectACL"
4328 }
4329
4330 fn bucket(&self) -> Result<&str, TosError> {
4331 Ok(&self.bucket)
4332 }
4333
4334 fn key(&self) -> Result<&str, TosError> {
4335 Ok(&self.key)
4336 }
4337}
4338
4339impl<B> InputTranslator<B> for PutObjectACLInput
4340where
4341 B: BuildBufferReader,
4342{
4343 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4344 let mut request = self.trans_key()?;
4345 request.method = HttpMethodPut;
4346 if self.acl.is_some() && self.grants.len() > 0 {
4347 return Err(TosError::client_error("both acl and grants are set for put object acl"));
4348 }
4349
4350 if self.acl.is_some() {
4351 set_acl_header(&mut request.header, self);
4352 } else if self.grants.len() == 0 {
4353 return Err(TosError::client_error("neither acl nor grants is set for put object acl"));
4354 } else if self.owner.id == "" {
4355 return Err(TosError::client_error("empty owner id for put object acl"));
4356 } else {
4357 match serde_json::to_string(self) {
4358 Err(e) => return Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
4359 Ok(json) => {
4360 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
4361 request.body = Some(body);
4362 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
4363 }
4364 }
4365 }
4366
4367 let mut query = HashMap::with_capacity(2);
4368 query.insert("acl", "".to_string());
4369 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
4370
4371 request.query = Some(query);
4372 Ok(request)
4373 }
4374}
4375
4376impl PutObjectACLInput {
4377 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4378 let mut input = Self::default();
4379 input.bucket = bucket.into();
4380 input.key = key.into();
4381 input
4382 }
4383
4384 pub fn new_with_acl(bucket: impl Into<String>, key: impl Into<String>, acl: impl Into<ACLType>) -> Self {
4385 let mut input = Self::default();
4386 input.bucket = bucket.into();
4387 input.key = key.into();
4388 input.acl = Some(acl.into());
4389 input
4390 }
4391 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
4392 let mut input = Self::default();
4393 input.bucket = bucket.into();
4394 input.key = key.into();
4395 input.version_id = version_id.into();
4396 input
4397 }
4398 pub fn bucket(&self) -> &str {
4399 &self.bucket
4400 }
4401 pub fn key(&self) -> &str {
4402 &self.key
4403 }
4404 pub fn version_id(&self) -> &str {
4405 &self.version_id
4406 }
4407 pub fn owner(&self) -> &Owner {
4408 &self.owner
4409 }
4410 pub fn grants(&self) -> &Vec<Grant> {
4411 &self.grants
4412 }
4413 pub fn bucket_owner_entrusted(&self) -> bool {
4414 self.bucket_owner_entrusted
4415 }
4416 pub fn is_default(&self) -> bool {
4417 self.is_default
4418 }
4419 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4420 self.bucket = bucket.into();
4421 }
4422 pub fn set_key(&mut self, key: impl Into<String>) {
4423 self.key = key.into();
4424 }
4425 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
4426 self.version_id = version_id.into();
4427 }
4428 pub fn set_owner(&mut self, owner: impl Into<Owner>) {
4429 self.owner = owner.into();
4430 }
4431 pub fn set_grants(&mut self, grants: impl Into<Vec<Grant>>) {
4432 self.grants = grants.into();
4433 }
4434 pub fn set_bucket_owner_entrusted(&mut self, bucket_owner_entrusted: bool) {
4435 self.bucket_owner_entrusted = bucket_owner_entrusted;
4436 }
4437
4438 pub fn set_is_default(&mut self, is_default: bool) {
4439 self.is_default = is_default;
4440 }
4441}
4442
4443#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
4444pub struct PutObjectACLOutput {
4445 pub(crate) request_info: RequestInfo,
4446}
4447
4448impl OutputParser for PutObjectACLOutput {
4449 fn parse_by_ref<B>(_: &HttpRequest<B>, _: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
4450 Ok(Self { request_info })
4451 }
4452}
4453
4454#[derive(Debug, Clone, PartialEq, Default, HttpBasicHeader, GenericInput)]
4455pub struct SetObjectMetaInput {
4456 pub(crate) generic_input: GenericInput,
4457 pub(crate) bucket: String,
4458 pub(crate) key: String,
4459 pub(crate) version_id: String,
4460 pub(crate) content_length: i64,
4461 pub(crate) cache_control: String,
4462 pub(crate) content_disposition: String,
4463 pub(crate) content_encoding: String,
4464 pub(crate) content_language: String,
4465 pub(crate) content_type: String,
4466 pub(crate) expires: Option<DateTime<Utc>>,
4467 pub(crate) meta: HashMap<String, String>,
4468 pub(crate) metadata_directive: Option<MetadataDirectiveType>,
4469}
4470
4471impl InputDescriptor for SetObjectMetaInput {
4472 fn operation(&self) -> &str {
4473 "SetObjectMeta"
4474 }
4475 fn bucket(&self) -> Result<&str, TosError> {
4476 Ok(&self.bucket)
4477 }
4478
4479 fn key(&self) -> Result<&str, TosError> {
4480 Ok(&self.key)
4481 }
4482}
4483
4484impl<B> InputTranslator<B> for SetObjectMetaInput {
4485 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4486 let mut request = self.trans_key()?;
4487 request.method = HttpMethodPost;
4488 let header = &mut request.header;
4489 set_http_basic_header(header, config_holder.disable_encoding_meta, self);
4490 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
4491 if let Some(metadata_directive) = &self.metadata_directive {
4492 header.insert(HEADER_METADATA_DIRECTIVE, metadata_directive.as_str().to_string());
4493 }
4494 let mut query = HashMap::with_capacity(2);
4495 query.insert("metadata", "".to_string());
4496 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
4497 request.query = Some(query);
4498 Ok(request)
4499 }
4500}
4501
4502impl SetObjectMetaInput {
4503 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4504 let mut input = Self::default();
4505 input.bucket = bucket.into();
4506 input.key = key.into();
4507 input.content_length = -1;
4508 input
4509 }
4510 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
4511 let mut input = Self::default();
4512 input.bucket = bucket.into();
4513 input.key = key.into();
4514 input.version_id = version_id.into();
4515 input.content_length = -1;
4516 input
4517 }
4518
4519 pub fn bucket(&self) -> &str {
4520 &self.bucket
4521 }
4522 pub fn key(&self) -> &str {
4523 &self.key
4524 }
4525 pub fn version_id(&self) -> &str {
4526 &self.version_id
4527 }
4528 pub fn meta(&self) -> &HashMap<String, String> {
4529 &self.meta
4530 }
4531 pub fn metadata_directive(&self) -> &Option<MetadataDirectiveType> {
4532 &self.metadata_directive
4533 }
4534 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4535 self.bucket = bucket.into();
4536 }
4537 pub fn set_key(&mut self, key: impl Into<String>) {
4538 self.key = key.into();
4539 }
4540 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
4541 self.version_id = version_id.into();
4542 }
4543 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
4544 self.meta = meta.into();
4545 }
4546 pub fn set_metadata_directive(&mut self, metadata_directive: impl Into<MetadataDirectiveType>) {
4547 self.metadata_directive = Some(metadata_directive.into());
4548 }
4549}
4550
4551#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
4552pub struct SetObjectMetaOutput {
4553 pub(crate) request_info: RequestInfo,
4554}
4555
4556impl OutputParser for SetObjectMetaOutput {
4557 fn parse_by_ref<B>(_: &HttpRequest<B>, _: &mut HttpResponse, request_info: RequestInfo, _: Meta) -> Result<Self, TosError> {
4558 Ok(Self { request_info })
4559 }
4560}
4561#[derive(Debug, Clone, PartialEq, Default, Serialize, GenericInput)]
4562pub struct PutObjectTaggingInput {
4563 #[serde(skip)]
4564 pub(crate) generic_input: GenericInput,
4565 #[serde(skip)]
4566 pub(crate) bucket: String,
4567 #[serde(skip)]
4568 pub(crate) key: String,
4569 #[serde(skip)]
4570 pub(crate) version_id: String,
4571 #[serde(rename = "TagSet")]
4572 pub(crate) tag_set: TagSet,
4573}
4574
4575impl PutObjectTaggingInput {
4576 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4577 let mut input = Self::default();
4578 input.bucket = bucket.into();
4579 input.key = key.into();
4580 input
4581 }
4582 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
4583 let mut input = Self::default();
4584 input.bucket = bucket.into();
4585 input.key = key.into();
4586 input.version_id = version_id.into();
4587 input
4588 }
4589
4590 pub fn bucket(&self) -> &str {
4591 &self.bucket
4592 }
4593
4594 pub fn key(&self) -> &str {
4595 &self.key
4596 }
4597
4598 pub fn version_id(&self) -> &str {
4599 &self.version_id
4600 }
4601
4602 pub fn tag_set(&self) -> &TagSet {
4603 &self.tag_set
4604 }
4605
4606 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4607 self.bucket = bucket.into();
4608 }
4609
4610 pub fn set_key(&mut self, key: impl Into<String>) {
4611 self.key = key.into();
4612 }
4613
4614 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
4615 self.version_id = version_id.into();
4616 }
4617
4618 pub fn set_tag_set(&mut self, tag_set: impl Into<TagSet>) {
4619 self.tag_set = tag_set.into();
4620 }
4621}
4622
4623impl InputDescriptor for PutObjectTaggingInput {
4624 fn operation(&self) -> &str {
4625 "PutObjectTagging"
4626 }
4627
4628 fn bucket(&self) -> Result<&str, TosError> {
4629 Ok(&self.bucket)
4630 }
4631
4632 fn key(&self) -> Result<&str, TosError> {
4633 Ok(&self.key)
4634 }
4635}
4636
4637impl<B> InputTranslator<B> for PutObjectTaggingInput
4638where
4639 B: BuildBufferReader,
4640{
4641 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4642 match serde_json::to_string(self) {
4643 Err(e) => Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
4644 Ok(json) => {
4645 let mut request = self.trans_key()?;
4646 request.method = HttpMethodPut;
4647 let mut query = HashMap::with_capacity(2);
4648 query.insert("tagging", "".to_string());
4649 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
4650 request.query = Some(query);
4651 request.header.insert(HEADER_CONTENT_MD5, base64_md5(&json));
4652 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
4653 request.body = Some(body);
4654 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
4655 Ok(request)
4656 }
4657 }
4658 }
4659}
4660
4661#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
4662pub struct PutObjectTaggingOutput {
4663 pub(crate) request_info: RequestInfo,
4664 pub(crate) version_id: String,
4665}
4666#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
4667pub struct GetObjectTaggingInput {
4668 pub(crate) generic_input: GenericInput,
4669 pub(crate) bucket: String,
4670 pub(crate) key: String,
4671 pub(crate) version_id: String,
4672}
4673
4674impl GetObjectTaggingInput {
4675 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4676 let mut input = Self::default();
4677 input.bucket = bucket.into();
4678 input.key = key.into();
4679 input
4680 }
4681 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
4682 let mut input = Self::default();
4683 input.bucket = bucket.into();
4684 input.key = key.into();
4685 input.version_id = version_id.into();
4686 input
4687 }
4688
4689 pub fn bucket(&self) -> &str {
4690 &self.bucket
4691 }
4692
4693 pub fn key(&self) -> &str {
4694 &self.key
4695 }
4696
4697 pub fn version_id(&self) -> &str {
4698 &self.version_id
4699 }
4700
4701 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4702 self.bucket = bucket.into();
4703 }
4704
4705 pub fn set_key(&mut self, key: impl Into<String>) {
4706 self.key = key.into();
4707 }
4708
4709 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
4710 self.version_id = version_id.into();
4711 }
4712}
4713
4714impl InputDescriptor for GetObjectTaggingInput {
4715 fn operation(&self) -> &str {
4716 "GetObjectTagging"
4717 }
4718
4719 fn bucket(&self) -> Result<&str, TosError> {
4720 Ok(&self.bucket)
4721 }
4722
4723 fn key(&self) -> Result<&str, TosError> {
4724 Ok(&self.key)
4725 }
4726}
4727
4728impl<B> InputTranslator<B> for GetObjectTaggingInput {
4729 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4730 let mut request = self.trans_key()?;
4731 request.method = HttpMethodGet;
4732 let mut query = HashMap::with_capacity(2);
4733 query.insert("tagging", "".to_string());
4734 if self.version_id != "" {
4735 query.insert(QUERY_VERSION_ID, self.version_id.clone());
4736 }
4737 request.query = Some(query);
4738 Ok(request)
4739 }
4740}
4741
4742#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
4743pub struct GetObjectTaggingOutput {
4744 #[serde(skip)]
4745 pub(crate) request_info: RequestInfo,
4746 #[serde(skip)]
4747 pub(crate) version_id: String,
4748 #[serde(rename = "TagSet")]
4749 pub(crate) tag_set: TagSet,
4750}
4751
4752impl GetObjectTaggingOutput {
4753 pub fn version_id(&self) -> &str {
4754 &self.version_id
4755 }
4756
4757 pub fn tag_set(&self) -> &TagSet {
4758 &self.tag_set
4759 }
4760}
4761#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
4762pub struct DeleteObjectTaggingInput {
4763 pub(crate) generic_input: GenericInput,
4764 pub(crate) bucket: String,
4765 pub(crate) key: String,
4766 pub(crate) version_id: String,
4767}
4768
4769impl DeleteObjectTaggingInput {
4770 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4771 let mut input = Self::default();
4772 input.bucket = bucket.into();
4773 input.key = key.into();
4774 input
4775 }
4776 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
4777 let mut input = Self::default();
4778 input.bucket = bucket.into();
4779 input.key = key.into();
4780 input.version_id = version_id.into();
4781 input
4782 }
4783
4784 pub fn bucket(&self) -> &str {
4785 &self.bucket
4786 }
4787
4788 pub fn key(&self) -> &str {
4789 &self.key
4790 }
4791
4792 pub fn version_id(&self) -> &str {
4793 &self.version_id
4794 }
4795
4796 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
4797 self.bucket = bucket.into();
4798 }
4799
4800 pub fn set_key(&mut self, key: impl Into<String>) {
4801 self.key = key.into();
4802 }
4803
4804 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
4805 self.version_id = version_id.into();
4806 }
4807}
4808
4809impl InputDescriptor for DeleteObjectTaggingInput {
4810 fn operation(&self) -> &str {
4811 "DeleteObjectTagging"
4812 }
4813
4814 fn bucket(&self) -> Result<&str, TosError> {
4815 Ok(&self.bucket)
4816 }
4817
4818 fn key(&self) -> Result<&str, TosError> {
4819 Ok(&self.key)
4820 }
4821}
4822
4823impl<B> InputTranslator<B> for DeleteObjectTaggingInput {
4824 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
4825 let mut request = self.trans_key()?;
4826 request.method = HttpMethodDelete;
4827 let mut query = HashMap::with_capacity(2);
4828 query.insert("tagging", "".to_string());
4829 if self.version_id != "" {
4830 query.insert(QUERY_VERSION_ID, self.version_id.clone());
4831 }
4832 request.query = Some(query);
4833 Ok(request)
4834 }
4835}
4836
4837#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
4838pub struct DeleteObjectTaggingOutput {
4839 pub(crate) request_info: RequestInfo,
4840 pub(crate) version_id: String,
4841}
4842
4843#[derive(
4844 Debug,
4845 Clone,
4846 HttpBasicHeader,
4847 AclHeader,
4848 SseHeader,
4849 SsecHeader,
4850 MiscHeader,
4851 ObjectLock,
4852 IfMatch,
4853 Serialize,
4854 GenericInput,
4855)]
4856pub struct FetchObjectInput {
4857 #[serde(skip)]
4858 pub(crate) generic_input: GenericInput,
4859 #[serde(skip)]
4860 pub(crate) bucket: String,
4861 #[serde(rename = "Object")]
4862 pub(crate) key: String,
4863 #[serde(rename = "URL")]
4864 pub(crate) url: String,
4865 #[serde(rename = "IgnoreSameKey")]
4866 #[serde(skip_serializing_if = "<&bool as std::ops::Not>::not")]
4867 pub(crate) ignore_same_key: bool,
4868 #[serde(rename = "ContentMD5")]
4869 #[serde(skip_serializing_if = "String::is_empty")]
4870 pub(crate) content_md5: String,
4871 #[serde(skip)]
4872 pub(crate) content_length: i64,
4873 #[serde(skip)]
4874 pub(crate) cache_control: String,
4875 #[serde(skip)]
4876 pub(crate) content_disposition: String,
4877 #[serde(skip)]
4878 pub(crate) content_encoding: String,
4879 #[serde(skip)]
4880 pub(crate) content_language: String,
4881 #[serde(skip)]
4882 pub(crate) content_type: String,
4883 #[serde(skip)]
4884 pub(crate) expires: Option<DateTime<Utc>>,
4885 #[serde(skip)]
4886 pub(crate) acl: Option<ACLType>,
4887 #[serde(skip)]
4888 pub(crate) grant_full_control: String,
4889 #[serde(skip)]
4890 pub(crate) grant_read: String,
4891 #[serde(skip)]
4892 pub(crate) grant_read_acp: String,
4893 #[serde(skip)]
4894 pub(crate) grant_write: String,
4895 #[serde(skip)]
4896 pub(crate) grant_write_acp: String,
4897 #[serde(skip)]
4898 pub(crate) ssec_algorithm: String,
4899 #[serde(skip)]
4900 pub(crate) ssec_key: String,
4901 #[serde(skip)]
4902 pub(crate) ssec_key_md5: String,
4903 #[serde(skip)]
4904 pub(crate) server_side_encryption: String,
4905 #[serde(skip)]
4906 pub(crate) server_side_encryption_key_id: String,
4907 #[serde(skip)]
4908 pub(crate) meta: HashMap<String, String>,
4909 #[serde(skip)]
4910 pub(crate) website_redirect_location: String,
4911 #[serde(skip)]
4912 pub(crate) storage_class: Option<StorageClassType>,
4913 #[serde(skip)]
4914 pub(crate) traffic_limit: i64,
4915 #[serde(skip)]
4916 pub(crate) forbid_overwrite: bool,
4917 #[serde(skip)]
4918 pub(crate) if_match: String,
4919 #[serde(skip)]
4920 pub(crate) if_none_match: String,
4921 #[serde(skip)]
4922 pub(crate) tagging: String,
4923 #[serde(skip)]
4924 pub(crate) notification_custom_parameters: String,
4925 #[serde(skip)]
4926 pub(crate) detect_mime_type: bool,
4927 #[serde(skip)]
4928 pub(crate) object_expires: i64,
4929 #[serde(skip)]
4930 pub(crate) object_lock_mode: Option<ObjectLockModeType>,
4931 #[serde(skip)]
4932 pub(crate) object_lock_retain_util_date: Option<DateTime<Utc>>,
4933}
4934
4935impl Default for FetchObjectInput {
4936 fn default() -> Self {
4937 Self {
4938 generic_input: Default::default(),
4939 bucket: "".to_string(),
4940 key: "".to_string(),
4941 url: "".to_string(),
4942 ignore_same_key: false,
4943 content_md5: "".to_string(),
4944 content_length: -1,
4945 cache_control: "".to_string(),
4946 content_disposition: "".to_string(),
4947 content_encoding: "".to_string(),
4948 content_language: "".to_string(),
4949 content_type: "".to_string(),
4950 expires: None,
4951 acl: None,
4952 grant_full_control: "".to_string(),
4953 grant_read: "".to_string(),
4954 grant_read_acp: "".to_string(),
4955 grant_write: "".to_string(),
4956 grant_write_acp: "".to_string(),
4957 ssec_algorithm: "".to_string(),
4958 ssec_key: "".to_string(),
4959 ssec_key_md5: "".to_string(),
4960 server_side_encryption: "".to_string(),
4961 server_side_encryption_key_id: "".to_string(),
4962 meta: Default::default(),
4963 website_redirect_location: "".to_string(),
4964 storage_class: None,
4965 traffic_limit: 0,
4966 forbid_overwrite: false,
4967 if_match: "".to_string(),
4968 if_none_match: "".to_string(),
4969 tagging: "".to_string(),
4970 notification_custom_parameters: "".to_string(),
4971 detect_mime_type: false,
4972 object_expires: -1,
4973 object_lock_mode: None,
4974 object_lock_retain_util_date: None,
4975 }
4976 }
4977}
4978
4979impl FetchObjectInput
4980{
4981 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
4982 let mut input = Self::default();
4983 input.bucket = bucket.into();
4984 input.key = key.into();
4985 input
4986 }
4987 pub fn new_with_url(bucket: impl Into<String>, key: impl Into<String>, url: impl Into<String>) -> Self {
4988 let mut input = Self::default();
4989 input.bucket = bucket.into();
4990 input.key = key.into();
4991 input.url = url.into();
4992 input
4993 }
4994 pub fn bucket(&self) -> &str {
4995 &self.bucket
4996 }
4997 pub fn key(&self) -> &str {
4998 &self.key
4999 }
5000
5001 pub fn url(&self) -> &str {
5002 &self.url
5003 }
5004
5005 pub fn ignore_same_key(&self) -> bool {
5006 self.ignore_same_key
5007 }
5008
5009 pub fn content_md5(&self) -> &str {
5010 &self.content_md5
5011 }
5012 pub fn meta(&self) -> &HashMap<String, String> {
5013 &self.meta
5014 }
5015 pub fn traffic_limit(&self) -> i64 {
5016 self.traffic_limit
5017 }
5018 pub fn forbid_overwrite(&self) -> bool {
5019 self.forbid_overwrite
5020 }
5021 pub fn tagging(&self) -> &str {
5022 &self.tagging
5023 }
5024
5025 pub fn notification_custom_parameters(&self) -> &str {
5026 &self.notification_custom_parameters
5027 }
5028
5029 pub fn detect_mime_type(&self) -> bool {
5030 self.detect_mime_type
5031 }
5032
5033 pub fn object_expires(&self) -> i64 {
5034 self.object_expires
5035 }
5036 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
5037 self.bucket = bucket.into();
5038 }
5039 pub fn set_key(&mut self, key: impl Into<String>) {
5040 self.key = key.into();
5041 }
5042
5043 pub fn set_url(&mut self, url: impl Into<String>) {
5044 self.url = url.into();
5045 }
5046
5047 pub fn set_ignore_same_key(&mut self, ignore_same_key: bool) {
5048 self.ignore_same_key = ignore_same_key;
5049 }
5050
5051 pub fn set_content_md5(&mut self, content_md5: impl Into<String>) {
5052 self.content_md5 = content_md5.into();
5053 }
5054 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
5055 self.meta = meta.into();
5056 }
5057 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
5058 self.traffic_limit = traffic_limit;
5059 }
5060 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
5061 self.forbid_overwrite = forbid_overwrite;
5062 }
5063 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
5064 self.tagging = tagging.into();
5065 }
5066
5067 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
5068 self.notification_custom_parameters = notification_custom_parameters.into();
5069 }
5070
5071 pub fn set_detect_mime_type(&mut self, detect_mime_type: bool) {
5072 self.detect_mime_type = detect_mime_type;
5073 }
5074
5075 pub fn set_object_expires(&mut self, object_expires: i64) {
5076 self.object_expires = object_expires;
5077 }
5078}
5079
5080impl InputDescriptor for FetchObjectInput {
5081 fn operation(&self) -> &str {
5082 "FetchObject"
5083 }
5084 fn bucket(&self) -> Result<&str, TosError> {
5085 Ok(&self.bucket)
5086 }
5087
5088 fn key(&self) -> Result<&str, TosError> {
5089 Ok(&self.key)
5090 }
5091}
5092
5093impl<B> InputTranslator<B> for FetchObjectInput
5094where
5095 B: BuildBufferReader,
5096{
5097 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
5098 if self.url == "" {
5099 return Err(TosError::client_error("empty url"));
5100 }
5101
5102 match serde_json::to_string(self) {
5103 Err(e) => Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
5104 Ok(json) => {
5105 let mut request = self.trans_key()?;
5106 request.method = HttpMethodPost;
5107 let header = &mut request.header;
5108 header.insert(HEADER_CONTENT_MD5, base64_md5(&json));
5109 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
5110 request.body = Some(body);
5111 header.insert(HEADER_CONTENT_LENGTH, len.to_string());
5112 set_http_basic_header_for_fetch(header, config_holder.disable_encoding_meta, self);
5113 set_acl_header(header, self);
5114 set_sse_header(header, self)?;
5115 set_ssec_header(header, &self.server_side_encryption, self)?;
5116 set_if_match_header(header, self);
5117 set_object_lock_header(header, self);
5118 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
5119 set_misc_header_for_fetch(header, self);
5120 if self.forbid_overwrite {
5121 header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
5122 }
5123 if self.traffic_limit > 0 {
5124 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
5125 }
5126 if self.tagging != "" {
5127 header.insert(HEADER_TAGGING, self.tagging.clone());
5128 }
5129
5130 if self.object_expires >= 0 {
5131 header.insert(HEADER_OBJECT_EXPIRES, self.object_expires.to_string());
5132 }
5133 if self.notification_custom_parameters != "" {
5134 header.insert(HEADER_NOTIFICATION_CUSTOM_PARAMETERS, self.notification_custom_parameters.to_string());
5135 }
5136 if self.detect_mime_type {
5137 header.insert(HEADER_FETCH_DETECT_MIME_TYPE, "true".to_string());
5138 }
5139 request.query = Some(HashMap::from([("fetch", "".to_string())]));
5140 Ok(request)
5141 }
5142 }
5143 }
5144}
5145
5146#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
5147pub struct FetchObjectOutput {
5148 pub(crate) request_info: RequestInfo,
5149 pub(crate) etag: String,
5150 pub(crate) version_id: String,
5151 pub(crate) ssec_algorithm: String,
5152 pub(crate) ssec_key_md5: String,
5153 pub(crate) server_side_encryption: String,
5154 pub(crate) server_side_encryption_key_id: String,
5155 pub(crate) source_content_type: String,
5156 pub(crate) source_content_length: i64,
5157 pub(crate) md5: String,
5158}
5159
5160impl FetchObjectOutput {
5161 pub fn etag(&self) -> &str {
5162 &self.etag
5163 }
5164
5165 pub fn version_id(&self) -> &str {
5166 &self.version_id
5167 }
5168
5169 pub fn ssec_algorithm(&self) -> &str {
5170 &self.ssec_algorithm
5171 }
5172
5173 pub fn ssec_key_md5(&self) -> &str {
5174 &self.ssec_key_md5
5175 }
5176
5177 pub fn server_side_encryption(&self) -> &str {
5178 &self.server_side_encryption
5179 }
5180
5181 pub fn server_side_encryption_key_id(&self) -> &str {
5182 &self.server_side_encryption_key_id
5183 }
5184
5185 pub fn source_content_type(&self) -> &str {
5186 &self.source_content_type
5187 }
5188
5189 pub fn source_content_length(&self) -> i64 {
5190 self.source_content_length
5191 }
5192
5193 pub fn md5(&self) -> &str {
5194 &self.md5
5195 }
5196}
5197
5198#[derive(
5199 Debug,
5200 Clone,
5201 HttpBasicHeader,
5202 AclHeader,
5203 SseHeader,
5204 SsecHeader,
5205 MiscHeader,
5206 ObjectLock,
5207 IfMatch,
5208 Serialize,
5209 GenericInput
5210)]
5211pub struct PutFetchTaskInput {
5212 #[serde(skip)]
5213 pub(crate) generic_input: GenericInput,
5214 #[serde(skip)]
5215 pub(crate) bucket: String,
5216 #[serde(rename = "Object")]
5217 pub(crate) key: String,
5218 #[serde(rename = "URL")]
5219 pub(crate) url: String,
5220 #[serde(rename = "IgnoreSameKey")]
5221 #[serde(skip_serializing_if = "<&bool as std::ops::Not>::not")]
5222 pub(crate) ignore_same_key: bool,
5223 #[serde(rename = "ContentMD5")]
5224 #[serde(skip_serializing_if = "String::is_empty")]
5225 pub(crate) content_md5: String,
5226 #[serde(rename = "CallbackUrl")]
5227 #[serde(skip_serializing_if = "String::is_empty")]
5228 pub(crate) callback_url: String,
5229 #[serde(rename = "CallbackHost")]
5230 #[serde(skip_serializing_if = "String::is_empty")]
5231 pub(crate) callback_host: String,
5232 #[serde(rename = "CallbackBodyType")]
5233 #[serde(skip_serializing_if = "String::is_empty")]
5234 pub(crate) callback_body_type: String,
5235 #[serde(rename = "CallbackBody")]
5236 #[serde(skip_serializing_if = "String::is_empty")]
5237 pub(crate) callback_body: String,
5238 #[serde(skip)]
5239 pub(crate) content_length: i64,
5240 #[serde(skip)]
5241 pub(crate) cache_control: String,
5242 #[serde(skip)]
5243 pub(crate) content_disposition: String,
5244 #[serde(skip)]
5245 pub(crate) content_encoding: String,
5246 #[serde(skip)]
5247 pub(crate) content_language: String,
5248 #[serde(skip)]
5249 pub(crate) content_type: String,
5250 #[serde(skip)]
5251 pub(crate) expires: Option<DateTime<Utc>>,
5252 #[serde(skip)]
5253 pub(crate) acl: Option<ACLType>,
5254 #[serde(skip)]
5255 pub(crate) grant_full_control: String,
5256 #[serde(skip)]
5257 pub(crate) grant_read: String,
5258 #[serde(skip)]
5259 pub(crate) grant_read_acp: String,
5260 #[serde(skip)]
5261 pub(crate) grant_write: String,
5262 #[serde(skip)]
5263 pub(crate) grant_write_acp: String,
5264 #[serde(skip)]
5265 pub(crate) ssec_algorithm: String,
5266 #[serde(skip)]
5267 pub(crate) ssec_key: String,
5268 #[serde(skip)]
5269 pub(crate) ssec_key_md5: String,
5270 #[serde(skip)]
5271 pub(crate) server_side_encryption: String,
5272 #[serde(skip)]
5273 pub(crate) server_side_encryption_key_id: String,
5274 #[serde(skip)]
5275 pub(crate) meta: HashMap<String, String>,
5276 #[serde(skip)]
5277 pub(crate) website_redirect_location: String,
5278 #[serde(skip)]
5279 pub(crate) storage_class: Option<StorageClassType>,
5280 #[serde(skip)]
5281 pub(crate) traffic_limit: i64,
5282 #[serde(skip)]
5283 pub(crate) forbid_overwrite: bool,
5284 #[serde(skip)]
5285 pub(crate) if_match: String,
5286 #[serde(skip)]
5287 pub(crate) if_none_match: String,
5288 #[serde(skip)]
5289 pub(crate) tagging: String,
5290 #[serde(skip)]
5291 pub(crate) notification_custom_parameters: String,
5292 #[serde(skip)]
5293 pub(crate) detect_mime_type: bool,
5294 #[serde(skip)]
5295 pub(crate) object_expires: i64,
5296 #[serde(skip)]
5297 pub(crate) object_lock_mode: Option<ObjectLockModeType>,
5298 #[serde(skip)]
5299 pub(crate) object_lock_retain_util_date: Option<DateTime<Utc>>,
5300}
5301
5302impl Default for PutFetchTaskInput {
5303 fn default() -> Self {
5304 Self {
5305 generic_input: Default::default(),
5306 bucket: "".to_string(),
5307 key: "".to_string(),
5308 url: "".to_string(),
5309 ignore_same_key: false,
5310 content_md5: "".to_string(),
5311 callback_url: "".to_string(),
5312 callback_host: "".to_string(),
5313 callback_body_type: "".to_string(),
5314 callback_body: "".to_string(),
5315 content_length: -1,
5316 cache_control: "".to_string(),
5317 content_disposition: "".to_string(),
5318 content_encoding: "".to_string(),
5319 content_language: "".to_string(),
5320 content_type: "".to_string(),
5321 expires: None,
5322 acl: None,
5323 grant_full_control: "".to_string(),
5324 grant_read: "".to_string(),
5325 grant_read_acp: "".to_string(),
5326 grant_write: "".to_string(),
5327 grant_write_acp: "".to_string(),
5328 ssec_algorithm: "".to_string(),
5329 ssec_key: "".to_string(),
5330 ssec_key_md5: "".to_string(),
5331 server_side_encryption: "".to_string(),
5332 server_side_encryption_key_id: "".to_string(),
5333 meta: Default::default(),
5334 website_redirect_location: "".to_string(),
5335 storage_class: None,
5336 traffic_limit: 0,
5337 forbid_overwrite: false,
5338 if_match: "".to_string(),
5339 if_none_match: "".to_string(),
5340 tagging: "".to_string(),
5341 notification_custom_parameters: "".to_string(),
5342 detect_mime_type: false,
5343 object_expires: -1,
5344 object_lock_mode: None,
5345 object_lock_retain_util_date: None,
5346 }
5347 }
5348}
5349
5350impl PutFetchTaskInput {
5351 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
5352 let mut input = Self::default();
5353 input.bucket = bucket.into();
5354 input.key = key.into();
5355 input
5356 }
5357 pub fn new_with_url(bucket: impl Into<String>, key: impl Into<String>, url: impl Into<String>) -> Self {
5358 let mut input = Self::default();
5359 input.bucket = bucket.into();
5360 input.key = key.into();
5361 input.url = url.into();
5362 input
5363 }
5364 pub fn bucket(&self) -> &str {
5365 &self.bucket
5366 }
5367 pub fn key(&self) -> &str {
5368 &self.key
5369 }
5370
5371 pub fn url(&self) -> &str {
5372 &self.url
5373 }
5374
5375 pub fn ignore_same_key(&self) -> bool {
5376 self.ignore_same_key
5377 }
5378
5379 pub fn content_md5(&self) -> &str {
5380 &self.content_md5
5381 }
5382 pub fn callback_url(&self) -> &str {
5383 &self.callback_url
5384 }
5385
5386 pub fn callback_host(&self) -> &str {
5387 &self.callback_host
5388 }
5389
5390 pub fn callback_body_type(&self) -> &str {
5391 &self.callback_body_type
5392 }
5393
5394 pub fn callback_body(&self) -> &str {
5395 &self.callback_body
5396 }
5397
5398 pub fn meta(&self) -> &HashMap<String, String> {
5399 &self.meta
5400 }
5401 pub fn traffic_limit(&self) -> i64 {
5402 self.traffic_limit
5403 }
5404 pub fn forbid_overwrite(&self) -> bool {
5405 self.forbid_overwrite
5406 }
5407 pub fn tagging(&self) -> &str {
5408 &self.tagging
5409 }
5410
5411 pub fn notification_custom_parameters(&self) -> &str {
5412 &self.notification_custom_parameters
5413 }
5414
5415 pub fn detect_mime_type(&self) -> bool {
5416 self.detect_mime_type
5417 }
5418
5419 pub fn object_expires(&self) -> i64 {
5420 self.object_expires
5421 }
5422 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
5423 self.bucket = bucket.into();
5424 }
5425 pub fn set_key(&mut self, key: impl Into<String>) {
5426 self.key = key.into();
5427 }
5428
5429 pub fn set_url(&mut self, url: impl Into<String>) {
5430 self.url = url.into();
5431 }
5432
5433 pub fn set_ignore_same_key(&mut self, ignore_same_key: bool) {
5434 self.ignore_same_key = ignore_same_key;
5435 }
5436 pub fn set_content_md5(&mut self, content_md5: impl Into<String>) {
5437 self.content_md5 = content_md5.into();
5438 }
5439
5440 pub fn set_callback_url(&mut self, callback_url: impl Into<String>) {
5441 self.callback_url = callback_url.into();
5442 }
5443
5444 pub fn set_callback_host(&mut self, callback_host: impl Into<String>) {
5445 self.callback_host = callback_host.into();
5446 }
5447
5448 pub fn set_callback_body_type(&mut self, callback_body_type: impl Into<String>) {
5449 self.callback_body_type = callback_body_type.into();
5450 }
5451
5452 pub fn set_callback_body(&mut self, callback_body: impl Into<String>) {
5453 self.callback_body = callback_body.into();
5454 }
5455 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
5456 self.meta = meta.into();
5457 }
5458 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
5459 self.traffic_limit = traffic_limit;
5460 }
5461 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
5462 self.forbid_overwrite = forbid_overwrite;
5463 }
5464 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
5465 self.tagging = tagging.into();
5466 }
5467
5468 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
5469 self.notification_custom_parameters = notification_custom_parameters.into();
5470 }
5471
5472 pub fn set_detect_mime_type(&mut self, detect_mime_type: bool) {
5473 self.detect_mime_type = detect_mime_type;
5474 }
5475
5476 pub fn set_object_expires(&mut self, object_expires: i64) {
5477 self.object_expires = object_expires;
5478 }
5479}
5480
5481impl InputDescriptor for PutFetchTaskInput {
5482 fn operation(&self) -> &str {
5483 "PutFetchTask"
5484 }
5485
5486 fn bucket(&self) -> Result<&str, TosError> {
5487 Ok(&self.bucket)
5488 }
5489
5490 fn key(&self) -> Result<&str, TosError> {
5491 Ok(&self.key)
5492 }
5493}
5494
5495impl<B> InputTranslator<B> for PutFetchTaskInput
5496where
5497 B: BuildBufferReader,
5498{
5499 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
5500 if self.url == "" {
5501 return Err(TosError::client_error("empty url"));
5502 }
5503
5504 match serde_json::to_string(self) {
5505 Err(e) => Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
5506 Ok(json) => {
5507 let mut request = self.trans_key()?;
5508 request.method = HttpMethodPost;
5509 let header = &mut request.header;
5510 header.insert(HEADER_CONTENT_MD5, base64_md5(&json));
5511 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
5512 request.body = Some(body);
5513 header.insert(HEADER_CONTENT_LENGTH, len.to_string());
5514 set_http_basic_header_for_fetch(header, config_holder.disable_encoding_meta, self);
5515 set_acl_header(header, self);
5516 set_sse_header(header, self)?;
5517 set_ssec_header(header, &self.server_side_encryption, self)?;
5518 set_if_match_header(header, self);
5519 set_object_lock_header(header, self);
5520 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
5521 set_misc_header_for_fetch(header, self);
5522 if self.forbid_overwrite {
5523 header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
5524 }
5525 if self.traffic_limit > 0 {
5526 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
5527 }
5528 if self.tagging != "" {
5529 header.insert(HEADER_TAGGING, self.tagging.clone());
5530 }
5531
5532 if self.object_expires >= 0 {
5533 header.insert(HEADER_OBJECT_EXPIRES, self.object_expires.to_string());
5534 }
5535 if self.notification_custom_parameters != "" {
5536 header.insert(HEADER_NOTIFICATION_CUSTOM_PARAMETERS, self.notification_custom_parameters.to_string());
5537 }
5538 if self.detect_mime_type {
5539 header.insert(HEADER_FETCH_DETECT_MIME_TYPE, "true".to_string());
5540 }
5541 request.query = Some(HashMap::from([("fetchTask", "".to_string())]));
5542 Ok(request)
5543 }
5544 }
5545 }
5546}
5547#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
5548pub struct PutFetchTaskOutput {
5549 #[serde(skip)]
5550 pub(crate) request_info: RequestInfo,
5551 #[serde(rename = "TaskId")]
5552 pub(crate) task_id: String,
5553}
5554impl PutFetchTaskOutput {
5555 pub fn task_id(&self) -> &str {
5556 &self.task_id
5557 }
5558}
5559#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
5560pub struct GetFetchTaskInput {
5561 pub(crate) generic_input: GenericInput,
5562 pub(crate) bucket: String,
5563 pub(crate) task_id: String,
5564}
5565
5566impl GetFetchTaskInput {
5567 pub fn new(bucket: impl Into<String>, task_id: impl Into<String>) -> Self {
5568 Self {
5569 generic_input: Default::default(),
5570 bucket: bucket.into(),
5571 task_id: task_id.into(),
5572 }
5573 }
5574
5575 pub fn bucket(&self) -> &str {
5576 &self.bucket
5577 }
5578
5579 pub fn task_id(&self) -> &str {
5580 &self.task_id
5581 }
5582
5583 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
5584 self.bucket = bucket.into();
5585 }
5586
5587 pub fn set_task_id(&mut self, task_id: impl Into<String>) {
5588 self.task_id = task_id.into();
5589 }
5590}
5591
5592impl InputDescriptor for GetFetchTaskInput {
5593 fn operation(&self) -> &str {
5594 "GetFetchTask"
5595 }
5596
5597 fn bucket(&self) -> Result<&str, TosError> {
5598 Ok(&self.bucket)
5599 }
5600}
5601
5602impl<B> InputTranslator<B> for GetFetchTaskInput {
5603 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
5604 if self.task_id == "" {
5605 return Err(TosError::client_error("empty task id"));
5606 }
5607
5608 let mut request = self.trans_bucket()?;
5609 request.method = HttpMethodGet;
5610 let mut query = HashMap::with_capacity(2);
5611 query.insert("fetchTask", "".to_string());
5612 map_insert(&mut query, QUERY_TASK_ID, &self.task_id);
5613 request.query = Some(query);
5614 Ok(request)
5615 }
5616}
5617
5618#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
5619pub struct GetFetchTaskOutput {
5620 #[serde(skip)]
5621 pub(crate) request_info: RequestInfo,
5622 #[serde(rename = "State")]
5623 #[serde(default)]
5624 pub(crate) state: String,
5625 #[serde(rename = "Err")]
5626 #[serde(default)]
5627 pub(crate) err: String,
5628 #[serde(rename = "Task")]
5629 pub(crate) task: Option<FetchTask>,
5630}
5631impl GetFetchTaskOutput {
5632 pub fn state(&self) -> &str {
5633 &self.state
5634 }
5635
5636 pub fn err(&self) -> &str {
5637 &self.err
5638 }
5639
5640 pub fn task(&self) -> &Option<FetchTask> {
5641 &self.task
5642 }
5643}
5644#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
5645pub struct FetchTask {
5646 #[serde(rename = "URL")]
5647 #[serde(default)]
5648 pub(crate) url: String,
5649 #[serde(rename = "IgnoreSameKey")]
5650 #[serde(default)]
5651 pub(crate) ignore_same_key: bool,
5652 #[serde(rename = "ContentMD5")]
5653 #[serde(default)]
5654 pub(crate) content_md5: String,
5655 #[serde(rename = "Bucket")]
5656 #[serde(default)]
5657 pub(crate) bucket: String,
5658 #[serde(rename = "Key")]
5659 #[serde(default)]
5660 pub(crate) key: String,
5661 #[serde(rename = "CallbackUrl")]
5662 #[serde(default)]
5663 pub(crate) callback_url: String,
5664 #[serde(rename = "CallbackHost")]
5665 #[serde(default)]
5666 pub(crate) callback_host: String,
5667 #[serde(rename = "CallbackBodyType")]
5668 #[serde(default)]
5669 pub(crate) callback_body_type: String,
5670 #[serde(rename = "CallbackBody")]
5671 #[serde(default)]
5672 pub(crate) callback_body: String,
5673 #[serde(rename = "StorageClass")]
5674 pub(crate) storage_class: Option<StorageClassType>,
5675 #[serde(rename = "Acl")]
5676 pub(crate) acl: Option<ACLType>,
5677 #[serde(rename = "GrantFullControl")]
5678 #[serde(default)]
5679 pub(crate) grant_fullcontrol: String,
5680 #[serde(rename = "GrantRead")]
5681 #[serde(default)]
5682 pub(crate) grant_read: String,
5683 #[serde(rename = "GrantReadAcp")]
5684 #[serde(default)]
5685 pub(crate) grant_read_acp: String,
5686 #[serde(rename = "GrantWrite")]
5687 #[serde(default)]
5688 pub(crate) grant_write: String,
5689 #[serde(rename = "GrantWriteAcp")]
5690 #[serde(default)]
5691 pub(crate) grant_write_acp: String,
5692 #[serde(rename = "SSECAlgorithm")]
5693 #[serde(default)]
5694 pub(crate) ssec_algorithm: String,
5695 #[serde(rename = "SSECKey")]
5696 #[serde(default)]
5697 pub(crate) ssec_key: String,
5698 #[serde(rename = "SSECKeyMd5")]
5699 #[serde(default)]
5700 pub(crate) ssec_key_md5: String,
5701 #[serde(rename = "UserMeta")]
5702 #[serde(default)]
5703 pub(crate) user_meta: Vec<UserMeta>,
5704 #[serde(skip)]
5705 pub(crate) meta: HashMap<String, String>,
5706}
5707
5708impl FetchTask {
5709 pub fn url(&self) -> &str {
5710 &self.url
5711 }
5712
5713 pub fn ignore_same_key(&self) -> bool {
5714 self.ignore_same_key
5715 }
5716
5717 pub fn content_md5(&self) -> &str {
5718 &self.content_md5
5719 }
5720
5721 pub fn bucket(&self) -> &str {
5722 &self.bucket
5723 }
5724
5725 pub fn key(&self) -> &str {
5726 &self.key
5727 }
5728 pub fn callback_body(&self) -> &str {
5729 &self.callback_body
5730 }
5731
5732 pub fn callback_body_type(&self) -> &str {
5733 &self.callback_body_type
5734 }
5735
5736 pub fn callback_host(&self) -> &str {
5737 &self.callback_host
5738 }
5739
5740 pub fn callback_url(&self) -> &str {
5741 &self.callback_url
5742 }
5743 pub fn storage_class(&self) -> &Option<StorageClassType> {
5744 &self.storage_class
5745 }
5746
5747 pub fn acl(&self) -> &Option<ACLType> {
5748 &self.acl
5749 }
5750
5751 pub fn grant_fullcontrol(&self) -> &str {
5752 &self.grant_fullcontrol
5753 }
5754
5755 pub fn grant_read(&self) -> &str {
5756 &self.grant_read
5757 }
5758
5759 pub fn grant_read_acp(&self) -> &str {
5760 &self.grant_read_acp
5761 }
5762
5763 pub fn grant_write(&self) -> &str {
5764 &self.grant_write
5765 }
5766
5767 pub fn grant_write_acp(&self) -> &str {
5768 &self.grant_write_acp
5769 }
5770
5771 pub fn ssec_algorithm(&self) -> &str {
5772 &self.ssec_algorithm
5773 }
5774
5775 pub fn ssec_key(&self) -> &str {
5776 &self.ssec_key
5777 }
5778
5779 pub fn ssec_key_md5(&self) -> &str {
5780 &self.ssec_key_md5
5781 }
5782
5783 pub fn meta(&self) -> &HashMap<String, String> {
5784 &self.meta
5785 }
5786}
5787#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
5788pub struct RenameObjectInput {
5789 pub(crate) generic_input: GenericInput,
5790 pub(crate) bucket: String,
5791 pub(crate) key: String,
5792 pub(crate) new_key: String,
5793 pub(crate) recursive_mkdir: bool,
5794 pub(crate) forbid_overwrite: bool,
5795 pub(crate) notification_custom_parameters: String,
5796}
5797
5798impl RenameObjectInput {
5799 pub fn new(bucket: impl Into<String>, key: impl Into<String>, new_key: impl Into<String>) -> Self {
5800 Self {
5801 generic_input: Default::default(),
5802 bucket: bucket.into(),
5803 key: key.into(),
5804 new_key: new_key.into(),
5805 recursive_mkdir: false,
5806 forbid_overwrite: false,
5807 notification_custom_parameters: "".to_string(),
5808 }
5809 }
5810
5811 pub fn bucket(&self) -> &str {
5812 &self.bucket
5813 }
5814
5815 pub fn key(&self) -> &str {
5816 &self.key
5817 }
5818
5819 pub fn new_key(&self) -> &str {
5820 &self.new_key
5821 }
5822
5823 pub fn recursive_mkdir(&self) -> bool {
5824 self.recursive_mkdir
5825 }
5826
5827 pub fn forbid_overwrite(&self) -> bool {
5828 self.forbid_overwrite
5829 }
5830
5831 pub fn notification_custom_parameters(&self) -> &str {
5832 &self.notification_custom_parameters
5833 }
5834
5835 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
5836 self.bucket = bucket.into();
5837 }
5838
5839 pub fn set_key(&mut self, key: impl Into<String>) {
5840 self.key = key.into();
5841 }
5842
5843 pub fn set_new_key(&mut self, new_key: impl Into<String>) {
5844 self.new_key = new_key.into();
5845 }
5846
5847 pub fn set_recursive_mkdir(&mut self, recursive_mkdir: bool) {
5848 self.recursive_mkdir = recursive_mkdir;
5849 }
5850
5851 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
5852 self.forbid_overwrite = forbid_overwrite;
5853 }
5854
5855 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
5856 self.notification_custom_parameters = notification_custom_parameters.into();
5857 }
5858}
5859
5860impl InputDescriptor for RenameObjectInput {
5861 fn operation(&self) -> &str {
5862 "RenameObject"
5863 }
5864
5865 fn bucket(&self) -> Result<&str, TosError> {
5866 Ok(&self.bucket)
5867 }
5868
5869 fn key(&self) -> Result<&str, TosError> {
5870 Ok(&self.key)
5871 }
5872}
5873
5874impl<B> InputTranslator<B> for RenameObjectInput {
5875 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
5876 if self.new_key == "" {
5877 return Err(TosError::client_error("empty new key"));
5878 }
5879 let mut request = self.trans_key()?;
5880 request.method = HttpMethodPut;
5881 if self.recursive_mkdir {
5882 request.header.insert(HEADER_RECURSIVE_MKDIR, self.recursive_mkdir.to_string());
5883 }
5884 if self.forbid_overwrite {
5885 request.header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
5886 }
5887 map_insert(&mut request.header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
5888 let mut query = HashMap::with_capacity(2);
5889 query.insert("rename", "".to_string());
5890 query.insert("name", self.new_key.to_string());
5891 request.query = Some(query);
5892 Ok(request)
5893 }
5894}
5895
5896#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
5897pub struct RenameObjectOutput {
5898 pub(crate) request_info: RequestInfo,
5899}
5900#[derive(Debug, Clone, PartialEq, Default, Serialize, GenericInput)]
5901pub struct RestoreObjectInput {
5902 #[serde(skip)]
5903 pub(crate) generic_input: GenericInput,
5904 #[serde(skip)]
5905 pub(crate) bucket: String,
5906 #[serde(skip)]
5907 pub(crate) key: String,
5908 #[serde(skip)]
5909 pub(crate) version_id: String,
5910 #[serde(rename = "Days")]
5911 #[serde(skip_serializing_if = "is_non_positive")]
5912 pub(crate) days: isize,
5913 #[serde(rename = "RestoreJobParameters")]
5914 #[serde(skip_serializing_if = "Option::is_none")]
5915 pub(crate) restore_job_parameters: Option<RestoreJobParameters>,
5916 #[serde(skip)]
5917 pub(crate) notification_custom_parameters: String,
5918}
5919impl RestoreObjectInput {
5920 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
5921 Self {
5922 generic_input: Default::default(),
5923 bucket: bucket.into(),
5924 key: key.into(),
5925 version_id: "".to_string(),
5926 days: 0,
5927 restore_job_parameters: None,
5928 notification_custom_parameters: "".to_string(),
5929 }
5930 }
5931 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
5932 Self {
5933 generic_input: Default::default(),
5934 bucket: bucket.into(),
5935 key: key.into(),
5936 version_id: version_id.into(),
5937 days: 0,
5938 restore_job_parameters: None,
5939 notification_custom_parameters: "".to_string(),
5940 }
5941 }
5942
5943 pub fn bucket(&self) -> &str {
5944 &self.bucket
5945 }
5946
5947 pub fn key(&self) -> &str {
5948 &self.key
5949 }
5950
5951 pub fn version_id(&self) -> &str {
5952 &self.version_id
5953 }
5954
5955 pub fn days(&self) -> isize {
5956 self.days
5957 }
5958
5959 pub fn restore_job_parameters(&self) -> &Option<RestoreJobParameters> {
5960 &self.restore_job_parameters
5961 }
5962
5963 pub fn notification_custom_parameters(&self) -> &str {
5964 &self.notification_custom_parameters
5965 }
5966
5967 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
5968 self.bucket = bucket.into();
5969 }
5970
5971 pub fn set_key(&mut self, key: impl Into<String>) {
5972 self.key = key.into();
5973 }
5974
5975 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
5976 self.version_id = version_id.into();
5977 }
5978
5979 pub fn set_days(&mut self, days: isize) {
5980 self.days = days;
5981 }
5982
5983 pub fn set_restore_job_parameters(&mut self, restore_job_parameters: impl Into<RestoreJobParameters>) {
5984 self.restore_job_parameters = Some(restore_job_parameters.into());
5985 }
5986
5987 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
5988 self.notification_custom_parameters = notification_custom_parameters.into();
5989 }
5990}
5991
5992impl InputDescriptor for RestoreObjectInput {
5993 fn operation(&self) -> &str {
5994 "RestoreObject"
5995 }
5996
5997 fn bucket(&self) -> Result<&str, TosError> {
5998 Ok(&self.bucket)
5999 }
6000
6001 fn key(&self) -> Result<&str, TosError> {
6002 Ok(&self.key)
6003 }
6004}
6005
6006impl<B> InputTranslator<B> for RestoreObjectInput
6007where
6008 B: BuildBufferReader,
6009{
6010 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6011 match serde_json::to_string(self) {
6012 Err(e) => Err(TosError::client_error_with_cause("trans json error", GenericError::JsonError(e.to_string()))),
6013 Ok(json) => {
6014 let mut request = self.trans_key()?;
6015 request.method = HttpMethodPost;
6016 map_insert(&mut request.header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
6017 let mut query = HashMap::with_capacity(2);
6018 query.insert("restore", "".to_string());
6019 map_insert(&mut query, QUERY_VERSION_ID, &self.version_id);
6020 request.query = Some(query);
6021 request.header.insert(HEADER_CONTENT_MD5, base64_md5(&json));
6022 let (body, len) = B::new(Bytes::from(json.into_bytes()))?;
6023 request.body = Some(body);
6024 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
6025 Ok(request)
6026 }
6027 }
6028 }
6029}
6030
6031
6032#[derive(Debug, Clone, PartialEq, Default, Serialize)]
6033pub struct RestoreJobParameters {
6034 #[serde(rename = "Tier")]
6035 #[serde(default)]
6036 pub(crate) tier: TierType,
6037}
6038
6039impl RestoreJobParameters {
6040 pub fn new(tier: impl Into<TierType>) -> Self {
6041 Self {
6042 tier: tier.into(),
6043 }
6044 }
6045
6046 pub fn tier(&self) -> &TierType {
6047 &self.tier
6048 }
6049
6050 pub fn set_tier(&mut self, tier: impl Into<TierType>) {
6051 self.tier = tier.into();
6052 }
6053}
6054#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
6055pub struct RestoreObjectOutput {
6056 pub(crate) request_info: RequestInfo,
6057}
6058
6059#[derive(
6060 Debug,
6061 Clone,
6062 HttpBasicHeader,
6063 AclHeader,
6064 GenericInput
6065)]
6066pub struct PutSymlinkInput {
6067 pub(crate) generic_input: GenericInput,
6068 pub(crate) bucket: String,
6069 pub(crate) key: String,
6070 pub(crate) symlink_target_key: String,
6071 pub(crate) symlink_target_bucket: String,
6072
6073 pub(crate) content_length: i64,
6074 pub(crate) cache_control: String,
6075 pub(crate) content_disposition: String,
6076 pub(crate) content_encoding: String,
6077 pub(crate) content_language: String,
6078 pub(crate) content_type: String,
6079 pub(crate) expires: Option<DateTime<Utc>>,
6080
6081 pub(crate) acl: Option<ACLType>,
6082 pub(crate) grant_full_control: String,
6083 pub(crate) grant_read: String,
6084 pub(crate) grant_read_acp: String,
6085 pub(crate) grant_write: String,
6086 pub(crate) grant_write_acp: String,
6087
6088 pub(crate) storage_class: Option<StorageClassType>,
6089 pub(crate) meta: HashMap<String, String>,
6090 pub(crate) forbid_overwrite: bool,
6091 pub(crate) tagging: String,
6092}
6093
6094impl PutSymlinkInput {
6095 pub fn new(bucket: impl Into<String>, key: impl Into<String>, symlink_target_key: impl Into<String>) -> Self {
6096 Self {
6097 generic_input: Default::default(),
6098 bucket: bucket.into(),
6099 key: key.into(),
6100 symlink_target_key: symlink_target_key.into(),
6101 symlink_target_bucket: "".to_string(),
6102 content_length: -1,
6103 cache_control: "".to_string(),
6104 content_disposition: "".to_string(),
6105 content_encoding: "".to_string(),
6106 content_language: "".to_string(),
6107 content_type: "".to_string(),
6108 expires: None,
6109 acl: None,
6110 grant_full_control: "".to_string(),
6111 grant_read: "".to_string(),
6112 grant_read_acp: "".to_string(),
6113 grant_write: "".to_string(),
6114 grant_write_acp: "".to_string(),
6115 storage_class: None,
6116 meta: Default::default(),
6117 forbid_overwrite: false,
6118 tagging: "".to_string(),
6119 }
6120 }
6121
6122 pub fn bucket(&self) -> &str {
6123 &self.bucket
6124 }
6125
6126 pub fn key(&self) -> &str {
6127 &self.key
6128 }
6129
6130 pub fn symlink_target_key(&self) -> &str {
6131 &self.symlink_target_key
6132 }
6133
6134 pub fn symlink_target_bucket(&self) -> &str {
6135 &self.symlink_target_bucket
6136 }
6137
6138 pub fn storage_class(&self) -> &Option<StorageClassType> {
6139 &self.storage_class
6140 }
6141
6142 pub fn meta(&self) -> &HashMap<String, String> {
6143 &self.meta
6144 }
6145
6146 pub fn forbid_overwrite(&self) -> bool {
6147 self.forbid_overwrite
6148 }
6149
6150 pub fn tagging(&self) -> &str {
6151 &self.tagging
6152 }
6153
6154 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6155 self.bucket = bucket.into();
6156 }
6157
6158 pub fn set_key(&mut self, key: impl Into<String>) {
6159 self.key = key.into();
6160 }
6161
6162 pub fn set_symlink_target_key(&mut self, symlink_target_key: impl Into<String>) {
6163 self.symlink_target_key = symlink_target_key.into();
6164 }
6165
6166 pub fn set_symlink_target_bucket(&mut self, symlink_target_bucket: impl Into<String>) {
6167 self.symlink_target_bucket = symlink_target_bucket.into();
6168 }
6169
6170 pub fn set_storage_class(&mut self, storage_class: impl Into<StorageClassType>) {
6171 self.storage_class = Some(storage_class.into());
6172 }
6173
6174 pub fn set_meta(&mut self, meta: impl Into<HashMap<String, String>>) {
6175 self.meta = meta.into();
6176 }
6177
6178 pub fn set_forbid_overwrite(&mut self, forbid_overwrite: bool) {
6179 self.forbid_overwrite = forbid_overwrite;
6180 }
6181
6182 pub fn set_tagging(&mut self, tagging: impl Into<String>) {
6183 self.tagging = tagging.into();
6184 }
6185}
6186
6187impl InputDescriptor for PutSymlinkInput {
6188 fn operation(&self) -> &str {
6189 "PutSymlink"
6190 }
6191
6192 fn bucket(&self) -> Result<&str, TosError> {
6193 Ok(&self.bucket)
6194 }
6195
6196 fn key(&self) -> Result<&str, TosError> {
6197 Ok(&self.key)
6198 }
6199}
6200
6201impl<B> InputTranslator<B> for PutSymlinkInput {
6202 fn trans(&self, config_holder: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6203 if self.symlink_target_key == "" {
6204 return Err(TosError::client_error("empty symlink target key"));
6205 }
6206
6207 let mut request = self.trans_key()?;
6208 request.method = HttpMethodPut;
6209 let header = &mut request.header;
6210 set_http_basic_header(header, config_holder.disable_encoding_meta, self);
6211 set_acl_header(header, self);
6212 request.meta = trans_meta(&self.meta, config_holder.disable_encoding_meta);
6213 if let Some(storage_class) = &self.storage_class {
6214 header.insert(HEADER_STORAGE_CLASS, storage_class.as_str().to_string());
6215 }
6216 if self.forbid_overwrite {
6217 header.insert(HEADER_FORBID_OVERWRITE, self.forbid_overwrite.to_string());
6218 }
6219 map_insert(header, HEADER_TAGGING, &self.tagging);
6220 map_insert(header, HEADER_SYMLINK_TARGET, url_encode_with_safe(&self.symlink_target_key, "/").as_str());
6221 map_insert(header, HEADER_SYMLINK_BUCKET, &self.symlink_target_bucket);
6222 let mut query = HashMap::with_capacity(2);
6223 query.insert("symlink", "".to_string());
6224 request.query = Some(query);
6225 Ok(request)
6226 }
6227}
6228#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
6229pub struct PutSymlinkOutput {
6230 pub(crate) request_info: RequestInfo,
6231 pub(crate) version_id: String,
6232}
6233
6234impl PutSymlinkOutput {
6235 pub fn version_id(&self) -> &str {
6236 &self.version_id
6237 }
6238}
6239
6240#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
6241pub struct GetSymlinkInput {
6242 pub(crate) generic_input: GenericInput,
6243 pub(crate) bucket: String,
6244 pub(crate) key: String,
6245 pub(crate) version_id: String,
6246}
6247
6248impl GetSymlinkInput {
6249 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
6250 Self {
6251 generic_input: Default::default(),
6252 bucket: bucket.into(),
6253 key: key.into(),
6254 version_id: "".to_string(),
6255 }
6256 }
6257 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
6258 Self {
6259 generic_input: Default::default(),
6260 bucket: bucket.into(),
6261 key: key.into(),
6262 version_id: version_id.into(),
6263 }
6264 }
6265 pub fn bucket(&self) -> &str {
6266 &self.bucket
6267 }
6268 pub fn key(&self) -> &str {
6269 &self.key
6270 }
6271 pub fn version_id(&self) -> &str {
6272 &self.version_id
6273 }
6274 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6275 self.bucket = bucket.into();
6276 }
6277 pub fn set_key(&mut self, key: impl Into<String>) {
6278 self.key = key.into();
6279 }
6280 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
6281 self.version_id = version_id.into();
6282 }
6283}
6284
6285impl InputDescriptor for GetSymlinkInput {
6286 fn operation(&self) -> &str {
6287 "GetSymlink"
6288 }
6289 fn bucket(&self) -> Result<&str, TosError> {
6290 Ok(&self.bucket)
6291 }
6292 fn key(&self) -> Result<&str, TosError> {
6293 Ok(&self.key)
6294 }
6295}
6296
6297impl<B> InputTranslator<B> for GetSymlinkInput {
6298 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6299 let mut request = self.trans_key()?;
6300 request.method = HttpMethodGet;
6301 let mut query = HashMap::with_capacity(2);
6302 query.insert("symlink", "".to_string());
6303 if self.version_id != "" {
6304 query.insert(QUERY_VERSION_ID, self.version_id.to_string());
6305 }
6306 request.query = Some(query);
6307 Ok(request)
6308 }
6309}
6310
6311#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
6312pub struct GetSymlinkOutput {
6313 pub(crate) request_info: RequestInfo,
6314 pub(crate) version_id: String,
6315 pub(crate) symlink_target_key: String,
6316 pub(crate) symlink_target_bucket: String,
6317 pub(crate) etag: String,
6318 pub(crate) last_modified: Option<DateTime<Utc>>,
6319}
6320
6321impl GetSymlinkOutput {
6322 pub fn request_info(&self) -> &RequestInfo {
6323 &self.request_info
6324 }
6325
6326 pub fn version_id(&self) -> &str {
6327 &self.version_id
6328 }
6329
6330 pub fn symlink_target_key(&self) -> &str {
6331 &self.symlink_target_key
6332 }
6333
6334 pub fn symlink_target_bucket(&self) -> &str {
6335 &self.symlink_target_bucket
6336 }
6337 pub fn etag(&self) -> &str {
6338 &self.etag
6339 }
6340 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
6341 self.last_modified
6342 }
6343}
6344#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
6345pub struct GetFileStatusInput {
6346 pub(crate) generic_input: GenericInput,
6347 pub(crate) bucket: String,
6348 pub(crate) key: String,
6349}
6350
6351impl GetFileStatusInput {
6352 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
6353 Self {
6354 generic_input: Default::default(),
6355 bucket: bucket.into(),
6356 key: key.into(),
6357 }
6358 }
6359 pub fn bucket(&self) -> &str {
6360 &self.bucket
6361 }
6362 pub fn key(&self) -> &str {
6363 &self.key
6364 }
6365 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6366 self.bucket = bucket.into();
6367 }
6368 pub fn set_key(&mut self, key: impl Into<String>) {
6369 self.key = key.into();
6370 }
6371}
6372
6373impl InputDescriptor for GetFileStatusInput {
6374 fn operation(&self) -> &str {
6375 "GetFileStatus"
6376 }
6377 fn bucket(&self) -> Result<&str, TosError> {
6378 Ok(&self.bucket)
6379 }
6380 fn key(&self) -> Result<&str, TosError> {
6381 Ok(&self.key)
6382 }
6383}
6384
6385impl<B> InputTranslator<B> for GetFileStatusInput {
6386 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6387 let mut request = self.trans_key()?;
6388 request.method = HttpMethodGet;
6389 let mut query = HashMap::with_capacity(2);
6390 query.insert("stat", "".to_string());
6391 request.query = Some(query);
6392 Ok(request)
6393 }
6394}
6395#[derive(Debug, Clone, PartialEq, Default, RequestInfo, Deserialize)]
6396pub struct GetFileStatusOutput {
6397 #[serde(skip)]
6398 pub(crate) request_info: RequestInfo,
6399 #[serde(rename = "Key")]
6400 #[serde(default)]
6401 pub(crate) key: String,
6402 #[serde(rename = "Size")]
6403 #[serde(default)]
6404 pub(crate) size: i64,
6405 #[serde(rename = "LastModified")]
6406 #[serde(default)]
6407 pub(crate) last_modified_string: Option<String>,
6408 #[serde(skip)]
6409 pub(crate) last_modified: Option<DateTime<Utc>>,
6410 #[serde(rename = "CRC32")]
6411 #[serde(default)]
6412 pub(crate) crc32: String,
6413 #[serde(rename = "CRC64")]
6414 #[serde(default)]
6415 pub(crate) crc64: String,
6416 #[serde(rename = "ETag")]
6417 #[serde(default)]
6418 pub(crate) etag: String,
6419 #[serde(rename = "Type")]
6420 #[serde(default)]
6421 pub(crate) object_type: String,
6422}
6423
6424impl GetFileStatusOutput {
6425 pub fn key(&self) -> &str {
6426 &self.key
6427 }
6428
6429 pub fn size(&self) -> i64 {
6430 self.size
6431 }
6432
6433 pub fn last_modified(&self) -> Option<DateTime<Utc>> {
6434 self.last_modified
6435 }
6436
6437 pub fn crc32(&self) -> &str {
6438 &self.crc32
6439 }
6440
6441 pub fn crc64(&self) -> &str {
6442 &self.crc64
6443 }
6444
6445 pub fn etag(&self) -> &str {
6446 &self.etag
6447 }
6448
6449 pub fn object_type(&self) -> &str {
6450 &self.object_type
6451 }
6452}
6453#[derive(Debug, Clone, GenericInput)]
6454#[handle_content]
6455pub(crate) struct ModifyObjectInput<B> {
6456 pub(crate) generic_input: GenericInput,
6457 pub(crate) bucket: String,
6458 pub(crate) key: String,
6459 pub(crate) offset: i64,
6460 pub(crate) content: Arc<RefCell<Option<B>>>,
6461
6462 pub(crate) content_length: i64,
6463 pub(crate) traffic_limit: i64,
6464 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
6465 pub(crate) notification_custom_parameters: String,
6466 pub(crate) if_match: String,
6467
6468 pub(crate) pre_hash_crc64ecma: u64,
6469}
6470
6471unsafe impl<B> Sync for ModifyObjectInput<B> {}
6472
6473unsafe impl<B> Send for ModifyObjectInput<B> {}
6474
6475impl<B> Default for ModifyObjectInput<B> {
6476 fn default() -> Self {
6477 Self {
6478 generic_input: Default::default(),
6479 bucket: "".to_string(),
6480 key: "".to_string(),
6481 offset: 0,
6482 content: Arc::new(RefCell::new(None)),
6483 content_length: -1,
6484 traffic_limit: 0,
6485 async_data_transfer_listener: None,
6486 notification_custom_parameters: "".to_string(),
6487 if_match: "".to_string(),
6488 pre_hash_crc64ecma: 0,
6489 }
6490 }
6491}
6492
6493impl<B> ModifyObjectInput<B>
6494{
6495 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
6496 let mut input = Self::default();
6497 input.bucket = bucket.into();
6498 input.key = key.into();
6499 input
6500 }
6501
6502 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl Into<B>) -> Self {
6503 let mut input = Self::default();
6504 input.bucket = bucket.into();
6505 input.key = key.into();
6506 input.set_content(content);
6507 input
6508 }
6509 pub fn bucket(&self) -> &str {
6510 &self.bucket
6511 }
6512 pub fn key(&self) -> &str {
6513 &self.key
6514 }
6515 pub fn content(&self) -> Ref<Option<B>> {
6516 self.content.borrow()
6517 }
6518
6519 pub fn offset(&self) -> i64 {
6520 self.offset
6521 }
6522
6523 pub fn content_length(&self) -> i64 {
6524 self.content_length
6525 }
6526
6527 pub fn traffic_limit(&self) -> i64 {
6528 self.traffic_limit
6529 }
6530
6531 pub fn notification_custom_parameters(&self) -> &str {
6532 &self.notification_custom_parameters
6533 }
6534 pub fn if_match(&self) -> &str {
6535 &self.if_match
6536 }
6537
6538 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6539 self.bucket = bucket.into();
6540 }
6541
6542 pub fn set_key(&mut self, key: impl Into<String>) {
6543 self.key = key.into();
6544 }
6545
6546 pub fn set_offset(&mut self, offset: i64) {
6547 self.offset = offset;
6548 }
6549
6550 pub fn set_content(&mut self, content: impl Into<B>)
6551 {
6552 self.content = Arc::new(RefCell::new(Some(content.into())));
6553 }
6554
6555 pub fn set_content_length(&mut self, content_length: i64) {
6556 self.content_length = content_length;
6557 }
6558
6559 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
6560 self.traffic_limit = traffic_limit;
6561 }
6562
6563 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
6564 self.notification_custom_parameters = notification_custom_parameters.into();
6565 }
6566
6567 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
6568 self.if_match = if_match.into();
6569 }
6570}
6571
6572impl<B> InputDescriptor for ModifyObjectInput<B> {
6573 fn operation(&self) -> &str {
6574 "ModifyObject"
6575 }
6576
6577 fn bucket(&self) -> Result<&str, TosError> {
6578 Ok(&self.bucket)
6579 }
6580
6581 fn key(&self) -> Result<&str, TosError> {
6582 Ok(&self.key)
6583 }
6584}
6585
6586impl<B> InputTranslator<B> for ModifyObjectInput<B> {
6587 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6588 if self.offset < 0
6589 {
6590 return Err(TosError::client_error("invalid offset for modify object"));
6591 }
6592 let mut request = self.trans_key()?;
6593 request.method = HttpMethodPost;
6594
6595 if let Some(ref adts) = self.async_data_transfer_listener {
6596 if request.request_context.is_some() {
6597 request.request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
6598 } else {
6599 let mut rc = RequestContext::default();
6600 rc.async_data_transfer_listener = Some(adts.clone());
6601 request.request_context = Some(rc);
6602 }
6603 }
6604
6605 if self.pre_hash_crc64ecma > 0 {
6606 if request.request_context.is_some() {
6607 request.request_context.as_mut().unwrap().init_crc64 = Some(self.pre_hash_crc64ecma);
6608 } else {
6609 let mut rc = RequestContext::default();
6610 rc.init_crc64 = Some(self.pre_hash_crc64ecma);
6611 request.request_context = Some(rc);
6612 }
6613 }
6614
6615 let header = &mut request.header;
6616 if self.content_length >= 0 {
6617 header.insert(HEADER_CONTENT_LENGTH, self.content_length.to_string());
6618 }
6619 if self.traffic_limit > 0 {
6620 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
6621 }
6622 map_insert(header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
6623 map_insert(header, HEADER_X_IF_MATCH, &self.if_match);
6624 let mut query = HashMap::with_capacity(2);
6625 query.insert("modify", "".to_string());
6626 query.insert(QUERY_OFFSET, self.offset.to_string());
6627 request.query = Some(query);
6628 request.body = self.content.take();
6629 Ok(request)
6630 }
6631}
6632#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
6633pub(crate) struct ModifyObjectOutput {
6634 pub(crate) request_info: RequestInfo,
6635 pub(crate) next_modify_offset: i64,
6636 pub(crate) hash_crc64ecma: u64,
6637}
6638
6639impl ModifyObjectOutput {
6640 pub fn next_modify_offset(&self) -> i64 {
6641 self.next_modify_offset
6642 }
6643
6644 pub fn hash_crc64ecma(&self) -> u64 {
6645 self.hash_crc64ecma
6646 }
6647}
6648
6649#[derive(Debug, Clone, GenericInput)]
6650pub(crate) struct ModifyObjectFromBufferInput {
6651 pub(crate) generic_input: GenericInput,
6652 pub(crate) bucket: String,
6653 pub(crate) key: String,
6654 pub(crate) offset: i64,
6655 pub(crate) content: Option<MultiBytes>,
6656
6657 pub(crate) content_length: i64,
6658 pub(crate) traffic_limit: i64,
6659 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
6660 pub(crate) notification_custom_parameters: String,
6661 pub(crate) if_match: String,
6662
6663 pub(crate) pre_hash_crc64ecma: u64,
6664}
6665
6666impl Default for ModifyObjectFromBufferInput {
6667 fn default() -> Self {
6668 Self {
6669 generic_input: Default::default(),
6670 bucket: "".to_string(),
6671 key: "".to_string(),
6672 offset: 0,
6673 content: None,
6674 content_length: -1,
6675 traffic_limit: 0,
6676 async_data_transfer_listener: None,
6677 notification_custom_parameters: "".to_string(),
6678 if_match: "".to_string(),
6679 pre_hash_crc64ecma: 0,
6680 }
6681 }
6682}
6683
6684impl ModifyObjectFromBufferInput {
6685 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
6686 let mut input = Self::default();
6687 input.bucket = bucket.into();
6688 input.key = key.into();
6689 input
6690 }
6691 pub fn new_with_offset(bucket: impl Into<String>, key: impl Into<String>, offset: i64) -> Self {
6692 let mut input = Self::default();
6693 input.bucket = bucket.into();
6694 input.key = key.into();
6695 input.offset = offset;
6696 input
6697 }
6698 pub fn new_with_content(bucket: impl Into<String>, key: impl Into<String>, content: impl AsRef<[u8]>) -> Self {
6699 let mut input = Self::default();
6700 input.bucket = bucket.into();
6701 input.key = key.into();
6702 input.set_content(content);
6703 input
6704 }
6705 pub fn new_with_offset_content(bucket: impl Into<String>, key: impl Into<String>, offset: i64, content: impl AsRef<[u8]>) -> Self {
6706 let mut input = Self::default();
6707 input.bucket = bucket.into();
6708 input.key = key.into();
6709 input.offset = offset;
6710 input.set_content(content);
6711 input
6712 }
6713 pub fn bucket(&self) -> &str {
6714 &self.bucket
6715 }
6716 pub fn key(&self) -> &str {
6717 &self.key
6718 }
6719 pub fn content(&self) -> Option<impl Iterator<Item=&Bytes>> {
6720 match &self.content {
6721 None => None,
6722 Some(x) => Some(x.inner.iter()),
6723 }
6724 }
6725 pub fn offset(&self) -> i64 {
6726 self.offset
6727 }
6728
6729 pub fn content_length(&self) -> i64 {
6730 self.content_length
6731 }
6732
6733 pub fn traffic_limit(&self) -> i64 {
6734 self.traffic_limit
6735 }
6736
6737 pub fn notification_custom_parameters(&self) -> &str {
6738 &self.notification_custom_parameters
6739 }
6740 pub fn if_match(&self) -> &str {
6741 &self.if_match
6742 }
6743
6744 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6745 self.bucket = bucket.into();
6746 }
6747
6748 pub fn set_key(&mut self, key: impl Into<String>) {
6749 self.key = key.into();
6750 }
6751
6752 pub fn set_offset(&mut self, offset: i64) {
6753 self.offset = offset;
6754 }
6755 pub fn set_content_with_bytes_list(&mut self, bytes_list: impl Iterator<Item=impl Into<Bytes>>) {
6756 let mut list = LinkedList::new();
6757 let mut size = 0;
6758 for item in bytes_list {
6759 let item = item.into();
6760 size += item.len();
6761 list.push_back(item);
6762 }
6763 self.content = Some(MultiBytes::new(list, size));
6764 }
6765 pub fn set_content(&mut self, content: impl AsRef<[u8]>) {
6766 let item = content.as_ref().to_owned();
6767 let size = item.len();
6768 let mut list = LinkedList::new();
6769 list.push_back(Bytes::from(item));
6770 self.content = Some(MultiBytes::new(list, size));
6771 }
6772 pub fn append_content(&mut self, content: impl AsRef<[u8]>) {
6773 if let Some(contents) = &mut self.content {
6774 contents.push(Bytes::from(content.as_ref().to_owned()));
6775 } else {
6776 self.set_content(content);
6777 }
6778 }
6779 pub fn set_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
6780 let item = content.into();
6781 let size = item.len();
6782 let mut list = LinkedList::new();
6783 list.push_back(Bytes::from(item));
6784 self.content = Some(MultiBytes::new(list, size));
6785 }
6786
6787 pub fn append_content_nocopy(&mut self, content: impl Into<Vec<u8>>) {
6788 if let Some(contents) = &mut self.content {
6789 contents.push(Bytes::from(content.into()));
6790 } else {
6791 self.set_content_nocopy(content);
6792 }
6793 }
6794 pub fn set_content_length(&mut self, content_length: i64) {
6795 self.content_length = content_length;
6796 }
6797
6798 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
6799 self.traffic_limit = traffic_limit;
6800 }
6801
6802 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
6803 self.notification_custom_parameters = notification_custom_parameters.into();
6804 }
6805 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
6806 self.if_match = if_match.into();
6807 }
6808}
6809
6810impl InputDescriptor for ModifyObjectFromBufferInput {
6811 fn operation(&self) -> &str {
6812 "ModifyObjectFromBuffer"
6813 }
6814 fn bucket(&self) -> Result<&str, TosError> {
6815 Ok(&self.bucket)
6816 }
6817 fn key(&self) -> Result<&str, TosError> {
6818 Ok(&self.key)
6819 }
6820}
6821
6822impl<B> InputTranslator<B> for ModifyObjectFromBufferInput
6823where
6824 B: BuildMultiBufferReader,
6825{
6826 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
6827 if self.offset < 0
6828 {
6829 return Err(TosError::client_error("invalid offset for modify object"));
6830 }
6831 let mut request = self.trans_key()?;
6832 request.method = HttpMethodPost;
6833
6834 if let Some(ref adts) = self.async_data_transfer_listener {
6835 if request.request_context.is_some() {
6836 request.request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
6837 } else {
6838 let mut rc = RequestContext::default();
6839 rc.async_data_transfer_listener = Some(adts.clone());
6840 request.request_context = Some(rc);
6841 }
6842 }
6843
6844 if self.pre_hash_crc64ecma > 0 {
6845 if request.request_context.is_some() {
6846 request.request_context.as_mut().unwrap().init_crc64 = Some(self.pre_hash_crc64ecma);
6847 } else {
6848 let mut rc = RequestContext::default();
6849 rc.init_crc64 = Some(self.pre_hash_crc64ecma);
6850 request.request_context = Some(rc);
6851 }
6852 }
6853
6854 let header = &mut request.header;
6855 if self.content_length >= 0 {
6856 header.insert(HEADER_CONTENT_LENGTH, self.content_length.to_string());
6857 }
6858 if self.traffic_limit > 0 {
6859 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
6860 }
6861 map_insert(header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
6862 map_insert(header, HEADER_X_IF_MATCH, &self.if_match);
6863 let mut query = HashMap::with_capacity(2);
6864 query.insert("modify", "".to_string());
6865 query.insert(QUERY_OFFSET, self.offset.to_string());
6866 request.query = Some(query);
6867 if let Some(content) = &self.content {
6868 let (body, len) = B::new(content.clone())?;
6869 request.body = Some(body);
6870 if self.content_length < 0 {
6871 request.header.insert(HEADER_CONTENT_LENGTH, len.to_string());
6872 }
6873 }
6874 Ok(request)
6875 }
6876}
6877
6878#[derive(Debug, Clone, GenericInput)]
6879pub(crate) struct ModifyObjectFromFileInput {
6880 pub(crate) generic_input: GenericInput,
6881 pub(crate) bucket: String,
6882 pub(crate) key: String,
6883 pub(crate) offset: i64,
6884 pub(crate) file_path: String,
6885
6886 pub(crate) content_length: i64,
6887 pub(crate) traffic_limit: i64,
6888 pub(crate) async_data_transfer_listener: Option<async_channel::Sender<DataTransferStatus>>,
6889 pub(crate) notification_custom_parameters: String,
6890 pub(crate) if_match: String,
6891
6892 pub(crate) pre_hash_crc64ecma: u64,
6893}
6894
6895impl Default for ModifyObjectFromFileInput {
6896 fn default() -> Self {
6897 Self {
6898 generic_input: Default::default(),
6899 bucket: "".to_string(),
6900 key: "".to_string(),
6901 offset: 0,
6902 file_path: "".to_string(),
6903 content_length: -1,
6904 traffic_limit: 0,
6905 async_data_transfer_listener: None,
6906 notification_custom_parameters: "".to_string(),
6907 if_match: "".to_string(),
6908 pre_hash_crc64ecma: 0,
6909 }
6910 }
6911}
6912
6913impl ModifyObjectFromFileInput {
6914 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
6915 let mut input = Self::default();
6916 input.bucket = bucket.into();
6917 input.key = key.into();
6918 input
6919 }
6920 pub fn new_with_offset(bucket: impl Into<String>, key: impl Into<String>, offset: i64) -> Self {
6921 let mut input = Self::default();
6922 input.bucket = bucket.into();
6923 input.key = key.into();
6924 input.offset = offset;
6925 input
6926 }
6927 pub fn new_with_file_path(bucket: impl Into<String>, key: impl Into<String>, file_path: impl Into<String>) -> Self {
6928 let mut input = Self::default();
6929 input.bucket = bucket.into();
6930 input.key = key.into();
6931 input.file_path = file_path.into();
6932 input
6933 }
6934 pub fn new_with_offset_content(bucket: impl Into<String>, key: impl Into<String>, offset: i64, file_path: impl Into<String>) -> Self {
6935 let mut input = Self::default();
6936 input.bucket = bucket.into();
6937 input.key = key.into();
6938 input.offset = offset;
6939 input.file_path = file_path.into();
6940 input
6941 }
6942 pub fn bucket(&self) -> &str {
6943 &self.bucket
6944 }
6945 pub fn key(&self) -> &str {
6946 &self.key
6947 }
6948 pub fn file_path(&self) -> &str {
6949 &self.file_path
6950 }
6951 pub fn offset(&self) -> i64 {
6952 self.offset
6953 }
6954
6955 pub fn content_length(&self) -> i64 {
6956 self.content_length
6957 }
6958
6959 pub fn traffic_limit(&self) -> i64 {
6960 self.traffic_limit
6961 }
6962
6963 pub fn notification_custom_parameters(&self) -> &str {
6964 &self.notification_custom_parameters
6965 }
6966 pub fn if_match(&self) -> &str {
6967 &self.if_match
6968 }
6969
6970 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
6971 self.bucket = bucket.into();
6972 }
6973
6974 pub fn set_key(&mut self, key: impl Into<String>) {
6975 self.key = key.into();
6976 }
6977
6978 pub fn set_offset(&mut self, offset: i64) {
6979 self.offset = offset;
6980 }
6981 pub fn set_file_path(&mut self, file_path: impl Into<String>) {
6982 self.file_path = file_path.into();
6983 }
6984 pub fn set_content_length(&mut self, content_length: i64) {
6985 self.content_length = content_length;
6986 }
6987
6988 pub fn set_traffic_limit(&mut self, traffic_limit: i64) {
6989 self.traffic_limit = traffic_limit;
6990 }
6991
6992 pub fn set_notification_custom_parameters(&mut self, notification_custom_parameters: impl Into<String>) {
6993 self.notification_custom_parameters = notification_custom_parameters.into();
6994 }
6995 pub fn set_if_match(&mut self, if_match: impl Into<String>) {
6996 self.if_match = if_match.into();
6997 }
6998
6999 pub(crate) fn inner_trans<'a>(&self) -> Result<(HttpMethodType, Option<RequestContext<'a>>, HashMap<&'a str, String>,
7000 Option<HashMap<&'a str, String>>,), TosError> {
7001 if self.offset < 0
7002 {
7003 return Err(TosError::client_error("invalid offset for modify object"));
7004 }
7005
7006 let mut request_context: Option<RequestContext<'a>> = None;
7007 if let Some(ref adts) = self.async_data_transfer_listener {
7008 if request_context.is_some() {
7009 request_context.as_mut().unwrap().async_data_transfer_listener = Some(adts.clone());
7010 } else {
7011 let mut rc = RequestContext::default();
7012 rc.async_data_transfer_listener = Some(adts.clone());
7013 request_context = Some(rc);
7014 }
7015 }
7016
7017 if self.pre_hash_crc64ecma > 0 {
7018 if request_context.is_some() {
7019 request_context.as_mut().unwrap().init_crc64 = Some(self.pre_hash_crc64ecma);
7020 } else {
7021 let mut rc = RequestContext::default();
7022 rc.init_crc64 = Some(self.pre_hash_crc64ecma);
7023 request_context = Some(rc);
7024 }
7025 }
7026
7027 let mut header = HashMap::new();
7028 if self.content_length >= 0 {
7029 header.insert(HEADER_CONTENT_LENGTH, self.content_length.to_string());
7030 }
7031 if self.traffic_limit > 0 {
7032 header.insert(HEADER_TRAFFIC_LIMIT, self.traffic_limit.to_string());
7033 }
7034 map_insert(&mut header, HEADER_NOTIFICATION_CUSTOM_PARAMETERS, &self.notification_custom_parameters);
7035 map_insert(&mut header, HEADER_X_IF_MATCH, &self.if_match);
7036 let mut query = HashMap::with_capacity(2);
7037 query.insert("modify", "".to_string());
7038 query.insert(QUERY_OFFSET, self.offset.to_string());
7039 Ok((HttpMethodPost, request_context, header, Some(query)))
7040 }
7041}
7042
7043impl InputDescriptor for ModifyObjectFromFileInput {
7044 fn operation(&self) -> &str {
7045 "ModifyObjectFromFile"
7046 }
7047 fn bucket(&self) -> Result<&str, TosError> {
7048 Ok(&self.bucket)
7049 }
7050 fn key(&self) -> Result<&str, TosError> {
7051 Ok(&self.key)
7052 }
7053}
7054
7055impl<B> InputTranslator<B> for ModifyObjectFromFileInput
7056where
7057 B: BuildFileReader,
7058{
7059 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
7060 let mut request = self.trans_key()?;
7061 let (method, request_context, header, query) = self.inner_trans()?;
7062 request.method = method;
7063 request.request_context = request_context;
7064 request.header = header;
7065 request.query = query;
7066 if self.file_path != "" {
7067 let (body, len) = B::new(&self.file_path)?;
7068 request.body = Some(body);
7069 if let Some(l) = len {
7070 if self.content_length < 0 {
7071 request.header.insert(HEADER_CONTENT_LENGTH, l.to_string());
7072 }
7073 }
7074 }
7075 Ok(request)
7076 }
7077}
7078
7079#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
7080pub struct DoesObjectExistInput {
7081 pub(crate) generic_input: GenericInput,
7082 pub(crate) bucket: String,
7083 pub(crate) key: String,
7084 pub(crate) version_id: String,
7085 pub(crate) is_only_in_tos: bool,
7087}
7088
7089impl DoesObjectExistInput {
7090 pub fn new(bucket: impl Into<String>, key: impl Into<String>) -> Self {
7091 Self {
7092 generic_input: Default::default(),
7093 bucket: bucket.into(),
7094 key: key.into(),
7095 version_id: "".to_string(),
7096 is_only_in_tos: false,
7097 }
7098 }
7099
7100 pub fn new_with_version_id(bucket: impl Into<String>, key: impl Into<String>, version_id: impl Into<String>) -> Self {
7101 Self {
7102 generic_input: Default::default(),
7103 bucket: bucket.into(),
7104 key: key.into(),
7105 version_id: version_id.into(),
7106 is_only_in_tos: false,
7107 }
7108 }
7109
7110 pub fn bucket(&self) -> &str {
7111 &self.bucket
7112 }
7113
7114 pub fn key(&self) -> &str {
7115 &self.key
7116 }
7117
7118 pub fn version_id(&self) -> &str {
7119 &self.version_id
7120 }
7121
7122 pub(crate) fn is_only_in_tos(&self) -> bool {
7123 self.is_only_in_tos
7124 }
7125
7126 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
7127 self.bucket = bucket.into();
7128 }
7129
7130 pub fn set_key(&mut self, key: impl Into<String>) {
7131 self.key = key.into();
7132 }
7133
7134 pub fn set_version_id(&mut self, version_id: impl Into<String>) {
7135 self.version_id = version_id.into();
7136 }
7137
7138 pub(crate) fn set_is_only_in_tos(&mut self, is_only_in_tos: bool) {
7139 self.is_only_in_tos = is_only_in_tos;
7140 }
7141}
7142#[derive(Debug, Clone, PartialEq, Default, GenericInput)]
7143pub struct SetObjectTimeInput {
7144 pub(crate) generic_input: GenericInput,
7145 pub(crate) bucket: String,
7146 pub(crate) key: String,
7147 pub(crate) modify_timestamp: DateTime<Utc>,
7148}
7149
7150impl SetObjectTimeInput {
7151 pub fn new(bucket: impl Into<String>, key: impl Into<String>, modify_timestamp: impl Into<DateTime<Utc>>) -> Self {
7152 Self {
7153 generic_input: Default::default(),
7154 bucket: bucket.into(),
7155 key: key.into(),
7156 modify_timestamp: modify_timestamp.into(),
7157 }
7158 }
7159
7160 pub fn bucket(&self) -> &str {
7161 &self.bucket
7162 }
7163
7164 pub fn key(&self) -> &str {
7165 &self.key
7166 }
7167
7168 pub fn modify_timestamp(&self) -> DateTime<Utc> {
7169 self.modify_timestamp
7170 }
7171
7172 pub fn set_bucket(&mut self, bucket: impl Into<String>) {
7173 self.bucket = bucket.into();
7174 }
7175
7176 pub fn set_key(&mut self, key: impl Into<String>) {
7177 self.key = key.into();
7178 }
7179
7180 pub fn set_modify_timestamp(&mut self, modify_timestamp: impl Into<DateTime<Utc>>) {
7181 self.modify_timestamp = modify_timestamp.into();
7182 }
7183}
7184
7185impl InputDescriptor for SetObjectTimeInput {
7186 fn operation(&self) -> &str {
7187 "SetObjectTime"
7188 }
7189
7190 fn bucket(&self) -> Result<&str, TosError> {
7191 Ok(&self.bucket)
7192 }
7193
7194 fn key(&self) -> Result<&str, TosError> {
7195 Ok(&self.key)
7196 }
7197}
7198
7199impl<B> InputTranslator<B> for SetObjectTimeInput {
7200 fn trans(&self, _: Arc<ConfigHolder>) -> Result<HttpRequest<B>, TosError> {
7201 let mut request = self.trans_key()?;
7202 request.method = HttpMethodPost;
7203 let seconds = self.modify_timestamp.timestamp();
7204 let ns = self.modify_timestamp.timestamp_subsec_nanos();
7205 request.header.insert(HEADER_MODIFY_TIMESTAMP, seconds.to_string());
7206 request.header.insert(HEADER_MODIFY_TIMESTAMP_NS, ns.to_string());
7207
7208 let mut query = HashMap::with_capacity(1);
7209 query.insert("time", "".to_string());
7210 request.query = Some(query);
7211 Ok(request)
7212 }
7213}
7214
7215#[derive(Debug, Clone, PartialEq, Default, RequestInfo)]
7216pub struct SetObjectTimeOutput {
7217 pub(crate) request_info: RequestInfo,
7218}