azure-blob 0.4.1 → 0.5.0
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/.terraform.lock.hcl +22 -0
- data/CHANGELOG.md +15 -2
- data/README.md +94 -22
- data/Rakefile +51 -1
- data/azure-blob.gemspec +3 -2
- data/devenv.lock +11 -11
- data/devenv.nix +27 -3
- data/devenv.yaml +1 -1
- data/input.tf +44 -0
- data/lib/active_storage/service/azure_blob_service.rb +4 -4
- data/lib/azure_blob/blob.rb +7 -0
- data/lib/azure_blob/blob_list.rb +18 -0
- data/lib/azure_blob/block_list.rb +3 -1
- data/lib/azure_blob/canonicalized_headers.rb +1 -1
- data/lib/azure_blob/canonicalized_resource.rb +1 -1
- data/lib/azure_blob/client.rb +126 -5
- data/lib/azure_blob/entra_id_signer.rb +115 -0
- data/lib/azure_blob/http.rb +19 -3
- data/lib/azure_blob/identity_token.rb +65 -0
- data/lib/azure_blob/metadata.rb +1 -1
- data/lib/azure_blob/{signer.rb → shared_key_signer.rb} +6 -6
- data/lib/azure_blob/user_delegation_key.rb +67 -0
- data/lib/azure_blob/version.rb +1 -1
- data/main.tf +187 -0
- data/output.tf +30 -0
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94edcaaaa7717925c1fb8238b9e7420949b26c98c90344cbf54930d5e0ff3b19
|
4
|
+
data.tar.gz: aae153da753212659590ed4a3ae029c86cf7ed66b4f924dac1a5f3a5ff3b2e05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 102c3d5fd08761199413e96bd8e4bae8a84ac5478d7bb1202e232fbff346703f7cb3b8f344553983b607dbacec56942452ce18aa0afc184a4c994d31dc94118c
|
7
|
+
data.tar.gz: 646636874dd381757595f82999dd0b7b5647a740512c8e2baf86bdc2045e579cdf78354a4690c746452280efb7ff92cbf9c49c95775ccbcf6a690eb0ae05131f
|
data/.terraform.lock.hcl
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file is maintained automatically by "terraform init".
|
2
|
+
# Manual edits may be lost in future updates.
|
3
|
+
|
4
|
+
provider "registry.terraform.io/hashicorp/azurerm" {
|
5
|
+
version = "3.113.0"
|
6
|
+
constraints = "~> 3.0"
|
7
|
+
hashes = [
|
8
|
+
"h1:eEUtt0lrLdpVaF6FiDq8BGQPgEcykmhj0aNIL7hTOGw=",
|
9
|
+
"zh:12479f5664288943400447b55e50df675c28ae82ad8d373cc2e5682f3a3411f0",
|
10
|
+
"zh:1b42a14e80e568429d3b55fed753ca3ef0df9dcdfa107890d7264599c020940f",
|
11
|
+
"zh:381be6ca617f848de3baa3985a6e1788e91a803afe04a3c5c727453528b6310d",
|
12
|
+
"zh:3e70e2e07b6db1c363de3e5d0ca47f27fc956473df03329c7d2e54d3ac29176b",
|
13
|
+
"zh:87c7633aeaa828098c6055da9e67d4acaf4b46748b6b3f0267e105e55f05de25",
|
14
|
+
"zh:8d0d98226901f874770dd5220d4701a12ae8bd586994615aa7dcba12b9736bec",
|
15
|
+
"zh:9fd913acd42a60c3a90a18ce803567ef861db8779a59aacced91f2cbd86de9d9",
|
16
|
+
"zh:b6f3f7ae0a055437fb36c139af9bb3135e7f4dad172157ae1eb0177dc74d703f",
|
17
|
+
"zh:b927027ba2bf40d34e03d742fd2b6c5299023b5ab8e6f05e50aac76a46ad1094",
|
18
|
+
"zh:ceb5187b9d2a439f4e48944f3ffeeeaf47a03dbe6f3325ea1775bf659ce0aa88",
|
19
|
+
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
20
|
+
"zh:fb9d78dfeca7489bffca9b1a1f3abee7f16dbbcba31388aea1102062c1d6dce8",
|
21
|
+
]
|
22
|
+
}
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.
|
3
|
+
## [0.5.0] 2024-09-09
|
4
4
|
|
5
|
-
-
|
5
|
+
- Added support for Managed Identities (Entra ID)
|
6
|
+
|
7
|
+
## [0.4.2] 2024-06-06
|
8
|
+
|
9
|
+
- Documentation
|
10
|
+
- Fix an issue with integrity check on multi block upload
|
11
|
+
|
12
|
+
|
13
|
+
## [0.4.1] 2024-05-27
|
14
|
+
|
15
|
+
First working release.
|
16
|
+
|
17
|
+
- Re-implemented the required parts of the azure-storage-blob API to make Active Storage work.
|
18
|
+
- Extracted the AzureStorage adapter from Rails.
|
data/README.md
CHANGED
@@ -2,41 +2,113 @@
|
|
2
2
|
|
3
3
|
This gem was built to replace azure-storage-blob (deprecated) in Active Storage, but was written to be Rails agnostic.
|
4
4
|
|
5
|
+
## Active Storage
|
6
|
+
|
7
|
+
### Migration
|
8
|
+
To migrate from azure-storage-blob to azure-blob:
|
9
|
+
|
10
|
+
1. Replace `azure-storage-blob` in your Gemfile with `azure-blob`
|
11
|
+
2. Run `bundle install`
|
12
|
+
3. Change the `AzureStorage` service to `AzureBlob` in your Active Storage config (`config/storage.yml`)
|
13
|
+
4. Restart or deploy the app.
|
14
|
+
|
15
|
+
### Managed Identity (Entra ID)
|
16
|
+
|
17
|
+
AzureBlob supports managed identities on :
|
18
|
+
- Azure VM
|
19
|
+
- App Service
|
20
|
+
- Azure Functions (Untested but should work)
|
21
|
+
- Azure Containers (Untested but should work)
|
22
|
+
|
23
|
+
AKS support will likely require more work. Contributions are welcome.
|
24
|
+
|
25
|
+
To authenticate through managed identities instead of a shared key, omit `storage_access_key` from your `storage.yml` file.
|
26
|
+
|
27
|
+
It is recommended to add the identity's `principal_id` to the config.
|
28
|
+
|
29
|
+
ActiveStorage config example:
|
30
|
+
|
31
|
+
```
|
32
|
+
prod:
|
33
|
+
service: AzureBlob
|
34
|
+
container: container_name
|
35
|
+
storage_account_name: account_name
|
36
|
+
principal_id: 71b34410-4c50-451d-b456-95ead1b18cce
|
37
|
+
```
|
38
|
+
|
39
|
+
## Standalone
|
40
|
+
|
41
|
+
Instantiate a client with your account name, an access key and the container name:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
client = AzureBlob::Client.new(
|
45
|
+
account_name: @account_name,
|
46
|
+
access_key: @access_key,
|
47
|
+
container: @container,
|
48
|
+
)
|
49
|
+
|
50
|
+
path = "some/new/file"
|
51
|
+
|
52
|
+
# Upload
|
53
|
+
client.create_block_blob(path, "Hello world!")
|
54
|
+
|
55
|
+
# Download
|
56
|
+
client.get_blob(path) #=> "Hello world!"
|
57
|
+
|
58
|
+
# Delete
|
59
|
+
client.delete_blob(path)
|
60
|
+
```
|
61
|
+
|
62
|
+
For the full list of methods: https://www.rubydoc.info/gems/azure-blob/AzureBlob/Client
|
63
|
+
|
5
64
|
## Contributing
|
6
65
|
|
7
|
-
###
|
66
|
+
### Dev environment
|
8
67
|
|
9
|
-
|
68
|
+
A dev environment is supplied through Nix with [devenv](https://devenv.sh/).
|
10
69
|
|
11
|
-
|
70
|
+
1. Install [devenv](https://devenv.sh/).
|
71
|
+
2. Enter the dev environment by cd into the repo and running `devenv shell` (or `direnv allow` if you are a direnv user).
|
72
|
+
3. Log into azure CLI with `az login`
|
73
|
+
4. `terraform init`
|
74
|
+
5. `terraform apply` This will generate the necessary infrastructure on azure.
|
75
|
+
6. Generate devenv.local.nix with your private key and container information: `generate-env-file`
|
76
|
+
7. If you are using direnv, the environment will reload automatically. If not, exit the shell and reopen it by hitting <C-d> and running `devenv shell` again.
|
12
77
|
|
13
|
-
|
14
|
-
- `AZURE_ACCESS_KEY`
|
15
|
-
- `AZURE_PRIVATE_CONTAINER`
|
16
|
-
- `AZURE_PUBLIC_CONTAINER`
|
78
|
+
#### Entra ID
|
17
79
|
|
80
|
+
To test with Entra ID, the `AZURE_ACCESS_KEY` environment variable must be unset and the code must be ran or proxied through a VPS with the proper roles.
|
18
81
|
|
19
|
-
|
82
|
+
For cost saving, the terraform variable `create_vm` is false by default.
|
83
|
+
To create the VPS, Create a var file `var.tfvars` containing:
|
20
84
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
4- Start the shell with `devenv shell` or with [direnv](https://direnv.net/).
|
85
|
+
```
|
86
|
+
create_vm = true
|
87
|
+
```
|
88
|
+
and re-apply terraform: `terraform apply -var-file=var.tfvars`.
|
26
89
|
|
27
|
-
|
90
|
+
This will create the VPS and required managed identities.
|
28
91
|
|
29
|
-
`bin/rake test
|
92
|
+
`bin/rake test_azure_vm` and `bin/rake test_app_service` will establish a VPN connection to the VM or App service container and run the test suite. You might be prompted for a sudo password when the VPN starts (sshuttle).
|
30
93
|
|
31
|
-
|
94
|
+
After you are done, run terraform again without the var file (`terraform apply`) to destroy the VPS and App service application.
|
32
95
|
|
33
|
-
|
34
|
-
|
96
|
+
#### Cleanup
|
97
|
+
|
98
|
+
Some tests copied over from Rails don't clean after themselves. A rake task is provided to empty your containers and keep cost low: `bin/rake flush_test_container`
|
99
|
+
|
100
|
+
#### Run without devenv/nix
|
35
101
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
102
|
+
If you prefer not using devenv/nix:
|
103
|
+
|
104
|
+
Ensure your version of Ruby fit the minimum version in `azure-blob.gemspec`
|
105
|
+
|
106
|
+
and setup those Env variables:
|
107
|
+
|
108
|
+
- `AZURE_ACCOUNT_NAME`
|
109
|
+
- `AZURE_ACCESS_KEY`
|
110
|
+
- `AZURE_PRIVATE_CONTAINER`
|
111
|
+
- `AZURE_PUBLIC_CONTAINER`
|
40
112
|
|
41
113
|
## License
|
42
114
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,57 @@
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "minitest/test_task"
|
5
|
+
require "azure_blob"
|
6
|
+
require_relative "test/support/app_service_vpn"
|
7
|
+
require_relative "test/support/azure_vm_vpn"
|
5
8
|
|
6
|
-
Minitest::TestTask.create
|
9
|
+
Minitest::TestTask.create(:test_rails) do
|
10
|
+
self.test_globs = [ "test/rails/**/test_*.rb",
|
11
|
+
"test/rails/**/*_test.rb", ]
|
12
|
+
end
|
13
|
+
|
14
|
+
Minitest::TestTask.create(:test_client) do
|
15
|
+
self.test_globs = [ "test/client/**/test_*.rb",
|
16
|
+
"test/client/**/*_test.rb", ]
|
17
|
+
end
|
7
18
|
|
8
19
|
task default: %i[test]
|
20
|
+
|
21
|
+
task :test do
|
22
|
+
Rake::Task["test_client"].execute
|
23
|
+
Rake::Task["test_rails"].execute
|
24
|
+
end
|
25
|
+
|
26
|
+
task :test_app_service do |t|
|
27
|
+
vpn = AppServiceVpn.new
|
28
|
+
ENV["IDENTITY_ENDPOINT"] = vpn.endpoint
|
29
|
+
ENV["IDENTITY_HEADER"] = vpn.header
|
30
|
+
Rake::Task["test_entra_id"].execute
|
31
|
+
ensure
|
32
|
+
vpn.kill
|
33
|
+
end
|
34
|
+
|
35
|
+
task :test_azure_vm do |t|
|
36
|
+
vpn = AzureVmVpn.new
|
37
|
+
Rake::Task["test_entra_id"].execute
|
38
|
+
ensure
|
39
|
+
vpn.kill
|
40
|
+
end
|
41
|
+
|
42
|
+
task :test_entra_id do |t|
|
43
|
+
ENV["AZURE_ACCESS_KEY"] = nil
|
44
|
+
Rake::Task["test"].execute
|
45
|
+
end
|
46
|
+
|
47
|
+
task :flush_test_container do |t|
|
48
|
+
AzureBlob::Client.new(
|
49
|
+
account_name: ENV["AZURE_ACCOUNT_NAME"],
|
50
|
+
access_key: ENV["AZURE_ACCESS_KEY"],
|
51
|
+
container: ENV["AZURE_PRIVATE_CONTAINER"],
|
52
|
+
).delete_prefix ""
|
53
|
+
AzureBlob::Client.new(
|
54
|
+
account_name: ENV["AZURE_ACCOUNT_NAME"],
|
55
|
+
access_key: ENV["AZURE_ACCESS_KEY"],
|
56
|
+
container: ENV["AZURE_PUBLIC_CONTAINER"],
|
57
|
+
).delete_prefix ""
|
58
|
+
end
|
data/azure-blob.gemspec
CHANGED
@@ -9,13 +9,14 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = [ "joe@dupuis.io" ]
|
10
10
|
|
11
11
|
spec.summary = "Azure blob client"
|
12
|
-
spec.homepage = "https://github.com/
|
12
|
+
spec.homepage = "https://github.com/testdouble/azure-blob"
|
13
13
|
spec.license = "MIT"
|
14
14
|
spec.required_ruby_version = ">= 3.1"
|
15
15
|
|
16
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
16
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
18
|
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
-
spec.metadata["changelog_uri"] = "https://github.com/
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/testdouble/azure-blob/blob/main/CHANGELOG.md"
|
19
20
|
|
20
21
|
spec.add_dependency "rexml"
|
21
22
|
|
data/devenv.lock
CHANGED
@@ -108,16 +108,16 @@
|
|
108
108
|
},
|
109
109
|
"nixpkgs": {
|
110
110
|
"locked": {
|
111
|
-
"lastModified":
|
111
|
+
"lastModified": 1725001927,
|
112
112
|
"owner": "NixOS",
|
113
113
|
"repo": "nixpkgs",
|
114
|
-
"rev": "
|
115
|
-
"treeHash": "
|
114
|
+
"rev": "6e99f2a27d600612004fbd2c3282d614bfee6421",
|
115
|
+
"treeHash": "1e85443cc9f0ba302df2cf61cacb8014943e2d19",
|
116
116
|
"type": "github"
|
117
117
|
},
|
118
118
|
"original": {
|
119
119
|
"owner": "NixOS",
|
120
|
-
"ref": "nixos-
|
120
|
+
"ref": "nixos-24.05",
|
121
121
|
"repo": "nixpkgs",
|
122
122
|
"type": "github"
|
123
123
|
}
|
@@ -129,11 +129,11 @@
|
|
129
129
|
"nixpkgs": "nixpkgs_2"
|
130
130
|
},
|
131
131
|
"locked": {
|
132
|
-
"lastModified":
|
132
|
+
"lastModified": 1724737223,
|
133
133
|
"owner": "bobvanderlinden",
|
134
134
|
"repo": "nixpkgs-ruby",
|
135
|
-
"rev": "
|
136
|
-
"treeHash": "
|
135
|
+
"rev": "175b5867babcbc471b94be9fd5576f2973bbdb6d",
|
136
|
+
"treeHash": "2fe3404ac0eeb7bcb7ac7b5f5f8b9b6a7e460147",
|
137
137
|
"type": "github"
|
138
138
|
},
|
139
139
|
"original": {
|
@@ -160,16 +160,16 @@
|
|
160
160
|
},
|
161
161
|
"nixpkgs_2": {
|
162
162
|
"locked": {
|
163
|
-
"lastModified":
|
163
|
+
"lastModified": 1725001927,
|
164
164
|
"owner": "NixOS",
|
165
165
|
"repo": "nixpkgs",
|
166
|
-
"rev": "
|
167
|
-
"treeHash": "
|
166
|
+
"rev": "6e99f2a27d600612004fbd2c3282d614bfee6421",
|
167
|
+
"treeHash": "1e85443cc9f0ba302df2cf61cacb8014943e2d19",
|
168
168
|
"type": "github"
|
169
169
|
},
|
170
170
|
"original": {
|
171
171
|
"owner": "NixOS",
|
172
|
-
"ref": "nixos-
|
172
|
+
"ref": "nixos-24.05",
|
173
173
|
"repo": "nixpkgs",
|
174
174
|
"type": "github"
|
175
175
|
}
|
data/devenv.nix
CHANGED
@@ -1,12 +1,36 @@
|
|
1
|
-
{ pkgs, ... }:
|
1
|
+
{ pkgs, config, ... }:
|
2
2
|
|
3
3
|
{
|
4
|
+
env = {
|
5
|
+
LD_LIBRARY_PATH = "${config.devenv.profile}/lib";
|
6
|
+
};
|
7
|
+
|
4
8
|
packages = with pkgs; [
|
5
9
|
git
|
6
10
|
libyaml
|
11
|
+
terraform
|
12
|
+
azure-cli
|
13
|
+
glib
|
14
|
+
vips
|
15
|
+
sshuttle
|
16
|
+
sshpass
|
17
|
+
rsync
|
7
18
|
];
|
8
19
|
|
9
|
-
|
10
20
|
languages.ruby.enable = true;
|
11
|
-
languages.ruby.version = "3.1.
|
21
|
+
languages.ruby.version = "3.1.6";
|
22
|
+
|
23
|
+
scripts.generate-env-file.exec = ''
|
24
|
+
terraform output -raw devenv_local_nix > devenv.local.nix
|
25
|
+
'';
|
26
|
+
|
27
|
+
scripts.proxy-vps.exec = ''
|
28
|
+
exec sshuttle -e "ssh -o CheckHostIP=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" -r "$(terraform output --raw vm_username)@$(terraform output --raw vm_ip)" 0/0
|
29
|
+
'';
|
30
|
+
|
31
|
+
scripts.start-app-service-ssh.exec = ''
|
32
|
+
resource_group=$(terraform output --raw "resource_group")
|
33
|
+
app_name=$(terraform output --raw "app_service_app_name")
|
34
|
+
exec az webapp create-remote-connection --resource-group $resource_group --name $app_name
|
35
|
+
'';
|
12
36
|
}
|
data/devenv.yaml
CHANGED
data/input.tf
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
variable "location" {
|
2
|
+
type = string
|
3
|
+
default = "westus2"
|
4
|
+
}
|
5
|
+
|
6
|
+
variable "prefix" {
|
7
|
+
type = string
|
8
|
+
default = "azure-blob"
|
9
|
+
}
|
10
|
+
|
11
|
+
variable "storage_account_name" {
|
12
|
+
type = string
|
13
|
+
default = "azureblobrubygemdev"
|
14
|
+
}
|
15
|
+
|
16
|
+
variable "create_vm" {
|
17
|
+
type = bool
|
18
|
+
default = false
|
19
|
+
}
|
20
|
+
|
21
|
+
variable "vm_size" {
|
22
|
+
type = string
|
23
|
+
default = "Standard_B2s"
|
24
|
+
}
|
25
|
+
|
26
|
+
variable "vm_username" {
|
27
|
+
type = string
|
28
|
+
default = "azureblob"
|
29
|
+
}
|
30
|
+
|
31
|
+
variable "vm_password" {
|
32
|
+
type = string
|
33
|
+
default = "qwe123QWE!@#"
|
34
|
+
}
|
35
|
+
|
36
|
+
variable "create_app_service" {
|
37
|
+
type = bool
|
38
|
+
default = false
|
39
|
+
}
|
40
|
+
|
41
|
+
variable "ssh_key" {
|
42
|
+
type = string
|
43
|
+
default = ""
|
44
|
+
}
|
@@ -25,17 +25,17 @@
|
|
25
25
|
require "active_support/core_ext/numeric/bytes"
|
26
26
|
require "active_storage/service"
|
27
27
|
|
28
|
-
require
|
28
|
+
require "azure_blob"
|
29
29
|
|
30
30
|
module ActiveStorage
|
31
|
-
# = Active Storage \Azure
|
31
|
+
# = Active Storage \Azure Blob \Service
|
32
32
|
#
|
33
33
|
# Wraps the Microsoft Azure Storage Blob Service as an Active Storage service.
|
34
|
-
# See ActiveStorage::Service for
|
34
|
+
# See {ActiveStorage::Service}[https://api.rubyonrails.org/classes/ActiveStorage/Service.html] for more details.
|
35
35
|
class Service::AzureBlobService < Service
|
36
36
|
attr_reader :client, :container, :signer
|
37
37
|
|
38
|
-
def initialize(storage_account_name:, storage_access_key
|
38
|
+
def initialize(storage_account_name:, storage_access_key: nil, container:, public: false, **options)
|
39
39
|
@container = container
|
40
40
|
@public = public
|
41
41
|
@client = AzureBlob::Client.new(
|
data/lib/azure_blob/blob.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module AzureBlob
|
4
|
+
# AzureBlob::Blob holds the metada for a given Blob.
|
4
5
|
class Blob
|
6
|
+
# You should not instanciate this object directly,
|
7
|
+
# but obtain one when calling relevant methods of AzureBlob::Client.
|
8
|
+
#
|
9
|
+
# Expects a Net::HTTPResponse object from a
|
10
|
+
# HEAD or GET request to a blob uri.
|
5
11
|
def initialize(response)
|
6
12
|
@response = response
|
7
13
|
end
|
@@ -26,6 +32,7 @@ module AzureBlob
|
|
26
32
|
response.code == "200"
|
27
33
|
end
|
28
34
|
|
35
|
+
# Returns the custom Azure metada tagged on the blob.
|
29
36
|
def metadata
|
30
37
|
@metadata || response
|
31
38
|
.to_hash
|
data/lib/azure_blob/blob_list.rb
CHANGED
@@ -3,10 +3,28 @@
|
|
3
3
|
require "rexml"
|
4
4
|
|
5
5
|
module AzureBlob
|
6
|
+
# Enumerator class to lazily iterate over a list of Blob keys.
|
6
7
|
class BlobList
|
7
8
|
include REXML
|
8
9
|
include Enumerable
|
9
10
|
|
11
|
+
# You should not instanciate this object directly,
|
12
|
+
# but obtain one when calling relevant methods of AzureBlob::Client.
|
13
|
+
#
|
14
|
+
# Expects a callable object that takes an Azure API page marker as an
|
15
|
+
# argument and returns the raw body response of a call to the list blob endpoint.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# fetcher = ->(marker) do
|
20
|
+
# uri.query = URI.encode_www_form(
|
21
|
+
# marker: marker,
|
22
|
+
# ...
|
23
|
+
# )
|
24
|
+
# response = Http.new(uri, signer:).get
|
25
|
+
# end
|
26
|
+
# AzureBlob::BlobList.new(fetcher)
|
27
|
+
#
|
10
28
|
def initialize(fetcher)
|
11
29
|
@fetcher = fetcher
|
12
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "cgi"
|
2
2
|
|
3
3
|
module AzureBlob
|
4
|
-
class CanonicalizedResource
|
4
|
+
class CanonicalizedResource # :nodoc:
|
5
5
|
def initialize(uri, account_name, service_name: nil, url_safe: true)
|
6
6
|
# This next line is needed because CanonicalizedResource
|
7
7
|
# need to be escaped for auhthorization headers, but not SAS tokens
|