patron 0.6.1 → 0.6.3

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: 10e347aa0ab1915c0d428cbfaf4bd6888ae2a9ba
4
- data.tar.gz: 76476a77a366bd7b5b2aacc7fe946b26e142b995
3
+ metadata.gz: c363a7f520fb90344efb2251b25a0dbbc6e0d5db
4
+ data.tar.gz: f95d681849dd57101b33408327fc3aa38d0dc2e3
5
5
  SHA512:
6
- metadata.gz: 66045fc85f95a730550b061b255cc1420c4b0e6feee1a5cf5252d5cda68dad5792a146ea290208b683d5fe05c596d767864ef6189cade817c84792b4ae963f47
7
- data.tar.gz: c7292c8749d8c70e051b032069fe136e6715c8158c4b8b5a9b9c24967a629aa2314b77ea8e5addca9880163facebe728b255e7a3063a803b8fbc33ee100b2bc6
6
+ metadata.gz: 1945f68df49b6f96ee53166382807ac5e5a19bd00d2746e325d3af02ffe54b14db6f5ad92a55fe6322f5183b25b047cd2879503b6dfbb5bc9c1afc69c5c617ee
7
+ data.tar.gz: a487793a4bb938d77804e4f0ea083c61afad062014cacbadcb40343f31ddb3fb55889f844f7b0610101f06f1a765f3c53fe1257bf9b48cabe4fda2ae71398334
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- patron (0.6.1)
4
+ patron (0.6.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -77,19 +77,6 @@ static size_t session_write_handler(char* stream, size_t size, size_t nmemb, mem
77
77
  return size * nmemb;
78
78
  }
79
79
 
80
- static size_t session_read_handler(char* stream, size_t size, size_t nmemb, char **buffer) {
81
- size_t result = 0;
82
-
83
- if (buffer != NULL && *buffer != NULL) {
84
- size_t len = size * nmemb;
85
- char *s1 = strncpy(stream, *buffer, len);
86
- result = strlen(s1);
87
- *buffer += result;
88
- }
89
-
90
- return result;
91
- }
92
-
93
80
  /* A non-zero return value from the progress handler will terminate the current
94
81
  * request. We use this fact in order to interrupt any request when either the
95
82
  * user calls the "interrupt" method on the session or when the Ruby interpreter
@@ -319,6 +306,16 @@ static int formadd_files(VALUE data_key, VALUE data_value, VALUE self) {
319
306
  return 0;
320
307
  }
321
308
 
309
+ // Set the given char pointer and it's length to be the CURL request body
310
+ static void set_curl_request_body(CURL* curl, char* buf, curl_off_t len) {
311
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
312
+ #ifdef CURLOPT_POSTFIELDSIZE_LARGE
313
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, len);
314
+ #else
315
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
316
+ #endif
317
+ }
318
+
322
319
  static void set_chunked_encoding(struct curl_state *state) {
323
320
  state->headers = curl_slist_append(state->headers, "Transfer-Encoding: chunked");
324
321
  }
@@ -353,10 +350,10 @@ static void set_options_from_request(VALUE self, VALUE request) {
353
350
  VALUE cacert = Qnil;
354
351
  VALUE ssl_version = Qnil;
355
352
  VALUE buffer_size = Qnil;
356
- VALUE action_name = rb_iv_get(request, "@action");
357
- VALUE a_c_encoding = rb_iv_get(request, "@automatic_content_encoding");
353
+ VALUE action_name = rb_funcall(request, rb_intern("action"), 0);
354
+ VALUE a_c_encoding = rb_funcall(request, rb_intern("automatic_content_encoding"), 0);
358
355
 
359
- headers = rb_iv_get(request, "@headers");
356
+ headers = rb_funcall(request, rb_intern("headers"), 0);
360
357
  if (!NIL_P(headers)) {
361
358
  if (rb_type(headers) != T_HASH) {
362
359
  rb_raise(rb_eArgError, "Headers must be passed in a hash.");
@@ -366,23 +363,20 @@ static void set_options_from_request(VALUE self, VALUE request) {
366
363
  }
367
364
 
368
365
  action = SYM2ID(action_name);
369
- if(rb_iv_get(request, "@force_ipv4")) {
366
+ if(rb_funcall(request, rb_intern("force_ipv4"), 0)) {
370
367
  curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
371
368
  }
372
369
  if (action == rb_intern("get")) {
373
- VALUE data = rb_iv_get(request, "@upload_data");
374
- VALUE download_file = rb_iv_get(request, "@file_name");
370
+ VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
371
+ VALUE download_file = rb_funcall(request, rb_intern("file_name"), 0);
375
372
 
376
373
  curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
377
374
  if (!NIL_P(data)) {
378
375
  data = rb_funcall(data, rb_intern("to_s"), 0);
379
376
  long len = RSTRING_LEN(data);
380
377
  state->upload_buf = StringValuePtr(data);
381
- curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
378
+ set_curl_request_body(curl, state->upload_buf, len);
382
379
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
383
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, &session_read_handler);
384
- curl_easy_setopt(curl, CURLOPT_READDATA, &state->upload_buf);
385
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, len);
386
380
  }
387
381
  if (!NIL_P(download_file)) {
388
382
  state->download_file = open_file(download_file, "wb");
@@ -390,35 +384,32 @@ static void set_options_from_request(VALUE self, VALUE request) {
390
384
  } else {
391
385
  state->download_file = NULL;
392
386
  }
393
- } else if (action == rb_intern("post") || action == rb_intern("put")) {
394
- VALUE data = rb_iv_get(request, "@upload_data");
395
- VALUE filename = rb_iv_get(request, "@file_name");
396
- VALUE multipart = rb_iv_get(request, "@multipart");
397
-
387
+ } else if (action == rb_intern("post") || action == rb_intern("put") || action == rb_intern("patch")) {
388
+ VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
389
+ VALUE filename = rb_funcall(request, rb_intern("file_name"), 0);
390
+ VALUE multipart = rb_funcall(request, rb_intern("multipart"), 0);
391
+
392
+ if (action == rb_intern("post")) {
393
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
394
+ } else if (action == rb_intern("put")) {
395
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
396
+ } else if (action == rb_intern("patch")) {
397
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
398
+ }
399
+
398
400
  if (!NIL_P(data) && NIL_P(multipart)) {
399
401
  data = rb_funcall(data, rb_intern("to_s"), 0);
400
- long len = RSTRING_LEN(data);
401
- state->upload_buf = StringValuePtr(data);
402
-
403
402
  if (action == rb_intern("post")) {
404
403
  curl_easy_setopt(curl, CURLOPT_POST, 1);
405
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, state->upload_buf);
406
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
407
- } else {
408
- curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
409
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, &session_read_handler);
410
- curl_easy_setopt(curl, CURLOPT_READDATA, &state->upload_buf);
411
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, len);
412
404
  }
405
+ long len = RSTRING_LEN(data);
406
+ state->upload_buf = StringValuePtr(data);
407
+ set_curl_request_body(curl, state->upload_buf, len);
413
408
  } else if (!NIL_P(filename) && NIL_P(multipart)) {
414
409
  set_chunked_encoding(state);
415
410
 
416
411
  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
417
412
 
418
- if (action == rb_intern("post")) {
419
- curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
420
- }
421
-
422
413
  state->upload_file = open_file(filename, "rb");
423
414
  curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file);
424
415
  } else if (!NIL_P(multipart)) {
@@ -441,8 +432,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
441
432
 
442
433
  // support for data passed with a DELETE request (e.g.: used by elasticsearch)
443
434
  } else if (action == rb_intern("delete")) {
444
- VALUE data = rb_iv_get(request, "@upload_data");
445
-
435
+ VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
446
436
  if (!NIL_P(data)) {
447
437
  long len = RSTRING_LEN(data);
448
438
  state->upload_buf = StringValuePtr(data);
@@ -475,57 +465,58 @@ static void set_options_from_request(VALUE self, VALUE request) {
475
465
  #endif
476
466
  }
477
467
 
478
- url = rb_iv_get(request, "@url");
468
+ url = rb_funcall(request, rb_intern("url"), 0);
479
469
  if (NIL_P(url)) {
480
470
  rb_raise(rb_eArgError, "Must provide a URL");
481
471
  }
482
472
  curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
483
473
 
484
- timeout = rb_iv_get(request, "@timeout");
474
+ timeout = rb_funcall(request, rb_intern("timeout"), 0);
485
475
  if (!NIL_P(timeout)) {
486
476
  curl_easy_setopt(curl, CURLOPT_TIMEOUT, FIX2INT(timeout));
487
477
  }
488
478
 
489
- timeout = rb_iv_get(request, "@connect_timeout");
479
+ timeout = rb_funcall(request, rb_intern("connect_timeout"), 0);
490
480
  if (!NIL_P(timeout)) {
491
481
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FIX2INT(timeout));
492
482
  }
493
483
 
494
- redirects = rb_iv_get(request, "@max_redirects");
484
+ redirects = rb_funcall(request, rb_intern("max_redirects"), 0);
495
485
  if (!NIL_P(redirects)) {
496
486
  int r = FIX2INT(redirects);
497
487
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, r == 0 ? 0 : 1);
498
488
  curl_easy_setopt(curl, CURLOPT_MAXREDIRS, r);
499
489
  }
500
490
 
501
- proxy = rb_iv_get(request, "@proxy");
491
+ proxy = rb_funcall(request, rb_intern("proxy"), 0);
502
492
  if (!NIL_P(proxy)) {
503
493
  curl_easy_setopt(curl, CURLOPT_PROXY, StringValuePtr(proxy));
504
494
  }
505
495
 
506
- proxy_type = rb_iv_get(request, "@proxy_type");
496
+ proxy_type = rb_funcall(request, rb_intern("proxy_type"), 0);
507
497
  if (!NIL_P(proxy_type)) {
508
498
  curl_easy_setopt(curl, CURLOPT_PROXYTYPE, NUM2LONG(proxy_type));
509
499
  }
510
500
 
511
501
  credentials = rb_funcall(request, rb_intern("credentials"), 0);
512
502
  if (!NIL_P(credentials)) {
513
- curl_easy_setopt(curl, CURLOPT_HTTPAUTH, NUM2LONG(rb_iv_get(request, "@auth_type")));
503
+ VALUE auth_type = rb_funcall(request, rb_intern("auth_type"), 0);
504
+ curl_easy_setopt(curl, CURLOPT_HTTPAUTH, NUM2LONG(auth_type));
514
505
  curl_easy_setopt(curl, CURLOPT_USERPWD, StringValuePtr(credentials));
515
506
  }
516
507
 
517
- ignore_content_length = rb_iv_get(request, "@ignore_content_length");
508
+ ignore_content_length = rb_funcall(request, rb_intern("ignore_content_length"), 0);
518
509
  if (!NIL_P(ignore_content_length)) {
519
510
  curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1);
520
511
  }
521
512
 
522
- insecure = rb_iv_get(request, "@insecure");
513
+ insecure = rb_funcall(request, rb_intern("insecure"), 0);
523
514
  if(!NIL_P(insecure)) {
524
515
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
525
516
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
526
517
  }
527
518
 
528
- ssl_version = rb_iv_get(request, "@ssl_version");
519
+ ssl_version = rb_funcall(request, rb_intern("ssl_version"), 0);
529
520
  if(!NIL_P(ssl_version)) {
530
521
  VALUE ssl_version_str = rb_funcall(ssl_version, rb_intern("to_s"), 0);
531
522
  char* version = StringValuePtr(ssl_version_str);
@@ -540,12 +531,12 @@ static void set_options_from_request(VALUE self, VALUE request) {
540
531
  }
541
532
  }
542
533
 
543
- cacert = rb_iv_get(request, "@cacert");
534
+ cacert = rb_funcall(request, rb_intern("cacert"), 0);
544
535
  if(!NIL_P(cacert)) {
545
536
  curl_easy_setopt(curl, CURLOPT_CAINFO, StringValuePtr(cacert));
546
537
  }
547
538
 
548
- buffer_size = rb_iv_get(request, "@buffer_size");
539
+ buffer_size = rb_funcall(request, rb_intern("buffer_size"), 0);
549
540
  if (!NIL_P(buffer_size)) {
550
541
  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, NUM2LONG(buffer_size));
551
542
  }
@@ -575,7 +566,7 @@ static VALUE create_response(VALUE self, CURL* curl, VALUE header_buffer, VALUE
575
566
 
576
567
  args[3] = header_buffer;
577
568
  args[4] = body_buffer;
578
- args[5] = rb_iv_get(self, "@default_response_charset");
569
+ args[5] = rb_funcall(self, rb_intern("default_response_charset"), 0);
579
570
 
580
571
  responseKlass = rb_funcall(self, rb_intern("response_class"), 0);
581
572
  return rb_class_new_instance(6, args, responseKlass);
@@ -34,7 +34,7 @@ module Patron
34
34
  class Request
35
35
 
36
36
  # Contains the valid HTTP verbs that can be used to perform requests
37
- VALID_ACTIONS = %w[GET PUT POST DELETE HEAD COPY]
37
+ VALID_ACTIONS = %w[GET PUT POST DELETE HEAD COPY PATCH]
38
38
 
39
39
  # Initializes a new Request, which defaults to the GET HTTP verb and
40
40
  # has it's timeouts set to 0
@@ -232,6 +232,18 @@ module Patron
232
232
  request(:put, url, headers, :data => data)
233
233
  end
234
234
 
235
+ # Uploads the passed `data` to the specified `url` using an HTTP PATCH. Note that
236
+ # unline ++post++, a Hash is not accepted as the ++data++ argument.
237
+ #
238
+ # @todo inconsistency with "post" - Hash not accepted
239
+ # @param url[String] the URL to fetch
240
+ # @param data[#to_s] an object that can be converted to a String to create the request body
241
+ # @param headers[Hash] the hash of header keys to values
242
+ # @return [Patron::Response]
243
+ def patch(url, data, headers = {})
244
+ request(:patch, url, headers, :data => data)
245
+ end
246
+
235
247
  # Uploads the contents of `file` to the specified `url` using an HTTP PUT. The file will be
236
248
  # sent "as-is" without any multipart encoding.
237
249
  #
@@ -1,3 +1,3 @@
1
1
  module Patron
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.3"
3
3
  end
@@ -194,14 +194,33 @@ describe Patron::Session do
194
194
  expect(body.request_method).to be == "GET"
195
195
  end
196
196
 
197
+ it "should upload data with :get" do
198
+ # Sending a request body with a GET request is a technique seldom used,
199
+ # but it does get used nevertheless - for instance, it is a usual
200
+ # practice when interacting with an ElasticSearch cluster where
201
+ # you can have very deeply going queries, which are still technically GETs
202
+ data = SecureRandom.random_bytes(1024 * 24)
203
+ response = @session.request(:get, "/test", {}, :data => data)
204
+ body = YAML::load(response.body)
205
+ expect(body.request_method).to be == "GET"
206
+ expect(body.header['content-length']).to be == [data.size.to_s]
207
+ end
208
+
197
209
  it "should upload data with :put" do
198
- data = "upload data"
210
+ data = SecureRandom.random_bytes(1024 * 24)
199
211
  response = @session.put("/test", data)
200
212
  body = YAML::load(response.body)
201
213
  expect(body.request_method).to be == "PUT"
202
214
  expect(body.header['content-length']).to be == [data.size.to_s]
203
215
  end
204
216
 
217
+ it "should upload data with :patch" do
218
+ data = "upload data"
219
+ response = @session.patch("/testpatch", data)
220
+ body = YAML::load(response.body)
221
+ expect(body["body"]).to eq("upload data")
222
+ end
223
+
205
224
  it "should upload data with :delete" do
206
225
  data = "upload data"
207
226
  response = @session.request(:delete, "/test", {}, :data => data)
@@ -245,7 +264,7 @@ describe Patron::Session do
245
264
  expect(body.header['content-length']).to be == [data.size.to_s]
246
265
  end
247
266
 
248
- it "should post a hash of arguments as a urlencoded form" do
267
+ it "should POST a hash of arguments as a urlencoded form" do
249
268
  data = {:foo => 123, 'baz' => '++hello world++'}
250
269
  response = @session.post("/testpost", data)
251
270
  body = YAML::load(response.body)
@@ -115,6 +115,13 @@ class TestPostBodyServlet < HTTPServlet::AbstractServlet
115
115
  end
116
116
  end
117
117
 
118
+ class TestPatchBodyServlet < HTTPServlet::AbstractServlet
119
+ include RespondWith
120
+ def do_PATCH(req, res)
121
+ respond_with(:PATCH, {'body' => req.body, 'content_type' => req.content_type}, res)
122
+ end
123
+ end
124
+
118
125
  class SetCookieServlet < HTTPServlet::AbstractServlet
119
126
  def do_GET(req, res)
120
127
  res['Set-Cookie'] = "session_id=foo123"
@@ -178,6 +185,7 @@ class PatronTestServer
178
185
 
179
186
  @server.mount("/test", TestServlet)
180
187
  @server.mount("/testpost", TestPostBodyServlet)
188
+ @server.mount("/testpatch", TestPatchBodyServlet)
181
189
  @server.mount("/timeout", TimeoutServlet)
182
190
  @server.mount("/redirect", RedirectServlet)
183
191
  @server.mount("/picture", PictureServlet)
@@ -185,7 +193,6 @@ class PatronTestServer
185
193
  @server.mount("/repetitiveheader", RepetitiveHeaderServlet)
186
194
  @server.mount("/wrongcontentlength", WrongContentLengthServlet)
187
195
  @server.mount("/gzip-compressed", GzipServlet)
188
-
189
196
  end
190
197
 
191
198
  def start
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.1
4
+ version: 0.6.3
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-14 00:00:00.000000000 Z
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler