fast_curl 0.3.0 → 0.4.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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FastCurl
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
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,6 +78,10 @@ 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|
@@ -35,14 +101,56 @@ module FastCurl
35
101
 
36
102
  def build_requests(requests, method)
37
103
  requests.map do |req|
38
- r = { url: req[:url], method: method.to_s.upcase }
39
- r[:headers] = req[:headers] if req[:headers]
40
- if req[:body] && BODY_METHODS.include?(method)
41
- r[:body] = req[:body].is_a?(Hash) ? req[:body].to_json : req[:body].to_s
42
- r[:headers] = (r[:headers] || {}).merge("Content-Type" => "application/json") if req[:body].is_a?(Hash)
104
+ r = { url: build_url(req), method: method.to_s.upcase }
105
+ headers = req[:headers] ? req[:headers].dup : nil
106
+
107
+ if BODY_METHODS.include?(method)
108
+ body, content_type = build_body(req)
109
+ if body
110
+ r[:body] = body
111
+ if content_type && !content_type?(headers)
112
+ headers ||= {}
113
+ headers["Content-Type"] = content_type
114
+ end
115
+ end
43
116
  end
117
+
118
+ r[:headers] = headers if headers && !headers.empty?
44
119
  r
45
120
  end
46
121
  end
122
+
123
+ def build_url(req)
124
+ url = req[:url]
125
+ params = req[:params]
126
+ return url if params.nil? || params.empty? || !url.is_a?(String)
127
+
128
+ separator = url.include?("?") ? "&" : "?"
129
+ "#{url}#{separator}#{URI.encode_www_form(params)}"
130
+ end
131
+
132
+ # Returns [body_string, default_content_type].
133
+ # json: {...} or "..." -> application/json
134
+ # form: {...} -> application/x-www-form-urlencoded
135
+ # body: "..." -> application/octet-stream (set your own type)
136
+ # body: {...} -> application/json (kept for backwards compatibility)
137
+ def build_body(req)
138
+ if req.key?(:json)
139
+ value = req[:json]
140
+ [value.is_a?(String) ? value : value.to_json, JSON_TYPE]
141
+ elsif req.key?(:form)
142
+ value = req[:form]
143
+ [value.is_a?(String) ? value : URI.encode_www_form(value), FORM_TYPE]
144
+ elsif req.key?(:body) && !req[:body].nil?
145
+ value = req[:body]
146
+ value.is_a?(Hash) ? [value.to_json, JSON_TYPE] : [value.to_s, BINARY_TYPE]
147
+ end
148
+ end
149
+
150
+ def content_type?(headers)
151
+ return false unless headers
152
+
153
+ headers.any? { |k, _| k.to_s.casecmp("content-type").zero? }
154
+ end
47
155
  end
48
156
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_curl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - roman-haidarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-15 00:00:00.000000000 Z
11
+ date: 2026-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -28,72 +28,82 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '13.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '14'
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '13.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '14'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rake-compiler
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - "~>"
51
+ - - ">="
46
52
  - !ruby/object:Gem::Version
47
53
  version: '1.2'
54
+ - - "<"
55
+ - !ruby/object:Gem::Version
56
+ version: '2'
48
57
  type: :development
49
58
  prerelease: false
50
59
  version_requirements: !ruby/object:Gem::Requirement
51
60
  requirements:
52
- - - "~>"
61
+ - - ">="
53
62
  - !ruby/object:Gem::Version
54
63
  version: '1.2'
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '2'
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: minitest
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
59
- - - "~>"
71
+ - - ">="
60
72
  - !ruby/object:Gem::Version
61
- version: '5.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
73
+ version: '5.14'
74
+ - - "<"
67
75
  - !ruby/object:Gem::Version
68
- version: '5.0'
69
- - !ruby/object:Gem::Dependency
70
- name: benchmark-ips
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '2.0'
76
+ version: '6'
76
77
  type: :development
77
78
  prerelease: false
78
79
  version_requirements: !ruby/object:Gem::Requirement
79
80
  requirements:
80
- - - "~>"
81
+ - - ">="
81
82
  - !ruby/object:Gem::Version
82
- version: '2.0'
83
+ version: '5.14'
84
+ - - "<"
85
+ - !ruby/object:Gem::Version
86
+ version: '6'
83
87
  - !ruby/object:Gem::Dependency
84
88
  name: webrick
85
89
  requirement: !ruby/object:Gem::Requirement
86
90
  requirements:
87
- - - "~>"
91
+ - - ">="
88
92
  - !ruby/object:Gem::Version
89
93
  version: '1.8'
94
+ - - "<"
95
+ - !ruby/object:Gem::Version
96
+ version: '2'
90
97
  type: :development
91
98
  prerelease: false
92
99
  version_requirements: !ruby/object:Gem::Requirement
93
100
  requirements:
94
- - - "~>"
101
+ - - ">="
95
102
  - !ruby/object:Gem::Version
96
103
  version: '1.8'
104
+ - - "<"
105
+ - !ruby/object:Gem::Version
106
+ version: '2'
97
107
  description: Parallel HTTP requests via libcurl curl_multi API. Releases GVL during
98
108
  I/O, compatible with Async gem and Fiber scheduler. Supports execute (all), first_execute
99
109
  (first N), stream_execute (yield as ready). Built-in retry functionality for network
@@ -123,14 +133,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
133
  requirements:
124
134
  - - ">="
125
135
  - !ruby/object:Gem::Version
126
- version: 3.1.0
136
+ version: 2.7.0
127
137
  required_rubygems_version: !ruby/object:Gem::Requirement
128
138
  requirements:
129
139
  - - ">="
130
140
  - !ruby/object:Gem::Version
131
141
  version: '0'
132
142
  requirements: []
133
- rubygems_version: 3.3.27
143
+ rubygems_version: 3.4.22
134
144
  signing_key:
135
145
  specification_version: 4
136
146
  summary: Ultra-fast parallel HTTP client as Ruby C extension on libcurl multi