Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
aac69da
Support single-request multipart upload for setting metadata
sumeetattree Apr 4, 2022
953251c
Support for create_streamed_with (sync and async)
Apr 6, 2022
20cf311
Adding download_streamed in sync api
Apr 19, 2022
ce54bbc
Remove chrono dependency
ShellWowza Apr 21, 2022
e6b007c
Make options #[serde(default)]
ShellWowza May 10, 2022
7fc336a
Merge branch 'upstream-pr/remove-chrono-dependency' of https://github…
Jun 29, 2022
d47088e
Merge branch 'master' of https://github.com/ThouCheese/cloud-storage-rs
Jun 29, 2022
e335728
Add customizable reqwest client passing
alexpusch Aug 23, 2022
adcde09
Add ClientBuilder and support a configureable reqwest client
alexpusch Aug 26, 2022
87261d5
Implementation of url parameters for object CRUD operations
SergenN Sep 23, 2022
b319da0
Updated Readme file
SergenN Sep 23, 2022
e66987c
Merge branch 'ThouCheese:master' into master
ohadravid Mar 6, 2023
197122b
Add missing GCP locations
ohadravid Mar 6, 2023
e3cdffb
Merge branch 'master' of https://github.com/ThouCheese/cloud-storage-rs
Mar 20, 2023
df09492
Merge pull request #1 from alexpusch/master
SonnyX Apr 26, 2023
2ad314d
Merge pull request #2 from SergenN/master
SonnyX Apr 26, 2023
12c4e0f
Merge pull request #3 from Elykz/master
SonnyX Apr 28, 2023
2c47ab1
Merge pull request #4 from trigovision/master
SonnyX Apr 28, 2023
e8ef677
Update ergonomics of API, move models to seperate files, update depen…
SonnyX May 2, 2023
4dd9a71
fix ObjectClient
SonnyX May 2, 2023
d9d4b98
Fix warnings
SonnyX May 2, 2023
0fc5805
Make models public
SonnyX May 2, 2023
227f0b1
export time, so implementing libraries can use it
SonnyX May 2, 2023
b3a469b
unwrap_or_default
SonnyX May 3, 2023
e0be0e4
Fix the library
SonnyX May 3, 2023
36dac76
Fix the sync module
SonnyX May 4, 2023
e6eb452
Update ReadMe.md
SonnyX May 4, 2023
343db5c
Update changelog
SonnyX May 4, 2023
1f25e3d
Update documenation to reflect changes
SonnyX May 4, 2023
3637c98
minor updates
SonnyX May 4, 2023
86f65a7
Add missing locations
SonnyX May 19, 2023
0e7a16b
Don't unwrap on dotenv(), convert to option instead
SonnyX May 25, 2023
4652ad1
Remove unstable feature try_trait2
SonnyX Jun 14, 2023
e51adbe
fix clippy
SonnyX Jun 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
# Required for linking openssl on windows, has no effect on other platforms.
VCPKGRS_DYNAMIC="1"
12 changes: 5 additions & 7 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,24 @@ jobs:

steps:
- uses: actions/checkout@v2

# - name: Run cargo fmt
# uses: actions-rs/cargo@v1
# with:
# command: fmt
# args: -- --check

- name: Run cargo clippy
uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: -- -D warnings
- name: Create Secret
run: 'echo "$SECRET_FILE" > auth.json'
env:
SECRET_FILE: ${{secrets.GOOGLE_APPLICATION_CREDENTIALS}}
- name: Create Test File
run: 'echo "Temporary test text to test the transfer." > myemma.txt'

- name: Build
run: cargo build

- name: Run tests
run: cargo test ${{ matrix.features }} -- --test-threads=1
env:
GOOGLE_APPLICATION_CREDENTIALS: auth.json
SERVICE_ACCOUNT_JSON: ${{secrets.GOOGLE_APPLICATION_CREDENTIALS}}
TEST_BUCKET: cloud-storage-rs-test-bucket
64 changes: 0 additions & 64 deletions .rustfmt.toml

This file was deleted.

