wreq-rb 0.3.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.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +2688 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +179 -0
  5. data/ext/wreq_rb/Cargo.toml +39 -0
  6. data/ext/wreq_rb/extconf.rb +22 -0
  7. data/ext/wreq_rb/src/client.rs +565 -0
  8. data/ext/wreq_rb/src/error.rs +25 -0
  9. data/ext/wreq_rb/src/lib.rs +20 -0
  10. data/ext/wreq_rb/src/response.rs +132 -0
  11. data/lib/wreq-rb/version.rb +5 -0
  12. data/lib/wreq-rb.rb +17 -0
  13. data/patches/0001-add-transfer-size-tracking.patch +292 -0
  14. data/vendor/wreq/Cargo.toml +306 -0
  15. data/vendor/wreq/LICENSE +202 -0
  16. data/vendor/wreq/README.md +122 -0
  17. data/vendor/wreq/examples/cert_store.rs +77 -0
  18. data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
  19. data/vendor/wreq/examples/emulation.rs +118 -0
  20. data/vendor/wreq/examples/form.rs +14 -0
  21. data/vendor/wreq/examples/http1_websocket.rs +37 -0
  22. data/vendor/wreq/examples/http2_websocket.rs +45 -0
  23. data/vendor/wreq/examples/json_dynamic.rs +41 -0
  24. data/vendor/wreq/examples/json_typed.rs +47 -0
  25. data/vendor/wreq/examples/keylog.rs +16 -0
  26. data/vendor/wreq/examples/request_with_emulation.rs +115 -0
  27. data/vendor/wreq/examples/request_with_interface.rs +37 -0
  28. data/vendor/wreq/examples/request_with_local_address.rs +16 -0
  29. data/vendor/wreq/examples/request_with_proxy.rs +13 -0
  30. data/vendor/wreq/examples/request_with_redirect.rs +22 -0
  31. data/vendor/wreq/examples/request_with_version.rs +15 -0
  32. data/vendor/wreq/examples/tor_socks.rs +24 -0
  33. data/vendor/wreq/examples/unix_socket.rs +33 -0
  34. data/vendor/wreq/src/client/body.rs +304 -0
  35. data/vendor/wreq/src/client/conn/conn.rs +231 -0
  36. data/vendor/wreq/src/client/conn/connector.rs +549 -0
  37. data/vendor/wreq/src/client/conn/http.rs +1023 -0
  38. data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
  39. data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
  40. data/vendor/wreq/src/client/conn/proxy.rs +39 -0
  41. data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
  42. data/vendor/wreq/src/client/conn/uds.rs +44 -0
  43. data/vendor/wreq/src/client/conn/verbose.rs +149 -0
  44. data/vendor/wreq/src/client/conn.rs +323 -0
  45. data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
  46. data/vendor/wreq/src/client/core/body/length.rs +118 -0
  47. data/vendor/wreq/src/client/core/body.rs +34 -0
  48. data/vendor/wreq/src/client/core/common/buf.rs +149 -0
  49. data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
  50. data/vendor/wreq/src/client/core/common/watch.rs +76 -0
  51. data/vendor/wreq/src/client/core/common.rs +3 -0
  52. data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
  53. data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
  54. data/vendor/wreq/src/client/core/conn.rs +11 -0
  55. data/vendor/wreq/src/client/core/dispatch.rs +299 -0
  56. data/vendor/wreq/src/client/core/error.rs +435 -0
  57. data/vendor/wreq/src/client/core/ext.rs +201 -0
  58. data/vendor/wreq/src/client/core/http1.rs +178 -0
  59. data/vendor/wreq/src/client/core/http2.rs +483 -0
  60. data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
  61. data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
  62. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
  63. data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
  64. data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
  65. data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
  66. data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
  67. data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
  68. data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
  69. data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
  70. data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
  71. data/vendor/wreq/src/client/core/proto.rs +58 -0
  72. data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
  73. data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
  74. data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
  75. data/vendor/wreq/src/client/core/rt.rs +25 -0
  76. data/vendor/wreq/src/client/core/upgrade.rs +267 -0
  77. data/vendor/wreq/src/client/core.rs +16 -0
  78. data/vendor/wreq/src/client/emulation.rs +161 -0
  79. data/vendor/wreq/src/client/http/client/error.rs +142 -0
  80. data/vendor/wreq/src/client/http/client/exec.rs +29 -0
  81. data/vendor/wreq/src/client/http/client/extra.rs +77 -0
  82. data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
  83. data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
  84. data/vendor/wreq/src/client/http/client/util.rs +104 -0
  85. data/vendor/wreq/src/client/http/client.rs +1003 -0
  86. data/vendor/wreq/src/client/http/future.rs +99 -0
  87. data/vendor/wreq/src/client/http.rs +1629 -0
  88. data/vendor/wreq/src/client/layer/config/options.rs +156 -0
  89. data/vendor/wreq/src/client/layer/config.rs +116 -0
  90. data/vendor/wreq/src/client/layer/cookie.rs +161 -0
  91. data/vendor/wreq/src/client/layer/decoder.rs +139 -0
  92. data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
  93. data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
  94. data/vendor/wreq/src/client/layer/redirect.rs +145 -0
  95. data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
  96. data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
  97. data/vendor/wreq/src/client/layer/retry.rs +151 -0
  98. data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
  99. data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
  100. data/vendor/wreq/src/client/layer/timeout.rs +177 -0
  101. data/vendor/wreq/src/client/layer.rs +15 -0
  102. data/vendor/wreq/src/client/multipart.rs +717 -0
  103. data/vendor/wreq/src/client/request.rs +818 -0
  104. data/vendor/wreq/src/client/response.rs +534 -0
  105. data/vendor/wreq/src/client/ws/json.rs +99 -0
  106. data/vendor/wreq/src/client/ws/message.rs +453 -0
  107. data/vendor/wreq/src/client/ws.rs +714 -0
  108. data/vendor/wreq/src/client.rs +27 -0
  109. data/vendor/wreq/src/config.rs +140 -0
  110. data/vendor/wreq/src/cookie.rs +579 -0
  111. data/vendor/wreq/src/dns/gai.rs +249 -0
  112. data/vendor/wreq/src/dns/hickory.rs +78 -0
  113. data/vendor/wreq/src/dns/resolve.rs +180 -0
  114. data/vendor/wreq/src/dns.rs +69 -0
  115. data/vendor/wreq/src/error.rs +502 -0
  116. data/vendor/wreq/src/ext.rs +398 -0
  117. data/vendor/wreq/src/hash.rs +143 -0
  118. data/vendor/wreq/src/header.rs +506 -0
  119. data/vendor/wreq/src/into_uri.rs +187 -0
  120. data/vendor/wreq/src/lib.rs +586 -0
  121. data/vendor/wreq/src/proxy/mac.rs +82 -0
  122. data/vendor/wreq/src/proxy/matcher.rs +806 -0
  123. data/vendor/wreq/src/proxy/uds.rs +66 -0
  124. data/vendor/wreq/src/proxy/win.rs +31 -0
  125. data/vendor/wreq/src/proxy.rs +569 -0
  126. data/vendor/wreq/src/redirect.rs +575 -0
  127. data/vendor/wreq/src/retry.rs +198 -0
  128. data/vendor/wreq/src/sync.rs +129 -0
  129. data/vendor/wreq/src/tls/conn/cache.rs +123 -0
  130. data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
  131. data/vendor/wreq/src/tls/conn/ext.rs +82 -0
  132. data/vendor/wreq/src/tls/conn/macros.rs +34 -0
  133. data/vendor/wreq/src/tls/conn/service.rs +138 -0
  134. data/vendor/wreq/src/tls/conn.rs +681 -0
  135. data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
  136. data/vendor/wreq/src/tls/keylog.rs +99 -0
  137. data/vendor/wreq/src/tls/options.rs +464 -0
  138. data/vendor/wreq/src/tls/x509/identity.rs +122 -0
  139. data/vendor/wreq/src/tls/x509/parser.rs +71 -0
  140. data/vendor/wreq/src/tls/x509/store.rs +228 -0
  141. data/vendor/wreq/src/tls/x509.rs +68 -0
  142. data/vendor/wreq/src/tls.rs +154 -0
  143. data/vendor/wreq/src/trace.rs +55 -0
  144. data/vendor/wreq/src/util.rs +122 -0
  145. data/vendor/wreq/tests/badssl.rs +228 -0
  146. data/vendor/wreq/tests/brotli.rs +350 -0
  147. data/vendor/wreq/tests/client.rs +1098 -0
  148. data/vendor/wreq/tests/connector_layers.rs +227 -0
  149. data/vendor/wreq/tests/cookie.rs +306 -0
  150. data/vendor/wreq/tests/deflate.rs +347 -0
  151. data/vendor/wreq/tests/emulation.rs +260 -0
  152. data/vendor/wreq/tests/gzip.rs +347 -0
  153. data/vendor/wreq/tests/layers.rs +261 -0
  154. data/vendor/wreq/tests/multipart.rs +165 -0
  155. data/vendor/wreq/tests/proxy.rs +438 -0
  156. data/vendor/wreq/tests/redirect.rs +629 -0
  157. data/vendor/wreq/tests/retry.rs +135 -0
  158. data/vendor/wreq/tests/support/delay_server.rs +117 -0
  159. data/vendor/wreq/tests/support/error.rs +16 -0
  160. data/vendor/wreq/tests/support/layer.rs +183 -0
  161. data/vendor/wreq/tests/support/mod.rs +9 -0
  162. data/vendor/wreq/tests/support/server.rs +232 -0
  163. data/vendor/wreq/tests/timeouts.rs +281 -0
  164. data/vendor/wreq/tests/unix_socket.rs +135 -0
  165. data/vendor/wreq/tests/upgrade.rs +98 -0
  166. data/vendor/wreq/tests/zstd.rs +559 -0
  167. metadata +225 -0
