patron 0.5.1 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 018a03fb6977a92e0dbf70f4e8473ef273d7576c
4
- data.tar.gz: 611bde5b709c9f24007fa8805b369310baa8ed6d
3
+ metadata.gz: c0a3e8dc6975392e43cac53cb03387ef07c3cab3
4
+ data.tar.gz: c58f5c72242c526bd2b8a9a70f13fa53248512e4
5
5
  SHA512:
6
- metadata.gz: a2e176e3648ab4293bc69cbaca8e048ba7effb544ebf49de0cd3647b99cd1105e0b52f1afaef32e3c9ab899ff5c41cc01e8fa2d97861de0f3064c405d0af4865
7
- data.tar.gz: a1525278695ce34f891f3d06f2bb352e841d97fba8b4f50b71a21b6fe960964cd4f8f9e39ca5dab1d65ac8d30e8fd97dd80b8d3c9ff8cc63d78eb331756c35df
6
+ metadata.gz: d4e0312f0cf82ed1db7d980bd93771016e710e7d2b1c6c3b7d7eaf965ff654eba61199eaa6a54df44e9c9ece0f610a8b16eb4bde37fce15b84fb733abf61f531
7
+ data.tar.gz: 28e92d83ad9d9e7e173c327c7797b6d11240e41c1fceadb4e3cfdbc9a35abe0597150c2ab32626d183992ec835d5bfd1a6c771df506e10b2fe44c9ca3ada15d1
@@ -223,16 +223,18 @@ static VALUE libcurl_version(VALUE klass) {
223
223
  * URL escapes the provided string.
224
224
  */
225
225
  static VALUE session_escape(VALUE self, VALUE value) {
226
- struct curl_state *state = get_curl_state(self);
226
+
227
227
  VALUE string = StringValue(value);
228
228
  char* escaped = NULL;
229
229
  VALUE retval = Qnil;
230
230
 
231
+ struct curl_state* state = curl_easy_init();
231
232
  escaped = curl_easy_escape(state->handle,
232
233
  RSTRING_PTR(string),
233
234
  (int) RSTRING_LEN(string));
234
235
 
235
236
  retval = rb_str_new2(escaped);
237
+ curl_easy_cleanup(state);
236
238
  curl_free(escaped);
237
239
 
238
240
  return retval;
@@ -244,11 +246,11 @@ static VALUE session_escape(VALUE self, VALUE value) {
244
246
  * Unescapes the provided string.
245
247
  */
246
248
  static VALUE session_unescape(VALUE self, VALUE value) {
247
- struct curl_state *state = get_curl_state(self);
248
249
  VALUE string = StringValue(value);
249
250
  char* unescaped = NULL;
250
251
  VALUE retval = Qnil;
251
252
 
253
+ struct curl_state* state = curl_easy_init();
252
254
  unescaped = curl_easy_unescape(state->handle,
253
255
  RSTRING_PTR(string),
254
256
  (int) RSTRING_LEN(string),
@@ -256,6 +258,7 @@ static VALUE session_unescape(VALUE self, VALUE value) {
256
258
 
257
259
  retval = rb_str_new2(unescaped);
258
260
  curl_free(unescaped);
261
+ curl_easy_cleanup(state);
259
262
 
260
263
  return retval;
261
264
  }
@@ -347,6 +350,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
347
350
  VALUE ssl_version = Qnil;
348
351
  VALUE buffer_size = Qnil;
349
352
  VALUE action_name = rb_iv_get(request, "@action");
353
+ VALUE a_c_encoding = rb_iv_get(request, "@automatic_content_encoding");
350
354
 
351
355
  headers = rb_iv_get(request, "@headers");
352
356
  if (!NIL_P(headers)) {
@@ -454,6 +458,12 @@ static void set_options_from_request(VALUE self, VALUE request) {
454
458
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
455
459
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error_buf);
456
460
 
461
+ // Enable automatic content-encoding support via gzip/deflate if set in the request,
462
+ // see https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html
463
+ if(RTEST(a_c_encoding)) {
464
+ curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
465
+ }
466
+
457
467
  url = rb_iv_get(request, "@url");
458
468
  if (NIL_P(url)) {
459
469
  rb_raise(rb_eArgError, "Must provide a URL");
@@ -777,8 +787,14 @@ void Init_session_ext() {
777
787
  cRequest = rb_define_class_under(mPatron, "Request", rb_cObject);
778
788
  rb_define_alloc_func(cSession, session_alloc);
779
789
 
790
+ // Make "escape" available both as a class method and as an instance method,
791
+ // to make it usable to the Util module which does not have access to
792
+ // the Session object internally
793
+ rb_define_singleton_method(cSession, "escape", session_escape, 1);
780
794
  rb_define_method(cSession, "escape", session_escape, 1);
795
+ rb_define_singleton_method(cSession, "unescape", session_unescape, 1);
781
796
  rb_define_method(cSession, "unescape", session_unescape, 1);
797
+
782
798
  rb_define_method(cSession, "handle_request", session_handle_request, 1);
783
799
  rb_define_method(cSession, "reset", session_reset, 0);
784
800
  rb_define_method(cSession, "interrupt", session_interrupt, 0);
@@ -46,12 +46,12 @@ module Patron
46
46
  :url, :username, :password, :file_name, :proxy, :proxy_type, :insecure,
47
47
  :ignore_content_length, :multipart, :action, :timeout, :connect_timeout,
48
48
  :max_redirects, :headers, :auth_type, :upload_data, :buffer_size, :cacert,
49
- :ssl_version, :force_ipv4
49
+ :ssl_version, :automatic_content_encoding, :force_ipv4
50
50
  ]
51
51
 
52
52
  WRITER_VARS = [
53
53
  :url, :username, :password, :file_name, :proxy, :proxy_type, :insecure,
54
- :ignore_content_length, :multipart, :cacert, :ssl_version, :force_ipv4
54
+ :ignore_content_length, :multipart, :cacert, :ssl_version, :automatic_content_encoding, :force_ipv4
55
55
  ]
56
56
 
57
57
  attr_reader *READER_VARS
@@ -87,6 +87,9 @@ module Patron
87
87
  # Force curl to use IPv4
88
88
  attr_accessor :force_ipv4
89
89
 
90
+ # Support automatic Content-Encoding decompression and set liberal Accept-Encoding headers
91
+ attr_accessor :automatic_content_encoding
92
+
90
93
  private :handle_request, :enable_cookie_session, :set_debug_file
91
94
 
92
95
  # Create a new Session object.
@@ -236,6 +239,7 @@ module Patron
236
239
  Request.new.tap do |req|
237
240
  req.action = action
238
241
  req.headers = self.headers.merge headers
242
+ req.automatic_content_encoding = options.fetch :automatic_content_encoding, self.automatic_content_encoding
239
243
  req.timeout = options.fetch :timeout, self.timeout
240
244
  req.connect_timeout = options.fetch :connect_timeout, self.connect_timeout
241
245
  req.force_ipv4 = options.fetch :force_ipv4, self.force_ipv4
@@ -23,8 +23,6 @@
23
23
  ##
24
24
  ## -------------------------------------------------------------------
25
25
 
26
- require 'cgi'
27
-
28
26
  module Patron
29
27
  module Util
30
28
  extend self
@@ -34,7 +32,7 @@ module Patron
34
32
  recursive = Proc.new do |h, prefix|
35
33
  h.each_pair do |k,v|
36
34
  key = prefix == '' ? k : "#{prefix}[#{k}]"
37
- v = CGI::escape(v.to_s) if escape_values
35
+ v = Patron::Session.escape(v.to_s) if escape_values
38
36
  v.is_a?(Hash) ? recursive.call(v, key) : pairs << "#{key}=#{v}"
39
37
  end
40
38
  end
@@ -1,3 +1,3 @@
1
1
  module Patron
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -38,14 +38,30 @@ describe Patron::Session do
38
38
  @session.force_ipv4 = true
39
39
  expect { @session.get("/test") }.to_not raise_error
40
40
  end
41
-
42
- it "should escape and unescape strings symetrically" do
43
- string = "foo~bar baz/"
44
- escaped = @session.escape(string)
45
- unescaped = @session.unescape(escaped)
46
- expect(unescaped).to be == string
41
+
42
+ describe '.escape and #escape' do
43
+ it 'makes escape() and unescape() available on the class' do
44
+ string = "foo~bar baz/"
45
+ escaped = described_class.escape(string)
46
+ unescaped = described_class.unescape(escaped)
47
+ expect(unescaped).to be == string
48
+ end
49
+
50
+ it "should escape and unescape strings symetrically" do
51
+ string = "foo~bar baz/"
52
+ escaped = @session.escape(string)
53
+ unescaped = @session.unescape(escaped)
54
+ expect(unescaped).to be == string
55
+ end
56
+
57
+ it "should make e and unescape strings symetrically" do
58
+ string = "foo~bar baz/"
59
+ escaped = @session.escape(string)
60
+ unescaped = @session.unescape(escaped)
61
+ expect(unescaped).to be == string
62
+ end
47
63
  end
48
-
64
+
49
65
  it "should raise an error when passed an invalid action" do
50
66
  expect { @session.request(:bogus, "/test", {}) }.to raise_error(ArgumentError)
51
67
  end
@@ -329,6 +345,17 @@ describe Patron::Session do
329
345
  expect(body.request_method).to be == "GET"
330
346
  end
331
347
 
348
+ it "should automatically decompress using Content-Encoding if requested" do
349
+ @session.automatic_content_encoding = true
350
+ response = @session.get('/gzip-compressed')
351
+
352
+ expect(response.headers['Content-Length']).to eq('125')
353
+
354
+ body = response.body
355
+ expect(body).to match(/Some highly compressible data/)
356
+ expect(body.bytesize).to eq(29696)
357
+ end
358
+
332
359
  it "should serialize query params and append them to the url" do
333
360
  response = @session.request(:get, "/test", {}, :query => {:foo => "bar"})
334
361
  request = YAML::load(response.body)
@@ -70,6 +70,29 @@ class TestServlet < HTTPServlet::AbstractServlet
70
70
  end
71
71
  end
72
72
 
73
+ class GzipServlet < HTTPServlet::AbstractServlet
74
+
75
+ def do_GET(req,res)
76
+ raise "Need to have the right Accept-Encoding: header" unless req.header['Accept-Encoding']
77
+
78
+ out = StringIO.new
79
+ z = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION)
80
+ 1024.times {
81
+ out << z.deflate('Some highly compressible data')
82
+ }
83
+ out << z.finish
84
+ z.close
85
+
86
+ content_length = out.size
87
+ # Content-Length gets set automatically by WEBrick, and if we do it manually
88
+ # here then two headers will be set.
89
+ # res.header['Content-Length'] = content_length
90
+ res.header['Content-Encoding'] = 'deflate'
91
+ res.header['Vary'] = 'Accept-Encoding'
92
+ res.body = out.string
93
+ end
94
+ end
95
+
73
96
  class TimeoutServlet < HTTPServlet::AbstractServlet
74
97
  def do_GET(req,res)
75
98
  sleep(1.1)
@@ -83,7 +106,6 @@ class RedirectServlet < HTTPServlet::AbstractServlet
83
106
  end
84
107
  end
85
108
 
86
-
87
109
  class TestPostBodyServlet < HTTPServlet::AbstractServlet
88
110
  include RespondWith
89
111
  def do_POST(req, res)
@@ -91,8 +113,6 @@ class TestPostBodyServlet < HTTPServlet::AbstractServlet
91
113
  end
92
114
  end
93
115
 
94
-
95
-
96
116
  class SetCookieServlet < HTTPServlet::AbstractServlet
97
117
  def do_GET(req, res)
98
118
  res['Set-Cookie'] = "session_id=foo123"
@@ -162,6 +182,7 @@ class PatronTestServer
162
182
  @server.mount("/setcookie", SetCookieServlet)
163
183
  @server.mount("/repetitiveheader", RepetitiveHeaderServlet)
164
184
  @server.mount("/wrongcontentlength", WrongContentLengthServlet)
185
+ @server.mount("/gzip-compressed", GzipServlet)
165
186
 
166
187
  end
167
188
 
@@ -26,6 +26,7 @@ require File.expand_path("./spec") + '/spec_helper.rb'
26
26
  describe Patron::Util do
27
27
 
28
28
  describe :build_query_pairs_from_hash do
29
+
29
30
  it "correctly serializes a simple hash" do
30
31
  hash = {:foo => "bar", "baz" => 42}
31
32
  array = Patron::Util.build_query_pairs_from_hash(hash)
@@ -33,6 +34,7 @@ describe Patron::Util do
33
34
  expect(array).to include("foo=bar")
34
35
  expect(array).to include("baz=42")
35
36
  end
37
+
36
38
  it "correctly serializes a more complex hash" do
37
39
  hash = {
38
40
  :foo => "bar",
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.5.1
4
+ version: 0.6.0
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-03-14 00:00:00.000000000 Z
11
+ date: 2016-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler