patron 0.13.4 → 0.14.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/.github/dependabot.yml +6 -0
- data/.github/workflows/ci.yml +56 -3
- data/CHANGELOG.md +20 -0
- data/Gemfile +2 -1
- data/README.md +30 -1
- data/ext/patron/extconf.rb +4 -0
- data/ext/patron/session_ext.c +285 -75
- data/lib/patron/error.rb +4 -0
- data/lib/patron/request.rb +6 -4
- data/lib/patron/response.rb +5 -0
- data/lib/patron/session.rb +17 -0
- data/lib/patron/version.rb +1 -1
- data/patron.gemspec +2 -1
- data/script/generate_client_certs +65 -0
- data/spec/request_spec.rb +12 -0
- data/spec/session_spec.rb +178 -11
- data/spec/session_ssl_spec.rb +126 -8
- data/spec/spec_helper.rb +6 -0
- data/spec/support/certs/client.p12 +0 -0
- data/spec/support/certs/client_ca.pem +20 -0
- data/spec/support/certs/client_cert.pem +20 -0
- data/spec/support/certs/client_key.pem +30 -0
- data/spec/support/certs/rogue_client.p12 +0 -0
- data/spec/support/config.ru +7 -0
- data/spec/support/raw_request_capture.rb +93 -0
- data/spec/support/test_server.rb +6 -3
- data/spec/support/valgrind.supp +2 -0
- metadata +13 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 355b38921e6368ee1ad7815cd78ad9135630b10c82d60365978747e4189be390
|
|
4
|
+
data.tar.gz: efbebf2f2e6393e93411d5583c9062b3170e0bf4e30ae370d1e998110b19c3c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 760418bb81862c742f9873caa2513a6ed60093a084145b77e9f21996f041b0e848a0a6914e0248c0dca806bc5313c59eed68afd2546c828218a2e0aa52734ecf
|
|
7
|
+
data.tar.gz: 77510952d581ea162ef55e93260fc8188e58b5f919dd97912c6d7b40863c94e2c517027c6de5fe2b5041431fb9645c85ad674b08f37ce7e2fcdb37b4f16f2da2
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -4,15 +4,19 @@ on: [push, pull_request]
|
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
6
|
test:
|
|
7
|
-
runs-on: ubuntu-
|
|
7
|
+
runs-on: ubuntu-24.04
|
|
8
|
+
continue-on-error: ${{ matrix.allow-failure || false }}
|
|
8
9
|
strategy:
|
|
9
10
|
fail-fast: false
|
|
10
11
|
matrix:
|
|
11
|
-
ruby-version: [2.4,
|
|
12
|
+
ruby-version: ["2.4", "3.0", "3.4.1", "4.0.5"]
|
|
13
|
+
include:
|
|
14
|
+
- ruby-version: "head"
|
|
15
|
+
allow-failure: true
|
|
12
16
|
|
|
13
17
|
name: Specs - Ruby ${{ matrix.ruby-version }}
|
|
14
18
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@v7
|
|
16
20
|
- name: Install libcurl
|
|
17
21
|
run: |
|
|
18
22
|
sudo apt-get update
|
|
@@ -24,3 +28,52 @@ jobs:
|
|
|
24
28
|
bundler-cache: true # 'bundle install' and cache
|
|
25
29
|
- name: Run tests
|
|
26
30
|
run: bundle exec rake
|
|
31
|
+
|
|
32
|
+
valgrind:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
name: Specs under valgrind memcheck
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v7
|
|
37
|
+
- name: Install libcurl and valgrind
|
|
38
|
+
run: |
|
|
39
|
+
sudo apt-get update
|
|
40
|
+
sudo apt-get -y install libcurl4-openssl-dev valgrind
|
|
41
|
+
- name: Set up Ruby
|
|
42
|
+
uses: ruby/setup-ruby@v1
|
|
43
|
+
with:
|
|
44
|
+
ruby-version: "3.4"
|
|
45
|
+
bundler-cache: true
|
|
46
|
+
- name: Compile the extension with debug info
|
|
47
|
+
run: bundle exec rake clobber compile
|
|
48
|
+
env:
|
|
49
|
+
PATRON_EXTRA_CFLAGS: "-g -O1"
|
|
50
|
+
- name: Run the specs under memcheck
|
|
51
|
+
# The ruby process itself is under valgrind (bundle exec only sets up the environment).
|
|
52
|
+
# Specs tagged :timing assert on wall-clock windows that valgrind's slowdown breaks.
|
|
53
|
+
run: |
|
|
54
|
+
bundle exec valgrind --error-exitcode=99 --leak-check=no --undef-value-errors=no \
|
|
55
|
+
--child-silent-after-fork=yes --num-callers=30 \
|
|
56
|
+
--suppressions=spec/support/valgrind.supp \
|
|
57
|
+
ruby -S rspec --tag ~timing
|
|
58
|
+
|
|
59
|
+
malloc-check:
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
name: Specs with glibc malloc checking
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v7
|
|
64
|
+
- name: Install libcurl
|
|
65
|
+
run: |
|
|
66
|
+
sudo apt-get update
|
|
67
|
+
sudo apt-get -y install libcurl4-openssl-dev
|
|
68
|
+
- name: Set up Ruby
|
|
69
|
+
uses: ruby/setup-ruby@v1
|
|
70
|
+
with:
|
|
71
|
+
ruby-version: "3.4"
|
|
72
|
+
bundler-cache: true
|
|
73
|
+
- name: Run tests
|
|
74
|
+
# glibc aborts on heap corruption and fills freed memory with 0xA5, so a use-after-free
|
|
75
|
+
# shows up as garbage data rather than passing by luck
|
|
76
|
+
run: bundle exec rake
|
|
77
|
+
env:
|
|
78
|
+
MALLOC_CHECK_: "3"
|
|
79
|
+
MALLOC_PERTURB_: "165"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
### Unreleased
|
|
2
|
+
|
|
3
|
+
### 0.14.0
|
|
4
|
+
|
|
5
|
+
* Expose libcurl's transfer timings (name lookup, connect, TLS, first byte, total) as `Response#timings`
|
|
6
|
+
* Add `ssl_cert`, `ssl_cert_type`, `ssl_key` and `ssl_key_password` for presenting a client certificate (mutual TLS). Thanks @lenage for the original contribution in #165
|
|
7
|
+
* Raise `Patron::ClientCertificateError` when the client certificate or its key can't be used
|
|
8
|
+
* Accept a `Pathname` for `cacert`
|
|
9
|
+
* Fix a request whose options fail to apply (for example an option of the wrong type) leaking its headers and open files into the next request on the same `Session`
|
|
10
|
+
* Fix the request body being read from freed memory when `upload_data` is not a String (its `#to_s` result was not kept alive during the transfer)
|
|
11
|
+
* Fix multipart field names and values pointing at temporary Strings, and binary multipart values being cut at the first NUL byte
|
|
12
|
+
* Fix an exception raised inside `progress_callback` (including `Timeout.timeout` and `Thread#raise`) unwinding through libcurl; it is now re-raised after the transfer is aborted
|
|
13
|
+
* Raise `Patron::Error` when a second thread uses a `Session` that is already performing a request, instead of corrupting both requests
|
|
14
|
+
* Fix the progress callback being declared with `size_t` arguments where libcurl passes `curl_off_t`
|
|
15
|
+
* Accept `download_byte_limit` above 2 GiB, and Floats for `dns_cache_timeout`, `low_speed_time` and `low_speed_limit`
|
|
16
|
+
* Fix `Session#unescape` cutting the result at a `%00`, and raise instead of crashing when libcurl fails to escape or unescape
|
|
17
|
+
* Reject file paths containing NUL bytes for cookie files, debug output and uploads
|
|
18
|
+
* Raise `NoMemoryError` instead of crashing later when libcurl cannot allocate a Session's handles
|
|
19
|
+
* Register the exception classes the extension looks up at load time with the GC, so heap compaction (`GC.compact`, `GC.auto_compact`) cannot move them out from under `rb_raise`
|
|
20
|
+
|
|
1
21
|
### 0.13.4
|
|
2
22
|
|
|
3
23
|
* Format README a bit better using code fences
|
data/Gemfile
CHANGED
|
@@ -11,7 +11,8 @@ gem "simplecov", "~> 0.10"
|
|
|
11
11
|
gem "yard", "~> 0.9.20"
|
|
12
12
|
rack_version = RUBY_VERSION >= "3.3" ? "~> 2.2" : "~> 2.1.4"
|
|
13
13
|
gem "rack", rack_version
|
|
14
|
-
gem "puma", '~>
|
|
14
|
+
gem "puma", '~> 5.6'
|
|
15
15
|
gem "rake-compiler"
|
|
16
16
|
gem "webrick", "~> 1.8"
|
|
17
17
|
gem "base64"
|
|
18
|
+
gem "ostruct"
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Patron
|
|
2
2
|
|
|
3
|
-
[](https://github.com/toland/patron/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
5
|
Patron is a Ruby HTTP client library based on libcurl. It does not try to expose
|
|
6
6
|
the full "power" (read complexity) of libcurl but instead tries to provide a
|
|
@@ -70,6 +70,35 @@ You can ship custom headers with a single request:
|
|
|
70
70
|
sess.post("/foo/stuff", "some data", {"Content-Type" => "text/plain"})
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
libcurl's transfer timings are available on the response, in seconds since the request started:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
resp = sess.get("/foo/bar")
|
|
77
|
+
resp.timings # => {namelookup: 0.001, connect: 0.012, appconnect: 0.045, pretransfer: 0.045,
|
|
78
|
+
# starttransfer: 0.210, redirect: 0.0, total: 0.214}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
To authenticate with a client certificate (mutual TLS), point Patron at a PKCS#12 bundle:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
sess.ssl_cert = "/path/to/client.p12"
|
|
85
|
+
sess.ssl_cert_type = "P12"
|
|
86
|
+
sess.ssl_key_password = "secret"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
or at a PEM certificate with a separate private key:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
sess.ssl_cert = "/path/to/client.pem"
|
|
93
|
+
sess.ssl_key = "/path/to/client_key.pem"
|
|
94
|
+
sess.ssl_key_password = "secret" # if the key is encrypted
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the certificate or key can't be loaded (wrong password, missing file) the request raises `Patron::ClientCertificateError`.
|
|
98
|
+
This depends on the TLS library libcurl is built against: with GnuTLS these surface as a plain `Patron::Error`.
|
|
99
|
+
Client certificates are tested with the OpenSSL and LibreSSL backends - libcurl's Secure Transport backend
|
|
100
|
+
can't load a PEM certificate from a file at all.
|
|
101
|
+
|
|
73
102
|
## Threading
|
|
74
103
|
|
|
75
104
|
By itself, the `Patron::Session` objects are not thread safe (each `Session` holds a single `curl_state` pointer
|
data/ext/patron/extconf.rb
CHANGED
|
@@ -23,4 +23,8 @@ if CONFIG['CC'] =~ /clang/
|
|
|
23
23
|
$CFLAGS << ' -pedantic -Wall -Wno-void-pointer-to-enum-cast'
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Lets CI build with debug info for valgrind without editing this file, like so:
|
|
27
|
+
# PATRON_EXTRA_CFLAGS="-g -O1" rake compile
|
|
28
|
+
$CFLAGS << ' ' << ENV['PATRON_EXTRA_CFLAGS'] if ENV['PATRON_EXTRA_CFLAGS']
|
|
29
|
+
|
|
26
30
|
create_makefile 'patron/session_ext'
|