opendal 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +49 -37
- data/Cargo.toml +1 -1
- data/DEPENDENCIES.rust.tsv +39 -28
- data/core/CHANGELOG.md +100 -0
- data/core/Cargo.lock +184 -266
- data/core/Cargo.toml +99 -93
- data/core/DEPENDENCIES.rust.tsv +20 -20
- data/core/benches/metadata/README.md +21 -0
- data/core/benches/metadata/main.rs +541 -0
- data/core/benches/vs_fs/Cargo.toml +1 -1
- data/core/benches/vs_s3/Cargo.toml +1 -1
- data/core/core/CHANGELOG.md +6027 -0
- data/core/core/Cargo.toml +6 -1
- data/core/core/src/blocking/delete.rs +5 -1
- data/core/core/src/blocking/operator.rs +12 -0
- data/core/core/src/blocking/read/std_reader.rs +25 -0
- data/core/core/src/docs/concepts.rs +70 -94
- data/core/core/src/docs/internals/accessor.rs +62 -293
- data/core/core/src/docs/internals/layer.rs +43 -59
- data/core/core/src/docs/internals/mod.rs +21 -23
- data/core/core/src/docs/mod.rs +11 -7
- data/core/core/src/docs/performance/concurrent_write.md +92 -55
- data/core/core/src/docs/performance/http_optimization.md +120 -104
- data/core/core/src/docs/performance/mod.rs +8 -6
- data/core/core/src/docs/rfcs/5485_conditional_reader.md +4 -0
- data/core/core/src/docs/rfcs/7182_restore_api.md +139 -557
- data/core/core/src/docs/rfcs/7945_limited_read.md +210 -0
- data/core/core/src/docs/rfcs/8109_writer_copy_from.md +330 -0
- data/core/core/src/docs/rfcs/8145_conflict_error_kind.md +210 -0
- data/core/core/src/docs/rfcs/8147_write_if_not_changed.md +233 -0
- data/core/core/src/docs/rfcs/8188_compose_api.md +292 -0
- data/core/core/src/docs/rfcs/8194_compact_metadata_and_operation_args.md +444 -0
- data/core/core/src/docs/rfcs/README.md +14 -3
- data/core/core/src/docs/rfcs/mod.rs +46 -26
- data/core/core/src/docs/specs/README.md +34 -0
- data/core/core/src/docs/specs/conditional-operations.md +156 -0
- data/core/core/src/docs/specs/metadata.md +63 -0
- data/core/core/src/docs/specs/mod.rs +26 -0
- data/core/core/src/docs/upgrade.md +114 -1
- data/core/core/src/layers/capability_override.rs +15 -2
- data/core/core/src/layers/complete.rs +347 -43
- data/core/core/src/layers/correctness_check.rs +718 -51
- data/core/core/src/layers/error_context.rs +76 -2
- data/core/core/src/layers/simulate.rs +91 -28
- data/core/core/src/lib.rs +1 -0
- data/core/core/src/raw/accessor.rs +91 -15
- data/core/core/src/raw/enum_utils.rs +7 -0
- data/core/core/src/raw/http_util/header.rs +22 -17
- data/core/core/src/raw/oio/compose/api.rs +92 -0
- data/core/core/src/raw/oio/compose/mod.rs +19 -0
- data/core/core/src/raw/oio/copy/api.rs +3 -3
- data/core/core/src/raw/oio/copy/block_copy.rs +32 -4
- data/core/core/src/raw/oio/copy/multipart_copy.rs +36 -7
- data/core/core/src/raw/oio/entry.rs +48 -22
- data/core/core/src/raw/oio/list/flat_list.rs +1 -1
- data/core/core/src/raw/oio/list/hierarchy_list.rs +3 -2
- data/core/core/src/raw/oio/mod.rs +3 -0
- data/core/core/src/raw/oio/write/api.rs +40 -0
- data/core/core/src/raw/oio/write/append_write.rs +4 -4
- data/core/core/src/raw/oio/write/block_write.rs +2 -2
- data/core/core/src/raw/oio/write/multipart_write.rs +180 -47
- data/core/core/src/raw/oio/write/position_write.rs +1 -1
- data/core/core/src/raw/operation.rs +6 -0
- data/core/core/src/raw/ops.rs +1187 -455
- data/core/core/src/raw/rps.rs +11 -0
- data/core/core/src/raw/time.rs +14 -3
- data/core/core/src/services/memory/backend.rs +5 -10
- data/core/core/src/services/memory/lister.rs +4 -4
- data/core/core/src/services/memory/writer.rs +7 -6
- data/core/core/src/types/capability.rs +65 -0
- data/core/core/src/types/compact.rs +329 -0
- data/core/core/src/types/compose/composer.rs +183 -0
- data/core/core/src/types/compose/input.rs +57 -0
- data/core/core/src/types/compose/mod.rs +23 -0
- data/core/core/src/types/context/read.rs +16 -11
- data/core/core/src/types/context/write.rs +149 -1
- data/core/core/src/types/copy.rs +5 -3
- data/core/core/src/types/delete/deleter.rs +20 -12
- data/core/core/src/types/delete/input.rs +22 -64
- data/core/core/src/types/delete/mod.rs +0 -1
- data/core/core/src/types/entry.rs +8 -14
- data/core/core/src/types/error.rs +28 -11
- data/core/core/src/types/metadata.rs +709 -322
- data/core/core/src/types/mod.rs +9 -1
- data/core/core/src/types/operator/operator.rs +278 -29
- data/core/core/src/types/operator/operator_futures.rs +460 -102
- data/core/core/src/types/options.rs +621 -154
- data/core/core/src/types/read/futures_async_reader.rs +663 -50
- data/core/core/src/types/read/reader.rs +14 -5
- data/core/core/src/types/write/futures_async_writer.rs +27 -0
- data/core/core/src/types/write/writer.rs +47 -5
- data/core/http-transports/reqwest/Cargo.toml +1 -1
- data/core/layers/async-backtrace/Cargo.toml +2 -2
- data/core/layers/async-backtrace/src/lib.rs +21 -2
- data/core/layers/await-tree/Cargo.toml +2 -2
- data/core/layers/await-tree/src/lib.rs +25 -2
- data/core/layers/capability-check/Cargo.toml +2 -2
- data/core/layers/capability-check/src/lib.rs +98 -10
- data/core/layers/chaos/Cargo.toml +2 -2
- data/core/layers/chaos/src/lib.rs +18 -3
- data/core/layers/concurrent-limit/Cargo.toml +2 -2
- data/core/layers/concurrent-limit/src/lib.rs +50 -10
- data/core/layers/dtrace/Cargo.toml +2 -2
- data/core/layers/dtrace/src/lib.rs +29 -2
- data/core/layers/fastmetrics/Cargo.toml +3 -3
- data/core/layers/fastrace/Cargo.toml +2 -2
- data/core/layers/fastrace/src/lib.rs +28 -2
- data/core/layers/foyer/Cargo.toml +2 -2
- data/core/layers/foyer/src/full.rs +16 -19
- data/core/layers/foyer/src/lib.rs +67 -14
- data/core/layers/hotpath/Cargo.toml +2 -2
- data/core/layers/hotpath/src/lib.rs +20 -2
- data/core/layers/immutable-index/Cargo.toml +2 -2
- data/core/layers/immutable-index/src/lib.rs +48 -24
- data/core/layers/logging/Cargo.toml +2 -2
- data/core/layers/logging/src/lib.rs +46 -2
- data/core/layers/metrics/Cargo.toml +3 -3
- data/core/layers/mime-guess/Cargo.toml +2 -2
- data/core/layers/mime-guess/src/lib.rs +31 -4
- data/core/layers/observe-metrics-common/Cargo.toml +2 -2
- data/core/layers/observe-metrics-common/src/lib.rs +55 -2
- data/core/layers/otelmetrics/Cargo.toml +3 -3
- data/core/layers/oteltrace/Cargo.toml +2 -2
- data/core/layers/oteltrace/src/lib.rs +27 -2
- data/core/layers/prometheus/Cargo.toml +3 -3
- data/core/layers/prometheus-client/Cargo.toml +3 -3
- data/core/layers/retry/Cargo.toml +4 -4
- data/core/layers/retry/src/lib.rs +76 -19
- data/core/layers/route/Cargo.toml +3 -3
- data/core/layers/route/src/lib.rs +34 -7
- data/core/layers/tail-cut/Cargo.toml +2 -2
- data/core/layers/tail-cut/src/lib.rs +28 -2
- data/core/layers/throttle/Cargo.toml +2 -2
- data/core/layers/throttle/src/lib.rs +19 -2
- data/core/layers/timeout/Cargo.toml +3 -3
- data/core/layers/timeout/src/lib.rs +38 -13
- data/core/layers/tracing/Cargo.toml +2 -2
- data/core/layers/tracing/src/lib.rs +24 -3
- data/core/services/aliyun-drive/Cargo.toml +1 -1
- data/core/services/aliyun-drive/src/backend.rs +33 -23
- data/core/services/aliyun-drive/src/core.rs +142 -53
- data/core/services/aliyun-drive/src/lister.rs +19 -18
- data/core/services/aliyun-drive/src/reader.rs +4 -1
- data/core/services/aliyun-drive/src/writer.rs +3 -3
- data/core/services/alluxio/Cargo.toml +1 -1
- data/core/services/alluxio/src/backend.rs +1 -1
- data/core/services/alluxio/src/core.rs +113 -94
- data/core/services/alluxio/src/reader.rs +7 -3
- data/core/services/alluxio/src/writer.rs +2 -2
- data/core/services/azblob/Cargo.toml +2 -2
- data/core/services/azblob/src/backend.rs +16 -9
- data/core/services/azblob/src/copier.rs +41 -15
- data/core/services/azblob/src/core.rs +353 -135
- data/core/services/azblob/src/deleter.rs +41 -18
- data/core/services/azblob/src/lister.rs +16 -10
- data/core/services/azblob/src/reader.rs +4 -1
- data/core/services/azblob/src/writer.rs +48 -15
- data/core/services/azdls/Cargo.toml +2 -2
- data/core/services/azdls/src/backend.rs +45 -15
- data/core/services/azdls/src/config.rs +4 -1
- data/core/services/azdls/src/core.rs +276 -88
- data/core/services/azdls/src/deleter.rs +13 -4
- data/core/services/azdls/src/lister.rs +18 -12
- data/core/services/azdls/src/reader.rs +6 -2
- data/core/services/azdls/src/writer.rs +43 -22
- data/core/services/azfile/Cargo.toml +2 -2
- data/core/services/azfile/src/backend.rs +24 -8
- data/core/services/azfile/src/core.rs +194 -76
- data/core/services/azfile/src/deleter.rs +8 -1
- data/core/services/azfile/src/lister.rs +20 -14
- data/core/services/azfile/src/reader.rs +5 -2
- data/core/services/azfile/src/writer.rs +27 -15
- data/core/services/azure-common/Cargo.toml +1 -1
- data/core/services/b2/Cargo.toml +1 -1
- data/core/services/b2/src/backend.rs +17 -7
- data/core/services/b2/src/core.rs +133 -119
- data/core/services/b2/src/deleter.rs +1 -1
- data/core/services/b2/src/lister.rs +5 -2
- data/core/services/b2/src/reader.rs +5 -2
- data/core/services/b2/src/writer.rs +29 -12
- data/core/services/cacache/Cargo.toml +1 -1
- data/core/services/cacache/src/backend.rs +4 -5
- data/core/services/cacache/src/reader.rs +4 -1
- data/core/services/cacache/src/writer.rs +6 -2
- data/core/services/cloudflare-kv/Cargo.toml +1 -1
- data/core/services/cloudflare-kv/src/backend.rs +26 -15
- data/core/services/cloudflare-kv/src/config.rs +13 -2
- data/core/services/cloudflare-kv/src/core.rs +62 -56
- data/core/services/cloudflare-kv/src/deleter.rs +12 -3
- data/core/services/cloudflare-kv/src/lister.rs +18 -15
- data/core/services/cloudflare-kv/src/reader.rs +14 -9
- data/core/services/cloudflare-kv/src/writer.rs +10 -7
- data/core/services/compfs/Cargo.toml +1 -1
- data/core/services/compfs/src/backend.rs +11 -7
- data/core/services/compfs/src/lister.rs +7 -7
- data/core/services/compfs/src/writer.rs +1 -1
- data/core/services/cos/Cargo.toml +1 -1
- data/core/services/cos/src/backend.rs +38 -8
- data/core/services/cos/src/core.rs +176 -76
- data/core/services/cos/src/deleter.rs +4 -1
- data/core/services/cos/src/lister.rs +42 -27
- data/core/services/cos/src/reader.rs +6 -2
- data/core/services/cos/src/writer.rs +44 -20
- data/core/services/d1/Cargo.toml +1 -1
- data/core/services/d1/src/backend.rs +6 -5
- data/core/services/d1/src/core.rs +76 -60
- data/core/services/d1/src/reader.rs +4 -1
- data/core/services/d1/src/writer.rs +6 -2
- data/core/services/dashmap/Cargo.toml +1 -1
- data/core/services/dashmap/src/backend.rs +2 -2
- data/core/services/dashmap/src/reader.rs +4 -1
- data/core/services/dashmap/src/writer.rs +11 -8
- data/core/services/dbfs/Cargo.toml +1 -1
- data/core/services/dbfs/src/backend.rs +21 -15
- data/core/services/dbfs/src/core.rs +60 -55
- data/core/services/dbfs/src/deleter.rs +4 -1
- data/core/services/dbfs/src/lister.rs +8 -9
- data/core/services/dbfs/src/writer.rs +6 -3
- data/core/services/dropbox/Cargo.toml +1 -1
- data/core/services/dropbox/src/backend.rs +29 -22
- data/core/services/dropbox/src/core.rs +64 -62
- data/core/services/dropbox/src/deleter.rs +1 -1
- data/core/services/dropbox/src/lister.rs +17 -8
- data/core/services/dropbox/src/reader.rs +4 -1
- data/core/services/dropbox/src/writer.rs +13 -10
- data/core/services/etcd/Cargo.toml +1 -1
- data/core/services/etcd/src/backend.rs +8 -5
- data/core/services/etcd/src/core.rs +5 -11
- data/core/services/etcd/src/lister.rs +6 -1
- data/core/services/etcd/src/reader.rs +4 -1
- data/core/services/etcd/src/writer.rs +6 -3
- data/core/services/foundationdb/Cargo.toml +1 -1
- data/core/services/foundationdb/src/backend.rs +6 -5
- data/core/services/foundationdb/src/reader.rs +4 -1
- data/core/services/foundationdb/src/writer.rs +6 -2
- data/core/services/foyer/Cargo.toml +3 -3
- data/core/services/foyer/src/backend.rs +6 -5
- data/core/services/foyer/src/reader.rs +4 -1
- data/core/services/foyer/src/writer.rs +6 -2
- data/core/services/fs/Cargo.toml +1 -1
- data/core/services/fs/src/backend.rs +4 -3
- data/core/services/fs/src/core.rs +44 -26
- data/core/services/fs/src/lister.rs +9 -6
- data/core/services/fs/src/writer.rs +20 -13
- data/core/services/ftp/Cargo.toml +4 -6
- data/core/services/ftp/src/backend.rs +9 -5
- data/core/services/ftp/src/core.rs +9 -7
- data/core/services/ftp/src/lister.rs +7 -8
- data/core/services/ftp/src/reader.rs +3 -3
- data/core/services/ftp/src/writer.rs +3 -3
- data/core/services/gcs/Cargo.toml +4 -2
- data/core/services/gcs/src/backend.rs +53 -7
- data/core/services/gcs/src/composer.rs +705 -0
- data/core/services/gcs/src/copier.rs +14 -4
- data/core/services/gcs/src/core.rs +944 -126
- data/core/services/gcs/src/deleter.rs +33 -18
- data/core/services/gcs/src/lib.rs +1 -0
- data/core/services/gcs/src/lister.rs +21 -12
- data/core/services/gcs/src/reader.rs +12 -5
- data/core/services/gcs/src/writer.rs +632 -10
- data/core/services/gcs-grpc/Cargo.toml +58 -0
- data/core/services/gcs-grpc/README.md +19 -0
- data/core/services/gcs-grpc/proto/README.md +23 -0
- data/core/services/gcs-grpc/proto/google/storage/v2/storage.proto +171 -0
- data/core/services/gcs-grpc/proto/upstream-descriptor.bin +0 -0
- data/core/services/gcs-grpc/src/backend.rs +449 -0
- data/core/services/gcs-grpc/src/config.rs +116 -0
- data/core/services/gcs-grpc/src/copier.rs +98 -0
- data/core/services/gcs-grpc/src/core.rs +298 -0
- data/core/services/gcs-grpc/src/deleter.rs +65 -0
- data/core/services/gcs-grpc/src/docs.md +19 -0
- data/core/services/gcs-grpc/src/generated/google.storage.v2.rs +541 -0
- data/core/services/gcs-grpc/src/generated/mod.rs +24 -0
- data/core/services/gcs-grpc/src/lib.rs +43 -0
- data/core/services/gcs-grpc/src/lister.rs +125 -0
- data/core/services/gcs-grpc/src/reader.rs +140 -0
- data/core/services/gcs-grpc/src/writer.rs +780 -0
- data/core/services/gdrive/Cargo.toml +1 -1
- data/core/services/gdrive/src/backend.rs +122 -68
- data/core/services/gdrive/src/core.rs +86 -68
- data/core/services/gdrive/src/deleter.rs +8 -2
- data/core/services/gdrive/src/lister.rs +36 -24
- data/core/services/gdrive/src/reader.rs +9 -3
- data/core/services/gdrive/src/writer.rs +13 -7
- data/core/services/ghac/Cargo.toml +2 -2
- data/core/services/ghac/src/backend.rs +5 -2
- data/core/services/ghac/src/core.rs +59 -37
- data/core/services/ghac/src/reader.rs +5 -2
- data/core/services/ghac/src/writer.rs +16 -6
- data/core/services/github/Cargo.toml +1 -1
- data/core/services/github/src/backend.rs +16 -8
- data/core/services/github/src/core.rs +88 -76
- data/core/services/github/src/lister.rs +16 -14
- data/core/services/github/src/reader.rs +5 -2
- data/core/services/github/src/writer.rs +12 -6
- data/core/services/goosefs/Cargo.toml +3 -3
- data/core/services/goosefs/src/backend.rs +380 -51
- data/core/services/goosefs/src/config.rs +18 -10
- data/core/services/goosefs/src/core.rs +291 -208
- data/core/services/goosefs/src/docs.md +34 -3
- data/core/services/goosefs/src/lister.rs +2 -3
- data/core/services/goosefs/src/reader.rs +7 -3
- data/core/services/goosefs/src/writer.rs +21 -10
- data/core/services/goosefs/tests/master_addr_resolution.rs +103 -0
- data/core/services/goosefs/tests/safe_conditional_put.rs +37 -0
- data/core/services/gridfs/Cargo.toml +1 -1
- data/core/services/gridfs/src/backend.rs +6 -5
- data/core/services/gridfs/src/reader.rs +4 -1
- data/core/services/gridfs/src/writer.rs +6 -2
- data/core/services/hdfs/Cargo.toml +1 -1
- data/core/services/hdfs/src/backend.rs +1 -1
- data/core/services/hdfs/src/core.rs +7 -4
- data/core/services/hdfs/src/lister.rs +7 -9
- data/core/services/hdfs/src/writer.rs +5 -1
- data/core/services/hdfs-native/Cargo.toml +1 -1
- data/core/services/hdfs-native/src/backend.rs +1 -1
- data/core/services/hdfs-native/src/core.rs +44 -50
- data/core/services/hdfs-native/src/lister.rs +8 -10
- data/core/services/hdfs-native/src/writer.rs +5 -1
- data/core/services/hf/Cargo.toml +4 -3
- data/core/services/hf/src/backend.rs +3 -3
- data/core/services/hf/src/core.rs +892 -142
- data/core/services/hf/src/lister.rs +16 -6
- data/core/services/hf/src/reader.rs +377 -57
- data/core/services/hf/src/writer.rs +6 -2
- data/core/services/http/Cargo.toml +3 -3
- data/core/services/http/src/backend.rs +8 -6
- data/core/services/http/src/core.rs +57 -35
- data/core/services/http/src/reader.rs +5 -2
- data/core/services/ipfs/Cargo.toml +1 -1
- data/core/services/ipfs/src/backend.rs +6 -3
- data/core/services/ipfs/src/core.rs +43 -34
- data/core/services/ipfs/src/reader.rs +5 -2
- data/core/services/ipmfs/Cargo.toml +1 -1
- data/core/services/ipmfs/src/backend.rs +17 -8
- data/core/services/ipmfs/src/core.rs +66 -60
- data/core/services/ipmfs/src/deleter.rs +5 -2
- data/core/services/ipmfs/src/lister.rs +8 -8
- data/core/services/ipmfs/src/reader.rs +5 -2
- data/core/services/ipmfs/src/writer.rs +6 -3
- data/core/services/koofr/Cargo.toml +1 -1
- data/core/services/koofr/src/backend.rs +44 -15
- data/core/services/koofr/src/core.rs +62 -46
- data/core/services/koofr/src/deleter.rs +4 -1
- data/core/services/koofr/src/lister.rs +11 -10
- data/core/services/koofr/src/reader.rs +5 -2
- data/core/services/koofr/src/writer.rs +13 -7
- data/core/services/lakefs/Cargo.toml +1 -1
- data/core/services/lakefs/src/backend.rs +25 -8
- data/core/services/lakefs/src/core.rs +78 -72
- data/core/services/lakefs/src/deleter.rs +4 -1
- data/core/services/lakefs/src/lister.rs +11 -11
- data/core/services/lakefs/src/reader.rs +5 -2
- data/core/services/lakefs/src/writer.rs +11 -10
- data/core/services/memcached/Cargo.toml +1 -1
- data/core/services/memcached/src/backend.rs +57 -7
- data/core/services/memcached/src/config.rs +13 -2
- data/core/services/memcached/src/core.rs +11 -1
- data/core/services/memcached/src/reader.rs +4 -1
- data/core/services/memcached/src/writer.rs +6 -2
- data/core/services/mini_moka/Cargo.toml +1 -1
- data/core/services/mini_moka/src/backend.rs +8 -8
- data/core/services/mini_moka/src/reader.rs +4 -1
- data/core/services/mini_moka/src/writer.rs +11 -7
- data/core/services/moka/Cargo.toml +1 -1
- data/core/services/moka/src/backend.rs +7 -7
- data/core/services/moka/src/reader.rs +4 -1
- data/core/services/moka/src/writer.rs +10 -6
- data/core/services/mongodb/Cargo.toml +1 -1
- data/core/services/mongodb/src/backend.rs +6 -5
- data/core/services/mongodb/src/reader.rs +4 -1
- data/core/services/mongodb/src/writer.rs +6 -2
- data/core/services/monoiofs/Cargo.toml +2 -2
- data/core/services/monoiofs/src/backend.rs +16 -10
- data/core/services/monoiofs/src/core.rs +8 -9
- data/core/services/monoiofs/src/reader.rs +8 -10
- data/core/services/monoiofs/src/writer.rs +19 -24
- data/core/services/mysql/Cargo.toml +1 -1
- data/core/services/mysql/src/backend.rs +6 -5
- data/core/services/mysql/src/lister.rs +7 -3
- data/core/services/mysql/src/reader.rs +4 -1
- data/core/services/mysql/src/writer.rs +6 -2
- data/core/services/obs/Cargo.toml +1 -1
- data/core/services/obs/src/backend.rs +29 -11
- data/core/services/obs/src/core.rs +80 -81
- data/core/services/obs/src/deleter.rs +4 -1
- data/core/services/obs/src/lister.rs +12 -5
- data/core/services/obs/src/reader.rs +5 -2
- data/core/services/obs/src/writer.rs +40 -19
- data/core/services/onedrive/Cargo.toml +1 -1
- data/core/services/onedrive/src/backend.rs +19 -7
- data/core/services/onedrive/src/core.rs +178 -70
- data/core/services/onedrive/src/deleter.rs +5 -2
- data/core/services/onedrive/src/lister.rs +19 -13
- data/core/services/onedrive/src/reader.rs +6 -2
- data/core/services/onedrive/src/writer.rs +26 -15
- data/core/services/opfs/Cargo.toml +1 -1
- data/core/services/opfs/src/backend.rs +6 -13
- data/core/services/opfs/src/core.rs +33 -37
- data/core/services/opfs/src/lister.rs +4 -4
- data/core/services/opfs/src/writer.rs +1 -3
- data/core/services/oss/Cargo.toml +1 -1
- data/core/services/oss/src/backend.rs +40 -8
- data/core/services/oss/src/core.rs +169 -81
- data/core/services/oss/src/deleter.rs +16 -6
- data/core/services/oss/src/lister.rs +43 -27
- data/core/services/oss/src/reader.rs +6 -2
- data/core/services/oss/src/writer.rs +36 -12
- data/core/services/pcloud/Cargo.toml +1 -1
- data/core/services/pcloud/src/backend.rs +40 -6
- data/core/services/pcloud/src/core.rs +78 -66
- data/core/services/pcloud/src/deleter.rs +8 -1
- data/core/services/pcloud/src/lister.rs +4 -1
- data/core/services/pcloud/src/reader.rs +5 -2
- data/core/services/pcloud/src/writer.rs +6 -3
- data/core/services/persy/Cargo.toml +1 -1
- data/core/services/persy/src/backend.rs +6 -5
- data/core/services/persy/src/core.rs +60 -15
- data/core/services/persy/src/reader.rs +4 -1
- data/core/services/persy/src/writer.rs +6 -2
- data/core/services/postgresql/Cargo.toml +1 -1
- data/core/services/postgresql/src/backend.rs +6 -5
- data/core/services/postgresql/src/reader.rs +4 -1
- data/core/services/postgresql/src/writer.rs +6 -2
- data/core/services/redb/Cargo.toml +1 -1
- data/core/services/redb/src/backend.rs +6 -5
- data/core/services/redb/src/reader.rs +4 -1
- data/core/services/redb/src/writer.rs +6 -2
- data/core/services/redis/Cargo.toml +1 -1
- data/core/services/redis/src/backend.rs +18 -8
- data/core/services/redis/src/config.rs +13 -2
- data/core/services/redis/src/reader.rs +8 -4
- data/core/services/redis/src/writer.rs +6 -2
- data/core/services/rocksdb/Cargo.toml +1 -1
- data/core/services/rocksdb/src/backend.rs +6 -5
- data/core/services/rocksdb/src/lister.rs +6 -5
- data/core/services/rocksdb/src/reader.rs +4 -1
- data/core/services/rocksdb/src/writer.rs +6 -2
- data/core/services/s3/Cargo.toml +5 -4
- data/core/services/s3/src/backend.rs +966 -22
- data/core/services/s3/src/copier.rs +190 -55
- data/core/services/s3/src/core.rs +299 -190
- data/core/services/s3/src/deleter.rs +26 -7
- data/core/services/s3/src/docs.md +57 -0
- data/core/services/s3/src/lister.rs +55 -36
- data/core/services/s3/src/reader.rs +8 -5
- data/core/services/s3/src/writer.rs +154 -32
- data/core/services/seafile/Cargo.toml +1 -1
- data/core/services/seafile/src/backend.rs +2 -2
- data/core/services/seafile/src/core.rs +104 -78
- data/core/services/seafile/src/lister.rs +11 -8
- data/core/services/seafile/src/reader.rs +5 -2
- data/core/services/seafile/src/writer.rs +6 -3
- data/core/services/sftp/Cargo.toml +1 -1
- data/core/services/sftp/src/backend.rs +19 -4
- data/core/services/sftp/src/core.rs +51 -46
- data/core/services/sftp/src/lister.rs +4 -4
- data/core/services/sftp/src/writer.rs +1 -1
- data/core/services/sled/Cargo.toml +1 -1
- data/core/services/sled/src/backend.rs +6 -5
- data/core/services/sled/src/core.rs +28 -6
- data/core/services/sled/src/lister.rs +6 -5
- data/core/services/sled/src/reader.rs +4 -1
- data/core/services/sled/src/writer.rs +6 -2
- data/core/services/sqlite/Cargo.toml +1 -1
- data/core/services/sqlite/src/backend.rs +11 -6
- data/core/services/sqlite/src/reader.rs +4 -1
- data/core/services/sqlite/src/writer.rs +7 -3
- data/core/services/surrealdb/Cargo.toml +1 -1
- data/core/services/surrealdb/src/backend.rs +6 -5
- data/core/services/surrealdb/src/reader.rs +4 -1
- data/core/services/surrealdb/src/writer.rs +6 -2
- data/core/services/swift/Cargo.toml +1 -1
- data/core/services/swift/src/backend.rs +38 -8
- data/core/services/swift/src/core.rs +62 -66
- data/core/services/swift/src/deleter.rs +8 -2
- data/core/services/swift/src/lister.rs +11 -8
- data/core/services/swift/src/reader.rs +5 -2
- data/core/services/swift/src/writer.rs +17 -8
- data/core/services/tikv/Cargo.toml +1 -1
- data/core/services/tikv/src/backend.rs +6 -5
- data/core/services/tikv/src/core.rs +30 -13
- data/core/services/tikv/src/reader.rs +4 -1
- data/core/services/tikv/src/writer.rs +6 -2
- data/core/services/tos/Cargo.toml +1 -1
- data/core/services/tos/src/backend.rs +14 -14
- data/core/services/tos/src/copier.rs +44 -17
- data/core/services/tos/src/core.rs +112 -111
- data/core/services/tos/src/deleter.rs +9 -3
- data/core/services/tos/src/lister.rs +43 -28
- data/core/services/tos/src/reader.rs +5 -2
- data/core/services/tos/src/writer.rs +37 -16
- data/core/services/upyun/Cargo.toml +1 -1
- data/core/services/upyun/src/backend.rs +30 -7
- data/core/services/upyun/src/core.rs +97 -88
- data/core/services/upyun/src/deleter.rs +4 -1
- data/core/services/upyun/src/lister.rs +10 -10
- data/core/services/upyun/src/reader.rs +5 -2
- data/core/services/upyun/src/writer.rs +19 -7
- data/core/services/vercel-artifacts/Cargo.toml +1 -1
- data/core/services/vercel-artifacts/src/backend.rs +6 -3
- data/core/services/vercel-artifacts/src/core.rs +32 -27
- data/core/services/vercel-artifacts/src/reader.rs +5 -2
- data/core/services/vercel-artifacts/src/writer.rs +6 -3
- data/core/services/vercel-blob/Cargo.toml +1 -1
- data/core/services/vercel-blob/src/backend.rs +23 -6
- data/core/services/vercel-blob/src/core.rs +83 -77
- data/core/services/vercel-blob/src/reader.rs +5 -2
- data/core/services/vercel-blob/src/writer.rs +19 -7
- data/core/services/webdav/Cargo.toml +1 -1
- data/core/services/webdav/src/backend.rs +25 -5
- data/core/services/webdav/src/core.rs +116 -59
- data/core/services/webdav/src/deleter.rs +4 -1
- data/core/services/webdav/src/lister.rs +4 -1
- data/core/services/webdav/src/reader.rs +6 -2
- data/core/services/webdav/src/writer.rs +17 -7
- data/core/services/webhdfs/Cargo.toml +1 -1
- data/core/services/webhdfs/src/backend.rs +23 -10
- data/core/services/webhdfs/src/core.rs +97 -96
- data/core/services/webhdfs/src/deleter.rs +5 -2
- data/core/services/webhdfs/src/lister.rs +21 -9
- data/core/services/webhdfs/src/reader.rs +5 -2
- data/core/services/webhdfs/src/writer.rs +42 -13
- data/core/services/yandex-disk/Cargo.toml +1 -1
- data/core/services/yandex-disk/src/backend.rs +28 -6
- data/core/services/yandex-disk/src/core.rs +97 -79
- data/core/services/yandex-disk/src/deleter.rs +4 -1
- data/core/services/yandex-disk/src/lister.rs +5 -2
- data/core/services/yandex-disk/src/reader.rs +5 -2
- data/core/services/yandex-disk/src/writer.rs +6 -3
- data/core/src/lib.rs +5 -0
- data/core/testkit/Cargo.toml +4 -4
- data/core/tests/behavior/async_compose.rs +297 -0
- data/core/tests/behavior/async_copy.rs +162 -1
- data/core/tests/behavior/async_delete.rs +364 -3
- data/core/tests/behavior/async_read.rs +86 -0
- data/core/tests/behavior/async_restore.rs +162 -0
- data/core/tests/behavior/async_stat.rs +90 -0
- data/core/tests/behavior/async_write.rs +219 -10
- data/core/tests/behavior/main.rs +4 -0
- data/core/upgrade.md +114 -1
- data/src/capability.rs +0 -1
- data/src/io.rs +0 -1
- data/src/lister.rs +0 -1
- data/src/metadata.rs +0 -1
- data/src/operator_info.rs +0 -1
- metadata +42 -2
|
@@ -19,8 +19,8 @@ use std::sync::Arc;
|
|
|
19
19
|
|
|
20
20
|
use http::StatusCode;
|
|
21
21
|
|
|
22
|
-
use super::core::AzfileCore;
|
|
23
22
|
use super::core::parse_error;
|
|
23
|
+
use super::core::{AzfileCore, ErrorContext};
|
|
24
24
|
use opendal_core::raw::*;
|
|
25
25
|
use opendal_core::*;
|
|
26
26
|
|
|
@@ -50,17 +50,17 @@ impl AzfileWriter {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
fn parse_metadata(headers: &http::HeaderMap) -> Result<Metadata> {
|
|
53
|
-
let mut metadata =
|
|
53
|
+
let mut metadata = MetadataBuilder::unknown();
|
|
54
54
|
|
|
55
55
|
if let Some(last_modified) = parse_last_modified(headers)? {
|
|
56
|
-
metadata.
|
|
56
|
+
metadata.last_modified(last_modified);
|
|
57
57
|
}
|
|
58
58
|
let etag = parse_etag(headers)?;
|
|
59
59
|
if let Some(etag) = etag {
|
|
60
|
-
metadata.
|
|
60
|
+
metadata.etag(etag);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
Ok(metadata)
|
|
63
|
+
Ok(metadata.build())
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -78,7 +78,10 @@ impl oio::OneShotWrite for AzfileWriter {
|
|
|
78
78
|
match status {
|
|
79
79
|
StatusCode::OK | StatusCode::CREATED => {}
|
|
80
80
|
_ => {
|
|
81
|
-
return Err(
|
|
81
|
+
return Err(
|
|
82
|
+
parse_error(ErrorContext::new(ServiceOperation("CreateFile")), resp)
|
|
83
|
+
.with_operation("Backend::azfile_create_file"),
|
|
84
|
+
);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -87,11 +90,14 @@ impl oio::OneShotWrite for AzfileWriter {
|
|
|
87
90
|
.azfile_update(&self.ctx, &self.path, size as u64, 0, bs)
|
|
88
91
|
.await?;
|
|
89
92
|
let status = resp.status();
|
|
90
|
-
let mut meta = AzfileWriter::parse_metadata(resp.headers())
|
|
91
|
-
meta.
|
|
93
|
+
let mut meta = AzfileWriter::parse_metadata(resp.headers())?.into_builder();
|
|
94
|
+
meta.set_file(size as u64);
|
|
92
95
|
match status {
|
|
93
|
-
StatusCode::OK | StatusCode::CREATED => Ok(meta),
|
|
94
|
-
_ => Err(
|
|
96
|
+
StatusCode::OK | StatusCode::CREATED => Ok(meta.build()),
|
|
97
|
+
_ => Err(
|
|
98
|
+
parse_error(ErrorContext::new(ServiceOperation("PutRange")), resp)
|
|
99
|
+
.with_operation("Backend::azfile_update"),
|
|
100
|
+
),
|
|
95
101
|
}
|
|
96
102
|
}
|
|
97
103
|
}
|
|
@@ -109,7 +115,10 @@ impl oio::AppendWrite for AzfileWriter {
|
|
|
109
115
|
|
|
110
116
|
match status {
|
|
111
117
|
StatusCode::OK => Ok(parse_content_length(resp.headers())?.unwrap_or_default()),
|
|
112
|
-
_ => Err(parse_error(
|
|
118
|
+
_ => Err(parse_error(
|
|
119
|
+
ErrorContext::new(ServiceOperation("GetFileProperties")),
|
|
120
|
+
resp,
|
|
121
|
+
)),
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
|
|
@@ -120,11 +129,14 @@ impl oio::AppendWrite for AzfileWriter {
|
|
|
120
129
|
.await?;
|
|
121
130
|
|
|
122
131
|
let status = resp.status();
|
|
123
|
-
let mut meta = AzfileWriter::parse_metadata(resp.headers())
|
|
124
|
-
meta.
|
|
132
|
+
let mut meta = AzfileWriter::parse_metadata(resp.headers())?.into_builder();
|
|
133
|
+
meta.set_file(offset + size);
|
|
125
134
|
match status {
|
|
126
|
-
StatusCode::OK | StatusCode::CREATED => Ok(meta),
|
|
127
|
-
_ => Err(
|
|
135
|
+
StatusCode::OK | StatusCode::CREATED => Ok(meta.build()),
|
|
136
|
+
_ => Err(
|
|
137
|
+
parse_error(ErrorContext::new(ServiceOperation("PutRange")), resp)
|
|
138
|
+
.with_operation("Backend::azfile_update"),
|
|
139
|
+
),
|
|
128
140
|
}
|
|
129
141
|
}
|
|
130
142
|
}
|
data/core/services/b2/Cargo.toml
CHANGED
|
@@ -36,7 +36,7 @@ asyncband = { workspace = true }
|
|
|
36
36
|
bytes = { workspace = true }
|
|
37
37
|
http = { workspace = true }
|
|
38
38
|
log = { workspace = true }
|
|
39
|
-
opendal-core = { path = "../../core", version = "0.
|
|
39
|
+
opendal-core = { path = "../../core", version = "0.59.1", default-features = false }
|
|
40
40
|
serde = { workspace = true, features = ["derive"] }
|
|
41
41
|
serde_json = { workspace = true }
|
|
42
42
|
|
|
@@ -25,11 +25,11 @@ use log::debug;
|
|
|
25
25
|
|
|
26
26
|
use super::B2_SCHEME;
|
|
27
27
|
use super::config::B2Config;
|
|
28
|
-
use super::core::B2Core;
|
|
29
28
|
use super::core::B2Signer;
|
|
30
29
|
use super::core::constants;
|
|
31
30
|
use super::core::parse_error;
|
|
32
31
|
use super::core::parse_file_info;
|
|
32
|
+
use super::core::{B2Core, ErrorContext};
|
|
33
33
|
use super::deleter::B2Deleter;
|
|
34
34
|
use super::lister::B2Lister;
|
|
35
35
|
use super::reader::*;
|
|
@@ -224,6 +224,7 @@ impl Service for B2Backend {
|
|
|
224
224
|
type Lister = oio::PageLister<B2Lister>;
|
|
225
225
|
type Deleter = oio::OneShotDeleter<B2Deleter>;
|
|
226
226
|
type Copier = oio::OneShotCopier;
|
|
227
|
+
type Composer = ();
|
|
227
228
|
|
|
228
229
|
fn info(&self) -> ServiceInfo {
|
|
229
230
|
self.core.info.clone()
|
|
@@ -250,7 +251,7 @@ impl Service for B2Backend {
|
|
|
250
251
|
async fn stat(&self, ctx: &OperationContext, path: &str, _args: OpStat) -> Result<RpStat> {
|
|
251
252
|
// Stat root always returns a DIR.
|
|
252
253
|
if path == "/" {
|
|
253
|
-
return Ok(RpStat::new(
|
|
254
|
+
return Ok(RpStat::new(MetadataBuilder::dir().build()));
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
let delimiter = if path.ends_with('/') { Some("/") } else { None };
|
|
@@ -317,7 +318,6 @@ impl Service for B2Backend {
|
|
|
317
318
|
from: &str,
|
|
318
319
|
to: &str,
|
|
319
320
|
_args: OpCopy,
|
|
320
|
-
_opts: OpCopier,
|
|
321
321
|
) -> Result<Self::Copier> {
|
|
322
322
|
let core = self.core.clone();
|
|
323
323
|
let ctx = ctx.clone();
|
|
@@ -327,6 +327,7 @@ impl Service for B2Backend {
|
|
|
327
327
|
Ok(oio::OneShotCopier::new(async move {
|
|
328
328
|
let file_info = core.get_file_info(&ctx, &from, None).await?;
|
|
329
329
|
let source_file_id = file_info.file_id;
|
|
330
|
+
let source_content_length = file_info.content_length;
|
|
330
331
|
|
|
331
332
|
let Some(source_file_id) = source_file_id else {
|
|
332
333
|
return Err(Error::new(ErrorKind::IsADirectory, "is a directory"));
|
|
@@ -337,8 +338,14 @@ impl Service for B2Backend {
|
|
|
337
338
|
let status = resp.status();
|
|
338
339
|
|
|
339
340
|
match status {
|
|
340
|
-
StatusCode::OK =>
|
|
341
|
-
|
|
341
|
+
StatusCode::OK => {
|
|
342
|
+
let metadata = MetadataBuilder::file(source_content_length);
|
|
343
|
+
Ok(metadata.build())
|
|
344
|
+
}
|
|
345
|
+
_ => Err(parse_error(
|
|
346
|
+
ErrorContext::new(ServiceOperation("CopyFile")),
|
|
347
|
+
resp,
|
|
348
|
+
)),
|
|
342
349
|
}
|
|
343
350
|
}))
|
|
344
351
|
}
|
|
@@ -393,7 +400,7 @@ impl Service for B2Backend {
|
|
|
393
400
|
parts.headers,
|
|
394
401
|
)))
|
|
395
402
|
}
|
|
396
|
-
PresignOperation::Read(
|
|
403
|
+
PresignOperation::Read(range, _) => {
|
|
397
404
|
let resp = self
|
|
398
405
|
.core
|
|
399
406
|
.get_download_authorization(ctx, path, args.expire())
|
|
@@ -410,7 +417,10 @@ impl Service for B2Backend {
|
|
|
410
417
|
resp.authorization_token
|
|
411
418
|
);
|
|
412
419
|
|
|
413
|
-
let req = Request::get(url);
|
|
420
|
+
let mut req = Request::get(url);
|
|
421
|
+
if !range.is_full() {
|
|
422
|
+
req = req.header(http::header::RANGE, range.to_header());
|
|
423
|
+
}
|
|
414
424
|
|
|
415
425
|
let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
|
|
416
426
|
|
|
@@ -120,7 +120,10 @@ impl B2Core {
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
_ => {
|
|
123
|
-
return Err(parse_error(
|
|
123
|
+
return Err(parse_error(
|
|
124
|
+
ErrorContext::new(ServiceOperation("AuthorizeAccount")),
|
|
125
|
+
resp,
|
|
126
|
+
));
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
129
|
Ok(signer.auth_info.clone())
|
|
@@ -196,7 +199,10 @@ impl B2Core {
|
|
|
196
199
|
.map_err(new_json_deserialize_error)?;
|
|
197
200
|
Ok(resp)
|
|
198
201
|
}
|
|
199
|
-
_ => Err(parse_error(
|
|
202
|
+
_ => Err(parse_error(
|
|
203
|
+
ErrorContext::new(ServiceOperation("GetUploadUrl")),
|
|
204
|
+
resp,
|
|
205
|
+
)),
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
|
@@ -241,7 +247,10 @@ impl B2Core {
|
|
|
241
247
|
.map_err(new_json_deserialize_error)?;
|
|
242
248
|
Ok(resp)
|
|
243
249
|
}
|
|
244
|
-
_ => Err(parse_error(
|
|
250
|
+
_ => Err(parse_error(
|
|
251
|
+
ErrorContext::new(ServiceOperation("GetDownloadAuthorization")),
|
|
252
|
+
resp,
|
|
253
|
+
)),
|
|
245
254
|
}
|
|
246
255
|
}
|
|
247
256
|
|
|
@@ -331,7 +340,7 @@ impl B2Core {
|
|
|
331
340
|
// B2 uses fileInfo field for custom file info in start_large_file API.
|
|
332
341
|
if let Some(user_metadata) = args.user_metadata() {
|
|
333
342
|
let file_info: HashMap<String, String> = user_metadata
|
|
334
|
-
.
|
|
343
|
+
.into_iter()
|
|
335
344
|
.map(|(k, v)| (k.to_string(), percent_encode_path(v)))
|
|
336
345
|
.collect();
|
|
337
346
|
start_large_file_request.file_info = Some(file_info);
|
|
@@ -385,7 +394,10 @@ impl B2Core {
|
|
|
385
394
|
.map_err(new_json_deserialize_error)?;
|
|
386
395
|
Ok(resp)
|
|
387
396
|
}
|
|
388
|
-
_ => Err(parse_error(
|
|
397
|
+
_ => Err(parse_error(
|
|
398
|
+
ErrorContext::new(ServiceOperation("GetUploadPartUrl")),
|
|
399
|
+
resp,
|
|
400
|
+
)),
|
|
389
401
|
}
|
|
390
402
|
}
|
|
391
403
|
|
|
@@ -505,7 +517,10 @@ impl B2Core {
|
|
|
505
517
|
}
|
|
506
518
|
Ok(resp.files.swap_remove(0))
|
|
507
519
|
}
|
|
508
|
-
_ => Err(parse_error(
|
|
520
|
+
_ => Err(parse_error(
|
|
521
|
+
ErrorContext::new(ServiceOperation("ListFileNames")),
|
|
522
|
+
resp,
|
|
523
|
+
)),
|
|
509
524
|
}
|
|
510
525
|
}
|
|
511
526
|
|
|
@@ -783,19 +798,17 @@ pub struct File {
|
|
|
783
798
|
|
|
784
799
|
pub(super) fn parse_file_info(file: &File) -> Metadata {
|
|
785
800
|
if file.file_name.ends_with('/') {
|
|
786
|
-
return
|
|
801
|
+
return MetadataBuilder::dir().build();
|
|
787
802
|
}
|
|
788
803
|
|
|
789
|
-
let mut metadata =
|
|
790
|
-
|
|
791
|
-
metadata.set_content_length(file.content_length);
|
|
804
|
+
let mut metadata = MetadataBuilder::file(file.content_length);
|
|
792
805
|
|
|
793
806
|
if let Some(content_md5) = &file.content_md5 {
|
|
794
|
-
metadata.
|
|
807
|
+
metadata.content_md5(content_md5);
|
|
795
808
|
}
|
|
796
809
|
|
|
797
810
|
if let Some(content_type) = &file.content_type {
|
|
798
|
-
metadata.
|
|
811
|
+
metadata.content_type(content_type);
|
|
799
812
|
}
|
|
800
813
|
|
|
801
814
|
// Parse user metadata from file_info
|
|
@@ -808,11 +821,11 @@ pub(super) fn parse_file_info(file: &File) -> Metadata {
|
|
|
808
821
|
.map(|(k, v)| (k.to_lowercase(), percent_decode_path(v)))
|
|
809
822
|
.collect();
|
|
810
823
|
if !user_metadata.is_empty() {
|
|
811
|
-
metadata
|
|
824
|
+
metadata.user_metadata(user_metadata);
|
|
812
825
|
}
|
|
813
826
|
}
|
|
814
827
|
|
|
815
|
-
metadata
|
|
828
|
+
metadata.build()
|
|
816
829
|
}
|
|
817
830
|
|
|
818
831
|
#[derive(Debug, Serialize)]
|
|
@@ -843,123 +856,124 @@ pub struct GetDownloadAuthorizationResponse {
|
|
|
843
856
|
pub authorization_token: String,
|
|
844
857
|
}
|
|
845
858
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
/// the error response of b2
|
|
855
|
-
#[derive(Default, Debug, Deserialize)]
|
|
856
|
-
#[allow(dead_code)]
|
|
857
|
-
struct B2Error {
|
|
858
|
-
status: u32,
|
|
859
|
-
code: String,
|
|
860
|
-
message: String,
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
/// Parse error response into Error.
|
|
864
|
-
pub(crate) fn parse_error(resp: Response<Buffer>) -> Error {
|
|
865
|
-
let (parts, body) = resp.into_parts();
|
|
866
|
-
let bs = body.to_bytes();
|
|
867
|
-
|
|
868
|
-
let (mut kind, mut retryable) = match parts.status.as_u16() {
|
|
869
|
-
403 => (ErrorKind::PermissionDenied, false),
|
|
870
|
-
404 => (ErrorKind::NotFound, false),
|
|
871
|
-
304 | 412 => (ErrorKind::ConditionNotMatch, false),
|
|
872
|
-
// Service b2 could return 403, show the authorization error
|
|
873
|
-
401 => (ErrorKind::PermissionDenied, true),
|
|
874
|
-
429 => (ErrorKind::RateLimited, true),
|
|
875
|
-
500 | 502 | 503 | 504 => (ErrorKind::Unexpected, true),
|
|
876
|
-
_ => (ErrorKind::Unexpected, false),
|
|
877
|
-
};
|
|
878
|
-
|
|
879
|
-
let (message, b2_err) = serde_json::from_reader::<_, B2Error>(bs.clone().reader())
|
|
880
|
-
.map(|b2_err| (format!("{b2_err:?}"), Some(b2_err)))
|
|
881
|
-
.unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None));
|
|
882
|
-
|
|
883
|
-
if let Some(b2_err) = b2_err {
|
|
884
|
-
(kind, retryable) =
|
|
885
|
-
parse_b2_error_code(b2_err.code.as_str()).unwrap_or((kind, retryable));
|
|
886
|
-
};
|
|
887
|
-
|
|
888
|
-
let mut err = Error::new(kind, message);
|
|
859
|
+
/// the error response of b2
|
|
860
|
+
#[derive(Default, Debug, Deserialize)]
|
|
861
|
+
#[allow(dead_code)]
|
|
862
|
+
struct B2Error {
|
|
863
|
+
status: u32,
|
|
864
|
+
code: String,
|
|
865
|
+
message: String,
|
|
866
|
+
}
|
|
889
867
|
|
|
890
|
-
|
|
868
|
+
/// Context needed to classify an error from this service.
|
|
869
|
+
#[derive(Clone, Copy, Debug)]
|
|
870
|
+
pub(crate) struct ErrorContext {
|
|
871
|
+
service_operation: ServiceOperation,
|
|
872
|
+
}
|
|
891
873
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
}
|
|
874
|
+
impl ErrorContext {
|
|
875
|
+
pub(crate) const fn new(service_operation: ServiceOperation) -> Self {
|
|
876
|
+
Self { service_operation }
|
|
877
|
+
}
|
|
878
|
+
}
|
|
895
879
|
|
|
896
|
-
|
|
880
|
+
/// Parse an error response using its service request context.
|
|
881
|
+
pub(crate) fn parse_error(ctx: ErrorContext, resp: Response<Buffer>) -> Error {
|
|
882
|
+
let (parts, body) = resp.into_parts();
|
|
883
|
+
let bs = body.to_bytes();
|
|
884
|
+
|
|
885
|
+
let (mut kind, mut retryable) = match parts.status.as_u16() {
|
|
886
|
+
403 => (ErrorKind::PermissionDenied, false),
|
|
887
|
+
404 => (ErrorKind::NotFound, false),
|
|
888
|
+
304 | 412 => (ErrorKind::ConditionNotMatch, false),
|
|
889
|
+
// Service b2 could return 403, show the authorization error
|
|
890
|
+
401 => (ErrorKind::PermissionDenied, true),
|
|
891
|
+
429 => (ErrorKind::RateLimited, true),
|
|
892
|
+
500 | 502 | 503 | 504 => (ErrorKind::Unexpected, true),
|
|
893
|
+
_ => (ErrorKind::Unexpected, false),
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
let (message, b2_err) = serde_json::from_reader::<_, B2Error>(bs.clone().reader())
|
|
897
|
+
.map(|b2_err| (format!("{b2_err:?}"), Some(b2_err)))
|
|
898
|
+
.unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None));
|
|
899
|
+
|
|
900
|
+
if let Some(b2_err) = b2_err {
|
|
901
|
+
(kind, retryable) = parse_b2_error_code(b2_err.code.as_str()).unwrap_or((kind, retryable));
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
let mut err = Error::new(kind, message);
|
|
905
|
+
|
|
906
|
+
err = err.with_context("service_operation", ctx.service_operation.0);
|
|
907
|
+
err = with_error_response_context(err, parts);
|
|
908
|
+
|
|
909
|
+
if retryable {
|
|
910
|
+
err = err.set_temporary();
|
|
897
911
|
}
|
|
898
912
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
913
|
+
err
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/// Returns the `Error kind` of this code and whether the error is retryable.
|
|
917
|
+
pub(crate) fn parse_b2_error_code(code: &str) -> Option<(ErrorKind, bool)> {
|
|
918
|
+
match code {
|
|
919
|
+
"already_hidden" => Some((ErrorKind::AlreadyExists, false)),
|
|
920
|
+
"no_such_file" => Some((ErrorKind::NotFound, false)),
|
|
921
|
+
_ => None,
|
|
906
922
|
}
|
|
923
|
+
}
|
|
907
924
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
925
|
+
#[cfg(test)]
|
|
926
|
+
mod tests {
|
|
927
|
+
use http::StatusCode;
|
|
911
928
|
|
|
912
|
-
|
|
929
|
+
use super::*;
|
|
913
930
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
931
|
+
#[test]
|
|
932
|
+
fn test_parse_b2_error_code() {
|
|
933
|
+
let code = "already_hidden";
|
|
934
|
+
assert_eq!(
|
|
935
|
+
parse_b2_error_code(code),
|
|
936
|
+
Some((opendal_core::ErrorKind::AlreadyExists, false))
|
|
937
|
+
);
|
|
921
938
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
939
|
+
let code = "no_such_file";
|
|
940
|
+
assert_eq!(
|
|
941
|
+
parse_b2_error_code(code),
|
|
942
|
+
Some((opendal_core::ErrorKind::NotFound, false))
|
|
943
|
+
);
|
|
927
944
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
945
|
+
let code = "not_found";
|
|
946
|
+
assert_eq!(parse_b2_error_code(code), None);
|
|
947
|
+
}
|
|
931
948
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
949
|
+
#[tokio::test]
|
|
950
|
+
async fn test_parse_error() {
|
|
951
|
+
let err_res = vec![
|
|
952
|
+
(
|
|
953
|
+
r#"{"status": 403, "code": "access_denied", "message":"The provided customer-managed encryption key is wrong."}"#,
|
|
954
|
+
ErrorKind::PermissionDenied,
|
|
955
|
+
StatusCode::FORBIDDEN,
|
|
956
|
+
),
|
|
957
|
+
(
|
|
958
|
+
r#"{"status": 404, "code": "not_found", "message":"File is not in B2 Cloud Storage."}"#,
|
|
959
|
+
ErrorKind::NotFound,
|
|
960
|
+
StatusCode::NOT_FOUND,
|
|
961
|
+
),
|
|
962
|
+
(
|
|
963
|
+
r#"{"status": 401, "code": "bad_auth_token", "message":"The auth token used is not valid. Call b2_authorize_account again to either get a new one, or an error message describing the problem."}"#,
|
|
964
|
+
ErrorKind::PermissionDenied,
|
|
965
|
+
StatusCode::UNAUTHORIZED,
|
|
966
|
+
),
|
|
967
|
+
];
|
|
968
|
+
|
|
969
|
+
for res in err_res {
|
|
970
|
+
let bs = bytes::Bytes::from(res.0);
|
|
971
|
+
let body = Buffer::from(bs);
|
|
972
|
+
let resp = Response::builder().status(res.2).body(body).unwrap();
|
|
973
|
+
|
|
974
|
+
let err = parse_error(ErrorContext::new(ServiceOperation("Test")), resp);
|
|
975
|
+
|
|
976
|
+
assert_eq!(err.kind(), res.1);
|
|
961
977
|
}
|
|
962
978
|
}
|
|
963
979
|
}
|
|
964
|
-
|
|
965
|
-
pub(super) use error::*;
|
|
@@ -44,7 +44,7 @@ impl oio::OneShotDelete for B2Deleter {
|
|
|
44
44
|
match status {
|
|
45
45
|
StatusCode::OK => Ok(()),
|
|
46
46
|
_ => {
|
|
47
|
-
let err = parse_error(resp);
|
|
47
|
+
let err = parse_error(ErrorContext::new(ServiceOperation("HideFile")), resp);
|
|
48
48
|
match err.kind() {
|
|
49
49
|
ErrorKind::NotFound => Ok(()),
|
|
50
50
|
// Representative deleted
|
|
@@ -19,10 +19,10 @@ use std::sync::Arc;
|
|
|
19
19
|
|
|
20
20
|
use bytes::Buf;
|
|
21
21
|
|
|
22
|
-
use super::core::B2Core;
|
|
23
22
|
use super::core::ListFileNamesResponse;
|
|
24
23
|
use super::core::parse_error;
|
|
25
24
|
use super::core::parse_file_info;
|
|
25
|
+
use super::core::{B2Core, ErrorContext};
|
|
26
26
|
use opendal_core::raw::*;
|
|
27
27
|
use opendal_core::*;
|
|
28
28
|
|
|
@@ -80,7 +80,10 @@ impl oio::PageList for B2Lister {
|
|
|
80
80
|
.await?;
|
|
81
81
|
|
|
82
82
|
if resp.status() != http::StatusCode::OK {
|
|
83
|
-
return Err(parse_error(
|
|
83
|
+
return Err(parse_error(
|
|
84
|
+
ErrorContext::new(ServiceOperation("ListFileNames")),
|
|
85
|
+
resp,
|
|
86
|
+
));
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
let bs = resp.into_body();
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
18
|
use super::backend::*;
|
|
19
|
-
use super::core::parse_error;
|
|
19
|
+
use super::core::{ErrorContext, parse_error};
|
|
20
20
|
use http::Response;
|
|
21
21
|
use http::StatusCode;
|
|
22
22
|
use opendal_core::raw::*;
|
|
@@ -60,7 +60,10 @@ impl oio::StreamRead for B2Reader {
|
|
|
60
60
|
_ => {
|
|
61
61
|
let (part, mut body) = resp.into_parts();
|
|
62
62
|
let buf = body.to_buffer().await?;
|
|
63
|
-
return Err(parse_error(
|
|
63
|
+
return Err(parse_error(
|
|
64
|
+
ErrorContext::new(ServiceOperation("DownloadFileByName")),
|
|
65
|
+
Response::from_parts(part, buf),
|
|
66
|
+
));
|
|
64
67
|
}
|
|
65
68
|
};
|
|
66
69
|
|
|
@@ -20,11 +20,11 @@ use std::sync::Arc;
|
|
|
20
20
|
use bytes::Buf;
|
|
21
21
|
use http::StatusCode;
|
|
22
22
|
|
|
23
|
-
use super::core::B2Core;
|
|
24
23
|
use super::core::StartLargeFileResponse;
|
|
25
24
|
use super::core::UploadPartResponse;
|
|
26
25
|
use super::core::UploadResponse;
|
|
27
26
|
use super::core::parse_error;
|
|
27
|
+
use super::core::{B2Core, ErrorContext};
|
|
28
28
|
use opendal_core::raw::*;
|
|
29
29
|
use opendal_core::*;
|
|
30
30
|
|
|
@@ -49,19 +49,21 @@ impl B2Writer {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
pub fn parse_body_into_meta(path: &str, resp: UploadResponse) -> Metadata {
|
|
52
|
-
let mut meta =
|
|
52
|
+
let mut meta = if path.ends_with('/') {
|
|
53
|
+
MetadataBuilder::dir()
|
|
54
|
+
} else {
|
|
55
|
+
MetadataBuilder::file(resp.content_length)
|
|
56
|
+
};
|
|
53
57
|
|
|
54
58
|
if let Some(md5) = resp.content_md5 {
|
|
55
|
-
meta.
|
|
59
|
+
meta.content_md5(&md5);
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
if let Some(content_type) = resp.content_type {
|
|
59
|
-
meta.
|
|
63
|
+
meta.content_type(&content_type);
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
meta.
|
|
63
|
-
|
|
64
|
-
meta
|
|
66
|
+
meta.build()
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -85,7 +87,10 @@ impl oio::MultipartWrite for B2Writer {
|
|
|
85
87
|
|
|
86
88
|
Ok(meta)
|
|
87
89
|
}
|
|
88
|
-
_ => Err(parse_error(
|
|
90
|
+
_ => Err(parse_error(
|
|
91
|
+
ErrorContext::new(ServiceOperation("UploadFile")),
|
|
92
|
+
resp,
|
|
93
|
+
)),
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
@@ -106,7 +111,10 @@ impl oio::MultipartWrite for B2Writer {
|
|
|
106
111
|
|
|
107
112
|
Ok(result.file_id)
|
|
108
113
|
}
|
|
109
|
-
_ => Err(parse_error(
|
|
114
|
+
_ => Err(parse_error(
|
|
115
|
+
ErrorContext::new(ServiceOperation("StartLargeFile")),
|
|
116
|
+
resp,
|
|
117
|
+
)),
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
|
|
@@ -141,7 +149,10 @@ impl oio::MultipartWrite for B2Writer {
|
|
|
141
149
|
size: None,
|
|
142
150
|
})
|
|
143
151
|
}
|
|
144
|
-
_ => Err(parse_error(
|
|
152
|
+
_ => Err(parse_error(
|
|
153
|
+
ErrorContext::new(ServiceOperation("UploadPart")),
|
|
154
|
+
resp,
|
|
155
|
+
)),
|
|
145
156
|
}
|
|
146
157
|
}
|
|
147
158
|
|
|
@@ -180,7 +191,10 @@ impl oio::MultipartWrite for B2Writer {
|
|
|
180
191
|
|
|
181
192
|
Ok(meta)
|
|
182
193
|
}
|
|
183
|
-
_ => Err(parse_error(
|
|
194
|
+
_ => Err(parse_error(
|
|
195
|
+
ErrorContext::new(ServiceOperation("FinishLargeFile")),
|
|
196
|
+
resp,
|
|
197
|
+
)),
|
|
184
198
|
}
|
|
185
199
|
}
|
|
186
200
|
|
|
@@ -189,7 +203,10 @@ impl oio::MultipartWrite for B2Writer {
|
|
|
189
203
|
match resp.status() {
|
|
190
204
|
// b2 returns code 200 if abort succeeds.
|
|
191
205
|
StatusCode::OK => Ok(()),
|
|
192
|
-
_ => Err(parse_error(
|
|
206
|
+
_ => Err(parse_error(
|
|
207
|
+
ErrorContext::new(ServiceOperation("CancelLargeFile")),
|
|
208
|
+
resp,
|
|
209
|
+
)),
|
|
193
210
|
}
|
|
194
211
|
}
|
|
195
212
|
}
|