fast_curl 0.3.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/README.md +135 -11
- data/ext/fast_curl/fast_curl.c +1024 -132
- data/lib/fast_curl/version.rb +1 -1
- data/lib/fast_curl.rb +132 -9
- metadata +3 -6
data/lib/fast_curl/version.rb
CHANGED
data/lib/fast_curl.rb
CHANGED
|
@@ -1,13 +1,75 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
|
+
require 'uri'
|
|
4
5
|
require_relative "fast_curl/version"
|
|
5
|
-
require_relative "fast_curl/fast_curl"
|
|
6
6
|
|
|
7
7
|
module FastCurl
|
|
8
8
|
class Error < StandardError; end
|
|
9
9
|
class TimeoutError < Error; end
|
|
10
10
|
|
|
11
|
+
class Headers < Hash
|
|
12
|
+
def [](key)
|
|
13
|
+
super(normalize(key))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def []=(key, value)
|
|
17
|
+
super(normalize(key), value)
|
|
18
|
+
end
|
|
19
|
+
alias store []=
|
|
20
|
+
|
|
21
|
+
def fetch(key, *args, &block)
|
|
22
|
+
super(normalize(key), *args, &block)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def key?(key)
|
|
26
|
+
super(normalize(key))
|
|
27
|
+
end
|
|
28
|
+
alias has_key? key?
|
|
29
|
+
alias include? key?
|
|
30
|
+
alias member? key?
|
|
31
|
+
|
|
32
|
+
def delete(key, &block)
|
|
33
|
+
super(normalize(key), &block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def dig(key, *rest)
|
|
37
|
+
super(normalize(key), *rest)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def values_at(*keys)
|
|
41
|
+
super(*keys.map { |key| normalize(key) })
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def assoc(key)
|
|
45
|
+
super(normalize(key))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def merge(*others, &block)
|
|
49
|
+
others.inject(dup) { |acc, other| acc.merge!(other, &block) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def merge!(*others)
|
|
53
|
+
others.each do |other|
|
|
54
|
+
other.each do |key, value|
|
|
55
|
+
self[key] = block_given? && key?(key) ? yield(normalize(key), self[key], value) : value
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
self
|
|
59
|
+
end
|
|
60
|
+
alias update merge!
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def normalize(key)
|
|
65
|
+
key.is_a?(String) || key.is_a?(Symbol) ? key.to_s.downcase : key
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
require_relative "fast_curl/fast_curl"
|
|
71
|
+
|
|
72
|
+
module FastCurl
|
|
11
73
|
DEFAULT_OPTIONS = {
|
|
12
74
|
connections: 20,
|
|
13
75
|
timeout: 30
|
|
@@ -16,13 +78,18 @@ module FastCurl
|
|
|
16
78
|
METHODS = %i[get post put delete patch].freeze
|
|
17
79
|
BODY_METHODS = %i[post put patch].freeze
|
|
18
80
|
|
|
81
|
+
JSON_TYPE = "application/json"
|
|
82
|
+
FORM_TYPE = "application/x-www-form-urlencoded"
|
|
83
|
+
BINARY_TYPE = "application/octet-stream"
|
|
84
|
+
|
|
19
85
|
class << self
|
|
20
86
|
METHODS.each do |method|
|
|
21
87
|
define_method(method) do |requests, **options|
|
|
22
88
|
execute(build_requests(requests, method), **DEFAULT_OPTIONS.merge(options))
|
|
23
89
|
end
|
|
24
90
|
|
|
25
|
-
define_method(:"first_#{method}") do |requests, count: 1, **options|
|
|
91
|
+
define_method(:"first_#{method}") do |requests, count: 1, accept: nil, **options|
|
|
92
|
+
options[:accept] = accept unless accept.nil?
|
|
26
93
|
first_execute(build_requests(requests, method), count: count, **DEFAULT_OPTIONS.merge(options))
|
|
27
94
|
end
|
|
28
95
|
|
|
@@ -34,15 +101,71 @@ module FastCurl
|
|
|
34
101
|
private
|
|
35
102
|
|
|
36
103
|
def build_requests(requests, method)
|
|
37
|
-
requests.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
104
|
+
source = requests.is_a?(Hash) ? [requests] : requests
|
|
105
|
+
|
|
106
|
+
if source.is_a?(Array)
|
|
107
|
+
source.map { |request| build_request(request, method) }
|
|
108
|
+
elsif source.respond_to?(:each)
|
|
109
|
+
Enumerator.new do |yielder|
|
|
110
|
+
source.each { |request| yielder << build_request(request, method) }
|
|
43
111
|
end
|
|
44
|
-
|
|
112
|
+
else
|
|
113
|
+
raise ArgumentError, "requests must be a Hash, Array or respond to #each"
|
|
45
114
|
end
|
|
46
115
|
end
|
|
116
|
+
|
|
117
|
+
def build_request(req, method)
|
|
118
|
+
raise ArgumentError, "request must be a Hash" unless req.is_a?(Hash)
|
|
119
|
+
|
|
120
|
+
r = { url: build_url(req), method: method.to_s.upcase }
|
|
121
|
+
headers = req[:headers] ? req[:headers].dup : nil
|
|
122
|
+
|
|
123
|
+
if BODY_METHODS.include?(method)
|
|
124
|
+
body, content_type = build_body(req)
|
|
125
|
+
if body
|
|
126
|
+
r[:body] = body
|
|
127
|
+
if content_type && !content_type?(headers)
|
|
128
|
+
headers ||= {}
|
|
129
|
+
headers["Content-Type"] = content_type
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
r[:headers] = headers if headers && !headers.empty?
|
|
135
|
+
r
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def build_url(req)
|
|
139
|
+
url = req[:url]
|
|
140
|
+
params = req[:params]
|
|
141
|
+
return url if params.nil? || params.empty? || !url.is_a?(String)
|
|
142
|
+
|
|
143
|
+
separator = url.include?("?") ? "&" : "?"
|
|
144
|
+
"#{url}#{separator}#{URI.encode_www_form(params)}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Returns [body_string, default_content_type].
|
|
148
|
+
# json: {...} or "..." -> application/json
|
|
149
|
+
# form: {...} -> application/x-www-form-urlencoded
|
|
150
|
+
# body: "..." -> application/octet-stream (set your own type)
|
|
151
|
+
# body: {...} -> application/json (kept for backwards compatibility)
|
|
152
|
+
def build_body(req)
|
|
153
|
+
if req.key?(:json)
|
|
154
|
+
value = req[:json]
|
|
155
|
+
[value.is_a?(String) ? value : value.to_json, JSON_TYPE]
|
|
156
|
+
elsif req.key?(:form)
|
|
157
|
+
value = req[:form]
|
|
158
|
+
[value.is_a?(String) ? value : URI.encode_www_form(value), FORM_TYPE]
|
|
159
|
+
elsif req.key?(:body) && !req[:body].nil?
|
|
160
|
+
value = req[:body]
|
|
161
|
+
value.is_a?(Hash) ? [value.to_json, JSON_TYPE] : [value.to_s, BINARY_TYPE]
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def content_type?(headers)
|
|
166
|
+
return false unless headers
|
|
167
|
+
|
|
168
|
+
headers.any? { |k, _| k.to_s.casecmp("content-type").zero? }
|
|
169
|
+
end
|
|
47
170
|
end
|
|
48
171
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fast_curl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- roman-haidarov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: json
|
|
@@ -125,7 +124,6 @@ homepage: https://github.com/roman-haidarov/fast_curl
|
|
|
125
124
|
licenses:
|
|
126
125
|
- MIT
|
|
127
126
|
metadata: {}
|
|
128
|
-
post_install_message:
|
|
129
127
|
rdoc_options: []
|
|
130
128
|
require_paths:
|
|
131
129
|
- lib
|
|
@@ -140,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
140
138
|
- !ruby/object:Gem::Version
|
|
141
139
|
version: '0'
|
|
142
140
|
requirements: []
|
|
143
|
-
rubygems_version: 3.
|
|
144
|
-
signing_key:
|
|
141
|
+
rubygems_version: 3.6.7
|
|
145
142
|
specification_version: 4
|
|
146
143
|
summary: Ultra-fast parallel HTTP client as Ruby C extension on libcurl multi
|
|
147
144
|
test_files: []
|