From 06de6722cbcbe3ee1f93582a0fcbfd1887d85cce Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 23 Sep 2023 13:45:48 +1000 Subject: [PATCH] Include starting offset for GHAC upload Content-Range This adjusts the GitHub Action Cache service to handle multi-part uploads correctly: each upload part needs to specify exactly the range it is for, e.g. to upload an 11 byte file with parts <= 8 bytes, the two requests should set: 1. `Content-Range: bytes 0-8/*` (first 8 bytes) 2. `Content-Range: bytes 9-10/*` (final 3 bytes) Previously, the second request would be `Content-Range: 0-2/*`. This would leave the file not-fully written, and GitHub would reject it with an error. Fixes #3162 --- core/src/services/ghac/backend.rs | 5 +++-- core/src/services/ghac/writer.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/services/ghac/backend.rs b/core/src/services/ghac/backend.rs index e78fdb4055e3..379f98a38941 100644 --- a/core/src/services/ghac/backend.rs +++ b/core/src/services/ghac/backend.rs @@ -351,7 +351,7 @@ impl Accessor for GhacBackend { // Write only 1 byte to allow create. let req = self - .ghac_upload(cache_id, 1, AsyncBody::Bytes(Bytes::from_static(&[0]))) + .ghac_upload(cache_id, 0, 1, AsyncBody::Bytes(Bytes::from_static(&[0]))) .await?; let resp = self.client.send(req).await?; @@ -562,6 +562,7 @@ impl GhacBackend { pub async fn ghac_upload( &self, cache_id: i64, + offset: u64, size: u64, body: AsyncBody, ) -> Result> { @@ -575,7 +576,7 @@ impl GhacBackend { req = req.header( CONTENT_RANGE, BytesContentRange::default() - .with_range(0, size - 1) + .with_range(offset, offset + size - 1) .to_header(), ); diff --git a/core/src/services/ghac/writer.rs b/core/src/services/ghac/writer.rs index 76254c0bc62e..bdfe998764c7 100644 --- a/core/src/services/ghac/writer.rs +++ b/core/src/services/ghac/writer.rs @@ -64,13 +64,14 @@ impl oio::Write for GhacWriter { let backend = backend.take().expect("GhacWriter must be initialized"); let cache_id = self.cache_id; + let offset = self.size; let size = bs.remaining(); let bs = bs.bytes(size); let fut = async move { let res = async { let req = backend - .ghac_upload(cache_id, size as u64, AsyncBody::Bytes(bs)) + .ghac_upload(cache_id, offset, size as u64, AsyncBody::Bytes(bs)) .await?; let resp = backend.client.send(req).await?;