b2-client 1.0.6 → 1.0.7
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/lib/b2.rb +9 -1
- data/lib/b2/api_connection.rb +28 -11
- data/lib/b2/bucket.rb +4 -4
- data/lib/b2/connection.rb +36 -32
- data/lib/b2/errors.rb +3 -0
- data/lib/b2/file.rb +1 -9
- data/lib/b2/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70e5dc6cc5de5772f02f575cceefa1137ce7750cf2042067c6e06d1809e0758f
|
4
|
+
data.tar.gz: 96e70fb4bbd010ff178a3ac506a62cf5dd85c65d9c6477c78c89687aeda21b5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7908671a61289946d1330ffa0668d38c0952607ab07932520abb3791ff6a217c8ded4b97e66f2b98784368dac62a55aa412ed636ee386bade7d37c80b013c729
|
7
|
+
data.tar.gz: 5e38e319103709afaca046533501b82f30050b48db439ac927bfc67b0fd0ce7f222327c439092236658f821aa3e025d457280acbaf7b1f1faa57cffeb12f0e95
|
data/lib/b2.rb
CHANGED
@@ -11,6 +11,14 @@ require File.expand_path('../b2/upload_chunker', __FILE__)
|
|
11
11
|
|
12
12
|
class B2
|
13
13
|
|
14
|
+
def self.encode(value)
|
15
|
+
URI.encode_www_form_component(value.force_encoding(Encoding::UTF_8)).gsub("%2F", "/")
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.decode(value)
|
19
|
+
URI.decode_www_form_component(value, Encoding::UTF_8)
|
20
|
+
end
|
21
|
+
|
14
22
|
def initialize(key_id: , secret: )
|
15
23
|
@connection = B2::Connection.new(key_id, secret)
|
16
24
|
end
|
@@ -67,7 +75,7 @@ class B2
|
|
67
75
|
chunker = B2::UploadChunker.new(io_or_string)
|
68
76
|
req = Net::HTTP::Post.new(uri.path)
|
69
77
|
req['Authorization'] = upload['authorizationToken']
|
70
|
-
req['X-Bz-File-Name'] = B2
|
78
|
+
req['X-Bz-File-Name'] = B2.encode(key)
|
71
79
|
req['Content-Type'] = mime_type || 'b2/x-auto'
|
72
80
|
req['X-Bz-Content-Sha1'] = 'hex_digits_at_end'
|
73
81
|
info.each do |key, value|
|
data/lib/b2/api_connection.rb
CHANGED
@@ -34,7 +34,6 @@ class B2
|
|
34
34
|
@recommended_part_size = resp['recommendedPartSize']
|
35
35
|
@auth_token = resp['authorizationToken']
|
36
36
|
@download_url = resp['downloadUrl']
|
37
|
-
@buckets_cache = []
|
38
37
|
end
|
39
38
|
|
40
39
|
def account_id
|
@@ -73,24 +72,42 @@ class B2
|
|
73
72
|
end
|
74
73
|
|
75
74
|
def send_request(request, body=nil, &block)
|
75
|
+
retries = 0
|
76
76
|
request['Authorization'] = authorization_token
|
77
77
|
request.body = (body.is_a?(String) ? body : JSON.generate(body)) if body
|
78
78
|
|
79
79
|
return_value = nil
|
80
80
|
close_connection = false
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
81
|
+
begin
|
82
|
+
connection.request(request) do |response|
|
83
|
+
close_connection = response['Connection'] == 'close'
|
84
|
+
|
85
|
+
case response
|
86
|
+
when Net::HTTPSuccess
|
87
|
+
if block_given?
|
88
|
+
return_value = yield(response)
|
89
|
+
else
|
90
|
+
return_value = JSON.parse(response.body)
|
91
|
+
end
|
88
92
|
else
|
89
|
-
|
93
|
+
body = JSON.parse(response.body)
|
94
|
+
case body['code']
|
95
|
+
when 'not_found'
|
96
|
+
raise B2::NotFound(body['message'])
|
97
|
+
when 'expired_auth_token'
|
98
|
+
raise B2::ExpiredAuthToken(body['message'])
|
99
|
+
else
|
100
|
+
raise "Error connecting to B2 API #{response.body}"
|
101
|
+
end
|
90
102
|
end
|
91
|
-
else
|
92
|
-
raise "Error connecting to B2 API #{response.body}"
|
93
103
|
end
|
104
|
+
|
105
|
+
# Unexpected EOF (end of file) errors can occur when streaming from a
|
106
|
+
# remote because of Backblaze quota restrictions.
|
107
|
+
rescue B2::ExpiredAuthToken, EOFError
|
108
|
+
reconnect!
|
109
|
+
retries =+ 1
|
110
|
+
retry if retries < 2
|
94
111
|
end
|
95
112
|
disconnect! if close_connection
|
96
113
|
|
data/lib/b2/bucket.rb
CHANGED
@@ -27,12 +27,12 @@ class B2
|
|
27
27
|
chunker = sha1 ? io_or_string : B2::UploadChunker.new(io_or_string)
|
28
28
|
req = Net::HTTP::Post.new(uri.path)
|
29
29
|
req['Authorization'] = upload['authorizationToken']
|
30
|
-
req['X-Bz-File-Name'] = B2
|
30
|
+
req['X-Bz-File-Name'] = B2.encode(key)
|
31
31
|
req['Content-Type'] = mime_type || 'b2/x-auto'
|
32
32
|
req['X-Bz-Content-Sha1'] = sha1 ? sha1 : 'hex_digits_at_end'
|
33
|
-
req['X-Bz-Info-b2-content-disposition'] = content_disposition if content_disposition
|
33
|
+
req['X-Bz-Info-b2-content-disposition'] = B2.encode(content_disposition) if content_disposition
|
34
34
|
info.each do |key, value|
|
35
|
-
req["X-Bz-Info-#{key}"] = value
|
35
|
+
req["X-Bz-Info-#{key}"] = B2.encode(value)
|
36
36
|
end
|
37
37
|
req['Content-Length'] = chunker.size
|
38
38
|
req.body_stream = chunker
|
@@ -41,7 +41,7 @@ class B2
|
|
41
41
|
result = if resp.is_a?(Net::HTTPSuccess)
|
42
42
|
JSON.parse(resp.body)
|
43
43
|
else
|
44
|
-
raise "Error connecting to B2 API"
|
44
|
+
raise "Error connecting to B2 API #{resp.body}"
|
45
45
|
end
|
46
46
|
|
47
47
|
B2::File.new(result, @connection)
|
data/lib/b2/connection.rb
CHANGED
@@ -15,7 +15,7 @@ class B2
|
|
15
15
|
@key_id = key_id
|
16
16
|
@key_secret = secret
|
17
17
|
|
18
|
-
@buckets_cache = []
|
18
|
+
@buckets_cache = Hash.new { |hash, name| hash[name] = bucket(name) }
|
19
19
|
end
|
20
20
|
|
21
21
|
def account_id
|
@@ -65,13 +65,17 @@ class B2
|
|
65
65
|
B2::Bucket.new(b, self)
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
69
|
+
def bucket(name)
|
70
|
+
response = post('/b2api/v2/b2_list_buckets', {
|
71
|
+
accountId: account_id,
|
72
|
+
bucketName: name
|
73
|
+
})['buckets']
|
74
|
+
response.map { |b| B2::Bucket.new(b, self) }.first
|
75
|
+
end
|
68
76
|
|
69
77
|
def lookup_bucket_id(name)
|
70
|
-
|
71
|
-
return bucket.id if bucket
|
72
|
-
|
73
|
-
@buckets_cache = buckets
|
74
|
-
@buckets_cache.find{ |b| b.name == name }&.id
|
78
|
+
@buckets_cache[name].id
|
75
79
|
end
|
76
80
|
|
77
81
|
def get_download_url(bucket, filename, expires_in: 3_600, disposition: nil)
|
@@ -99,38 +103,38 @@ class B2
|
|
99
103
|
req = Net::HTTP::Get.new("/file/#{bucket}/#{key}")
|
100
104
|
req['Authorization'] = authorization_token
|
101
105
|
conn.start do |http|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
106
|
+
http.request(req) do |response|
|
107
|
+
case response
|
108
|
+
when Net::HTTPSuccess
|
109
|
+
response.read_body do |chunk|
|
110
|
+
digestor << chunk
|
111
|
+
if to
|
112
|
+
to << chunk
|
113
|
+
elsif block_given?
|
114
|
+
yield(chunk)
|
115
|
+
else
|
116
|
+
data << chunk
|
117
|
+
end
|
113
118
|
end
|
114
|
-
end
|
115
119
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
if response['X-Bz-Content-Sha1'] != 'none' && digestor.hexdigest != response['X-Bz-Content-Sha1']
|
121
|
+
rase B2::FileIntegrityError.new("SHA1 Mismatch, expected: \"#{response['X-Bz-Content-Sha1']}\", actual: \"#{digestor.hexdigest}\"")
|
122
|
+
end
|
123
|
+
when Net::HTTPNotFound
|
124
|
+
raise B2::NotFound.new(JSON.parse(response.body)['message'])
|
125
|
+
else
|
126
|
+
begin
|
127
|
+
body = JSON.parse(response.body)
|
124
128
|
if body['code'] == 'not_found'
|
125
|
-
|
126
|
-
|
127
|
-
|
129
|
+
raise B2::NotFound(body['message'])
|
130
|
+
else
|
131
|
+
raise "#{body['code']} (#{body['message']})"
|
132
|
+
end
|
133
|
+
rescue
|
134
|
+
raise response.body
|
128
135
|
end
|
129
|
-
rescue
|
130
|
-
raise response.body
|
131
136
|
end
|
132
137
|
end
|
133
|
-
end
|
134
138
|
end
|
135
139
|
|
136
140
|
if opened_file
|
data/lib/b2/errors.rb
CHANGED
data/lib/b2/file.rb
CHANGED
@@ -5,7 +5,7 @@ class B2
|
|
5
5
|
|
6
6
|
def initialize(attrs, connection)
|
7
7
|
@id = attrs['fileId']
|
8
|
-
@name = B2
|
8
|
+
@name = B2.decode(attrs['fileName'])
|
9
9
|
@account_id = attrs['accountId']
|
10
10
|
@bucket_id = attrs['bucketId']
|
11
11
|
@size = attrs['contentLength']
|
@@ -17,14 +17,6 @@ class B2
|
|
17
17
|
@connection = connection
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.encode_filename(str)
|
21
|
-
URI.encode_www_form_component(str.force_encoding(Encoding::UTF_8)).gsub("%2F", "/")
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.decode_filename(str)
|
25
|
-
URI.decode_www_form_component(str, Encoding::UTF_8)
|
26
|
-
end
|
27
|
-
|
28
20
|
def delete!
|
29
21
|
@connection.post('/b2api/v2/b2_delete_file_version', {
|
30
22
|
fileId: @id,
|
data/lib/b2/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: b2-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -48,7 +48,7 @@ homepage: https://github.com/malomalo/b2
|
|
48
48
|
licenses:
|
49
49
|
- MIT
|
50
50
|
metadata: {}
|
51
|
-
post_install_message:
|
51
|
+
post_install_message:
|
52
52
|
rdoc_options: []
|
53
53
|
require_paths:
|
54
54
|
- lib
|
@@ -63,8 +63,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
63
|
- !ruby/object:Gem::Version
|
64
64
|
version: '0'
|
65
65
|
requirements: []
|
66
|
-
rubygems_version: 3.
|
67
|
-
signing_key:
|
66
|
+
rubygems_version: 3.1.2
|
67
|
+
signing_key:
|
68
68
|
specification_version: 4
|
69
69
|
summary: Backblaze B2 Client
|
70
70
|
test_files: []
|