This is an automated email from the ASF dual-hosted git repository. silver pushed a commit to branch gcs-multipart in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 701200e7e5554538bbdfe0120bd3def40c515b1d Author: silver-ymz <[email protected]> AuthorDate: Thu Aug 10 11:54:05 2023 +0800 fix(services/gcs): migrate to new multipart impl for gcs_insert_object_request Signed-off-by: silver-ymz <[email protected]> --- core/src/services/gcs/core.rs | 48 +++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index 35cf401ee..b58bfad42 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -23,7 +23,6 @@ use std::time::Duration; use backon::ExponentialBuilder; use backon::Retryable; use bytes::Bytes; -use bytes::BytesMut; use http::header::CONTENT_LENGTH; use http::header::CONTENT_RANGE; use http::header::CONTENT_TYPE; @@ -234,28 +233,41 @@ impl GcsCore { req = req.header(CONTENT_LENGTH, size.unwrap_or_default()); if let Some(storage_class) = &self.default_storage_class { - req = req.header(CONTENT_TYPE, "multipart/related; boundary=my-boundary"); + let mut multipart = Multipart::new(); - let mut req_body = BytesMut::with_capacity(100); - write!( - &mut req_body, - "--my-boundary\nContent-Type: application/json; charset=UTF-8\n\n{{\"storageClass\": \"{}\"}}\n\n--my-boundary\n", - storage_class - ).unwrap(); + multipart = multipart.part( + FormDataPart::new("metadata") + .header( + CONTENT_TYPE, + "application/json; charset=UTF-8".parse().unwrap(), + ) + .content(format!("{{\"storageClass\": \"{}\"}}", storage_class)), + ); - if let Some(mime) = content_type { - write!(&mut req_body, "Content-Type: {}\n\n", mime).unwrap(); - } else { - write!(&mut req_body, "Content-Type: application/octet-stream\n\n").unwrap(); - } + let mut media_part = FormDataPart::new("media").header( + CONTENT_TYPE, + content_type + .unwrap_or("application/octet-stream") + .parse() + .unwrap(), + ); - if let AsyncBody::Bytes(bytes) = body { - req_body.extend_from_slice(&bytes); + match body { + AsyncBody::Empty => {} + AsyncBody::Bytes(bytes) => { + media_part = media_part.content(bytes); + } + AsyncBody::Stream(_) => { + return Err(Error::new( + ErrorKind::Unsupported, + "stream body is not supported", + )); + } } - write!(&mut req_body, "\n--my-boundary").unwrap(); - let req_body = AsyncBody::Bytes(req_body.freeze()); - let req = req.body(req_body).map_err(new_request_build_error)?; + multipart = multipart.part(media_part); + + let req = multipart.apply(Request::post(url))?; Ok(req) } else { if let Some(content_type) = content_type {
