patron 0.13.1 → 0.13.4
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 +5 -5
- data/.github/workflows/ci.yml +26 -0
- data/.travis.yml +10 -11
- data/CHANGELOG.md +21 -1
- data/Gemfile +14 -1
- data/README.md +92 -50
- data/ext/patron/extconf.rb +3 -4
- data/ext/patron/session_ext.c +111 -138
- data/lib/patron/request.rb +2 -2
- data/lib/patron/session.rb +2 -4
- data/lib/patron/version.rb +1 -1
- data/patron.gemspec +6 -14
- data/spec/patron_spec.rb +1 -1
- data/spec/session_spec.rb +119 -68
- data/spec/session_ssl_spec.rb +43 -40
- data/spec/spec_helper.rb +14 -2
- data/spec/support/config.ru +31 -15
- data/spec/support/fork.rb +70 -0
- data/spec/support/test_server.rb +12 -6
- metadata +13 -125
- /data/spec/{certs → support/certs}/cacert.pem +0 -0
- /data/spec/{certs → support/certs}/privkey.pem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f900014f4c841d87c4db54f3db3f33d9b624d5a6dde0eb9352b7a70cc6f330b7
|
4
|
+
data.tar.gz: 31b35805166302cb5527734b70c3607f9dbb951e2c1e3aafd465f7f8d5dbbb75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1989abb0ba1be73ed08df186d05349c6519a90663a7263799a1e97e024e5183ff6de9f49ab329ebf4e3b49c4c571d0e3ca7efed3bc5f803ad8edbe96a6554ff6
|
7
|
+
data.tar.gz: dc03c98c0f363d7d7bf273b72a62954dadb590c1236baf06739f6fdebd6ae5007afc243dc526c97359165c19244868779fc4168cc9f972c32cbf8fef81a56521
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby-version: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, 3.3, 3.4.1]
|
12
|
+
|
13
|
+
name: Specs - Ruby ${{ matrix.ruby-version }}
|
14
|
+
steps:
|
15
|
+
- uses: actions/checkout@v4
|
16
|
+
- name: Install libcurl
|
17
|
+
run: |
|
18
|
+
sudo apt-get update
|
19
|
+
sudo apt-get -y install libcurl4 libcurl4-openssl-dev
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true # 'bundle install' and cache
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
data/.travis.yml
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
rvm:
|
2
|
-
-
|
3
|
-
- 2.
|
4
|
-
- 2.
|
5
|
-
- 2.
|
6
|
-
-
|
7
|
-
|
8
|
-
sudo: false
|
2
|
+
- 2.3.8
|
3
|
+
- 2.4.5
|
4
|
+
- 2.5.3
|
5
|
+
- 2.6.1
|
6
|
+
- ruby-head
|
7
|
+
|
9
8
|
dist: trusty
|
10
9
|
cache: bundler
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
|
11
|
+
matrix:
|
12
|
+
allow_failures:
|
13
|
+
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,24 @@
|
|
1
|
-
### 0.13.
|
1
|
+
### 0.13.4
|
2
|
+
|
3
|
+
* Format README a bit better using code fences
|
4
|
+
* Depend explicitly on base64 for running tests
|
5
|
+
* Remove C code used for Ruby support below < 2.4 (GVL unlock etc.) and drop support for these versions
|
6
|
+
* In tests, close Tempfiles before allowing libcurl to use them (cookie jar)
|
7
|
+
* Fix incorrect ptr type in uses of `curl_easy_escape` / `_unescape`
|
8
|
+
* Define methods on `Session` as private instance methods from C instead of privatising them from Ruby
|
9
|
+
* Speed up the /slow endpoint test
|
10
|
+
* Remove use of `curl_easy_reset`. This should fix the bug with sessions resetting each other's state during `session_free`
|
11
|
+
|
12
|
+
### 0.13.3
|
13
|
+
|
14
|
+
* Run Puma test servers in separate processes instead of threads
|
15
|
+
|
16
|
+
### 0.13.2
|
17
|
+
|
18
|
+
* Eagerly initialize libCURL handle when creating the Session instance instead of initializing it lazily
|
19
|
+
* Remove special treatment of `Session#reset` and make it the same as `Session#interrupt`
|
20
|
+
|
21
|
+
### 0.13.0, 0.13.1
|
2
22
|
|
3
23
|
* Permit timeouts to be set as a Float of seconds and use `CURLOPT_(CONNECT)TIMEOUT_MS` instead of `CURLOPT_(CONNECT)TIMEOUT` so that
|
4
24
|
sub-second timeouts can be configured, which is useful for performant services using accelerated DNS resolution.
|
data/Gemfile
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
#
|
3
|
+
# Runtime dependencies are in the gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
# Gems below are only needed for Patron development
|
7
|
+
# and tests
|
8
|
+
gem "rake", ">= 12.3.3"
|
9
|
+
gem "rspec", ">= 2.3.0"
|
10
|
+
gem "simplecov", "~> 0.10"
|
11
|
+
gem "yard", "~> 0.9.20"
|
12
|
+
rack_version = RUBY_VERSION >= "3.3" ? "~> 2.2" : "~> 2.1.4"
|
13
|
+
gem "rack", rack_version
|
14
|
+
gem "puma", '~> 3.11'
|
15
|
+
gem "rake-compiler"
|
16
|
+
gem "webrick", "~> 1.8"
|
17
|
+
gem "base64"
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# Patron
|
2
|
+
|
3
|
+
[](https://travis-ci.org/toland/patron)
|
4
|
+
|
1
5
|
Patron is a Ruby HTTP client library based on libcurl. It does not try to expose
|
2
6
|
the full "power" (read complexity) of libcurl but instead tries to provide a
|
3
7
|
sane API while taking advantage of libcurl under the hood.
|
@@ -8,52 +12,114 @@ First, you instantiate a Session object. You can set a few
|
|
8
12
|
default options on the Session instance that will be used by all subsequent
|
9
13
|
requests:
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
```ruby
|
16
|
+
sess = Patron::Session.new
|
17
|
+
sess.timeout = 10
|
18
|
+
sess.base_url = "http://myserver.com:9900"
|
19
|
+
sess.headers['User-Agent'] = 'myapp/1.0'
|
20
|
+
```
|
15
21
|
|
16
22
|
You can set options with a hash in the constructor:
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
```ruby
|
25
|
+
sess = Patron::Session.new({ :timeout => 10,
|
26
|
+
:base_url => 'http://myserver.com:9900',
|
27
|
+
:headers => {'User-Agent' => 'myapp/1.0'} } )
|
28
|
+
```
|
21
29
|
|
22
30
|
Or the set options in a block:
|
23
31
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
```ruby
|
33
|
+
sess = Patron::Session.new do |patron|
|
34
|
+
patron.timeout = 10
|
35
|
+
patron.base_url = 'http://myserver.com:9900'
|
36
|
+
patron.headers = {'User-Agent' => 'myapp/1.0'}
|
37
|
+
end
|
38
|
+
```
|
29
39
|
|
30
40
|
Output debug log:
|
31
41
|
|
32
|
-
|
42
|
+
```ruby
|
43
|
+
sess.enable_debug "/tmp/patron.debug"
|
44
|
+
```
|
33
45
|
|
34
46
|
The Session is used to make HTTP requests.
|
35
47
|
|
36
|
-
|
48
|
+
```ruby
|
49
|
+
resp = sess.get("/foo/bar")
|
50
|
+
```
|
37
51
|
|
38
52
|
Requests return a Response object:
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
|
54
|
+
```ruby
|
55
|
+
if resp.status < 400
|
56
|
+
puts resp.body
|
57
|
+
end
|
58
|
+
```
|
43
59
|
|
44
60
|
The GET, HEAD, PUT, POST and DELETE operations are all supported.
|
45
61
|
|
46
|
-
|
47
|
-
|
62
|
+
```ruby
|
63
|
+
sess.put("/foo/baz", "some data")
|
64
|
+
sess.delete("/foo/baz")
|
65
|
+
```
|
48
66
|
|
49
67
|
You can ship custom headers with a single request:
|
50
68
|
|
51
|
-
|
69
|
+
```ruby
|
70
|
+
sess.post("/foo/stuff", "some data", {"Content-Type" => "text/plain"})
|
71
|
+
```
|
72
|
+
|
73
|
+
## Threading
|
74
|
+
|
75
|
+
By itself, the `Patron::Session` objects are not thread safe (each `Session` holds a single `curl_state` pointer
|
76
|
+
from initialization to garbage collection). At this time, Patron has no support for `curl_multi_*` family of functions
|
77
|
+
for doing concurrent requests. However, the actual code that interacts with libCURL does unlock the RVM GIL,
|
78
|
+
so using multiple `Session` objects in different threads actually enables a high degree of parallelism.
|
79
|
+
For sharing a resource of sessions between threads we recommend using the excellent [connection_pool](https://rubygems.org/gems/connection_pool) gem by Mike Perham.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
patron_pool = ConnectionPool.new(size: 5, timeout: 5) { Patron::Session.new }
|
83
|
+
patron_pool.with do |session|
|
84
|
+
session.get(...)
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
Sharing Session objects between requests will also allow you to benefit from persistent connections (connection reuse), see below.
|
89
|
+
|
90
|
+
## Persistent connections
|
91
|
+
|
92
|
+
Patron follows the libCURL guidelines on [connection reuse.](https://everything.curl.dev/libcurl/connectionreuse.html) If you create the Session
|
93
|
+
object once and use it for multiple requests, the same libCURL handle is going to be used across these requests and if requests go to
|
94
|
+
the same hostname/port/protocol the connection should get reused.
|
95
|
+
|
96
|
+
## Performance with parallel requests
|
97
|
+
|
98
|
+
When performing the libCURL request, Patron goes out of it's way to unlock the GVL (global VM lock) to allow other threads to be scheduled
|
99
|
+
in parallel. The GVL is going to be released when the libCURL request starts, and will then be shortly re-acquired to provide the progress
|
100
|
+
callback - if the callback has been configured, and then released again until the libCURL request has been performed and the response has
|
101
|
+
been read in full. This allows one to execute multiple libCURL requests in parallel, as well as perform other activities on other MRI threads
|
102
|
+
that are currently active in the process.
|
103
|
+
|
104
|
+
## Requirements
|
105
|
+
|
106
|
+
Patron 1.0 and up requires MRI Ruby 2.3 or newer. The 0.x versions support
|
107
|
+
Ruby 1.9.3 and these versions get tagged and developed on the `v0.x` branch.
|
108
|
+
|
109
|
+
A recent version of libCURL is required. We recommend at least 7.19.4 because
|
110
|
+
it [supports limiting the protocols](https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html),
|
111
|
+
and that is very important for security - especially if you follow redirects.
|
52
112
|
|
53
|
-
|
113
|
+
On OSX the provided libcurl is sufficient if you are not using fork+SSL combination (see below).
|
114
|
+
You will have to install the libcurl development packages on Debian or Ubuntu. Other Linux systems are probably
|
115
|
+
similar. For Windows we do not have an established build instruction at the moment, unfortunately.
|
54
116
|
|
55
|
-
|
56
|
-
|
117
|
+
## Forking webservers on macOS and SSL
|
118
|
+
|
119
|
+
Currently, [an issue is at play](https://github.com/curl/curl/issues/788) with OSX builds of `curl` which use
|
120
|
+
Apple's SecureTransport. Such builds (which Patron is linking to), are causing segfaults when performing HTTPS
|
121
|
+
requests in forked subprocesses. If you need to check whether your system is affected,
|
122
|
+
run the Patron test suite by performing
|
57
123
|
|
58
124
|
$ bundle install && bundle exec rspec
|
59
125
|
|
@@ -69,37 +135,13 @@ When doing so, `curl` will use openssl as it's SSL driver. You also need to
|
|
69
135
|
change the Patron compile flag:
|
70
136
|
|
71
137
|
|
72
|
-
$ brew install curl
|
73
|
-
gem install patron --with-curl-config=/usr/local/opt/curl/bin/curl-config
|
138
|
+
$ brew install curl-openssl && \
|
139
|
+
gem install patron -- --with-curl-config=/usr/local/opt/curl-openssl/bin/curl-config
|
74
140
|
|
75
141
|
You can also save this parameter for all future Bundler-driven gem installs by
|
76
142
|
setting this flag in Bundler proper:
|
77
143
|
|
78
|
-
$ bundle config build.patron --with-curl-config=/usr/local/opt/curl/bin/curl-config
|
79
|
-
|
80
|
-
## Threading
|
81
|
-
|
82
|
-
By itself, the `Patron::Session` objects are not thread safe (each `Session` holds a single `curl_state` pointer
|
83
|
-
during the request/response cycle). At this time, Patron has no support for `curl_multi_*` family of functions
|
84
|
-
for doing concurrent requests. However, the actual code that interacts with libCURL does unlock the RVM GIL,
|
85
|
-
so using multiple `Session` objects in different threads is possible with a high degree of concurrency.
|
86
|
-
For sharing a resource of sessions between threads we recommend using the excellent [connection_pool](https://rubygems.org/gems/connection_pool) gem by Mike Perham.
|
87
|
-
|
88
|
-
patron_pool = ConnectionPool.new(size: 5, timeout: 5) { Patron::Session.new }
|
89
|
-
patron_pool.with do |session|
|
90
|
-
session.get(...)
|
91
|
-
end
|
92
|
-
|
93
|
-
## Requirements
|
94
|
-
|
95
|
-
Patron uses encoding features of Ruby, so you need at least Ruby 1.9. Also, a
|
96
|
-
recent version of libCURL is required. We recommend at least 7.19.4 because
|
97
|
-
it [supports limiting the protocols](https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html),
|
98
|
-
and that is very important for security - especially if you follow redirects.
|
99
|
-
|
100
|
-
On OSX the provided libcurl is sufficient. You will have to install the libcurl
|
101
|
-
development packages on Debian or Ubuntu. Other Linux systems are probably
|
102
|
-
similar. For Windows we do not have an established build instruction at the moment, unfortunately.
|
144
|
+
$ bundle config build.patron --with-curl-config=/usr/local/opt/curl-openssl/bin/curl-config
|
103
145
|
|
104
146
|
## Installation
|
105
147
|
|
data/ext/patron/extconf.rb
CHANGED
@@ -19,9 +19,8 @@ if CONFIG['CC'] =~ /gcc/
|
|
19
19
|
$CFLAGS << ' -pedantic -Wall'
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
$
|
24
|
-
|
25
|
-
$defs.push("-DHAVE_TCWOGVL") if have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
|
22
|
+
if CONFIG['CC'] =~ /clang/
|
23
|
+
$CFLAGS << ' -pedantic -Wall -Wno-void-pointer-to-enum-cast'
|
24
|
+
end
|
26
25
|
|
27
26
|
create_makefile 'patron/session_ext'
|