Repository: tikv/tikv
File: components/cloud/aws/src/s3.rs (Rust)

Code before:
                .parts
                .iter()
                .map(|p| {
                    CompletedPart::builder()
                        .part_number(p.part_number)
                        .set_e_tag(p.e_tag.clone())
                        .build()
                })
                .collect();

            self.client
                .complete_multipart_upload()
                .bucket(self.bucket.clone())
                .key(&self.key)
                .upload_id(&self.upload_id)
                .multipart_upload(
                    CompletedMultipartUpload::builder()
                        .set_parts(Some(aws_parts))
                        .build(),
                )
                .customize()
                .mutate_request(|req| {
                    let body_len = req.body().content_length().unwrap_or(0);
                    req.headers_mut()
                        .insert("content-length", body_len.to_string());
                })
                .send()
                .await?;
            Ok(())
        };
        timeout(Self::get_timeout(), request)
            .await
            .map_err(|_| UploadError::Sdk {
                msg: "timeout after 15mins for upload in s3 storage".to_owned(),
                retryable: false,
            })?
    }

    /// Aborts the multipart upload process, deletes all uploaded parts.
    async fn abort(&self) -> Result<(), UploadError> {
        let request = async {
            self.client
                .abort_multipart_upload()
                .bucket(&self.bucket)
                .key(&self.key)
                .upload_id(&self.upload_id)
                .customize()
                .mutate_request(|req| {
                    req.headers_mut().insert("content-length", "0");
                })
                .send()

Review comment (suggestion):
In `complete()`, `req.headers_mut().insert("Content-Length", body_len.to_string())` likely won’t compile because `insert` expects a `HeaderValue`, not a `String`. Convert `body_len` to a `HeaderValue` (e.g. via `HeaderValue::from_str`) and prefer `http::header::CONTENT_LENGTH` for the name.

Code after:
                .parts
                .iter()
                .map(|p| {
                    CompletedPart::builder()
                        .part_number(p.part_number)
                        .set_e_tag(p.e_tag.clone())
                        .build()
                })
                .collect();

            self.client
                .complete_multipart_upload()
                .bucket(self.bucket.clone())
                .key(&self.key)
                .upload_id(&self.upload_id)
                .multipart_upload(
                    CompletedMultipartUpload::builder()
                        .set_parts(Some(aws_parts))
                        .build(),
                )
                .send()
                .await?;
            Ok(())
        };
        timeout(Self::get_timeout(), request)
            .await
            .map_err(|_| UploadError::Sdk {
                msg: "timeout after 15mins for upload in s3 storage".to_owned(),
                retryable: false,
            })?
    }

    /// Aborts the multipart upload process, deletes all uploaded parts.
    async fn abort(&self) -> Result<(), UploadError> {
        let request = async {
            self.client
                .abort_multipart_upload()
                .bucket(&self.bucket)
                .key(&self.key)
                .upload_id(&self.upload_id)
                .send()
                .await?;
            Ok(())
        };
        timeout(Self::get_timeout(), request)
            .await
            .map_err(|_| UploadError::Sdk {
                msg: "timeout after 15mins for upload in s3 storage".to_owned(),
                retryable: false,
            })?
    }