If this method is called after HEAD on "bucket/key" already returned a 404, can pass the given outcome to spare a spurious HEAD call.
| 2362 | // If this method is called after HEAD on "bucket/key" already returned a 404, |
| 2363 | // can pass the given outcome to spare a spurious HEAD call. |
| 2364 | Result<bool> IsEmptyDirectory( |
| 2365 | const std::string& bucket, const std::string& key, |
| 2366 | const S3Model::HeadObjectOutcome* previous_outcome = nullptr) { |
| 2367 | ARROW_ASSIGN_OR_RAISE(auto client_lock, holder_->Lock()); |
| 2368 | |
| 2369 | if (previous_outcome) { |
| 2370 | // Fetch the backend from the previous error |
| 2371 | if (GetOrSetBackend(previous_outcome->GetError()) != S3Backend::Minio) { |
| 2372 | // HEAD already returned a 404, nothing more to do |
| 2373 | return false; |
| 2374 | } |
| 2375 | } |
| 2376 | |
| 2377 | // We come here in one of two situations: |
| 2378 | // - we don't know the backend and there is no previous outcome |
| 2379 | // - the backend is Minio |
| 2380 | S3Model::HeadObjectRequest req; |
| 2381 | req.SetBucket(ToAwsString(bucket)); |
| 2382 | if (backend_ && *backend_ == S3Backend::Minio) { |
| 2383 | // Minio wants a slash at the end, Amazon doesn't |
| 2384 | req.SetKey(ToAwsString(key) + kSep); |
| 2385 | } else { |
| 2386 | req.SetKey(ToAwsString(key)); |
| 2387 | } |
| 2388 | |
| 2389 | auto outcome = client_lock.Move()->HeadObject(req); |
| 2390 | if (outcome.IsSuccess()) { |
| 2391 | return true; |
| 2392 | } |
| 2393 | if (!backend_) { |
| 2394 | if (GetOrSetBackend(outcome.GetError()) == S3Backend::Minio) { |
| 2395 | // Try again with separator-terminated key (see above) |
| 2396 | return IsEmptyDirectory(bucket, key); |
| 2397 | } |
| 2398 | } |
| 2399 | if (IsNotFound(outcome.GetError())) { |
| 2400 | return false; |
| 2401 | } |
| 2402 | return ErrorToStatus(std::forward_as_tuple("When reading information for key '", key, |
| 2403 | "' in bucket '", bucket, "': "), |
| 2404 | "HeadObject", outcome.GetError()); |
| 2405 | } |
| 2406 | |
| 2407 | Result<bool> IsEmptyDirectory( |
| 2408 | const S3Path& path, const S3Model::HeadObjectOutcome* previous_outcome = nullptr) { |
no test coverage detected