hetznercloud 2.0.0 → 2.2.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/CHANGELOG.md +12 -0
- data/Gemfile +5 -0
- data/README.md +17 -1
- data/config/inflections.rb +1 -0
- data/lib/core_ext/send_wrap.rb +2 -0
- data/lib/hcloud/action_collection.rb +1 -0
- data/lib/hcloud/client.rb +7 -3
- data/lib/hcloud/collection.rb +1 -0
- data/lib/hcloud/concerns/actionable.rb +1 -0
- data/lib/hcloud/concerns/concerns.rb +1 -0
- data/lib/hcloud/concerns/creatable.rb +3 -2
- data/lib/hcloud/concerns/deletable.rb +1 -0
- data/lib/hcloud/concerns/dynamic_attributes.rb +1 -0
- data/lib/hcloud/concerns/labelable.rb +1 -0
- data/lib/hcloud/concerns/meterable.rb +1 -0
- data/lib/hcloud/concerns/queryable.rb +1 -0
- data/lib/hcloud/concerns/singleton.rb +1 -0
- data/lib/hcloud/concerns/updatable.rb +1 -0
- data/lib/hcloud/entities/floating_ip_prices.rb +1 -1
- data/lib/hcloud/entities/price.rb +2 -0
- data/lib/hcloud/entities/primary_ip_prices.rb +1 -1
- data/lib/hcloud/entity.rb +1 -0
- data/lib/hcloud/http.rb +16 -4
- data/lib/hcloud/resource.rb +10 -0
- data/lib/hcloud/resource_type.rb +4 -2
- data/lib/hcloud/resources/pricing.rb +1 -1
- data/lib/hcloud/resources/server_type.rb +5 -7
- data/lib/hcloud/version.rb +2 -1
- data/lib/http/features/block_io.rb +18 -0
- data/lib/http/features/compression.rb +86 -0
- data/lib/http/features/request/brotli_body.rb +29 -0
- data/lib/http/features/request/compressed_body.rb +55 -0
- data/lib/http/features/request/gzipped_body.rb +22 -0
- data/lib/http/features/response/brotli_inflater.rb +34 -0
- data/lib/http/features/response/gzip_inflater.rb +16 -0
- data/lib/http/mime_type/yaml.rb +3 -0
- data/lib/http/rate_limiter.rb +2 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34a83a28ff685be48e3c59036aec00189356152540e96e3f0cdcd87dd927ea65
|
4
|
+
data.tar.gz: c3b9f90bd3bf142961216555382e62452e4bb0141bfba3d7ac5d09b2cbc9f93b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54cc55c7d63d2dc949fe2112847a53184fb6155be571fcd1ec2940905536f2da2ffab94b7808bba2c3eb42775bce7a86a9b0057b1afdf98e60507f799e2e0db3
|
7
|
+
data.tar.gz: 48ac006b7ee34632ad52f177b2e89d1e260161311421c61fdd57e778791cf8d302a9276ead67ede50f2d022af7e2661af9ffc57a9c50fbabb07a4b334d83056f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## HCloud v2.2.0 (2024-08-22)
|
4
|
+
|
5
|
+
- Add support for (de-)compression of HTTP requests
|
6
|
+
|
7
|
+
## HCloud v2.1.0 (2024-07-28)
|
8
|
+
|
9
|
+
- Add `included_traffic` attribute to `ServerType#prices` and `LoadBalancerType#prices`
|
10
|
+
- Add `price_per_tb_traffic` attribute to `ServerType#prices` and `LoadBalancerType#prices`
|
11
|
+
- Add deprecation warning for `Pricing#traffic`
|
12
|
+
- Add deprecation warning for `ServerType#included_traffic`
|
13
|
+
- Fix crash on prices when using `Pricing` API
|
14
|
+
|
3
15
|
## HCloud v2.0.0 (2024-01-10)
|
4
16
|
|
5
17
|
- Remove `deprecated` attribute from `ISO`
|
data/Gemfile
CHANGED
@@ -5,7 +5,12 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in hcloud.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
+
group :development do
|
9
|
+
gem "yard", require: false
|
10
|
+
end
|
11
|
+
|
8
12
|
group :development, :test do
|
13
|
+
gem "brotli"
|
9
14
|
gem "debug", require: false
|
10
15
|
gem "dotenv", require: false
|
11
16
|
gem "ffaker", require: false
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# HCloud
|
2
2
|
|
3
|
-

|
4
4
|

