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.
| 2421 | // If this method is called after HEAD on "bucket/key" already returned a 404, |
| 2422 | // can pass the given outcome to spare a spurious HEAD call. |
| 2423 | Result<bool> IsEmptyDirectory( |
| 2424 | const std::string& bucket, const std::string& key, |
| 2425 | const S3Model::HeadObjectOutcome* previous_outcome = nullptr) { |
| 2426 | ARROW_ASSIGN_OR_RAISE(auto client_lock, holder_->Lock()); |
| 2427 | |
| 2428 | if (previous_outcome) { |
| 2429 | // Fetch the backend from the previous error |
| 2430 | if (GetOrSetBackend(previous_outcome->GetError()) != S3Backend::Minio) { |
| 2431 | // HEAD already returned a 404, nothing more to do |
| 2432 | return false; |
| 2433 | } |
| 2434 | } |
| 2435 | |
| 2436 | // We come here in one of two situations: |
| 2437 | // - we don't know the backend and there is no previous outcome |
| 2438 | // - the backend is Minio |
| 2439 | S3Model::HeadObjectRequest req; |
| 2440 | req.SetBucket(ToAwsString(bucket)); |
| 2441 | if (backend_ && *backend_ == S3Backend::Minio) { |
| 2442 | // Minio wants a slash at the end, Amazon doesn't |
| 2443 | req.SetKey(ToAwsString(key) + kSep); |
| 2444 | } else { |
| 2445 | req.SetKey(ToAwsString(key)); |
| 2446 | } |
| 2447 | |
| 2448 | auto outcome = client_lock.Move()->HeadObject(req); |
| 2449 | if (outcome.IsSuccess()) { |
| 2450 | return true; |
| 2451 | } |
| 2452 | if (!backend_) { |
| 2453 | if (GetOrSetBackend(outcome.GetError()) == S3Backend::Minio) { |
| 2454 | // Try again with separator-terminated key (see above) |
| 2455 | return IsEmptyDirectory(bucket, key); |
| 2456 | } |
| 2457 | } |
| 2458 | if (IsNotFound(outcome.GetError())) { |
| 2459 | return false; |
| 2460 | } |
| 2461 | return ErrorToStatus(std::forward_as_tuple("When reading information for key '", key, |
| 2462 | "' in bucket '", bucket, "': "), |
| 2463 | "HeadObject", outcome.GetError()); |
| 2464 | } |
| 2465 | |
| 2466 | Result<bool> IsEmptyDirectory( |
| 2467 | const S3Path& path, const S3Model::HeadObjectOutcome* previous_outcome = nullptr) { |
no test coverage detected