1
0
зеркало из https://github.com/glebtv/yookassa.git synced 2026-09-03 09:46:16 +03:00

Replace ffi-backed HTTP client

Этот коммит содержится в:
Gleb Tv
2026-07-02 22:57:59 +03:00
родитель 85e97dc70c
Коммит 60319cb6bb
7 изменённых файлов: 209 добавлений и 142 удалений

7
.github/workflows/main.yml поставляемый
Просмотреть файл

@@ -14,12 +14,11 @@ jobs:
strategy:
matrix:
ruby:
- 2.6
- 2.7
- 3.0
- "3.3"
- "3.4"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:

Просмотреть файл

@@ -1,6 +1,7 @@
AllCops:
TargetRubyVersion: 2.6
TargetRubyVersion: 3.3
NewCops: enable
SuggestExtensions: false
Style/StringLiterals:
Enabled: true
@@ -17,4 +18,25 @@ Layout/LineLength:
Max: 150
Metrics/BlockLength:
IgnoredMethods: ['describe', 'context', 'shared_examples']
AllowedMethods: ["describe", "context", "shared_examples"]
Metrics/MethodLength:
Max: 15
Naming/PredicateMethod:
Enabled: false
Style/KeywordArgumentsMerging:
Enabled: false
Style/RedundantCurrentDirectoryInPath:
Enabled: false
Gemspec/AddRuntimeDependency:
Enabled: false
Gemspec/DeprecatedAttributeAssignment:
Enabled: false
Gemspec/RequireMFA:
Enabled: false

24
Gemfile
Просмотреть файл

@@ -5,22 +5,24 @@ source "https://rubygems.org"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# Specify your gem's dependencies in yookassa.gemspec
gem "httpclient", github: "glebtv/httpclient", branch: "master"
gemspec
group :documentation do
gem "rack"
gem "webrick"
gem "yard"
gem "rack", "~> 3.2"
gem "webrick", "~> 1.9"
gem "yard", "~> 0.9"
end
group :development, :test do
gem "pry"
gem "pry-byebug", "~> 3.8.0"
gem "rake", "~> 13.0"
gem "rspec", "~> 3.5"
gem "rubocop", "~> 1.22"
gem "pry", "~> 0.16"
gem "pry-byebug", "~> 3.8"
gem "rake", "~> 13.4"
gem "rspec", "~> 3.13"
gem "rubocop", "~> 1.88"
gem "rubocop-rake", "~> 0.6.0"
gem "rubocop-rspec", "~> 2.5"
gem "simplecov", "~> 0.16"
gem "webmock", "~> 3.14"
gem "rubocop-rspec", "~> 2.31"
gem "simplecov", "~> 0.22"
gem "webmock", "~> 3.26"
end

Просмотреть файл

