patron 0.13.1 → 0.13.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cdaf7a10ef1cf673746f7f87ae77a9d939b461fc
4
- data.tar.gz: 772139466802595a3906e24f297da437de3df880
2
+ SHA256:
3
+ metadata.gz: e766e45bfa71015943701e1340503df7f915d499cd001475649613175df4006d
4
+ data.tar.gz: 8b3a7d7fcb6d555dfff1705685c8685b925c900dfec95200816580028ffa9d53
5
5
  SHA512:
6
- metadata.gz: 94787a3fd98f9253862432e8069c5088dfc703f3bb6e69ebb2e60f86d70a489a8cb2c72d2134e690649d0e908ff08068631e0cc148f41b331fca5cf4f95dc6cb
7
- data.tar.gz: 19496dff4f0687cbcd664c3aa81969c5b1a810aba28f87ab9f918a05771a5567d348acdc8b862c2b430e9304854796e034fc9d68361aa2d5b16e2cd0b17bd63b
6
+ metadata.gz: 986e1bb343ea53368a6acb8f7d7ef84a48674408d4a08f7eabe1d2e2c6ff5c90f2afe0683d1e66ab751c72241a25c9f46c8e16c955c97b87c71a0bc2bd7db723
7
+ data.tar.gz: c285b097c1fc4022fce3484184ac44d471340a496bc246142233e655bfdf0a28653484490ce5b1802fac4d5b396bea8ca03cfd1c803867f7c07ff3d8a789335c
@@ -8,7 +8,3 @@ rvm:
8
8
  sudo: false
9
9
  dist: trusty
10
10
  cache: bundler
11
- install:
12
- - gem update --system 2.6.12 # https://github.com/rubygems/rubygems/issues/2024
13
- - gem install bundler
14
- - "bundle install --verbose --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}"
@@ -1,4 +1,13 @@
1
- ### 0.13.0
1
+ ### 0.13.3
2
+
3
+ * Fix a number of specs that were failing due to use of threads
4
+
5
+ ### 0.13.2
6
+
7
+ * Eagerly initialize libCURL handle when creating the Session instance instead of initializing it lazily
8
+ * Remove special treatment of `Session#reset` and make it the same as `Session#interrupt`
9
+
10
+ ### 0.13.0, 0.13.1
2
11
 
3
12
  * Permit timeouts to be set as a Float of seconds and use `CURLOPT_(CONNECT)TIMEOUT_MS` instead of `CURLOPT_(CONNECT)TIMEOUT` so that
4
13
  sub-second timeouts can be configured, which is useful for performant services using accelerated DNS resolution.
data/README.md CHANGED
@@ -50,10 +50,55 @@ You can ship custom headers with a single request:
50
50
 
51
51
  sess.post("/foo/stuff", "some data", {"Content-Type" => "text/plain"})
52
52
 
