Skip to content

Commit 664577a

Browse files
jyn514Joshua Nelson
authored and
Joshua Nelson
committed
Use HEAD instead of LIST
This is an order of magnitude cheaper with S3 pricing.
1 parent bf5fecc commit 664577a

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

src/storage/s3.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use log::warn;
1010
use rusoto_core::{region::Region, RusotoError};
1111
use rusoto_credential::DefaultCredentialsProvider;
1212
use rusoto_s3::{
13-
DeleteObjectsRequest, GetObjectError, GetObjectRequest, ListObjectsV2Request, ObjectIdentifier,
14-
PutObjectRequest, S3Client, S3,
13+
DeleteObjectsRequest, GetObjectError, GetObjectRequest, HeadObjectError, HeadObjectRequest,
14+
ListObjectsV2Request, ObjectIdentifier, PutObjectRequest, S3Client, S3,
1515
};
1616
use std::{convert::TryInto, io::Write};
1717
use tokio::runtime::Runtime;
@@ -56,15 +56,18 @@ impl S3Backend {
5656

5757
pub(super) fn exists(&self, path: &str) -> Result<bool, Error> {
5858
self.runtime.handle().block_on(async {
59-
let resp = self
60-
.client
61-
.list_objects_v2(ListObjectsV2Request {
62-
bucket: self.bucket.clone(),
63-
prefix: Some(path.into()),
64-
..Default::default()
65-
})
66-
.await?;
67-
Ok(resp.key_count.unwrap() > 0)
59+
let req = HeadObjectRequest {
60+
bucket: self.bucket.clone(),
61+
key: path.into(),
62+
..Default::default()
63+
};
64+
let resp = self.client.head_object(req).await;
65+
match resp {
66+
Ok(_) => Ok(true),
67+
Err(RusotoError::Service(HeadObjectError::NoSuchKey(_))) => Ok(false),
68+
Err(RusotoError::Unknown(resp)) if resp.status == 404 => Ok(false),
69+
Err(other) => Err(other.into()),
70+
}
6871
})
6972
}
7073

0 commit comments

Comments
 (0)