@@ -1,158 +1,183 @@
GIT
remote: https://github.com/glebtv/httpclient
revision: 28d3d1d4fb428e98cc52f04294fe21717db9b28f
branch: master
specs:
httpclient (2.9.0)
mutex_m
PATH
remote: .
specs:
yookassa (0.2.0)
dry-struct
dry-validation
http (~> 5.0.1)
httpclient (>= 2.9)
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2)
byebug (11.1.3)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
bigdecimal (4.1.2)
byebug (13.0.0)
reline (>= 0.6.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
crack (0.4.5)
concurrent-ruby (1.3.7)
crack (1.0.1)
bigdecimal
rexml
diff-lcs (1.4.4)
docile (1.4.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dry-configurable (0.13.0)
diff-lcs (1.6.2)
docile (1.4.1)
dry-configurable (1.4.0)
dry-core (~> 1.0)
zeitwerk (~> 2.6)
dry-core (1.2.0)
concurrent-ruby (~> 1.0)
dry-core (~> 0.6)
dry-container (0.9.0)
logger
zeitwerk (~> 2.6)
dry-inflector (1.3.1)
dry-initializer (3.2.0)
dry-logic (1.6.0)
bigdecimal
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.13, >= 0.13.0)
dry-core (0.7.1)
dry-core (~> 1.1)
zeitwerk (~> 2.6)
dry-schema (1.16.0)
concurrent-ruby (~> 1.0)
dry-inflector (0.2.1)
dry-initializer (3.0.4)
dry-logic (1.2.0)
concurrent-ruby (~> 1.0)
dry-core (~> 0.5, >= 0.5)
dry-schema (1.8.0)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.13, >= 0.13.0)
dry-core (~> 0.5, >= 0.5)
dry-initializer (~> 3.0)
dry-logic (~> 1.0)
dry-types (~> 1.5)
dry-struct (1.4.0)
dry-core (~> 0.5, >= 0.5)
dry-types (~> 1.5)
dry-configurable (~> 1.0, >= 1.0.1)
dry-core (~> 1.1)
dry-initializer (~> 3.2)
dry-logic (~> 1.6)
dry-types (~> 1.9, >= 1.9.1)
zeitwerk (~> 2.6)
dry-struct (1.8.1)
dry-core (~> 1.1)
dry-types (~> 1.8, >= 1.8.2)
ice_nine (~> 0.11)
dry-types (1.5.1)
zeitwerk (~> 2.6)
dry-types (1.9.1)
bigdecimal (>= 3.0)
concurrent-ruby (~> 1.0)
dry-container (~> 0.3)
dry-core (~> 0.5, >= 0.5)
dry-inflector (~> 0.1, >= 0.1.2)
dry-logic (~> 1.0, >= 1.0.2)
dry-validation (1.7.0)
dry-core (~> 1.0)
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
dry-validation (1.11.1)
concurrent-ruby (~> 1.0)
dry-container (~> 0.7, >= 0.7.1)
dry-core (~> 0.5, >= 0.5)
dry-initializer (~> 3.0)
dry-schema (~> 1.8, >= 1.8.0)
ffi (1.15.4)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
hashdiff (1.0.1)
http (5.0.4)
addressable (~> 2.8)
http-cookie (~> 1.0)
http-form_data (~> 2.2)
llhttp-ffi (~> 0.4.0)
http-cookie (1.0.4)
domain_name (~> 0.5)
http-form_data (2.3.0)
dry-core (~> 1.1)
dry-initializer (~> 3.2)
dry-schema (~> 1.14)
zeitwerk (~> 2.6)
hashdiff (1.2.1)
ice_nine (0.11.2)
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
method_source (1.0.0)
parallel (1.21.0)
parser (3.0.2.0)
io-console (0.8.2)
json (2.20.0)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
method_source (1.1.0)
mutex_m (0.3.0)
parallel (2.1.0)
parser (3.3.11.1)
ast (~> 2.4.1)
pry (0.14.1)
racc
prism (1.9.0)
pry (0.16.0)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.8.0)
byebug (~> 11.0)
pry (~> 0.10)
public_suffix (4.0.6)
rack (2.2.3)
rainbow (3.0.0)
rake (13.0.6)
regexp_parser (2.1.1)
rexml (3.2.5)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
reline (>= 0.6.0)
pry-byebug (3.12.0)
byebug (~> 13.0)
pry (>= 0.13, < 0.17)
public_suffix (7.0.5)
racc (1.8.1)
rack (3.2.6)
rainbow (3.1.1)
rake (13.4.2)
regexp_parser (2.12.0)
reline (0.6.3)
io-console (~> 0.5)
rexml (3.4.4)
rspec (3.13.2)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.6)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.8)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.2)
rubocop (1.22.3)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.7)
rubocop (1.88.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (>= 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.12.0, < 2.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.12.0)
parser (>= 3.0.1.1)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.49.1)
parser (>= 3.3.7.2)
prism (~> 1.7)
rubocop-capybara (2.23.0)
lint_roller (~> 1.1)
rubocop (~> 1.81)
rubocop-factory_bot (2.28.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
rubocop-rspec (2.5.0)
rubocop (~> 1.19)
ruby-progressbar (1.11.0)
simplecov (0.21.2)
rubocop-rspec (2.31.0)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
rubocop-rspec_rails (~> 2.28)
rubocop-rspec_rails (2.29.1)
rubocop (~> 1.61)
ruby-progressbar (1.13.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.3)
unf (0.1.4)
unf_ext
unf_ext (0.0.8)
unicode-display_width (2.1.0)
webmock (3.14.0)
simplecov-html (0.13.2)
simplecov_json_formatter (0.1.4)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.2.0)
webmock (3.26.2)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.7.0)
yard (0.9.26)
webrick (1.9.2)
yard (0.9.44)
zeitwerk (2.8.2)
PLATFORMS
ruby
DEPENDENCIES
pry
pry-byebug (~> 3.8.0)
rack
rake (~> 13.0)
rspec (~> 3.5)
rubocop (~> 1.22)
httpclient!
pry (~> 0.16)
pry-byebug (~> 3.8)
rack (~> 3.2)
rake (~> 13.4)
rspec (~> 3.13)
rubocop (~> 1.88)
rubocop-rake (~> 0.6.0)
rubocop-rspec (~> 2.5)
simplecov (~> 0.16)
webmock (~> 3.14)
webrick
yard
rubocop-rspec (~> 2.31)
simplecov (~> 0.22)
webmock (~> 3.26)
webrick (~> 1.9)
yard (~> 0.9)
yookassa!
BUNDLED WITH
2.2.22
4.0.11