27 changes: 18 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# 1.0.0
* Refactored the library to have one model per file, to improve maintainabillity.
* Refactor the library to use less static variables (mainly ServiceAccount)
* Made the unmaintained dependency `dotenv` optional
* Provided a new way to load in ServiceAccount configuration: `ServiceAccount::from_str()`
* Dramatically improved download performance by streaming an array of bytes, rather than a single byte per poll
* Moved variables used by all functions in a client to the constructor of the client, most commonly the bucket
* Added a ClientBuilder by [@alexpusch](https://github.com/alexpusch)
* Replaced `chrono` with `time` by [@Elykz](https://github.com/Elykz)
* Added optional QueryParameters to be sent along with the requests by [@SergenN](https://github.com/SergenN)
* Added missing GCP locations by [@trigovision](https://github.com/trigovision)

# 0.9
Refactor the library away from having a single global client, but provide a client of our own that
the user of the library is responsible for. This means that the user has control over the allocation
and destruction of the client. This solves issue #60 and is enabled due to tireless work by
shepmaster. Big thanks!
* Refactor the library away from having a single global client, but provide a client of our own that the user of the library is responsible for. This means that the user has control over the allocation and destruction of the client. This solves issue #60 and is enabled due to tireless work by shepmaster. Big thanks!

# 0.10
Small fix to the public interface of `sync::ObjectClient` that was not properly sync.
Fix urlencoding url paths correctly in several places.
Update cloud storage to use the new url, `www.googleapis.com` => `storage.googleapis.com`
* Small fix to the public interface of `sync::ObjectClient` that was not properly sync.
* Fix urlencoding url paths correctly in several places.
* Update cloud storage to use the new url, `www.googleapis.com` => `storage.googleapis.com`

# 0.11
@pseguin2011: Implemented a configurable authentication layer through the `TokenCache` trait.
* [@pseguin2011](https://github.com/pseguin2011): Implemented a configurable authentication layer through the `TokenCache` trait.

# 0.12
Implement customisable authentication providers, via the `Client::with_cache` method.
* Implement customisable authentication providers, via the `Client::with_cache` method.
49 changes: 25 additions & 24 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
[package]
name = "cloud-storage"
version = "0.11.1"
authors = ["Luuk Wester <[email protected]>"]
edition = "2018"
version = "1.0.0"
authors = ["Luuk Wester <[email protected]>", "SonnyX <[email protected]>"]
edition = "2021"
description = "A crate for uploading files to Google cloud storage, and for generating download urls."
license = "MIT"
repository = "https://github.com/ThouCheese/cloud-storage-rs"
documentation = "https://docs.rs/cloud-storage"
keywords = ["google", "cloud", "storage"]
readme = "README.md"
categories = ["api-bindings", "web-programming"]
resolver = "2"
# maintenance = { status = "actively-developed" }

[features]
default = ["native-tls"]
default = ["rustls-tls", "global-client", "sync", "dotenv"]

global-client = []
sync = ["reqwest/blocking"]
Expand All @@ -23,26 +22,28 @@ rustls-tls = ["reqwest/rustls-tls", "ring", "pem"]
trust-dns = ["reqwest/trust-dns"]

[dependencies]
reqwest = { version = "0.11", default-features = false, features = ["json", "stream"] }
percent-encoding = { version = "2", default-features = false }
jsonwebtoken = { version = "7", default-features = false }
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = { version = "1", default-features = false }
base64 = { version = "0.13", default-features = false }
lazy_static = { version = "1", default-features = false }
dotenv = { version = "0.15", default-features = false }
openssl = { version = "0.10", default-features = false, optional = true }
ring = { version = "0.16", default-features = false, optional = true }
pem = { version = "0.8", default-features = false, optional = true }
chrono = { version = "0.4", default-features = false, features = ["serde"] }
hex = { version = "0.4", default-features = false, features = ["alloc"] }
tokio = { version = "1.0", default-features = false, features = ["macros", "rt"] }
futures-util = { version = "0.3", default_features = false, features = ["alloc"] }
bytes = { version = "1.0", default-features = false }
async-trait = { version = "0.1.48", default-features = false }
reqwest = { version = "0.11.16", default-features = false, features = ["json", "stream", "multipart"] }
percent-encoding = { version = "2.2.0", default-features = false }
jsonwebtoken = { version = "8.3.0", default-features = false, features = ["use_pem"] }
serde = { version = "1.0.160", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.96", default-features = false }
base64 = { version = "0.21.0", default-features = false }
once_cell = { version = "1.17.1", default-features = false }
time = { version = "0.3.20", default-features = false, features = ["serde", "formatting", "parsing"]}
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
tokio = { version = "1.28.0", default-features = false, features = ["macros", "rt"] }
tokio-util = { version = "0.7.8", default-features = false, features = ["compat"] }
futures-util = { version = "0.3.28", default_features = false, features = ["alloc"] }
bytes = { version = "1.4.0", default-features = false }
async-trait = { version = "0.1.68", default-features = false }
# Optional features
openssl = { version = "0.10.52", default-features = false, optional = true }
ring = { version = "0.16.20", default-features = false, optional = true }
pem = { version = "2.0.1", default-features = false, optional = true, features = ["std"] }
dotenv = { version = "0.15.0", default-features = false, optional = true }

[dev-dependencies]
tokio = { version = "1.0", default-features = false, features = ["full"] }
tokio = { version = "1.28.0", default-features = false, features = ["full"] }

[package.metadata.docs.rs]
features = ["global-client", "sync"]
features = ["global-client", "sync"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 Luuk Wester
Copyright (c) 2023 Luuk Wester

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,42 @@ A library that can be used to push blobs to [Google Cloud Storage](https://cloud
Add the following line to your Cargo.toml
```toml
[dependencies]
cloud-storage = "0.10"
cloud-storage = "1.0.0"
```
### Examples
```rust
// create a new Bucket
let new_bucket = NewBucket { name: "mybucket", ..Default::default() }
let bucket = Bucket::create(new_bucket).await?;
let new_bucket = create::Bucket { name: "my_bucket".to_string(), ..Default::default() };
let bucket = Bucket::create(&new_bucket).await?;
// upload a file to our new bucket
let content = b"Your file is now on google cloud storage!";
bucket.upload(content, "folder/filename.txt", "application/text").await?;
let mut object = Object::create("mybucket", content, "folder/filename.txt", "application/text").await?;
let content = b"Your file is now on google cloud storage!".to_vec();
let object = Object::create(&bucket.name, content, "folder/filename.txt", "application/text", None).await?;
// let's copy the file
object.copy("mybucket2: electric boogaloo", "otherfolder/filename.txt").await?;
object.copy("my_other_bucket", "otherfolder/filename.txt", None).await?;
// print a link to the file
println!("{}", object.download_url(1000)); // download link for 1000 seconds
println!("{}", object.download_url(1000)?); // download link that expires after 1000 seconds
// remove the file from the bucket
object.delete().await?;
Object::delete(&bucket.name, "folder/filename.txt", None).await?;
```

Authorization can be granted using the `SERVICE_ACCOUNT` or `GOOGLE_APPLICATION_CREDENTIALS` environment variable, which should contain path to the `service-account-*******.json` file that contains the Google credentials. Alternatively, the service account credentials can be provided as JSON directly through the `SERVICE_ACCOUNT_JSON` or `GOOGLE_APPLICATION_CREDENTIALS_JSON` environment variable, which is useful when providing secrets in CI or k8s.
When using `CloudStorageClient::default()`, `sync::CloudStorageClient::new()` or the global client, an ServiceAccount will be created based on either of the environmental variables:
* `SERVICE_ACCOUNT` or `GOOGLE_APPLICATION_CREDENTIALS` which should contain path to the `service-account-*******.json`
* `SERVICE_ACCOUNT_JSON` or `GOOGLE_APPLICATION_CREDENTIALS_JSON` containing the contents of `service-account-*******.json`

The service account should also have the roles `Service Account Token Creator` (for generating access tokens) and `Storage Object Admin` (for generating sign urls to download the files).
The service account requires the roles `Service Account Token Creator` (for generating access tokens) and `Storage Object Admin` (for generating signed urls to download the files).

### Sync
If you're not (yet) interested in running an async executor, then `cloud_storage` exposes a sync api. To use it, enable the feature flag `sync`, and then call instead of calling `function().await`, call `function_sync()`.

You will need to set both the `global-client` and `sync` flags in your Cargo.toml, for example:

```
cloud-storage = { version = "0.11.0", features = ["global-client", "sync"] }
cloud-storage = { version = "1.0.0", features = ["global-client", "sync"] }
```

### Testing
To run the tests for this project, first create an enviroment parameter (or entry in the .env file) named TEST_BUCKET. Make sure that this name is not already in use! The tests will create this bucket for its testing purposes. It will also create a couple of other buckets with this name as prefix, but these will be deleted again. Next, you will need a Google Cloud Storage project, for which you must create a service account. Download the service-account.json file and place the path to the file in the `SERVICE_ACCOUNT` environment parameter. Then, run
```bash
sh test.sh
```
The `test-threads=1` is necessary so that the tests don't exceed the 2 per second bucket creating rate limit. (Depending on your internet speed, you may be able to use more than 1 test thread)
The `test-threads=1` is necessary so that the tests don't exceed the 2 per second bucket creating rate limit. (Depending on your internet speed, you may be able to use more than 1 test thread)
3 changes: 3 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
imports_granularity = "Crate"
edition = "2021"
error_on_line_overflow = true
1 change: 1 addition & 0 deletions src/builders/bucket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use crate::Error;
1 change: 1 addition & 0 deletions src/builders/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod bucket;
106 changes: 0 additions & 106 deletions src/client.rs

This file was deleted.

Loading