patron 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/Gemfile.lock +1 -1
- data/ext/patron/session_ext.c +48 -21
- data/lib/patron/session.rb +10 -4
- data/lib/patron/version.rb +1 -1
- data/spec/session_spec.rb +11 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f76646171763f7fa4dfc31e84faa095603d0a436
|
4
|
+
data.tar.gz: 1afb07a23dac44e8a082049cd5e5c4500a3ae6f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e082c9ffc4a0fca0384aa00393761ca50dbbece9745b13e66c8e5776b195c2865ea03ccc79849907ab3c084a40570fff1bdd38b5e690e327a8d268e93e6058fc
|
7
|
+
data.tar.gz: eaa0104eddc56283dd2561a5aae9c4736dd5e24c433cc2a08d360900173a6ac18c1c2dd7731881a339fadf7f802a8224d22476120c01ac884746983d7bd2895f
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/ext/patron/session_ext.c
CHANGED
@@ -26,6 +26,7 @@
|
|
26
26
|
#if defined(USE_TBR) && defined(HAVE_THREAD_H)
|
27
27
|
#include <ruby/thread.h>
|
28
28
|
#endif
|
29
|
+
#include <sys/stat.h>
|
29
30
|
#include <curl/curl.h>
|
30
31
|
#include "membuffer.h"
|
31
32
|
#include "sglib.h" /* Simple Generic Library -> http://sglib.sourceforge.net */
|
@@ -51,8 +52,8 @@ struct curl_state {
|
|
51
52
|
CURL* handle;
|
52
53
|
char* upload_buf;
|
53
54
|
FILE* download_file;
|
54
|
-
FILE* upload_file;
|
55
55
|
FILE* debug_file;
|
56
|
+
FILE* request_body_file;
|
56
57
|
char error_buf[CURL_ERROR_SIZE];
|
57
58
|
struct curl_slist* headers;
|
58
59
|
struct curl_httppost* post;
|
@@ -329,12 +330,47 @@ static FILE* open_file(VALUE filename, const char* perms) {
|
|
329
330
|
return handle;
|
330
331
|
}
|
331
332
|
|
333
|
+
static void set_request_body_file(struct curl_state* state, VALUE r_path_str) {
|
334
|
+
CURL* curl = state->handle;
|
335
|
+
|
336
|
+
state->request_body_file = open_file(r_path_str, "rb");
|
337
|
+
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
338
|
+
curl_easy_setopt(curl, CURLOPT_READDATA, state->request_body_file);
|
339
|
+
#ifdef CURLOPT_INFILESIZE_LARGE
|
340
|
+
struct stat stat_info;
|
341
|
+
fstat(fileno(state->request_body_file), &stat_info);
|
342
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, stat_info.st_size);
|
343
|
+
#else
|
344
|
+
struct stat stat_info;
|
345
|
+
fstat(fileno(state->request_body_file), &stat_info);
|
346
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, stat_info.st_size);
|
347
|
+
#endif
|
348
|
+
}
|
349
|
+
|
350
|
+
static void set_request_body(struct curl_state* state, VALUE stringable_or_file) {
|
351
|
+
CURL* curl = state->handle;
|
352
|
+
if(rb_respond_to(stringable_or_file, rb_intern("to_path"))) {
|
353
|
+
// Set up a file read callback (read the entire request body from a file).
|
354
|
+
// Instead of using the Ruby file reads, use #to_path to obtain the
|
355
|
+
// file path on the file system and open a file pointer to it
|
356
|
+
VALUE r_path_str = rb_funcall(stringable_or_file, rb_intern("to_path"), 0);
|
357
|
+
r_path_str = rb_funcall(r_path_str, rb_intern("to_s"), 0);
|
358
|
+
set_request_body_file(state, r_path_str);
|
359
|
+
} else {
|
360
|
+
// Set the request body from a String
|
361
|
+
VALUE data = rb_funcall(stringable_or_file, rb_intern("to_s"), 0);
|
362
|
+
long len = RSTRING_LEN(data);
|
363
|
+
state->upload_buf = StringValuePtr(data);
|
364
|
+
set_curl_request_body(curl, state->upload_buf, len);
|
365
|
+
}
|
366
|
+
}
|
367
|
+
|
332
368
|
/* Set the options on the Curl handle from a Request object. Takes each field
|
333
369
|
* in the Request object and uses it to set the appropriate option on the Curl
|
334
370
|
* handle.
|
335
371
|
*/
|
336
372
|
static void set_options_from_request(VALUE self, VALUE request) {
|
337
|
-
struct curl_state
|
373
|
+
struct curl_state* state = get_curl_state(self);
|
338
374
|
CURL* curl = state->handle;
|
339
375
|
|
340
376
|
ID action = Qnil;
|
@@ -372,10 +408,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
|
|
372
408
|
|
373
409
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
374
410
|
if (RTEST(data)) {
|
375
|
-
|
376
|
-
long len = RSTRING_LEN(data);
|
377
|
-
state->upload_buf = StringValuePtr(data);
|
378
|
-
set_curl_request_body(curl, state->upload_buf, len);
|
411
|
+
set_request_body(state, data);
|
379
412
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
|
380
413
|
}
|
381
414
|
if (RTEST(download_file)) {
|
@@ -398,30 +431,24 @@ static void set_options_from_request(VALUE self, VALUE request) {
|
|
398
431
|
}
|
399
432
|
|
400
433
|
if (RTEST(data) && !RTEST(multipart)) {
|
401
|
-
data = rb_funcall(data, rb_intern("to_s"), 0);
|
402
434
|
if (action == rb_intern("post")) {
|
403
435
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
404
436
|
}
|
405
|
-
|
406
|
-
state->upload_buf = StringValuePtr(data);
|
407
|
-
set_curl_request_body(curl, state->upload_buf, len);
|
437
|
+
set_request_body(state, data);
|
408
438
|
} else if (RTEST(filename) && !RTEST(multipart)) {
|
409
439
|
set_chunked_encoding(state);
|
410
|
-
|
411
|
-
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
412
|
-
|
413
|
-
state->upload_file = open_file(filename, "rb");
|
414
|
-
curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file);
|
440
|
+
set_request_body_file(state, filename);
|
415
441
|
} else if (RTEST(multipart)) {
|
416
442
|
if (action == rb_intern("post")) {
|
417
443
|
if(RTEST(data) && RTEST(filename)) {
|
418
444
|
if (rb_type(data) == T_HASH && rb_type(filename) == T_HASH) {
|
419
445
|
rb_hash_foreach(data, formadd_values, self);
|
420
446
|
rb_hash_foreach(filename, formadd_files, self);
|
421
|
-
|
447
|
+
} else {
|
448
|
+
rb_raise(rb_eArgError, "Data and Filename must be passed in a hash.");
|
449
|
+
}
|
422
450
|
}
|
423
451
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, state->post);
|
424
|
-
|
425
452
|
} else {
|
426
453
|
rb_raise(rb_eArgError, "Multipart PUT not supported");
|
427
454
|
}
|
@@ -670,11 +697,11 @@ static VALUE cleanup(VALUE self) {
|
|
670
697
|
state->download_file = NULL;
|
671
698
|
}
|
672
699
|
|
673
|
-
if (state->
|
674
|
-
fclose(state->
|
675
|
-
state->
|
700
|
+
if (state->request_body_file) {
|
701
|
+
fclose(state->request_body_file);
|
702
|
+
state->request_body_file = NULL;
|
676
703
|
}
|
677
|
-
|
704
|
+
|
678
705
|
if (state->post) {
|
679
706
|
curl_formfree(state->post);
|
680
707
|
state->post = NULL;
|
data/lib/patron/session.rb
CHANGED
@@ -226,7 +226,9 @@ module Patron
|
|
226
226
|
#
|
227
227
|
# @todo inconsistency with "post" - Hash not accepted
|
228
228
|
# @param url[String] the URL to fetch
|
229
|
-
# @param data[#to_s] an object that can be converted to a String
|
229
|
+
# @param data[#to_s, #to_path] an object that can be converted to a String
|
230
|
+
# to create the request body, or that responds to #to_path to upload the
|
231
|
+
# entire request body from that file
|
230
232
|
# @param headers[Hash] the hash of header keys to values
|
231
233
|
# @return [Patron::Response]
|
232
234
|
def put(url, data, headers = {})
|
@@ -238,7 +240,9 @@ module Patron
|
|
238
240
|
#
|
239
241
|
# @todo inconsistency with "post" - Hash not accepted
|
240
242
|
# @param url[String] the URL to fetch
|
241
|
-
# @param data[#to_s] an object that can be converted to a String
|
243
|
+
# @param data[#to_s, #to_path] an object that can be converted to a String
|
244
|
+
# to create the request body, or that responds to #to_path to upload the
|
245
|
+
# entire request body from that file
|
242
246
|
# @param headers[Hash] the hash of header keys to values
|
243
247
|
# @return [Patron::Response]
|
244
248
|
def patch(url, data, headers = {})
|
@@ -259,7 +263,10 @@ module Patron
|
|
259
263
|
# Uploads the passed `data` to the specified `url` using an HTTP POST.
|
260
264
|
#
|
261
265
|
# @param url[String] the URL to fetch
|
262
|
-
# @param data[Hash, #to_s] a Hash of form fields/values,
|
266
|
+
# @param data[Hash, #to_s, #to_path] a Hash of form fields/values,
|
267
|
+
# or an object that can be converted to a String
|
268
|
+
# to create the request body, or an object that responds to #to_path to upload the
|
269
|
+
# entire request body from that file
|
263
270
|
# @param headers[Hash] the hash of header keys to values
|
264
271
|
# @return [Patron::Response]
|
265
272
|
def post(url, data, headers = {})
|
@@ -293,7 +300,6 @@ module Patron
|
|
293
300
|
request(:post, url, headers, {:data => data, :file => filename, :multipart => true})
|
294
301
|
end
|
295
302
|
|
296
|
-
|
297
303
|
# @!group WebDAV methods
|
298
304
|
# Sends a WebDAV COPY request to the specified +url+.
|
299
305
|
#
|
data/lib/patron/version.rb
CHANGED
data/spec/session_spec.rb
CHANGED
@@ -248,6 +248,17 @@ describe Patron::Session do
|
|
248
248
|
expect(body.header['content-length']).to be == [data.size.to_s]
|
249
249
|
end
|
250
250
|
|
251
|
+
it "should upload a Tempfile with :put" do
|
252
|
+
data = Tempfile.new 'data-buffer'
|
253
|
+
data << Random.new.bytes(1024 * 64)
|
254
|
+
data.flush; data.rewind
|
255
|
+
|
256
|
+
response = @session.put("/test", data, {'Expect' => ''})
|
257
|
+
body = YAML::load(response.body)
|
258
|
+
expect(body.request_method).to be == "PUT"
|
259
|
+
expect(body.header['content-length']).to be == [data.size.to_s]
|
260
|
+
end
|
261
|
+
|
251
262
|
it "should upload data with :patch" do
|
252
263
|
data = "upload data"
|
253
264
|
response = @session.patch("/testpatch", data)
|
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.
|
4
|
+
version: 0.7.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-
|
11
|
+
date: 2016-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|