s3_wire/client/multipart/
copy.rs1use http::{HeaderName, Method};
2
3use crate::client::S3Client;
4use crate::client::object::{copy_source_header, insert_conditions};
5use crate::client::request::{insert_header, protocol_error, request_headers};
6use crate::error::S3Error;
7use crate::operation::{UploadPartCopyOutput, UploadPartCopyRequest};
8use crate::protocol::{
9 ParsedS3Error, ProtocolError, UploadPartCopyResponse, parse_upload_part_copy,
10};
11
12use super::headers::request_ids;
13use super::query::upload_part_query;
14
15impl S3Client {
16 pub async fn upload_part_copy(
23 &self,
24 request: UploadPartCopyRequest,
25 ) -> Result<UploadPartCopyOutput, S3Error> {
26 let mut headers = request_headers(request.headers.clone())?;
27 insert_header(
28 &mut headers,
29 HeaderName::from_static("x-amz-copy-source"),
30 ©_source_header(&request.source),
31 )?;
32 if let Some(range) = request.source_range {
33 insert_header(
34 &mut headers,
35 HeaderName::from_static("x-amz-copy-source-range"),
36 &range.header_value(),
37 )?;
38 }
39 insert_conditions(
40 &mut headers,
41 &request.source_conditions,
42 "x-amz-copy-source-",
43 )?;
44 let target = self.operation_target(Some(request.destination().as_str()))?;
45 let query = upload_part_query(request.part_number().get(), request.upload_id());
46 let deadline = self.deadline();
47 let maximum = self.config().max_xml_response_size();
48 let response = self
49 .send_signed_collected_xml(
50 Method::PUT,
51 target,
52 &query,
53 headers,
54 None,
55 &deadline,
56 maximum,
57 upload_part_copy_embedded_error,
58 )
59 .await?;
60 match parse_upload_part_copy(&response.body, maximum).map_err(protocol_error)? {
61 UploadPartCopyResponse::Complete(result) => Ok(UploadPartCopyOutput {
62 part_number: request.part_number(),
63 e_tag: result.e_tag,
64 last_modified: result.last_modified,
65 checksum: result.checksum,
66 request_ids: request_ids(&response.headers),
67 }),
68 UploadPartCopyResponse::EmbeddedError(_) => {
69 unreachable!("embedded part-copy errors are handled by request execution")
70 }
71 }
72 }
73}
74
75fn upload_part_copy_embedded_error(
76 body: &[u8],
77 maximum: usize,
78) -> Result<Option<ParsedS3Error>, ProtocolError> {
79 match parse_upload_part_copy(body, maximum)? {
80 UploadPartCopyResponse::Complete(_) => Ok(None),
81 UploadPartCopyResponse::EmbeddedError(error) => Ok(Some(error)),
82 }
83}