Просмотреть файл

@@ -125,6 +125,16 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
- Write, clarify, or fix documentation
- Suggest or add new features
## Development
This gem uses the `glebtv/httpclient` fork for local development to avoid the `http` gem's `llhttp-ffi` dependency chain.
```sh
bin/setup
bundle exec rspec
bundle exec rubocop
```
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

Просмотреть файл

@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "http"
require "httpclient"
require "json"
require_relative "./entity/error"
module Yookassa
@@ -10,12 +11,15 @@ module Yookassa
attr_reader :http
def initialize(shop_id: Yookassa.config.shop_id, api_key: Yookassa.config.api_key, oauth_token: nil)
@http = HTTP.headers(accept: "application/json")
@http = HTTPClient.new(
default_header: { "Accept" => "application/json" },
force_basic_auth: true
)
if shop_id && api_key
@http.basic_auth(user: shop_id, pass: api_key)
@http.set_auth(API_URL, shop_id, api_key)
elsif oauth_token
@http.headers("Authorization" => "Bearer #{oauth_token}")
@http.default_header["Authorization"] = "Bearer #{oauth_token}"
else
message = "Specify `shop_id` and `api_key` settings in a `.configure` block " \
"or pass `oauth_token` to a client"
@@ -26,23 +30,28 @@ module Yookassa
private
def get(endpoint, query: {})
api_call { http.get("#{API_URL}#{endpoint}", params: query) }
api_call { http.get("#{API_URL}#{endpoint}", query: query) }
end
def post(endpoint, idempotency_key:, payload: {})
api_call { http.headers("Idempotence-Key" => idempotency_key).post("#{API_URL}#{endpoint}", json: payload) }
headers = json_headers.merge("Idempotence-Key" => idempotency_key)
api_call { http.post("#{API_URL}#{endpoint}", body: JSON.generate(payload), header: headers) }
end
def delete(endpoint, idempotency_key:)
api_call { http.headers("Idempotence-Key" => idempotency_key).delete("#{API_URL}#{endpoint}") }
api_call { http.delete("#{API_URL}#{endpoint}", header: { "Idempotence-Key" => idempotency_key }) }
end
def api_call
response = yield if block_given?
body = JSON.parse(response.body.to_s, symbolize_names: true)
return body if response.status.success?
return body if response.status.between?(200, 299)
Entity::Error.new(**body)
end
def json_headers
{ "Content-Type" => "application/json" }
end
end
end

Просмотреть файл

@@ -20,9 +20,9 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.required_ruby_version = ">= 2.6"
spec.required_ruby_version = ">= 3.3"
spec.add_runtime_dependency "dry-struct"
spec.add_runtime_dependency "dry-validation"
spec.add_runtime_dependency "http", "~> 5.0"
spec.add_runtime_dependency "httpclient", ">= 2.9"
end