|
5
5
|
|
6
6
|
Unofficial Ruby integration with the [Hetzner Cloud API](https://docs.hetzner.cloud/).
|
@@ -143,6 +143,22 @@ ssh_keys = HCloud::SSHKey.all # Will block until remaining requests have regener
|
|
143
143
|
Since rate limits are per hour and per project, using multiple clients at the same time will interfere with the rate limiting mechanism.
|
144
144
|
To prevent this, wrap client calls in a loop that retries the call after it fails with a `HCloud::RateLimitExceeded` error.
|
145
145
|
|
146
|
+
### Compression
|
147
|
+
|
148
|
+
Enable compression by passing an appropriate `compression` option to `HCloud::Client.new`.
|
149
|
+
Current supported options are `nil`, `"gzip"`, and `"brotli"`.
|
150
|
+
Compression is disabled by default.
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
client = HCloud::Client.new(access_token: "my_access_token", compression: "gzip")
|
154
|
+
```
|
155
|
+
|
156
|
+
To use Brotli compression, you need to install the `brotli` gem (at least version 0.3.0):
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
gem "brotli"
|
160
|
+
```
|
161
|
+
|
146
162
|
## Testing
|
147
163
|
|
148
164
|
```ssh
|
data/config/inflections.rb
CHANGED
data/lib/core_ext/send_wrap.rb
CHANGED
data/lib/hcloud/client.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "logger"
|
4
4
|
|
5
5
|
module HCloud
|
6
|
+
# @!visibility private
|
6
7
|
class NilConnection
|
7
8
|
def raise_error(...)
|
8
9
|
raise ArgumentError, "no default client configured, set HCloud::Client.connection to an instance of HCloud::Client"
|
@@ -14,18 +15,21 @@ module HCloud
|
|
14
15
|
alias delete raise_error
|
15
16
|
end
|
16
17
|
|
18
|
+
# @!visibility private
|
17
19
|
class Client
|
18
20
|
class_attribute :connection
|
19
21
|
|
20
22
|
self.connection = NilConnection.new
|
21
23
|
|
22
|
-
attr_reader :access_token, :endpoint, :logger, :rate_limit
|
24
|
+
attr_reader :access_token, :endpoint, :logger, :rate_limit, :timeout, :compression
|
23
25
|
|
24
|
-
def initialize(access_token:, endpoint: "https://api.hetzner.cloud/v1", logger: Logger.new("/dev/null"), rate_limit: false)
|
26
|
+
def initialize(access_token:, endpoint: "https://api.hetzner.cloud/v1", logger: Logger.new("/dev/null"), rate_limit: false, timeout: 10, compression: nil)
|
25
27
|
@access_token = access_token
|
26
28
|
@endpoint = endpoint
|
27
29
|
@logger = logger
|
28
30
|
@rate_limit = rate_limit
|
31
|
+
@timeout = timeout
|
32
|
+
@compression = compression
|
29
33
|
end
|
30
34
|
|
31
35
|
delegate :get, :put, :post, :delete, to: :http
|
@@ -33,7 +37,7 @@ module HCloud
|
|
33
37
|
private
|
34
38
|
|
35
39
|
def http
|
36
|
-
@http ||= HTTP.new(access_token, endpoint, logger, rate_limit)
|
40
|
+
@http ||= HTTP.new(access_token, endpoint, logger, rate_limit, timeout, compression)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
data/lib/hcloud/collection.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module HCloud
|
4
|
+
# @!visibility private
|
4
5
|
module Creatable
|
5
6
|
extend ActiveSupport::Concern
|
6
7
|
|
@@ -25,7 +26,7 @@ module HCloud
|
|
25
26
|
end
|
26
27
|
|
27
28
|
# Convert creatable_attributes into a key-value list
|
28
|
-
# rubocop:disable Metrics/
|
29
|
+
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
29
30
|
def creatable_params
|
30
31
|
# Split simple and nested attributes
|
31
32
|
nested_attributes, simple_attributes = creatable_attributes.partition { |a| a.respond_to? :each }
|
@@ -36,7 +37,7 @@ module HCloud
|
|
36
37
|
.merge(nested_attributes.reduce(&:merge).to_h { |k, v| [k.to_s, Array(v).filter_map { |w| send(k)&.send_wrap(w) }.first] })
|
37
38
|
.compact_blank
|
38
39
|
end
|
39
|
-
# rubocop:enable Metrics/
|
40
|
+
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
40
41
|
end
|
41
42
|
|
42
43
|
class_methods do
|
data/lib/hcloud/entity.rb
CHANGED
data/lib/hcloud/http.rb
CHANGED
@@ -3,15 +3,25 @@
|
|
3
3
|
require "http"
|
4
4
|
|
5
5
|
module HCloud
|
6
|
+
# @!visibility private
|
6
7
|
class HTTP
|
7
|
-
|
8
|
+
# Supported compression algorithms
|
9
|
+
COMPRESSION_ALGORITHMS = [
|
10
|
+
"gzip",
|
11
|
+
"brotli",
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
attr_reader :access_token, :endpoint, :logger, :rate_limit, :timeout, :compression
|
15
|
+
|
16
|
+
def initialize(access_token, endpoint, logger, rate_limit = false, timeout = 10, compression = nil)
|
17
|
+
raise ArgumentError, "invalid compression algorithm: #{compression}" if compression && !COMPRESSION_ALGORITHMS.include?(compression)
|
8
18
|
|
9
|
-
def initialize(access_token, endpoint, logger, rate_limit = false, timeout = 10)
|
10
19
|
@access_token = access_token
|
11
20
|
@endpoint = endpoint
|
12
21
|
@logger = logger
|
13
22
|
@rate_limit = rate_limit
|
14
23
|
@timeout = timeout
|
24
|
+
@compression = compression
|
15
25
|
end
|
16
26
|
|
17
27
|
def get(path, params = {})
|
@@ -78,10 +88,12 @@ module HCloud
|
|
78
88
|
|
79
89
|
def http
|
80
90
|
@http ||= ::HTTP
|
81
|
-
.headers(
|
91
|
+
.headers(user_agent: "#{HCloud::NAME}/#{HCloud::VERSION}")
|
92
|
+
.accept("application/json")
|
82
93
|
.timeout(timeout)
|
83
|
-
.use(logging: { logger: logger })
|
84
94
|
.then { |h| rate_limit ? h.use(:rate_limiter) : h }
|
95
|
+
.then { |h| compression ? h.use(compression: { method: compression }) : h }
|
96
|
+
.use(logging: { logger: logger })
|
85
97
|
.encoding("utf-8")
|
86
98
|
.auth("Bearer #{access_token}")
|
87
99
|
end
|
data/lib/hcloud/resource.rb
CHANGED
@@ -30,6 +30,16 @@ module HCloud
|
|
30
30
|
id && id == other.id
|
31
31
|
end
|
32
32
|
|
33
|
+
def self.attribute(name, *args, deprecated: false, **kwargs)
|
34
|
+
super(name, *args, **kwargs)
|
35
|
+
|
36
|
+
define_method(name) do |**params|
|
37
|
+
warn "[DEPRECATION] Field \"#{name}\" on #{self.class.name} is deprecated." if deprecated
|
38
|
+
|
39
|
+
super(**params)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
33
43
|
def self.resource_name
|
34
44
|
name.demodulize.underscore
|
35
45
|
end
|
data/lib/hcloud/resource_type.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
3
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
4
4
|
module HCloud
|
5
|
+
# @!visibility private
|
5
6
|
class ResourceType
|
6
7
|
class_attribute :resource_class_name
|
7
8
|
|
@@ -54,6 +55,7 @@ module HCloud
|
|
54
55
|
end
|
55
56
|
# rubocop:enable Naming/MethodName
|
56
57
|
|
58
|
+
# @!visibility private
|
57
59
|
class GenericType < ResourceType
|
58
60
|
def cast(value)
|
59
61
|
case value
|
@@ -78,7 +80,7 @@ module HCloud
|
|
78
80
|
end
|
79
81
|
end
|
80
82
|
end
|
81
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
83
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
82
84
|
|
83
85
|
ActiveModel::Type.register(:action, HCloud::ResourceType.Type("HCloud::Action"))
|
84
86
|
ActiveModel::Type.register(:algorithm, HCloud::ResourceType.Type("HCloud::Algorithm"))
|
@@ -30,21 +30,19 @@ module HCloud
|
|
30
30
|
attribute :cores, :integer
|
31
31
|
attribute :disk, :integer
|
32
32
|
attribute :memory, :integer
|
33
|
-
|
33
|
+
|
34
|
+
# FIXME: Attribute will return null on 2024-08-05
|
35
|
+
# FIXME: Attribute will be removed on 2024-11-05
|
36
|
+
attribute :included_traffic, :integer, deprecated: true
|
34
37
|
|
35
38
|
attribute :cpu_type
|
36
39
|
attribute :storage_type
|
37
40
|
|
38
41
|
attribute :prices, :price, array: true, default: -> { [] }
|
39
42
|
|
40
|
-
attribute :deprecated, :boolean
|
41
43
|
attribute :deprecation, :deprecation
|
42
44
|
|
43
|
-
|
44
|
-
warn "[DEPRECATION] Field \"deprecated\" on server types is deprecated."
|
45
|
-
|
46
|
-
super
|
47
|
-
end
|
45
|
+
attribute :deprecated, :boolean, deprecated: true
|
48
46
|
|
49
47
|
alias deprecated? deprecated
|
50
48
|
end
|
data/lib/hcloud/version.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module HTTP
|
5
|
+
# @!visibility private
|
6
|
+
module Features
|
7
|
+
# @!visibility private
|
8
|
+
class BlockIO
|
9
|
+
def initialize(block)
|
10
|
+
@block = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(data)
|
14
|
+
@block.call(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module HTTP
|
5
|
+
# @!visibility private
|
6
|
+
module Features
|
7
|
+
# @!visibility private
|
8
|
+
class Compression < Feature
|
9
|
+
SUPPORTED_ENCODING = {
|
10
|
+
"gzip" => "gzip",
|
11
|
+
"brotli" => "br",
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
HTTP::Options.register_feature(:compression, self)
|
15
|
+
|
16
|
+
attr_reader :method
|
17
|
+
|
18
|
+
def initialize(**)
|
19
|
+
super
|
20
|
+
|
21
|
+
@method = @opts.fetch(:method, "gzip").to_s || "gzip"
|
22
|
+
|
23
|
+
raise Error, "Only gzip and brotli methods are supported" unless SUPPORTED_ENCODING.key?(method)
|
24
|
+
end
|
25
|
+
|
26
|
+
def wrap_request(request)
|
27
|
+
return request unless method
|
28
|
+
|
29
|
+
# Set Accept-Encoding header
|
30
|
+
request.headers[Headers::ACCEPT_ENCODING] = SUPPORTED_ENCODING[method]
|
31
|
+
|
32
|
+
return request if request.body.size.zero? # rubocop:disable Style/ZeroLengthPredicate
|
33
|
+
|
34
|
+
# Delete Content-Length header, it is set automatically by HTTP::Request::Writer
|
35
|
+
request.headers.delete(Headers::CONTENT_LENGTH)
|
36
|
+
|
37
|
+
# Set Content-Encoding header
|
38
|
+
request.headers[Headers::CONTENT_ENCODING] = SUPPORTED_ENCODING[method]
|
39
|
+
|
40
|
+
HTTP::Request.new(
|
41
|
+
version: request.version,
|
42
|
+
verb: request.verb,
|
43
|
+
uri: request.uri,
|
44
|
+
headers: request.headers,
|
45
|
+
proxy: request.proxy,
|
46
|
+
body: compress(request.body),
|
47
|
+
uri_normalizer: request.uri_normalizer,
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def wrap_response(response)
|
52
|
+
return response unless SUPPORTED_ENCODING.value?(response.headers.get(Headers::CONTENT_ENCODING).first)
|
53
|
+
|
54
|
+
HTTP::Response.new(
|
55
|
+
status: response.status,
|
56
|
+
version: response.version,
|
57
|
+
headers: response.headers,
|
58
|
+
proxy_headers: response.proxy_headers,
|
59
|
+
connection: response.connection,
|
60
|
+
body: decompress(response.connection),
|
61
|
+
request: response.request,
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def compress(body)
|
68
|
+
case method
|
69
|
+
when "gzip"
|
70
|
+
Request::GzippedBody.new(body)
|
71
|
+
when "brotli"
|
72
|
+
Request::BrotliBody.new(body)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def decompress(connection)
|
77
|
+
case method
|
78
|
+
when "gzip"
|
79
|
+
HTTP::Response::Body.new(Response::GzipInflater.new(connection))
|
80
|
+
when "brotli"
|
81
|
+
HTTP::Response::Body.new(Response::BrotliInflater.new(connection))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "brotli"
|
5
|
+
|
6
|
+
version = Brotli::VERSION.split(".").map(&:to_i)
|
7
|
+
raise ArgumentError, "incompatible version of brotli: #{Brotli::VERSION}, needs to be at least 0.3.0" unless (version[0]).positive? || version[1] >= 3
|
8
|
+
rescue LoadError
|
9
|
+
# Ignore
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
module HTTP
|
14
|
+
# @!visibility private
|
15
|
+
module Features
|
16
|
+
# @!visibility private
|
17
|
+
module Request
|
18
|
+
# @!visibility private
|
19
|
+
class BrotliBody < CompressedBody
|
20
|
+
def compress(&block)
|
21
|
+
brotli = Brotli::Writer.new(BlockIO.new(block))
|
22
|
+
@body.each { |chunk| brotli.write(chunk) }
|
23
|
+
ensure
|
24
|
+
brotli.finish
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module HTTP
|
5
|
+
# @!visibility private
|
6
|
+
module Features
|
7
|
+
# @!visibility private
|
8
|
+
module Request
|
9
|
+
# @!visibility private
|
10
|
+
class CompressedBody < HTTP::Request::Body
|
11
|
+
def initialize(uncompressed_body) # rubocop:disable Lint/MissingSuper
|
12
|
+
@body = uncompressed_body
|
13
|
+
@compressed = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def size
|
17
|
+
compress_all! unless @compressed
|
18
|
+
@compressed.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
return to_enum __method__ unless block
|
23
|
+
|
24
|
+
if @compressed
|
25
|
+
compressed_each(&block)
|
26
|
+
else
|
27
|
+
compress(&block)
|
28
|
+
end
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def compress(&_block)
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def compressed_each
|
40
|
+
while (data = @compressed.read(Connection::BUFFER_SIZE))
|
41
|
+
yield data
|
42
|
+
end
|
43
|
+
ensure
|
44
|
+
@compressed.close!
|
45
|
+
end
|
46
|
+
|
47
|
+
def compress_all!
|
48
|
+
@compressed = Tempfile.new("http-compressed_body", binmode: true)
|
49
|
+
compress { |data| @compressed.write(data) }
|
50
|
+
@compressed.rewind
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zlib"
|
4
|
+
|
5
|
+
# @!visibility private
|
6
|
+
module HTTP
|
7
|
+
# @!visibility private
|
8
|
+
module Features
|
9
|
+
# @!visibility private
|
10
|
+
module Request
|
11
|
+
# @!visibility private
|
12
|
+
class GzippedBody < CompressedBody
|
13
|
+
def compress(&block)
|
14
|
+
gzip = Zlib::GzipWriter.new(BlockIO.new(block))
|
15
|
+
@body.each { |chunk| gzip.write(chunk) }
|
16
|
+
ensure
|
17
|
+
gzip.finish
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "brotli"
|
5
|
+
|
6
|
+
version = Brotli::VERSION.split(".").map(&:to_i)
|
7
|
+
raise ArgumentError, "incompatible version of brotli: #{Brotli::VERSION}, needs to be at least 0.3.0" unless (version[0]).positive? || version[1] >= 3
|
8
|
+
rescue LoadError
|
9
|
+
# Ignore
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
module HTTP
|
14
|
+
# @!visibility private
|
15
|
+
module Features
|
16
|
+
# @!visibility private
|
17
|
+
module Response
|
18
|
+
# @!visibility private
|
19
|
+
class BrotliInflater < HTTP::Response::Inflater
|
20
|
+
def readpartial(*args)
|
21
|
+
chunks = []
|
22
|
+
|
23
|
+
while (chunk = @connection.readpartial(*args))
|
24
|
+
chunks << chunk
|
25
|
+
end
|
26
|
+
|
27
|
+
return if chunks.empty?
|
28
|
+
|
29
|
+
Brotli.inflate(chunks.join)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zlib"
|
4
|
+
|
5
|
+
# @!visibility private
|
6
|
+
module HTTP
|
7
|
+
# @!visibility private
|
8
|
+
module Features
|
9
|
+
# @!visibility private
|
10
|
+
module Response
|
11
|
+
# @!visibility private
|
12
|
+
class GzipInflater < HTTP::Response::Inflater
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/http/mime_type/yaml.rb
CHANGED
data/lib/http/rate_limiter.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hetznercloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Dejonckheere
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -163,6 +163,13 @@ files:
|
|
163
163
|
- lib/hcloud/resources/ssh_key.rb
|
164
164
|
- lib/hcloud/resources/volume.rb
|
165
165
|
- lib/hcloud/version.rb
|
166
|
+
- lib/http/features/block_io.rb
|
167
|
+
- lib/http/features/compression.rb
|
168
|
+
- lib/http/features/request/brotli_body.rb
|
169
|
+
- lib/http/features/request/compressed_body.rb
|
170
|
+
- lib/http/features/request/gzipped_body.rb
|
171
|
+
- lib/http/features/response/brotli_inflater.rb
|
172
|
+
- lib/http/features/response/gzip_inflater.rb
|
166
173
|
- lib/http/mime_type/yaml.rb
|
167
174
|
- lib/http/rate_limiter.rb
|
168
175
|
homepage: https://github.com/floriandejonckheere/hcloud
|