data/Cargo.toml ADDED
@@ -0,0 +1,6 @@
1
+ [workspace]
2
+ members = ["ext/wreq_rb"]
3
+ resolver = "2"
4
+
5
+ [patch.crates-io]
6
+ wreq = { path = "vendor/wreq" }
data/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # wreq-rb
2
+
3
+ Ruby bindings for the [wreq](https://github.com/0x676e67/wreq) Rust HTTP client — featuring TLS fingerprint emulation, HTTP/2 support, cookie handling, and proxy support.
4
+
5
+ ## Installation
6
+
7
+ Add to your Gemfile:
8
+
9
+ ```ruby
10
+ gem "wreq-rb"
11
+ ```
12
+
13
+ Then run:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ > **Build prerequisites:** You need Rust (1.85+), Clang, CMake, and Perl installed, since wreq compiles BoringSSL from source. See [wreq's build guide](https://github.com/0x676e67/wreq#building) for details.
20
+
21
+ ## Quick Start
22
+
23
+ ```ruby
24
+ require "wreq-rb"
25
+
26
+ # Simple GET request
27
+ resp = Wreq.get("https://httpbin.org/get")
28
+ puts resp.status # => 200
29
+ puts resp.text # => response body as string
30
+ puts resp.json # => parsed Ruby Hash
31
+
32
+ # POST with JSON body
33
+ resp = Wreq.post("https://httpbin.org/post", json: { name: "wreq", version: 1 })
34
+
35
+ # POST with form data
36
+ resp = Wreq.post("https://httpbin.org/post", form: { key: "value" })
37
+
38
+ # Custom headers
39
+ resp = Wreq.get("https://httpbin.org/headers",
40
+ headers: { "X-Custom" => "value", "Accept" => "application/json" })
41
+
42
+ # Query parameters
43
+ resp = Wreq.get("https://httpbin.org/get", query: { foo: "bar", page: "1" })
44
+
45
+ # Authentication
46
+ resp = Wreq.get("https://httpbin.org/bearer", bearer: "my-token")
47
+ resp = Wreq.get("https://httpbin.org/basic-auth/user/pass", basic: ["user", "pass"])
48
+
49
+ # Browser emulation (enabled by default)
50
+ resp = Wreq.get("https://tls.peet.ws/api/all", emulation: "chrome_143")
51
+ ```
52
+
53
+ ## Using a Client
54
+
55
+ For best performance, create a `Wreq::Client` and reuse it across requests (connections are pooled internally):
56
+
57
+ ```ruby
58
+ client = Wreq::Client.new(
59
+ user_agent: "MyApp/1.0",
60
+ timeout: 30, # total timeout in seconds
61
+ connect_timeout: 5, # connection timeout
62
+ read_timeout: 15, # read timeout
63
+ redirect: 10, # follow up to 10 redirects (false to disable)
64
+ cookie_store: true, # enable cookie jar
65
+ proxy: "http://proxy:8080", # proxy URL (supports http, https, socks5)
66
+ proxy_user: "user", # proxy auth
67
+ proxy_pass: "pass",
68
+ no_proxy: true, # disable all proxies (including env-vars)
69
+ https_only: false, # restrict to HTTPS
70
+ verify_host: true, # verify TLS hostname (default: true)
71
+ verify_cert: true, # verify TLS certificate (default: true)
72
+ http1_only: false, # force HTTP/1.1 only
73
+ http2_only: false, # force HTTP/2 only
74
+ gzip: true, # enable gzip decompression
75
+ brotli: true, # enable brotli decompression
76
+ deflate: true, # enable deflate decompression
77
+ zstd: true, # enable zstd decompression
78
+ emulation: "chrome_143", # browser emulation (enabled by default)
79
+ headers: { # default headers for all requests
80
+ "Accept" => "application/json"
81
+ }
82
+ )
83
+
84
+ resp = client.get("https://api.example.com/data")
85
+ resp = client.post("https://api.example.com/data", json: { key: "value" })
86
+ ```
87
+
88
+ ## HTTP Methods
89
+
90
+ All methods are available on both `Wreq` (module-level) and `Wreq::Client` (instance-level):
91
+
92
+ | Method | Usage |
93
+ |--------|-------|
94
+ | `get(url, **opts)` | GET request |
95
+ | `post(url, **opts)` | POST request |
96
+ | `put(url, **opts)` | PUT request |
97
+ | `patch(url, **opts)` | PATCH request |
98
+ | `delete(url, **opts)` | DELETE request |
99
+ | `head(url, **opts)` | HEAD request |
100
+ | `options(url, **opts)` | OPTIONS request |
101
+
102
+ ### Per-Request Options
103
+
104
+ Pass an options hash as the second argument to any HTTP method:
105
+
106
+ | Option | Type | Description |
107
+ |--------|------|-------------|
108
+ | `headers` | Hash | Request headers |
109
+ | `body` | String | Raw request body |
110
+ | `json` | Hash/Array | JSON-serialized body (sets Content-Type) |
111
+ | `form` | Hash | URL-encoded form body |
112
+ | `query` | Hash | URL query parameters |
113
+ | `timeout` | Float | Per-request timeout (seconds) |
114
+ | `auth` | String | Raw Authorization header |
115
+ | `bearer` | String | Bearer token |
116
+ | `basic` | Array | `[username, password]` for Basic auth |
117
+ | `proxy` | String | Per-request proxy URL |
118
+ | `emulation` | String/Boolean | Per-request emulation override |
119
+
120
+ ## Browser Emulation
121
+
122
+ wreq-rb emulates real browser TLS fingerprints, HTTP/2 settings, and headers by default. **Chrome 143 is used when no emulation is specified.**
123
+
124
+ ```ruby
125
+ # Default: Chrome 143 emulation (automatic)
126
+ resp = Wreq.get("https://tls.peet.ws/api/all")
127
+
128
+ # Explicit browser emulation
129
+ client = Wreq::Client.new(emulation: "firefox_146")
130
+ client = Wreq::Client.new(emulation: "safari_18_5")
131
+ client = Wreq::Client.new(emulation: "edge_142")
132
+
133
+ # Disable emulation entirely
134
+ client = Wreq::Client.new(emulation: false)
135
+
136
+ # Emulation + custom user-agent (user_agent overrides emulation's UA)
137
+ client = Wreq::Client.new(emulation: "chrome_143", user_agent: "MyBot/1.0")
138
+
139
+ # Per-request emulation override
140
+ resp = client.get("https://example.com", emulation: "safari_26_2")
141
+ ```
142
+
143
+ ### Supported Browsers
144
+
145
+ | Browser | Example values |
146
+ |---------|---------------|
147
+ | Chrome | `chrome_100` .. `chrome_143` |
148
+ | Firefox | `firefox_109`, `firefox_146`, `firefox_private_135` |
149
+ | Safari | `safari_15_3` .. `safari_26_2`, `safari_ios_26`, `safari_ipad_18` |
150
+ | Edge | `edge_101` .. `edge_142` |
151
+ | Opera | `opera_116` .. `opera_119` |
152
+ | OkHttp | `okhttp_3_9` .. `okhttp_5` |
153
+
154
+ ## Response
155
+
156
+ The `Wreq::Response` object provides:
157
+
158
+ | Method | Returns | Description |
159
+ |--------|---------|-------------|
160
+ | `status` / `code` | Integer | HTTP status code |
161
+ | `text` / `body` | String | Response body as string |
162
+ | `body_bytes` | Array | Raw bytes |
163
+ | `headers` | Hash | Response headers |
164
+ | `json` | Hash/Array | JSON-parsed body |
165
+ | `url` | String | Final URL (after redirects) |
166
+ | `version` | String | HTTP version |
167
+ | `content_length` | Integer/nil | Content length if known |
168
+ | `success?` | Boolean | Status 2xx? |
169
+ | `redirect?` | Boolean | Status 3xx? |
170
+ | `client_error?` | Boolean | Status 4xx? |
171
+ | `server_error?` | Boolean | Status 5xx? |
172
+
173
+ ## Building from Source
174
+
175
+ ```bash
176
+ bundle install
177
+ bundle exec rake compile
178
+ bundle exec rake test
179
+ ```
@@ -0,0 +1,39 @@
1
+ [package]
2
+ name = "wreq_rb"
3
+ version = "0.3.0"
4
+ edition = "2021"
5
+ publish = false
6
+
7
+ [lib]
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ magnus = { version = "0.8", features = ["rb-sys"] }
12
+ rb-sys = "0.9"
13
+ wreq = { path = "../../vendor/wreq", features = [
14
+ "cookies",
15
+ "json",
16
+ "gzip",
17
+ "brotli",
18
+ "zstd",
19
+ "deflate",
20
+ "socks",
21
+ "multipart",
22
+ "charset",
23
+ "stream",
24
+ "query",
25
+ "form",
26
+ ] }
27
+ wreq-util = { version = "=3.0.0-rc.9", features = ["emulation", "emulation-serde"] }
28
+ tokio = { version = "1", features = ["full"] }
29
+ tokio-util = "0.7"
30
+ serde_json = "1.0"
31
+ bytes = "1"
32
+ http = "1"
33
+
34
+ [target.'cfg(target_os = "linux")'.dependencies]
35
+ wreq = { path = "../../vendor/wreq", features = [
36
+ "prefix-symbols",
37
+ ] }
38
+
39
+
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+ require "rb_sys/mkmf"
5
+
6
+ # Apply patches to vendored dependencies before compilation
7
+ patch_dir = File.expand_path("../../patches", __dir__)
8
+ wreq_dir = File.expand_path("../../vendor/wreq", __dir__)
9
+
10
+ if File.directory?(patch_dir)
11
+ Dir.glob(File.join(patch_dir, "*.patch")).sort.each do |patch|
12
+ check = `cd #{wreq_dir} && git apply --check --reverse #{patch} 2>&1`
13
+ if $?.success?
14
+ puts "Patch already applied: #{File.basename(patch)}"
15
+ else
16
+ puts "Applying patch: #{File.basename(patch)}"
17
+ system("cd #{wreq_dir} && git apply #{patch}") || abort("Failed to apply #{patch}")
18
+ end
19
+ end
20
+ end
21
+
22
+ create_rust_makefile("wreq_rb/wreq_rb")