wreq 1.2.16-x86_64-linux → 1.3.1-x86_64-linux
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 +1 -1
- data/crates/wreq-util/CHANGELOG.md +3 -0
- data/lib/wreq_ruby/3.3/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/3.4/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/4.0/wreq_ruby.so +0 -0
- data/lib/wreq_ruby/emulate.rb +13 -0
- data/test/emulation_test.rb +77 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca618048d11e2aa36fd374e9eabc3ea054f5455a759d9702fd4b75807879b2ac
|
|
4
|
+
data.tar.gz: 8f875eef73ca64f23533a9e7ecbae9834e109c58290647d41e2812f7ac571173
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89b37a1c3ac0f70c276b8cd93c0ae5b131b566beada627e6fad05fb8abcdcdc9212d9eee4d1af8525cb95c53dcc4b67945d16c466f4df186cd99b2c397a70795
|
|
7
|
+
data.tar.gz: 3eebdc7e7f6c67da8b74c1e8ed2761aa384d17fd37433fa59e5bad8553effdb873c63ea636abf8d715294c7f7d247c3daf39b845ad39ff3a694ac450ab807c9c
|
data/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Most browser device models share identical TLS and HTTP/2 configurations, differ
|
|
|
91
91
|
|
|
92
92
|
| **Browser** | **Versions** |
|
|
93
93
|
| ----------- | ------------ |
|
|
94
|
-
| **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147`, `Chrome148`, `Chrome149`, `Chrome150`, `Chrome151`, `Chrome152`, `Chrome153`, `Chrome154` |
|
|
94
|
+
| **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147`, `Chrome148`, `Chrome149`, `Chrome150`, `Chrome151`, `Chrome152`, `Chrome153`, `Chrome154`, `Chrome155` |
|
|
95
95
|
| **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134`, `Edge135`, `Edge136`, `Edge137`, `Edge138`, `Edge139`, `Edge140`, `Edge141`, `Edge142`, `Edge143`, `Edge144`, `Edge145`, `Edge146`, `Edge147`, `Edge148` |
|
|
96
96
|
| **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139`, `Firefox142`, `Firefox143`, `Firefox144`, `Firefox145`, `Firefox146`, `Firefox147`, `Firefox148`, `Firefox149`, `Firefox150`, `Firefox151`, `Firefox152` |
|
|
97
97
|
| **Safari** | `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari17_6`, `Safari18`, `Safari18_2`, `Safari18_3`, `Safari18_3_1`, `Safari18_5`, `Safari26`, `Safari26_1`, `Safari26_2`, `SafariIos16_5`, `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos18_1_1`, `SafariIos26`, `SafariIos26_2`, `SafariIPad18`, `SafariIPad26`, `SafariIpad26_2` |
|
|
@@ -13,10 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
13
13
|
- *(emulate)* Add Chrome 152 profile.
|
|
14
14
|
- *(emulate)* Add Chrome 153 profile.
|
|
15
15
|
- *(emulate)* Add Chrome 154 profile.
|
|
16
|
+
- *(emulate)* Add Chrome 155 profile, including the JPEG XL navigation Accept header.
|
|
16
17
|
- *(emulate)* Add Firefox 152 profile.
|
|
17
18
|
|
|
18
19
|
### Fixed
|
|
19
20
|
|
|
21
|
+
- Match Trust Anchor ID ordering by Chrome version: randomized per native configuration for 152/153, and sorted by raw ID bytes for 154.
|
|
22
|
+
|
|
20
23
|
- *(emulate)* Fix Firefox 150 and 151 cipher suite lists.
|
|
21
24
|
|
|
22
25
|
## [3.0.0-rc.14](https://github.com/0x676e67/wreq-util/compare/v3.0.0-rc.13...v3.0.0-rc.14) - 2026-07-04
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/wreq_ruby/emulate.rb
CHANGED
|
@@ -66,6 +66,7 @@ module Wreq
|
|
|
66
66
|
Chrome152 = nil
|
|
67
67
|
Chrome153 = nil
|
|
68
68
|
Chrome154 = nil
|
|
69
|
+
Chrome155 = nil
|
|
69
70
|
|
|
70
71
|
Edge101 = nil
|
|
71
72
|
Edge122 = nil
|
|
@@ -264,6 +265,14 @@ module Wreq
|
|
|
264
265
|
# for HTTP/2 and automatic default headers. The actual implementation is
|
|
265
266
|
# provided by Rust.
|
|
266
267
|
#
|
|
268
|
+
# Construction generates the native configuration once. For Chrome 152/153,
|
|
269
|
+
# the TLS trust_anchors extension's ID order is randomized at construction;
|
|
270
|
+
# Chrome 154/155 sort those IDs by their raw bytes instead. Reusing this object
|
|
271
|
+
# across clients or requests retains that order. Creating a new object generates
|
|
272
|
+
# a new configuration, including a fresh shuffle for Chrome 152/153.
|
|
273
|
+
# This does not freeze other per-handshake randomness or force a new handshake
|
|
274
|
+
# when a request reuses an existing connection.
|
|
275
|
+
#
|
|
267
276
|
# `profile:` defaults to the library's default profile when omitted.
|
|
268
277
|
# `platform:` defaults to the library's default platform when omitted.
|
|
269
278
|
#
|
|
@@ -289,6 +298,10 @@ module Wreq
|
|
|
289
298
|
# Native fields and methods are set by the extension.
|
|
290
299
|
# This stub is for documentation only.
|
|
291
300
|
unless singleton_methods(false).include?(:new)
|
|
301
|
+
# Generates a reusable native configuration. Chrome 152/153 Trust Anchor ID
|
|
302
|
+
# order is chosen here and retained when this object is reused; Chrome 154/155
|
|
303
|
+
# use raw-byte sorted order. See {Emulation} for connection semantics.
|
|
304
|
+
#
|
|
292
305
|
# @param profile [Wreq::Profile, nil] Fingerprint profile to emulate
|
|
293
306
|
# @param platform [Wreq::Platform, nil] Operating system platform to emulate
|
|
294
307
|
# @param http2 [Boolean, nil] Whether HTTP/2 emulation is enabled; defaults
|
data/test/emulation_test.rb
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "test_helper"
|
|
4
|
+
require "socket"
|
|
5
|
+
require "stringio"
|
|
6
|
+
require "timeout"
|
|
4
7
|
|
|
5
8
|
class EmulationTest < Minitest::Test
|
|
9
|
+
def test_reused_emulation_retains_trust_anchors_across_clients_and_requests
|
|
10
|
+
[Wreq::Profile::Chrome152, Wreq::Profile::Chrome153, Wreq::Profile::Chrome154, Wreq::Profile::Chrome155].each do |profile|
|
|
11
|
+
emulation = Wreq::Emulation.new(profile: profile)
|
|
12
|
+
client = Wreq::Client.new(emulation: emulation, no_proxy: true)
|
|
13
|
+
expected = capture_trust_anchors { |url| client.get(url, timeout: 5) }
|
|
14
|
+
refute_empty expected, profile.to_s
|
|
15
|
+
|
|
16
|
+
request_client = Wreq::Client.new(no_proxy: true)
|
|
17
|
+
2.times do
|
|
18
|
+
actual = capture_trust_anchors do |url|
|
|
19
|
+
request_client.get(url, emulation: emulation, timeout: 5)
|
|
20
|
+
end
|
|
21
|
+
assert_equal expected, actual, "#{profile}: reusing an object must retain its configuration"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
6
26
|
def test_all_emulation_device_constants_are_non_nil
|
|
7
27
|
Wreq::Profile.constants.each do |name|
|
|
8
28
|
const = Wreq::Profile.const_get(name)
|
|
@@ -23,6 +43,7 @@ class EmulationTest < Minitest::Test
|
|
|
23
43
|
Wreq::Profile::Chrome152 => "Chrome152",
|
|
24
44
|
Wreq::Profile::Chrome153 => "Chrome153",
|
|
25
45
|
Wreq::Profile::Chrome154 => "Chrome154",
|
|
46
|
+
Wreq::Profile::Chrome155 => "Chrome155",
|
|
26
47
|
Wreq::Profile::Firefox152 => "Firefox152"
|
|
27
48
|
}.each do |profile, name|
|
|
28
49
|
assert_equal name, profile.to_s
|
|
@@ -37,4 +58,60 @@ class EmulationTest < Minitest::Test
|
|
|
37
58
|
"#{name} should be Platform, got #{const.inspect}"
|
|
38
59
|
end
|
|
39
60
|
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# Each listener forces a new connection. Stop after ClientHello so this test
|
|
65
|
+
# inspects the extension bytes without depending on certificates or the network.
|
|
66
|
+
def capture_trust_anchors
|
|
67
|
+
server = TCPServer.new("127.0.0.1", 0)
|
|
68
|
+
thread = Thread.new do
|
|
69
|
+
socket = nil
|
|
70
|
+
Timeout.timeout(5) do
|
|
71
|
+
socket = server.accept
|
|
72
|
+
handshake = +"".b
|
|
73
|
+
loop do
|
|
74
|
+
header = read_tls_bytes(socket, 5)
|
|
75
|
+
raise "expected a TLS handshake record" unless header.getbyte(0) == 22
|
|
76
|
+
handshake << read_tls_bytes(socket, header.byteslice(3, 2).unpack1("n"))
|
|
77
|
+
next if handshake.bytesize < 4
|
|
78
|
+
length = handshake.byteslice(1, 3).bytes.reduce(0) { |n, byte| (n << 8) | byte }
|
|
79
|
+
break if handshake.bytesize >= length + 4
|
|
80
|
+
end
|
|
81
|
+
trust_anchors_from_client_hello(handshake)
|
|
82
|
+
end
|
|
83
|
+
ensure
|
|
84
|
+
socket&.close
|
|
85
|
+
end
|
|
86
|
+
thread.report_on_exception = false
|
|
87
|
+
|
|
88
|
+
assert_raises(Wreq::ConnectionError) { yield "https://127.0.0.1:#{server.addr[1]}/" }
|
|
89
|
+
thread.value
|
|
90
|
+
ensure
|
|
91
|
+
server&.close
|
|
92
|
+
thread&.kill if thread&.alive?
|
|
93
|
+
thread&.join
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def read_tls_bytes(io, length)
|
|
97
|
+
bytes = io.read(length)
|
|
98
|
+
raise EOFError, "truncated ClientHello" unless bytes&.bytesize == length
|
|
99
|
+
bytes
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def trust_anchors_from_client_hello(handshake)
|
|
103
|
+
io = StringIO.new(handshake)
|
|
104
|
+
raise "expected ClientHello" unless read_tls_bytes(io, 1).unpack1("C") == 1
|
|
105
|
+
read_tls_bytes(io, 3 + 2 + 32) # Handshake length, legacy version and random.
|
|
106
|
+
read_tls_bytes(io, read_tls_bytes(io, 1).unpack1("C")) # Session ID.
|
|
107
|
+
read_tls_bytes(io, read_tls_bytes(io, 2).unpack1("n")) # Cipher suites.
|
|
108
|
+
read_tls_bytes(io, read_tls_bytes(io, 1).unpack1("C")) # Compression methods.
|
|
109
|
+
extensions = StringIO.new(read_tls_bytes(io, read_tls_bytes(io, 2).unpack1("n")))
|
|
110
|
+
until extensions.eof?
|
|
111
|
+
type, length = read_tls_bytes(extensions, 4).unpack("nn")
|
|
112
|
+
data = read_tls_bytes(extensions, length)
|
|
113
|
+
return data if type == 51764
|
|
114
|
+
end
|
|
115
|
+
raise "missing trust_anchors extension"
|
|
116
|
+
end
|
|
40
117
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wreq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: x86_64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- SearchApi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: An easy and powerful Ruby HTTP client with advanced browser fingerprinting
|
|
14
14
|
that accurately emulates Chrome, Edge, Firefox, Safari, Opera, and OkHttp with precise
|