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.
- checksums.yaml +7 -0
- data/Cargo.lock +2688 -0
- data/Cargo.toml +6 -0
- data/README.md +179 -0
- data/ext/wreq_rb/Cargo.toml +39 -0
- data/ext/wreq_rb/extconf.rb +22 -0
- data/ext/wreq_rb/src/client.rs +565 -0
- data/ext/wreq_rb/src/error.rs +25 -0
- data/ext/wreq_rb/src/lib.rs +20 -0
- data/ext/wreq_rb/src/response.rs +132 -0
- data/lib/wreq-rb/version.rb +5 -0
- data/lib/wreq-rb.rb +17 -0
- data/patches/0001-add-transfer-size-tracking.patch +292 -0
- data/vendor/wreq/Cargo.toml +306 -0
- data/vendor/wreq/LICENSE +202 -0
- data/vendor/wreq/README.md +122 -0
- data/vendor/wreq/examples/cert_store.rs +77 -0
- data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
- data/vendor/wreq/examples/emulation.rs +118 -0
- data/vendor/wreq/examples/form.rs +14 -0
- data/vendor/wreq/examples/http1_websocket.rs +37 -0
- data/vendor/wreq/examples/http2_websocket.rs +45 -0
- data/vendor/wreq/examples/json_dynamic.rs +41 -0
- data/vendor/wreq/examples/json_typed.rs +47 -0
- data/vendor/wreq/examples/keylog.rs +16 -0
- data/vendor/wreq/examples/request_with_emulation.rs +115 -0
- data/vendor/wreq/examples/request_with_interface.rs +37 -0
- data/vendor/wreq/examples/request_with_local_address.rs +16 -0
- data/vendor/wreq/examples/request_with_proxy.rs +13 -0
- data/vendor/wreq/examples/request_with_redirect.rs +22 -0
- data/vendor/wreq/examples/request_with_version.rs +15 -0
- data/vendor/wreq/examples/tor_socks.rs +24 -0
- data/vendor/wreq/examples/unix_socket.rs +33 -0
- data/vendor/wreq/src/client/body.rs +304 -0
- data/vendor/wreq/src/client/conn/conn.rs +231 -0
- data/vendor/wreq/src/client/conn/connector.rs +549 -0
- data/vendor/wreq/src/client/conn/http.rs +1023 -0
- data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
- data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
- data/vendor/wreq/src/client/conn/proxy.rs +39 -0
- data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
- data/vendor/wreq/src/client/conn/uds.rs +44 -0
- data/vendor/wreq/src/client/conn/verbose.rs +149 -0
- data/vendor/wreq/src/client/conn.rs +323 -0
- data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
- data/vendor/wreq/src/client/core/body/length.rs +118 -0
- data/vendor/wreq/src/client/core/body.rs +34 -0
- data/vendor/wreq/src/client/core/common/buf.rs +149 -0
- data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
- data/vendor/wreq/src/client/core/common/watch.rs +76 -0
- data/vendor/wreq/src/client/core/common.rs +3 -0
- data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
- data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
- data/vendor/wreq/src/client/core/conn.rs +11 -0
- data/vendor/wreq/src/client/core/dispatch.rs +299 -0
- data/vendor/wreq/src/client/core/error.rs +435 -0
- data/vendor/wreq/src/client/core/ext.rs +201 -0
- data/vendor/wreq/src/client/core/http1.rs +178 -0
- data/vendor/wreq/src/client/core/http2.rs +483 -0
- data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
- data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
- data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
- data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
- data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
- data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
- data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
- data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
- data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
- data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
- data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
- data/vendor/wreq/src/client/core/proto.rs +58 -0
- data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
- data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
- data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
- data/vendor/wreq/src/client/core/rt.rs +25 -0
- data/vendor/wreq/src/client/core/upgrade.rs +267 -0
- data/vendor/wreq/src/client/core.rs +16 -0
- data/vendor/wreq/src/client/emulation.rs +161 -0
- data/vendor/wreq/src/client/http/client/error.rs +142 -0
- data/vendor/wreq/src/client/http/client/exec.rs +29 -0
- data/vendor/wreq/src/client/http/client/extra.rs +77 -0
- data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
- data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
- data/vendor/wreq/src/client/http/client/util.rs +104 -0
- data/vendor/wreq/src/client/http/client.rs +1003 -0
- data/vendor/wreq/src/client/http/future.rs +99 -0
- data/vendor/wreq/src/client/http.rs +1629 -0
- data/vendor/wreq/src/client/layer/config/options.rs +156 -0
- data/vendor/wreq/src/client/layer/config.rs +116 -0
- data/vendor/wreq/src/client/layer/cookie.rs +161 -0
- data/vendor/wreq/src/client/layer/decoder.rs +139 -0
- data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
- data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
- data/vendor/wreq/src/client/layer/redirect.rs +145 -0
- data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
- data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
- data/vendor/wreq/src/client/layer/retry.rs +151 -0
- data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
- data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
- data/vendor/wreq/src/client/layer/timeout.rs +177 -0
- data/vendor/wreq/src/client/layer.rs +15 -0
- data/vendor/wreq/src/client/multipart.rs +717 -0
- data/vendor/wreq/src/client/request.rs +818 -0
- data/vendor/wreq/src/client/response.rs +534 -0
- data/vendor/wreq/src/client/ws/json.rs +99 -0
- data/vendor/wreq/src/client/ws/message.rs +453 -0
- data/vendor/wreq/src/client/ws.rs +714 -0
- data/vendor/wreq/src/client.rs +27 -0
- data/vendor/wreq/src/config.rs +140 -0
- data/vendor/wreq/src/cookie.rs +579 -0
- data/vendor/wreq/src/dns/gai.rs +249 -0
- data/vendor/wreq/src/dns/hickory.rs +78 -0
- data/vendor/wreq/src/dns/resolve.rs +180 -0
- data/vendor/wreq/src/dns.rs +69 -0
- data/vendor/wreq/src/error.rs +502 -0
- data/vendor/wreq/src/ext.rs +398 -0
- data/vendor/wreq/src/hash.rs +143 -0
- data/vendor/wreq/src/header.rs +506 -0
- data/vendor/wreq/src/into_uri.rs +187 -0
- data/vendor/wreq/src/lib.rs +586 -0
- data/vendor/wreq/src/proxy/mac.rs +82 -0
- data/vendor/wreq/src/proxy/matcher.rs +806 -0
- data/vendor/wreq/src/proxy/uds.rs +66 -0
- data/vendor/wreq/src/proxy/win.rs +31 -0
- data/vendor/wreq/src/proxy.rs +569 -0
- data/vendor/wreq/src/redirect.rs +575 -0
- data/vendor/wreq/src/retry.rs +198 -0
- data/vendor/wreq/src/sync.rs +129 -0
- data/vendor/wreq/src/tls/conn/cache.rs +123 -0
- data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
- data/vendor/wreq/src/tls/conn/ext.rs +82 -0
- data/vendor/wreq/src/tls/conn/macros.rs +34 -0
- data/vendor/wreq/src/tls/conn/service.rs +138 -0
- data/vendor/wreq/src/tls/conn.rs +681 -0
- data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
- data/vendor/wreq/src/tls/keylog.rs +99 -0
- data/vendor/wreq/src/tls/options.rs +464 -0
- data/vendor/wreq/src/tls/x509/identity.rs +122 -0
- data/vendor/wreq/src/tls/x509/parser.rs +71 -0
- data/vendor/wreq/src/tls/x509/store.rs +228 -0
- data/vendor/wreq/src/tls/x509.rs +68 -0
- data/vendor/wreq/src/tls.rs +154 -0
- data/vendor/wreq/src/trace.rs +55 -0
- data/vendor/wreq/src/util.rs +122 -0
- data/vendor/wreq/tests/badssl.rs +228 -0
- data/vendor/wreq/tests/brotli.rs +350 -0
- data/vendor/wreq/tests/client.rs +1098 -0
- data/vendor/wreq/tests/connector_layers.rs +227 -0
- data/vendor/wreq/tests/cookie.rs +306 -0
- data/vendor/wreq/tests/deflate.rs +347 -0
- data/vendor/wreq/tests/emulation.rs +260 -0
- data/vendor/wreq/tests/gzip.rs +347 -0
- data/vendor/wreq/tests/layers.rs +261 -0
- data/vendor/wreq/tests/multipart.rs +165 -0
- data/vendor/wreq/tests/proxy.rs +438 -0
- data/vendor/wreq/tests/redirect.rs +629 -0
- data/vendor/wreq/tests/retry.rs +135 -0
- data/vendor/wreq/tests/support/delay_server.rs +117 -0
- data/vendor/wreq/tests/support/error.rs +16 -0
- data/vendor/wreq/tests/support/layer.rs +183 -0
- data/vendor/wreq/tests/support/mod.rs +9 -0
- data/vendor/wreq/tests/support/server.rs +232 -0
- data/vendor/wreq/tests/timeouts.rs +281 -0
- data/vendor/wreq/tests/unix_socket.rs +135 -0
- data/vendor/wreq/tests/upgrade.rs +98 -0
- data/vendor/wreq/tests/zstd.rs +559 -0
- metadata +225 -0
data/Cargo.toml
ADDED
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")
|