53
- ## Known issues
53
+ ## Threading
54
+
55
+ By itself, the `Patron::Session` objects are not thread safe (each `Session` holds a single `curl_state` pointer
56
+ from initialization to garbage collection). At this time, Patron has no support for `curl_multi_*` family of functions
57
+ for doing concurrent requests. However, the actual code that interacts with libCURL does unlock the RVM GIL,
58
+ so using multiple `Session` objects in different threads actually enables a high degree of parallelism.
59
+ 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.
60
+
61
+ patron_pool = ConnectionPool.new(size: 5, timeout: 5) { Patron::Session.new }
62
+ patron_pool.with do |session|
63
+ session.get(...)
64
+ end
65
+
66
+ Sharing Session objects between requests will also allow you to benefit from persistent connections (connection reuse), see below.
67
+
68
+ ## Persistent connections
69
+
70
+ Patron follows the libCURL guidelines on [connection reuse.](https://ec.haxx.se/libcurl-connectionreuse.html) If you create the Session
71
+ 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
72
+ the same hostname/port/protocol the connection should get reused.
73
+
74
+ ## Performance with parallel requests
75
+
76
+ 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
77
+ 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
78
+ callback - if the callback has been configured, and then released again until the libCURL request has been performed and the response has
79
+ been read in full. This allows one to execute multiple libCURL requests in parallel, as well as perform other activities on other MRI threads
80
+ that are currently active in the process.
81
+
82
+ ## Requirements
83
+
84
+ Patron uses encoding features of Ruby, so you need at least Ruby 1.9. Also, a
85
+ recent version of libCURL is required. We recommend at least 7.19.4 because
86
+ it [supports limiting the protocols](https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html),
87
+ and that is very important for security - especially if you follow redirects.
88
+
89
+ On OSX the provided libcurl is sufficient if you are not using fork+SSL combination (see below).
90
+ You will have to install the libcurl development packages on Debian or Ubuntu. Other Linux systems are probably
91
+ similar. For Windows we do not have an established build instruction at the moment, unfortunately.
92
+
93
+ Versions of Patron below 1.0 will maintain compatibility down to Ruby 1.9.3,
94
+ versions below 2.0 will maintain compatibility down to Ruby 2.3
95
+
96
+ ## Forking webservers on macOS and SSL
54
97
 
55
- Currently, [an issue is at play](https://github.com/curl/curl/issues/788) with OSX builds of `curl` which use Apple's SecureTransport. Such builds (which Patron is linking to), are causing segfaults when performing HTTPS requests in forked subprocesses. If you need to check whether your
56
- system is affected, run the Patron test suite by performing
98
+ Currently, [an issue is at play](https://github.com/curl/curl/issues/788) with OSX builds of `curl` which use
99
+ Apple's SecureTransport. Such builds (which Patron is linking to), are causing segfaults when performing HTTPS
100
+ requests in forked subprocesses. If you need to check whether your system is affected,
101
+ run the Patron test suite by performing
57
102
 
58
103
  $ bundle install && bundle exec rspec
59
104
 
@@ -69,37 +114,13 @@ When doing so, `curl` will use openssl as it's SSL driver. You also need to
69
114
  change the Patron compile flag:
70
115
 
71
116
 
72
- $ brew install curl --with-openssl && \
73
- gem install patron --with-curl-config=/usr/local/opt/curl/bin/curl-config
117
+ $ brew install curl-openssl && \
118
+ gem install patron -- --with-curl-config=/usr/local/opt/curl-openssl/bin/curl-config
74
119
 
75
120
  You can also save this parameter for all future Bundler-driven gem installs by
76
121
  setting this flag in Bundler proper:
77
122
 
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.
123
+ $ bundle config build.patron --with-curl-config=/usr/local/opt/curl-openssl/bin/curl-config
103
124
 
104
125
  ## Installation
105
126
 
@@ -163,6 +163,7 @@ static void cs_list_remove(struct patron_curl_state *state) {
163
163
  }
164
164
  }
165
165
 
166
+ /* Gets attached to at_exit of the Ruby process to be able to abort all running libCURL requests and quit */
166
167
  static void cs_list_interrupt(VALUE data) {
167
168
  UNUSED_ARGUMENT(data);
168
169
 
@@ -182,7 +183,7 @@ static void session_close_debug_file(struct patron_curl_state *curl) {
182
183
  curl->debug_file = NULL;
183
184
  }
184
185
 
185
- /* Cleans up the Curl handle when the Session object is garbage collected. */
186
+ /* Cleans up the patron_curl_state data when the Session object is garbage collected. */
186
187
  void session_free(struct patron_curl_state *curl) {
187
188
  if (curl->handle) {
188
189
  curl_easy_cleanup(curl->handle);
@@ -201,12 +202,29 @@ void session_free(struct patron_curl_state *curl) {
201
202
 
202
203
  /* Allocates patron_curl_state data needed for a new Session object. */
203
204
  VALUE session_alloc(VALUE klass) {
204
- struct patron_curl_state* curl;
205
- VALUE obj = Data_Make_Struct(klass, struct patron_curl_state, NULL, session_free, curl);
206
-
207
- membuffer_init( &curl->header_buffer );
208
- membuffer_init( &curl->body_buffer );
209
- cs_list_append(curl);
205
+ struct patron_curl_state* state;
206
+ VALUE obj = Data_Make_Struct(klass, struct patron_curl_state, NULL, session_free, state);
207
+
208
+ membuffer_init(&state->header_buffer);
209
+ membuffer_init(&state->body_buffer);
210
+ cs_list_append(state);
211
+
212
+ /*
213
+ Eagerly initialize the curl handle. We initialize it only once and store it
214
+ in the struct until the Session object gets garbage-collected in session_free(). This allows libCURL to
215
+ reuse the TCP connection and can speed things up if the same resource - like a backend service -
216
+ gets accessed over and over with requests.
217
+ */
218
+ state->handle = curl_easy_init();
219
+ curl_easy_setopt(state->handle, CURLOPT_NOSIGNAL, 1);
220
+ curl_easy_setopt(state->handle, CURLOPT_NOPROGRESS, 0);
221
+ #if LIBCURL_VERSION_NUM >= 0x072000
222
+ /* this is libCURLv7.32.0 or later, supports CURLOPT_XFERINFOFUNCTION */
223
+ curl_easy_setopt(state->handle, CURLOPT_XFERINFOFUNCTION, &session_progress_handler);
224
+ #else
225
+ curl_easy_setopt(state->handle, CURLOPT_PROGRESSFUNCTION, &session_progress_handler);
226
+ #endif
227
+ curl_easy_setopt(state->handle, CURLOPT_PROGRESSDATA, state);
210
228
 
211
229
  return obj;
212
230
  }
@@ -215,25 +233,9 @@ VALUE session_alloc(VALUE klass) {
215
233
  static struct patron_curl_state* get_patron_curl_state(VALUE self) {
216
234
  struct patron_curl_state* state;
217
235
  Data_Get_Struct(self, struct patron_curl_state, state);
218
-
219
- if (NULL == state->handle) {
220
- state->handle = curl_easy_init();
221
- curl_easy_setopt(state->handle, CURLOPT_NOSIGNAL, 1);
222
- curl_easy_setopt(state->handle, CURLOPT_NOPROGRESS, 0);
223
- #if LIBCURL_VERSION_NUM >= 0x072000
224
- /* this is libCURLv7.32.0 or later, supports CURLOPT_XFERINFOFUNCTION */
225
- curl_easy_setopt(state->handle, CURLOPT_XFERINFOFUNCTION, &session_progress_handler);
226
- #else
227
- curl_easy_setopt(state->handle, CURLOPT_PROGRESSFUNCTION, &session_progress_handler);
228
- #endif
229
-
230
- curl_easy_setopt(state->handle, CURLOPT_PROGRESSDATA, state);
231
- }
232
-
233
236
  return state;
234
237
  }
235
238
 
236
-
237
239
  /*----------------------------------------------------------------------------*/
238
240
  /* Method implementations */
239
241
 
@@ -887,33 +889,9 @@ static VALUE session_handle_request(VALUE self, VALUE request) {
887
889
  return rb_ensure(&perform_request, self, &cleanup, self);
888
890
  }
889
891
 
890
- /*
891
- * FIXME: figure out how this method should be used at all given Session is not multithreaded.
892
- * FIXME: also: what is the difference with `interrupt()` and also relationship with `cleanup()`?
893
- * Reset the underlying cURL session. This effectively closes all open
894
- * connections and disables debug output. There is no need to call this method
895
- * manually after performing a request, since cleanup is performed automatically
896
- * but the method can be used from another thread
897
- * to abort a request currently in progress.
898
- *
899
- * @return self
900
- */
901
- static VALUE session_reset(VALUE self) {
902
- struct patron_curl_state *state;
903
- Data_Get_Struct(self, struct patron_curl_state, state);
904
-
905
- if (NULL != state->handle) {
906
- cleanup(self);
907
- curl_easy_cleanup(state->handle);
908
- state->handle = NULL;
909
- session_close_debug_file(state);
910
- }
911
-
912
- return self;
913
- }
914
-
915
892
  /* Interrupt any currently executing request. This will cause the current
916
- * request to error and raise an exception.
893
+ * request to error and raise an exception. The method can be called from another thread to
894
+ * abort the request in-flight.
917
895
  *
918
896
  * @return [void] This method always raises
919
897
  */
@@ -1009,7 +987,7 @@ void Init_session_ext() {
1009
987
  rb_define_method(cSession, "unescape", session_unescape, 1);
1010
988
 
1011
989
  rb_define_method(cSession, "handle_request", session_handle_request, 1);
1012
- rb_define_method(cSession, "reset", session_reset, 0);
990
+ rb_define_method(cSession, "reset", session_interrupt, 0);
1013
991
  rb_define_method(cSession, "interrupt", session_interrupt, 0);
1014
992
  rb_define_method(cSession, "add_cookie_file", add_cookie_file, 1);
1015
993
  rb_define_method(cSession, "set_debug_file", set_debug_file, 1);
@@ -1,3 +1,3 @@
1
1
  module Patron
2
- VERSION = "0.13.1"
2
+ VERSION = "0.13.3"
3
3
  end
@@ -36,7 +36,7 @@ SecureTransport-based builds might cause crashes in forking environment.
36
36
  For more info see https://github.com/curl/curl/issues/788
37
37
  }
38
38
  spec.add_development_dependency "rake", "~> 10"
39
- spec.add_development_dependency "bundler", ">= 1"
39
+ spec.add_development_dependency "bundler"
40
40
  spec.add_development_dependency "rspec", ">= 2.3.0"
41
41
  spec.add_development_dependency "simplecov", "~> 0.10"
42
42
  spec.add_development_dependency "yard", "~> 0.9.11"
@@ -10,7 +10,7 @@ describe Patron do
10
10
 
11
11
  it "should return the version number of the Patron library" do
12
12
  version = Patron.version
13
- expect(version).to match(%r|^\d+.\d+.\d+$|)
13
+ expect(version).to match(%r|^\d+.\d+.\d+(\.\w+\.\d+)?$|)
14
14
  end
15
15
 
16
16
  it "should return the version string of the libcurl library" do
@@ -16,9 +16,9 @@ describe Patron::Session do
16
16
  forbidden_protos = %w( smb tftp imap smtp telnet dict ftp sftp scp file gopher )
17
17
  forbidden_protos.each do |forbidden_proto|
18
18
  it "should deny a #{forbidden_proto.upcase} request" do
19
- @session.base_url = nil
20
19
  expect {
21
- @session.get('%s://localhost' % forbidden_proto)
20
+ @session.base_url = '%s://localhost' % forbidden_proto
21
+ @session.get('')
22
22
  }.to raise_error(Patron::UnsupportedProtocol)
23
23
  end
24
24
  end
@@ -208,9 +208,9 @@ describe Patron::Session do
208
208
  end
209
209
 
210
210
  it "is able to terminate the thread that is running a slow request" do
211
- t = Thread.new do
211
+ pid = Process.fork do
212
212
  trap('SIGINT') do
213
- exit # exit the thread
213
+ exit # exit the process
214
214
  end
215
215
  session = Patron::Session.new
216
216
  session.timeout = 40
@@ -222,8 +222,8 @@ describe Patron::Session do
222
222
  # using a signal during that time.
223
223
  started = Time.now.to_i
224
224
  sleep 5 # Less than what it takes for the server to respond
225
- Process.kill("INT", Process.pid) # Signal ourselves...
226
- t.join # wrap up the thread. If Patron is still busy there, this join call will still take 15s.
225
+ Process.kill("INT", pid) # Signal ourselves...
226
+ Process.wait(pid) # wrap up the process. If Patron is still busy there, this call will still take 15s.
227
227
  delta_s = Time.now.to_i - started
228
228
  expect(delta_s).to be_within(2).of(5)
229
229
  end
@@ -458,14 +458,14 @@ describe Patron::Session do
458
458
  it "should ignore a wrong Content-Length when asked to" do
459
459
  expect {
460
460
  @session.ignore_content_length = true
461
- @session.get("/wrongcontentlength")
461
+ @session.get("/wrongcontentlength", { 'Connection' => 'close' })
462
462
  }.to_not raise_error
463
463
  end
464
464
 
465
465
  it "should fail by default with a Content-Length too high" do
466
466
  expect {
467
467
  @session.ignore_content_length = nil
468
- @session.get("/wrongcontentlength")
468
+ @session.get("/wrongcontentlength", { 'Connection' => 'close' })
469
469
  }.to raise_error(Patron::PartialFileError)
470
470
  end
471
471
 
@@ -517,14 +517,12 @@ describe Patron::Session do
517
517
  it "should serialize query params and append them to the url" do
518
518
  response = @session.request(:get, "/test", {}, :query => {:foo => "bar"})
519
519
  request = YAML::load(response.body)
520
- request.parse
521
520
  expect(request.path + '?' + request.query_string).to be == "/test?foo=bar"
522
521
  end
523
522
 
524
523
  it "should merge parameters in the :query option with pre-existing query parameters" do
525
524
  response = @session.request(:get, "/test?foo=bar", {}, :query => {:baz => "quux"})
526
525
  request = YAML::load(response.body)
527
- request.parse
528
526
  expect(request.path + '?' + request.query_string).to be == "/test?foo=bar&baz=quux"
529
527
  end
530
528
 
@@ -32,12 +32,11 @@ describe Patron::Session do
32
32
  it "should download content in a forked subprocess" do
33
33
  # To trigger the bug, we need to perform a request in the master process first
34
34
  tmpfile = "/tmp/patron_test.yaml"
35
- @session.get_file "/test2", tmpfile
36
- File.unlink(tmpfile)
35
+ @session.get_file "/test", tmpfile
36
+ FileUtils.rm tmpfile
37
37
 
38
38
  # and this one segfaults
39
39
  pid = fork do
40
- tmpfile = "/tmp/patron_test.yaml"
41
40
  response = @session.get_file "/test", tmpfile
42
41
  expect(response.body).to be_nil
43
42
  body = YAML::load_file(tmpfile)
@@ -214,20 +213,6 @@ describe Patron::Session do
214
213
  expect(YAML::load(response).header).to_not include('cookie')
215
214
  end
216
215
 
217
- it "should ignore a wrong Content-Length when asked to" do
218
- expect {
219
- @session.ignore_content_length = true
220
- @session.get("/wrongcontentlength")
221
- }.to_not raise_error
222
- end
223
-
224
- it "should fail by default with a Content-Length too high" do
225
- expect {
226
- @session.ignore_content_length = nil
227
- @session.get("/wrongcontentlength")
228
- }.to raise_error(Patron::PartialFileError)
229
- end
230
-
231
216
  it "should raise exception if cookie store is not writable or readable" do
232
217
  expect { @session.handle_cookies("/trash/clash/foo") }.to raise_error(ArgumentError)
233
218
  end
@@ -254,14 +239,14 @@ describe Patron::Session do
254
239
 
255
240
  it "should work when insecure mode is off but certificate is supplied" do
256
241
  @session.insecure = nil
257
- @session.cacert = 'spec/certs/cacert.pem'
242
+ @session.cacert = File.join(__dir__, 'support', 'certs', 'cacert.pem')
258
243
  response = @session.get("/test")
259
244
  body = YAML::load(response.body)
260
245
  expect(body.request_method).to be == "GET"
261
246
  end
262
247
 
263
248
  it "should work with different SSL versions" do
264
- ['SSLv3','TLSv1'].each do |version|
249
+ ['TLSv1_0','TLSv1_1'].each do |version|
265
250
  @session.ssl_version = version
266
251
  response = @session.get("/test")
267
252
  expect(response.status).to be == 200
@@ -18,5 +18,14 @@ $stderr.puts "Build against #{Patron.libcurl_version}"
18
18
 
19
19
  Dir['./spec/support/**/*.rb'].each { |fn| require fn }
20
20
 
21
- Thread.new { PatronTestServer.start(false, 9001) }
22
- Thread.new { PatronTestServer.start(true, 9043) }
21
+ http_server_pid = Process.fork { PatronTestServer.start(false, 9001) }
22
+ https_server_pid = Process.fork { PatronTestServer.start(true, 9043) }
23
+
24
+ RSpec.configure do |c|
25
+ c.after(:suite) do
26
+ Process.kill("INT", http_server_pid)
27
+ Process.kill("INT", https_server_pid)
28
+ Process.wait(http_server_pid)
29
+ Process.wait(https_server_pid)
30
+ end
31
+ end
File without changes
@@ -1,5 +1,6 @@
1
1
  require 'yaml'
2
2
  require 'ostruct'
3
+ require 'zlib'
3
4
 
4
5
  ## HTTP test server for integration tests
5
6
 
@@ -25,7 +26,9 @@ Readback = Proc.new {|env|
25
26
  end
26
27
 
27
28
  fake_webrick_request_object = OpenStruct.new({
28
- :path => req.fullpath,
29
+ :fullpath => req.fullpath,
30
+ :path => req.path,
31
+ :query_string => req.query_string,
29
32
  :request_method => req.request_method.to_s,
30
33
  :header => Hash[req_headers],
31
34
  :body => env['rack.input'].read,
@@ -38,16 +41,20 @@ Readback = Proc.new {|env|
38
41
  GzipServlet = Proc.new {|env|
39
42
  raise "Need to have the right Accept-Encoding: header" unless env['HTTP_ACCEPT_ENCODING']
40
43
 
41
- body = Enumerator.new do |y|
42
- z = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION)
43
- 1024.times {
44
- y.yield(z.deflate('Some highly compressible data'))
45
- }
46
- y.yield(z.finish.to_s)
47
- y.yield(z.close.to_s)
44
+ body = []
45
+ content_length = 0
46
+ z = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION)
47
+ 1024.times do
48
+ chunk = z.deflate('Some highly compressible data')
49
+ content_length += chunk.bytesize
50
+ body << chunk
48
51
  end
52
+ fin = z.finish.to_s
53
+ body << fin
54
+ content_length += fin.bytesize
55
+ z.close
49
56
 
50
- [200, {'Content-Encoding' => 'deflate', 'Vary' => 'Accept-Encoding'}, body]
57
+ [200, {'Content-Encoding' => 'deflate', 'Content-Length' => content_length.to_s, 'Vary' => 'Accept-Encoding'}, body]
51
58
  }
52
59
 
53
60
  TimeoutServlet = Proc.new {|env|
@@ -67,8 +74,9 @@ SlowServlet = Proc.new {|env|
67
74
  }
68
75
 
69
76
  RedirectServlet = Proc.new {|env|
77
+ url_scheme = env.fetch('rack.url_scheme')
70
78
  port = env.fetch('SERVER_PORT')
71
- [301, {'Location' => "http://localhost:#{port}/test"}, []]
79
+ [301, {'Location' => "#{url_scheme}://localhost:#{port}/test"}, []]
72
80
  }
73
81
 
74
82
  EvilRedirectServlet = Proc.new {|env|
@@ -76,8 +84,8 @@ EvilRedirectServlet = Proc.new {|env|
76
84
  }
77
85
 
78
86
  BodyReadback = Proc.new {|env|
79
- readback = {'method' => env['REQUEST_METHOD'], 'body' => env['rack.input'].read, 'content_type' => env.fetch('HTTP_CONTENT_TYPE')}
80
- [200, {'Content-Type' => 'text/plain'}, [readback]]
87
+ readback = {'method' => env['REQUEST_METHOD'], 'body' => env['rack.input'].read, 'content_type' => env.fetch('CONTENT_TYPE')}
88
+ [200, {'Content-Type' => 'text/plain'}, [OpenStruct.new(readback).to_yaml]]
81
89
  }
82
90
 
83
91
  TestPatchBodyServlet = BodyReadback
@@ -3,18 +3,24 @@ require 'puma'
3
3
  require 'rack/handler/puma'
4
4
 
5
5
  class PatronTestServer
6
- APP = Rack::Builder.new { eval(File.read(File.dirname(__FILE__) + '/config.ru')) }
6
+ APP = Rack::Builder.new { eval(File.read(File.join(__dir__, 'config.ru'))) }
7
7
 
8
8
  def self.start(ssl = false, port = 9001 )
9
+ # Reset the RSpec's SIGINT handler that does not really terminate after
10
+ # the first Ctrl+C pressed.
11
+ # Useful to terminate the forked process before Puma is actually started:
12
+ # it happens when running one particular example that does not need Puma
13
+ # so the specs are in fact finished before the Puma started.
14
+ Signal.trap('INT', 'EXIT')
9
15
  @ssl = ssl
10
- keypath = File.expand_path(File.read(File.dirname(__FILE__) + '/../certs/privkey.pem'))
11
- certpath = File.expand_path(File.read(File.dirname(__FILE__) + '/../certs/cacert.pem'))
16
+ keypath = File.join(__dir__, 'certs', 'privkey.pem')
17
+ certpath = File.join(__dir__, 'certs', 'cacert.pem')
12
18
 
13
19
  host = if ssl
14
- 'ssl://127.0.0.1:%d?key=%s&cert=%s' % [port, keypath, certpath]
20
+ 'ssl://0.0.0.0:%d?key=%s&cert=%s' % [port, keypath, certpath]
15
21
  else
16
- 'tcp://127.0.0.1:%d' % port
22
+ '0.0.0.0'
17
23
  end
18
- Rack::Handler::Puma.run(APP, {:Port => port.to_i, :Verbose => true, :Host => '0.0.0.0'})
24
+ Rack::Handler::Puma.run(APP, {:Port => port.to_i, :Verbose => true, :Host => host})
19
25
  end
20
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phillip Toland
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-10 00:00:00.000000000 Z
11
+ date: 2019-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -160,8 +160,6 @@ files:
160
160
  - pic.png
161
161
  - script/console
162
162
  - script/test_server
163
- - spec/certs/cacert.pem
164
- - spec/certs/privkey.pem
165
163
  - spec/header_parser_spec.rb
166
164
  - spec/patron_spec.rb
167
165
  - spec/request_spec.rb
@@ -175,6 +173,8 @@ files:
175
173
  - spec/session_spec.rb
176
174
  - spec/session_ssl_spec.rb
177
175
  - spec/spec_helper.rb
176
+ - spec/support/certs/cacert.pem
177
+ - spec/support/certs/privkey.pem
178
178
  - spec/support/config.ru
179
179
  - spec/support/test_server.rb
180
180
  - spec/util_spec.rb
@@ -204,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
204
  version: 1.2.0
205
205
  requirements: []
206
206
  rubyforge_project: patron
207
- rubygems_version: 2.5.2
207
+ rubygems_version: 2.7.6
208
208
  signing_key:
209
209
  specification_version: 4
210
210
  summary: Patron HTTP Client