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 +4 -4
- data/Gemfile.lock +1 -1
- data/ext/patron/session_ext.c +48 -57
- data/lib/patron/request.rb +1 -1
- data/lib/patron/session.rb +12 -0
- data/lib/patron/version.rb +1 -1
- data/spec/session_spec.rb +21 -2
- data/spec/support/test_server.rb +8 -1
- 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: c363a7f520fb90344efb2251b25a0dbbc6e0d5db
|
4
|
+
data.tar.gz: f95d681849dd57101b33408327fc3aa38d0dc2e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1945f68df49b6f96ee53166382807ac5e5a19bd00d2746e325d3af02ffe54b14db6f5ad92a55fe6322f5183b25b047cd2879503b6dfbb5bc9c1afc69c5c617ee
|
7
|
+
data.tar.gz: a487793a4bb938d77804e4f0ea083c61afad062014cacbadcb40343f31ddb3fb55889f844f7b0610101f06f1a765f3c53fe1257bf9b48cabe4fda2ae71398334
|
data/Gemfile.lock
CHANGED
data/ext/patron/session_ext.c
CHANGED
@@ -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 =
|
357
|
-
VALUE a_c_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 =
|
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(
|
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 =
|
374
|
-
VALUE download_file =
|
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
|
-
|
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 =
|
395
|
-
VALUE filename =
|
396
|
-
VALUE 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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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] =
|
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);
|
data/lib/patron/request.rb
CHANGED
@@ -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
|
data/lib/patron/session.rb
CHANGED
@@ -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
|
#
|
data/lib/patron/version.rb
CHANGED
data/spec/session_spec.rb
CHANGED
@@ -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 =
|
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
|
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)
|
data/spec/support/test_server.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2016-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|