patron 0.6.3 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c363a7f520fb90344efb2251b25a0dbbc6e0d5db
4
- data.tar.gz: f95d681849dd57101b33408327fc3aa38d0dc2e3
3
+ metadata.gz: 6490486dce02935cfdeac506f347834248752534
4
+ data.tar.gz: 2054357e312513173440405a32c69ed1270d6f10
5
5
  SHA512:
6
- metadata.gz: 1945f68df49b6f96ee53166382807ac5e5a19bd00d2746e325d3af02ffe54b14db6f5ad92a55fe6322f5183b25b047cd2879503b6dfbb5bc9c1afc69c5c617ee
7
- data.tar.gz: a487793a4bb938d77804e4f0ea083c61afad062014cacbadcb40343f31ddb3fb55889f844f7b0610101f06f1a765f3c53fe1257bf9b48cabe4fda2ae71398334
6
+ metadata.gz: 96c2adbfe66641accbb6647faab050405950338938caac845ba3948d981e8f3371f24fd6e3c308cf44cc19248dc56ddb857058546c11ba798eb34ab65b5769f2
7
+ data.tar.gz: 66e5369b422608d214b0b1654a9fd9cdf075c42f01194b70497b6d3976f7e442d5c0b8926109c418d7e489fedea10d2c72fcad3519d4f0a38b1f584d5d31b525
data/CHANGELOG.md ADDED
@@ -0,0 +1,168 @@
1
+ ### 0.6.4
2
+
3
+ * Set the default User-Agent string, since some sites require it (like the Github API).
4
+ * Add Response#ok? and Response#error? for cleaner branching on the returned Response objects
5
+ * Explain a segfault with SSL in forked processes on OSX, document the way to avoid the issue
6
+ * Fix segfault when attempting multiple post requests with multipart (#119)
7
+
8
+ ### 0.6.3
9
+
10
+ * Fix timeout when uploading a body using all verbs except POST
11
+ * Add PATCH HTTP verb support
12
+ * Populate the curl state object from the reader methods of `Request`
13
+
14
+ ### 0.6.1
15
+
16
+ * Fix compilation on older versions of libCURL
17
+ * Fix cookie jar files not being saved after request
18
+ * Reformat the gem documentation to YARD, document a few behaviors
19
+
20
+ ### 0.6.0
21
+
22
+ * Add `Patron::Session#automatic_content_encoding` for automatic deflate handling via `Accept`/`Content-Encoding`
23
+
24
+ ### 0.5.1
25
+
26
+ * Allow customizing the class used for the response (now uses `Session#response_class` to determine the class at runtime)
27
+ * Do not fail body decoding if the charset name set in the header is invalid
28
+
29
+ ### 0.5.0
30
+
31
+ * Optimise response header parsing
32
+ * Fix a bug with `Session#base_url` being empty
33
+ * Fix memory corruption when Ruby would free a Patron buffer uninteltionally
34
+ * Modernize the wrapper for request execution, unlock the GVL if possible using the C function native to the version of Ruby we build on
35
+ * Add an option to force CURL to only use IPv4 (`Session#force_ipv4`)
36
+ * Fix a few bugs with base_url concatenation
37
+ * Support options- and block-constructor for `Session.new`
38
+ * Allow the `Request` object to be customized
39
+
40
+ ### 0.4.20
41
+
42
+ * Revert the HTTP verb to be a Symbol, but allow uppercase versions
43
+
44
+ ### 0.4.19
45
+
46
+ * Add an option to set `Session#ssl_version` (uses a String as value)
47
+ * Fix `Session#insecure`
48
+ * Add request body support for DELETE requests
49
+ * Add support for default headers via `Session#headers`
50
+ * Allow customizing the CA root file for SSL requests via `Session#cacert`
51
+ * Add gzip encoding support by setting explicit headers
52
+ * Allow `Session#base_url` to be overridden on a per-request basis
53
+ * Use binary mode flags in `fopen()` for `get_file` to improve Windows compatibility
54
+
55
+ ### 0.4.18
56
+
57
+ * Handle GET request body via buffers, not via post fields
58
+
59
+ ### 0.4.17
60
+
61
+ * Use libCURL for doing URL encoding
62
+ * Add `Session#interrupt`, which can be used to stop the request/response from another thread
63
+ * Add `Session#reset` to explicitly clear out the libCURL state
64
+ * Use sglib to register all running CURL sessions, to allow them to terminate rapidly when the host Ruby process exits abruptly, via interrupt or otherwise
65
+ * Use a test server in an external process when running rspec
66
+ * Ensure responses that are not text do not force response body decoding
67
+ * Improve thread blocking region handling during requests
68
+
69
+ ### 0.4.17
70
+
71
+ * Tweak response decoding
72
+
73
+ ### 0.4.15
74
+
75
+ * Remove rvm/rbenv service files from the repo
76
+ * Encode the response attributes based on the response charset
77
+ * Fix urlencode for Ruby 1.9 compatibility
78
+ * Enable Hash as argument for `Session#post`, which will be form-encoded
79
+ * Allow "timeout" and other options to be overridden at request instantiation
80
+
81
+ ### 0.4.14
82
+
83
+ * Fix ignore_content_length/ignore_content_size inconsistency
84
+ * Fix a few OSX compilation snags, do not force ARCHFLAGS
85
+
86
+ ### 0.4.13
87
+
88
+ * Add `Session#ignore_content_length`
89
+
90
+ ### 0.4.12
91
+
92
+ * Add `:query` option to `Session#request`, encode query parameters from a Hash of options when doing `Session#get`
93
+
94
+ ### 0.4.11
95
+
96
+ * Add URL encoding when an action is a POST
97
+ * Upgrade build system and rspec
98
+
99
+ ### 0.4.10
100
+
101
+ * Make the curl buffer size advisory customizable.
102
+ * Add SOCKS proxy support
103
+ * Add `Session#enable_debug` that will write debug info to a file or to STDERR
104
+
105
+ ### 0.4.9
106
+
107
+ * Use rb_hash_foreach for better jRuby/Rubinius compat
108
+
109
+ ### 0.4.8
110
+
111
+ * Remove Rubyforge build tasks
112
+ * Run the test server under 1.8 if the main test runs under 1.8
113
+ * Fix incorrect usage of `rb_define_const`
114
+
115
+ ### 0.4.7
116
+
117
+ * Fix incorrect usage of `rb_define_const`
118
+ * Preserve multiple headers with the same name (like `Set-Cookie`)
119
+ * Set `Expect` in the request to an empty string, to prevent upload hangs
120
+ * Fix a call to `rb_raise` when raising exceptions
121
+
122
+ ### 0.4.5
123
+
124
+ * Fix use with threads on 1.9.1
125
+ * Specify connection timeout in seconds, not in millis
126
+ * Default max redirects to 5
127
+
128
+ ### 0.4.4
129
+
130
+ * Fix a string comparison bug in `enable_cookie_session()`
131
+ * Raise an ArgumentError if no data or filename is provided to PUT or
132
+ POST
133
+
134
+ ### 0.4.3
135
+
136
+ * Add `Session#insecure` to bypass cert validation (defaults to off)
137
+ * Add a blocking region for 1.9 GIL
138
+ * Allow setting `Session#timeout` to `nil` to disable timeouts outright
139
+
140
+ ### 0.4.2
141
+
142
+ * Fix rubyforge release tasks
143
+ * Add simple cookie handling
144
+ * More 1.9 compatibility
145
+ * Set a default `Session#auth_type` to be HTTP Basic (`:basic`)
146
+
147
+ ### 0.4.1
148
+
149
+ * Add HTTP Digest authentication support
150
+ * Allow `Request` to use a Hash for body, using options
151
+
152
+ ### 0.4.0
153
+
154
+ * Documentation tweaks
155
+ * Add support for the COPY HTTP verb
156
+ * Make sure C helper functions are static
157
+ * Make `Session#request` public
158
+ * Add `get_file` to write the response body to a file outside of the Ruby heap
159
+ * Add initial HTTP prox suport
160
+ * Add license, copyright
161
+
162
+ ### 0.3.0
163
+
164
+ * Add connection timeout support
165
+
166
+ ### 0.2.0
167
+
168
+ * Initial tagged release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- patron (0.6.3)
4
+ patron (0.6.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -50,6 +50,33 @@ 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
54
+
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
57
+
58
+ $ bundle install && bundle exec rspec
59
+
60
+ in the Patron install directory. Most default curl configurations on OSX (both
61
+ the Apple-shipped version and the version available via Homebrew) are linked to
62
+ SecureTransport and are likely to be affected. This issue may also manifest in
63
+ forking webserver implementations (such as Unicorn or Passenger) and in forking
64
+ job execution engines (such as resque), so even though you may not be using
65
+ `fork()` directly your server engine might be doing it for you.
66
+
67
+ To circumvent the issue, you need to build `curl` with OpenSSL via homebrew.
68
+ When doing so, `curl` will use openssl as it's SSL driver. You also need to
69
+ change the Patron compile flag:
70
+
71
+
72
+ $ brew install curl --with-openssl && \
73
+ gem install patron --with-curl-config=/usr/local/opt/curl/bin/curl-config
74
+
75
+ You can also save this parameter for all future Bundler-driven gem installs by
76
+ setting this flag in Bundler proper:
77
+
78
+ $ bundle config build.patron --with-curl-config=/usr/local/opt/curl/bin/curl-config
79
+
53
80
  ## Threading
54
81
 
55
82
  By itself, the `Patron::Session` objects are not thread safe (each `Session` holds a single `curl_state` pointer
@@ -27,15 +27,15 @@ require 'mkmf'
27
27
  require 'rbconfig'
28
28
 
29
29
  dir_config('curl')
30
-
31
- if find_executable('curl-config')
32
- $CFLAGS << " #{`curl-config --cflags`.strip}"
33
- $LIBS << " #{`curl-config --libs`.strip}"
30
+ curl_config_path = with_config('curl-config') || find_executable('curl-config')
31
+ if curl_config_path
32
+ $CFLAGS << " " << `#{curl_config_path} --cflags`.strip
33
+ $LIBS << " " << `#{curl_config_path} --libs`.strip
34
34
  elsif !have_library('curl') or !have_header('curl/curl.h')
35
35
  fail <<-EOM
36
36
  Can't find libcurl or curl/curl.h
37
37
 
38
- Try passing --with-curl-dir or --with-curl-lib and --with-curl-include
38
+ Try passing --with-curl-config, --with-curl-dir, or --with-curl-lib and --with-curl-include
39
39
  options to extconf.
40
40
  EOM
41
41
  end
@@ -354,7 +354,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
354
354
  VALUE a_c_encoding = rb_funcall(request, rb_intern("automatic_content_encoding"), 0);
355
355
 
356
356
  headers = rb_funcall(request, rb_intern("headers"), 0);
357
- if (!NIL_P(headers)) {
357
+ if (RTEST(headers)) {
358
358
  if (rb_type(headers) != T_HASH) {
359
359
  rb_raise(rb_eArgError, "Headers must be passed in a hash.");
360
360
  }
@@ -371,14 +371,14 @@ static void set_options_from_request(VALUE self, VALUE request) {
371
371
  VALUE download_file = rb_funcall(request, rb_intern("file_name"), 0);
372
372
 
373
373
  curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
374
- if (!NIL_P(data)) {
374
+ if (RTEST(data)) {
375
375
  data = rb_funcall(data, rb_intern("to_s"), 0);
376
376
  long len = RSTRING_LEN(data);
377
377
  state->upload_buf = StringValuePtr(data);
378
378
  set_curl_request_body(curl, state->upload_buf, len);
379
379
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
380
380
  }
381
- if (!NIL_P(download_file)) {
381
+ if (RTEST(download_file)) {
382
382
  state->download_file = open_file(download_file, "wb");
383
383
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, state->download_file);
384
384
  } else {
@@ -397,7 +397,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
397
397
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
398
398
  }
399
399
 
400
- if (!NIL_P(data) && NIL_P(multipart)) {
400
+ if (RTEST(data) && !RTEST(multipart)) {
401
401
  data = rb_funcall(data, rb_intern("to_s"), 0);
402
402
  if (action == rb_intern("post")) {
403
403
  curl_easy_setopt(curl, CURLOPT_POST, 1);
@@ -405,16 +405,16 @@ static void set_options_from_request(VALUE self, VALUE request) {
405
405
  long len = RSTRING_LEN(data);
406
406
  state->upload_buf = StringValuePtr(data);
407
407
  set_curl_request_body(curl, state->upload_buf, len);
408
- } else if (!NIL_P(filename) && NIL_P(multipart)) {
408
+ } else if (RTEST(filename) && !RTEST(multipart)) {
409
409
  set_chunked_encoding(state);
410
410
 
411
411
  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
412
412
 
413
413
  state->upload_file = open_file(filename, "rb");
414
414
  curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file);
415
- } else if (!NIL_P(multipart)) {
415
+ } else if (RTEST(multipart)) {
416
416
  if (action == rb_intern("post")) {
417
- if(!NIL_P(data) && !NIL_P(filename)) {
417
+ if(RTEST(data) && RTEST(filename)) {
418
418
  if (rb_type(data) == T_HASH && rb_type(filename) == T_HASH) {
419
419
  rb_hash_foreach(data, formadd_values, self);
420
420
  rb_hash_foreach(filename, formadd_files, self);
@@ -433,7 +433,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
433
433
  // support for data passed with a DELETE request (e.g.: used by elasticsearch)
434
434
  } else if (action == rb_intern("delete")) {
435
435
  VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
436
- if (!NIL_P(data)) {
436
+ if (RTEST(data)) {
437
437
  long len = RSTRING_LEN(data);
438
438
  state->upload_buf = StringValuePtr(data);
439
439
  curl_easy_setopt(curl, CURLOPT_POST, 1);
@@ -466,58 +466,58 @@ static void set_options_from_request(VALUE self, VALUE request) {
466
466
  }
467
467
 
468
468
  url = rb_funcall(request, rb_intern("url"), 0);
469
- if (NIL_P(url)) {
469
+ if (!RTEST(url)) {
470
470
  rb_raise(rb_eArgError, "Must provide a URL");
471
471
  }
472
472
  curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
473
473
 
474
474
  timeout = rb_funcall(request, rb_intern("timeout"), 0);
475
- if (!NIL_P(timeout)) {
475
+ if (RTEST(timeout)) {
476
476
  curl_easy_setopt(curl, CURLOPT_TIMEOUT, FIX2INT(timeout));
477
477
  }
478
478
 
479
479
  timeout = rb_funcall(request, rb_intern("connect_timeout"), 0);
480
- if (!NIL_P(timeout)) {
480
+ if (RTEST(timeout)) {
481
481
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FIX2INT(timeout));
482
482
  }
483
483
 
484
484
  redirects = rb_funcall(request, rb_intern("max_redirects"), 0);
485
- if (!NIL_P(redirects)) {
485
+ if (RTEST(redirects)) {
486
486
  int r = FIX2INT(redirects);
487
487
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, r == 0 ? 0 : 1);
488
488
  curl_easy_setopt(curl, CURLOPT_MAXREDIRS, r);
489
489
  }
490
490
 
491
491
  proxy = rb_funcall(request, rb_intern("proxy"), 0);
492
- if (!NIL_P(proxy)) {
492
+ if (RTEST(proxy)) {
493
493
  curl_easy_setopt(curl, CURLOPT_PROXY, StringValuePtr(proxy));
494
494
  }
495
495
 
496
496
  proxy_type = rb_funcall(request, rb_intern("proxy_type"), 0);
497
- if (!NIL_P(proxy_type)) {
497
+ if (RTEST(proxy_type)) {
498
498
  curl_easy_setopt(curl, CURLOPT_PROXYTYPE, NUM2LONG(proxy_type));
499
499
  }
500
500
 
501
501
  credentials = rb_funcall(request, rb_intern("credentials"), 0);
502
- if (!NIL_P(credentials)) {
502
+ if (RTEST(credentials)) {
503
503
  VALUE auth_type = rb_funcall(request, rb_intern("auth_type"), 0);
504
504
  curl_easy_setopt(curl, CURLOPT_HTTPAUTH, NUM2LONG(auth_type));
505
505
  curl_easy_setopt(curl, CURLOPT_USERPWD, StringValuePtr(credentials));
506
506
  }
507
507
 
508
508
  ignore_content_length = rb_funcall(request, rb_intern("ignore_content_length"), 0);
509
- if (!NIL_P(ignore_content_length)) {
509
+ if (RTEST(ignore_content_length)) {
510
510
  curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1);
511
511
  }
512
512
 
513
513
  insecure = rb_funcall(request, rb_intern("insecure"), 0);
514
- if(!NIL_P(insecure)) {
514
+ if(RTEST(insecure)) {
515
515
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
516
516
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
517
517
  }
518
518
 
519
519
  ssl_version = rb_funcall(request, rb_intern("ssl_version"), 0);
520
- if(!NIL_P(ssl_version)) {
520
+ if(RTEST(ssl_version)) {
521
521
  VALUE ssl_version_str = rb_funcall(ssl_version, rb_intern("to_s"), 0);
522
522
  char* version = StringValuePtr(ssl_version_str);
523
523
  if(strcmp(version, "SSLv2") == 0) {
@@ -532,12 +532,12 @@ static void set_options_from_request(VALUE self, VALUE request) {
532
532
  }
533
533
 
534
534
  cacert = rb_funcall(request, rb_intern("cacert"), 0);
535
- if(!NIL_P(cacert)) {
535
+ if(RTEST(cacert)) {
536
536
  curl_easy_setopt(curl, CURLOPT_CAINFO, StringValuePtr(cacert));
537
537
  }
538
538
 
539
539
  buffer_size = rb_funcall(request, rb_intern("buffer_size"), 0);
540
- if (!NIL_P(buffer_size)) {
540
+ if (RTEST(buffer_size)) {
541
541
  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, NUM2LONG(buffer_size));
542
542
  }
543
543
 
@@ -669,6 +669,8 @@ static VALUE cleanup(VALUE self) {
669
669
 
670
670
  if (state->post) {
671
671
  curl_formfree(state->post);
672
+ state->post = NULL;
673
+ state->last = NULL;
672
674
  }
673
675
 
674
676
  state->upload_buf = NULL;
data/lib/patron.rb CHANGED
@@ -38,4 +38,10 @@ module Patron
38
38
  def self.version
39
39
  VERSION
40
40
  end
41
+
42
+ # Returns the default User-Agent string
43
+ # @return [String]
44
+ def self.user_agent_string
45
+ @ua ||= "Patron/Ruby-%s-%s" % [version, libcurl_version]
46
+ end
41
47
  end
@@ -76,6 +76,20 @@ module Patron
76
76
  end
77
77
  end
78
78
 
79
+ # Tells whether the HTTP response code is less than 400
80
+ #
81
+ # @return [Boolean]
82
+ def ok?
83
+ !error?
84
+ end
85
+
86
+ # Tells whether the HTTP response code is larger than 399
87
+ #
88
+ # @return [Boolean]
89
+ def error?
90
+ status >= 400
91
+ end
92
+
79
93
  private
80
94
 
81
95
  def determine_charset(header_data, body)
@@ -107,7 +107,7 @@ module Patron
107
107
 
108
108
  private :handle_request, :add_cookie_file, :set_debug_file
109
109
 
110
- # Create a new Session object.
110
+ # Create a new Session object for performing requests.
111
111
  #
112
112
  # @param args[Hash] options for the Session (same names as the writable attributes of the Session)
113
113
  # @yield self
@@ -124,6 +124,7 @@ module Patron
124
124
  end
125
125
 
126
126
  @headers ||= {}
127
+ @headers['User-Agent'] ||= Patron.user_agent_string
127
128
  @timeout ||= 5
128
129
  @connect_timeout ||= 1
129
130
  @max_redirects ||= 5
@@ -1,3 +1,3 @@
1
1
  module Patron
2
- VERSION = "0.6.3"
2
+ VERSION = "0.6.4"
3
3
  end
data/patron.gemspec CHANGED
@@ -24,5 +24,10 @@ Gem::Specification.new do |s|
24
24
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
25
25
  s.require_paths = ["lib", "ext"]
26
26
  s.extensions = ["ext/patron/extconf.rb"]
27
- end
27
+ s.post_install_message = %q{
28
+ Thank you for installing Patron. On OSX, make sure you are using libCURL with OpenSSL.
29
+ SecureTransport-based builds might cause crashes in forking environments.
28
30
 
31
+ For more info see https://github.com/curl/curl/issues/788
32
+ }
33
+ end
data/spec/patron_spec.rb CHANGED
@@ -27,6 +27,12 @@ require File.expand_path("./spec") + '/spec_helper.rb'
27
27
 
28
28
  describe Patron do
29
29
 
30
+ it 'should return the user agent string' do
31
+ ua_str = Patron.user_agent_string
32
+ expect(ua_str).to include('curl')
33
+ expect(ua_str).to include('Patron')
34
+ end
35
+
30
36
  it "should return the version number of the Patron library" do
31
37
  version = Patron.version
32
38
  expect(version).to match(%r|^\d+.\d+.\d+$|)
@@ -37,6 +37,34 @@ describe Patron::Response do
37
37
  @session.base_url = "http://localhost:9001"
38
38
  end
39
39
 
40
+ it 'recovers the status code' do
41
+ response = @session.get("/repetitiveheader")
42
+ expect(response.status).to be_kind_of(Fixnum)
43
+ expect(response.status).to eq(200)
44
+ end
45
+
46
+ it 'saves the definitive URL in the url attribute' do
47
+ headers = "HTTP/1.1 200 OK \r\nContent-Type: text/plain\r\n"
48
+ response = Patron::Response.new("http://example.com/url", 200, 0, headers, '', "UTF-8")
49
+ expect(response.url).to eq("http://example.com/url")
50
+ end
51
+
52
+ it 'parses the status code and supports ok? and error?' do
53
+ headers = "HTTP/1.1 200 OK \r\nContent-Type: text/plain\r\n"
54
+ body = "abc"
55
+ response = Patron::Response.new("url", 200, 0, headers, body, "UTF-8")
56
+ expect(response.status).to eq(200)
57
+ expect(response).to be_ok
58
+ expect(response).not_to be_error
59
+
60
+ headers = "HTTP/1.1 400 Bad Request \r\nContent-Type: text/plain\r\n"
61
+ body = "abc"
62
+ response = Patron::Response.new("url", 400, 0, headers, body, "UTF-8")
63
+ expect(response.status).to eq(400)
64
+ expect(response).not_to be_ok
65
+ expect(response).to be_error
66
+ end
67
+
40
68
  it "should strip extra spaces from header values" do
41
69
  response = @session.get("/test")
42
70
  # All digits, no spaces
data/spec/session_spec.rb CHANGED
@@ -107,6 +107,19 @@ describe Patron::Session do
107
107
  FileUtils.rm tmpfile
108
108
  end
109
109
 
110
+ it "should not send the user-agent if it has been deleted from headers" do
111
+ @session.headers.delete 'User-Agent'
112
+ response = @session.get("/test")
113
+ body = YAML::load(response.body)
114
+ expect(body.header["user-agent"]).to be_nil
115
+ end
116
+
117
+ it "should set the default User-agent" do
118
+ response = @session.get("/test")
119
+ body = YAML::load(response.body)
120
+ expect(body.header["user-agent"]).to be == [Patron.user_agent_string]
121
+ end
122
+
110
123
  it "should include custom headers in a request" do
111
124
  response = @session.get("/test", {"User-Agent" => "PatronTest"})
112
125
  body = YAML::load(response.body)
@@ -52,6 +52,28 @@ describe Patron::Session do
52
52
  FileUtils.rm tmpfile
53
53
  end
54
54
 
55
+ # See https://github.com/curl/curl/issues/788
56
+ # Basically any HTTPS operation crashes on OSX with securetransport-enabled libCURL
57
+ it "should download content in a forked subprocess" do
58
+ # To trigger the bug, we need to perform a request in the master process first
59
+ tmpfile = "/tmp/patron_test.yaml"
60
+ @session.get_file "/test2", tmpfile
61
+ File.unlink(tmpfile)
62
+
63
+ # and this one segfaults
64
+ pid = fork do
65
+ tmpfile = "/tmp/patron_test.yaml"
66
+ response = @session.get_file "/test", tmpfile
67
+ expect(response.body).to be_nil
68
+ body = YAML::load_file(tmpfile)
69
+ expect(body.request_method).to be == "GET"
70
+ FileUtils.rm tmpfile
71
+ end
72
+
73
+ exit_pid, status = Process.wait2(pid)
74
+ expect(status.exitstatus).to be_zero
75
+ end
76
+
55
77
  it "should download correctly(md5 ok) with get_file" do
56
78
  tmpfile = "/tmp/picture"
57
79
  response = @session.get_file "/picture", tmpfile
data/spec/spec_helper.rb CHANGED
@@ -39,6 +39,8 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
39
39
  $:.unshift(File.dirname(__FILE__) + '/../ext')
40
40
  require 'patron'
41
41
 
42
+ $stderr.puts "Build against #{Patron.libcurl_version}"
43
+
42
44
  Dir['./spec/support/**/*.rb'].each { |fn| require fn }
43
45
 
44
46
  PatronTestServer.start(nil, false, 9001) if RUBY_VERSION >= '1.9'
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.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phillip Toland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-28 00:00:00.000000000 Z
11
+ date: 2016-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -92,6 +92,7 @@ files:
92
92
  - ".gitignore"
93
93
  - ".rspec"
94
94
  - ".travis.yml"
95
+ - CHANGELOG.md
95
96
  - Gemfile
96
97
  - Gemfile.lock
97
98
  - LICENSE
@@ -128,7 +129,12 @@ files:
128
129
  homepage: https://github.com/toland/patron
129
130
  licenses: []
130
131
  metadata: {}
131
- post_install_message:
132
+ post_install_message: |2
133
+
134
+ Thank you for installing Patron. On OSX, make sure you are using libCURL with OpenSSL.
135
+ SecureTransport-based builds might cause crashes in forking environments.
136
+
137
+ For more info see https://github.com/curl/curl/issues/788
132
138
  rdoc_options: []
133
139
  require_paths:
134
140
  - lib