patron 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -1
- data/ext/patron/session_ext.c +90 -36
- data/lib/patron.rb +3 -2
- data/lib/patron/request.rb +9 -3
- data/lib/patron/response.rb +1 -0
- data/lib/patron/session.rb +52 -10
- data/spec/request_spec.rb +2 -2
- data/spec/response_spec.rb +40 -0
- data/spec/session_spec.rb +50 -0
- metadata +4 -2
data/Rakefile
CHANGED
@@ -26,6 +26,7 @@ require 'rake/clean'
|
|
26
26
|
require 'rake/rdoctask'
|
27
27
|
require 'spec/rake/spectask'
|
28
28
|
require 'jeweler'
|
29
|
+
require 'yard'
|
29
30
|
|
30
31
|
require 'rbconfig'
|
31
32
|
include Config
|
@@ -101,6 +102,11 @@ Rake::RDocTask.new do |rdoc|
|
|
101
102
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
102
103
|
end
|
103
104
|
|
105
|
+
YARD::Rake::YardocTask.new do |t|
|
106
|
+
t.files = ['lib/**/*.rb']
|
107
|
+
t.options = ['--readme', 'README.txt']
|
108
|
+
end
|
109
|
+
|
104
110
|
desc "Run specs"
|
105
111
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
106
112
|
t.spec_opts = ['--options', "spec/spec.opts"]
|
@@ -137,7 +143,7 @@ begin
|
|
137
143
|
|
138
144
|
host = "#{config['username']}@rubyforge.org"
|
139
145
|
remote_dir = "/var/www/gforge-projects/patron/"
|
140
|
-
local_dir = '
|
146
|
+
local_dir = 'doc'
|
141
147
|
|
142
148
|
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
143
149
|
end
|
data/ext/patron/session_ext.c
CHANGED
@@ -40,6 +40,8 @@ static VALUE eTooManyRedirects = Qnil;
|
|
40
40
|
struct curl_state {
|
41
41
|
CURL* handle;
|
42
42
|
char* upload_buf;
|
43
|
+
FILE* download_file;
|
44
|
+
FILE* upload_file;
|
43
45
|
char error_buf[CURL_ERROR_SIZE];
|
44
46
|
struct curl_slist* headers;
|
45
47
|
};
|
@@ -156,43 +158,86 @@ static VALUE each_http_header(VALUE header, VALUE self) {
|
|
156
158
|
return Qnil;
|
157
159
|
}
|
158
160
|
|
161
|
+
static void set_chunked_encoding(struct curl_state *state) {
|
162
|
+
state->headers = curl_slist_append(state->headers, "Transfer-Encoding: chunked");
|
163
|
+
}
|
164
|
+
|
165
|
+
static FILE* open_file(VALUE filename, char* perms) {
|
166
|
+
FILE* handle = fopen(StringValuePtr(filename), perms);
|
167
|
+
if (!handle) {
|
168
|
+
rb_raise(rb_eArgError, "Unable to open specified file.");
|
169
|
+
}
|
170
|
+
|
171
|
+
return handle;
|
172
|
+
}
|
173
|
+
|
159
174
|
// Set the options on the Curl handle from a Request object. Takes each field
|
160
175
|
// in the Request object and uses it to set the appropriate option on the Curl
|
161
176
|
// handle.
|
162
|
-
void set_options_from_request(VALUE self, VALUE request) {
|
177
|
+
static void set_options_from_request(VALUE self, VALUE request) {
|
163
178
|
struct curl_state *state;
|
164
179
|
Data_Get_Struct(self, struct curl_state, state);
|
165
180
|
|
166
181
|
CURL* curl = state->handle;
|
167
182
|
|
183
|
+
VALUE headers = rb_iv_get(request, "@headers");
|
184
|
+
if (!NIL_P(headers)) {
|
185
|
+
if (rb_type(headers) != T_HASH) {
|
186
|
+
rb_raise(rb_eArgError, "Headers must be passed in a hash.");
|
187
|
+
}
|
188
|
+
|
189
|
+
rb_iterate(rb_each, headers, each_http_header, self);
|
190
|
+
}
|
191
|
+
|
168
192
|
ID action = SYM2ID(rb_iv_get(request, "@action"));
|
169
193
|
if (action == rb_intern("get")) {
|
170
194
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
171
|
-
} else if (action == rb_intern("post")) {
|
172
|
-
VALUE data = rb_iv_get(request, "@upload_data");
|
173
|
-
|
174
|
-
state->upload_buf = StringValuePtr(data);
|
175
|
-
int len = RSTRING_LEN(data);
|
176
195
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
196
|
+
VALUE download_file = rb_iv_get(request, "@file_name");
|
197
|
+
if (!NIL_P(download_file)) {
|
198
|
+
state->download_file = open_file(download_file, "w");
|
199
|
+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, state->download_file);
|
200
|
+
} else {
|
201
|
+
state->download_file = NULL;
|
202
|
+
}
|
203
|
+
} else if (action == rb_intern("post") || action == rb_intern("put")) {
|
181
204
|
VALUE data = rb_iv_get(request, "@upload_data");
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
205
|
+
VALUE filename = rb_iv_get(request, "@file_name");
|
206
|
+
|
207
|
+
if (!NIL_P(data)) {
|
208
|
+
state->upload_buf = StringValuePtr(data);
|
209
|
+
int len = RSTRING_LEN(data);
|
210
|
+
|
211
|
+
if (action == rb_intern("post")) {
|
212
|
+
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
213
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, state->upload_buf);
|
214
|
+
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
215
|
+
} else {
|
216
|
+
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
217
|
+
curl_easy_setopt(curl, CURLOPT_READFUNCTION, &session_read_handler);
|
218
|
+
curl_easy_setopt(curl, CURLOPT_READDATA, &state->upload_buf);
|
219
|
+
curl_easy_setopt(curl, CURLOPT_INFILESIZE, len);
|
220
|
+
}
|
221
|
+
} else if (!NIL_P(filename)) {
|
222
|
+
set_chunked_encoding(state);
|
223
|
+
|
224
|
+
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
225
|
+
|
226
|
+
if (action == rb_intern("post")) {
|
227
|
+
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
228
|
+
}
|
229
|
+
|
230
|
+
state->upload_file = open_file(filename, "r");
|
231
|
+
curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file);
|
232
|
+
}
|
192
233
|
} else if (action == rb_intern("head")) {
|
193
234
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
235
|
+
} else {
|
236
|
+
VALUE action_name = rb_funcall(request, rb_intern("action_name"), 0);
|
237
|
+
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, StringValuePtr(action_name));
|
194
238
|
}
|
195
239
|
|
240
|
+
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
196
241
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error_buf);
|
197
242
|
|
198
243
|
VALUE url = rb_iv_get(request, "@url");
|
@@ -218,17 +263,11 @@ void set_options_from_request(VALUE self, VALUE request) {
|
|
218
263
|
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, r);
|
219
264
|
}
|
220
265
|
|
221
|
-
VALUE
|
222
|
-
if (!NIL_P(
|
223
|
-
|
224
|
-
rb_raise(rb_eArgError, "Headers must be passed in a hash.");
|
225
|
-
}
|
226
|
-
|
227
|
-
rb_iterate(rb_each, headers, each_http_header, self);
|
266
|
+
VALUE proxy = rb_iv_get(request, "@proxy");
|
267
|
+
if (!NIL_P(proxy)) {
|
268
|
+
curl_easy_setopt(curl, CURLOPT_PROXY, StringValuePtr(proxy));
|
228
269
|
}
|
229
270
|
|
230
|
-
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
231
|
-
|
232
271
|
VALUE credentials = rb_funcall(request, rb_intern("credentials"), 0);
|
233
272
|
if (!NIL_P(credentials)) {
|
234
273
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
@@ -237,7 +276,7 @@ void set_options_from_request(VALUE self, VALUE request) {
|
|
237
276
|
}
|
238
277
|
|
239
278
|
// Use the info in a Curl handle to create a new Response object.
|
240
|
-
VALUE create_response(CURL* curl) {
|
279
|
+
static VALUE create_response(CURL* curl) {
|
241
280
|
VALUE response = rb_class_new_instance(0, 0,
|
242
281
|
rb_const_get(mPatron, rb_intern("Response")));
|
243
282
|
|
@@ -257,7 +296,7 @@ VALUE create_response(CURL* curl) {
|
|
257
296
|
}
|
258
297
|
|
259
298
|
// Raise an exception based on the Curl error code.
|
260
|
-
VALUE select_error(CURLcode code) {
|
299
|
+
static VALUE select_error(CURLcode code) {
|
261
300
|
VALUE error = Qnil;
|
262
301
|
switch (code) {
|
263
302
|
case CURLE_UNSUPPORTED_PROTOCOL: error = eUnsupportedProtocol; break;
|
@@ -287,14 +326,19 @@ static VALUE perform_request(VALUE self) {
|
|
287
326
|
curl_easy_setopt(curl, CURLOPT_HEADERDATA, header_buffer);
|
288
327
|
|
289
328
|
// body
|
290
|
-
VALUE body_buffer =
|
291
|
-
|
292
|
-
|
329
|
+
VALUE body_buffer = Qnil;
|
330
|
+
if (!state->download_file) {
|
331
|
+
body_buffer = rb_str_buf_new(32768);
|
332
|
+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &session_write_handler);
|
333
|
+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, body_buffer);
|
334
|
+
}
|
293
335
|
|
294
336
|
CURLcode ret = curl_easy_perform(curl);
|
295
337
|
if (CURLE_OK == ret) {
|
296
338
|
VALUE response = create_response(curl);
|
297
|
-
|
339
|
+
if (!NIL_P(body_buffer)) {
|
340
|
+
rb_iv_set(response, "@body", body_buffer);
|
341
|
+
}
|
298
342
|
rb_funcall(response, rb_intern("parse_headers"), 1, header_buffer);
|
299
343
|
return response;
|
300
344
|
} else {
|
@@ -315,6 +359,16 @@ static VALUE cleanup(VALUE self) {
|
|
315
359
|
state->headers = NULL;
|
316
360
|
}
|
317
361
|
|
362
|
+
if (state->download_file) {
|
363
|
+
fclose(state->download_file);
|
364
|
+
state->download_file = NULL;
|
365
|
+
}
|
366
|
+
|
367
|
+
if (state->upload_file) {
|
368
|
+
fclose(state->upload_file);
|
369
|
+
state->upload_file = NULL;
|
370
|
+
}
|
371
|
+
|
318
372
|
state->upload_buf = NULL;
|
319
373
|
|
320
374
|
return Qnil;
|
@@ -330,7 +384,7 @@ VALUE session_handle_request(VALUE self, VALUE request) {
|
|
330
384
|
//
|
331
385
|
|
332
386
|
void Init_session_ext() {
|
333
|
-
curl_global_init(
|
387
|
+
curl_global_init(CURL_GLOBAL_ALL);
|
334
388
|
rb_require("patron/error");
|
335
389
|
|
336
390
|
mPatron = rb_define_module("Patron");
|
data/lib/patron.rb
CHANGED
@@ -34,9 +34,10 @@ module Patron #:nodoc:
|
|
34
34
|
# Returns the version number of the Patron library as a string
|
35
35
|
def self.version
|
36
36
|
cwd = Pathname(__FILE__).dirname
|
37
|
-
yaml = YAML.load_file(cwd.expand_path
|
37
|
+
yaml = YAML.load_file(cwd.expand_path + '../VERSION.yml')
|
38
38
|
major = (yaml['major'] || yaml[:major]).to_i
|
39
39
|
minor = (yaml['minor'] || yaml[:minor]).to_i
|
40
|
-
|
40
|
+
patch = (yaml['patch'] || yaml[:patch]).to_i
|
41
|
+
"#{major}.#{minor}.#{patch}"
|
41
42
|
end
|
42
43
|
end
|
data/lib/patron/request.rb
CHANGED
@@ -30,6 +30,8 @@ module Patron
|
|
30
30
|
# used in every request.
|
31
31
|
class Request
|
32
32
|
|
33
|
+
VALID_ACTIONS = [:get, :put, :post, :delete, :head, :copy]
|
34
|
+
|
33
35
|
def initialize
|
34
36
|
@action = :get
|
35
37
|
@headers = {}
|
@@ -38,12 +40,12 @@ module Patron
|
|
38
40
|
@max_redirects = -1
|
39
41
|
end
|
40
42
|
|
41
|
-
attr_accessor :url, :username, :password, :upload_data
|
43
|
+
attr_accessor :url, :username, :password, :upload_data, :file_name, :proxy
|
42
44
|
attr_reader :action, :timeout, :connect_timeout, :max_redirects, :headers
|
43
45
|
|
44
46
|
def action=(new_action)
|
45
|
-
if !
|
46
|
-
raise ArgumentError, "Action must be one of
|
47
|
+
if !VALID_ACTIONS.include?(new_action)
|
48
|
+
raise ArgumentError, "Action must be one of #{VALID_ACTIONS.join(', ')}"
|
47
49
|
end
|
48
50
|
|
49
51
|
@action = new_action
|
@@ -81,6 +83,10 @@ module Patron
|
|
81
83
|
@headers = new_headers
|
82
84
|
end
|
83
85
|
|
86
|
+
def action_name
|
87
|
+
@action.to_s.upcase
|
88
|
+
end
|
89
|
+
|
84
90
|
def credentials
|
85
91
|
return nil if username.nil? || password.nil?
|
86
92
|
"#{username}:#{password}"
|
data/lib/patron/response.rb
CHANGED
data/lib/patron/session.rb
CHANGED
@@ -50,12 +50,15 @@ module Patron
|
|
50
50
|
# Username and password for http authentication
|
51
51
|
attr_accessor :username, :password
|
52
52
|
|
53
|
+
# HTTP proxy URL
|
54
|
+
attr_accessor :proxy
|
55
|
+
|
53
56
|
# Standard set of headers that are used in all requests.
|
54
57
|
attr_reader :headers
|
55
58
|
|
56
59
|
private :ext_initialize, :handle_request
|
57
60
|
|
58
|
-
# Create
|
61
|
+
# Create a new Session object.
|
59
62
|
def initialize
|
60
63
|
ext_initialize
|
61
64
|
@headers = {}
|
@@ -64,36 +67,73 @@ module Patron
|
|
64
67
|
@max_redirects = -1
|
65
68
|
end
|
66
69
|
|
70
|
+
###################################################################
|
71
|
+
### Standard HTTP methods
|
72
|
+
###
|
73
|
+
|
67
74
|
# Retrieve the contents of the specified +url+ optionally sending the
|
68
75
|
# specified headers. If the +base_url+ varaible is set then it is prepended
|
69
76
|
# to the +url+ parameter. Any custom headers are merged with the contents
|
70
77
|
# of the +headers+ instance variable. The results are returned in a
|
71
78
|
# Response object.
|
72
79
|
def get(url, headers = {})
|
73
|
-
|
80
|
+
request(:get, url, headers)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retrieve the contents of the specified +url+ as with #get, but the
|
84
|
+
# content at the URL is downloaded directly into the specified file.
|
85
|
+
def get_file(url, filename, headers = {})
|
86
|
+
request(:get, url, headers, :file => filename)
|
74
87
|
end
|
75
88
|
|
76
89
|
# As #get but sends an HTTP HEAD request.
|
77
90
|
def head(url, headers = {})
|
78
|
-
|
91
|
+
request(:head, url, headers)
|
79
92
|
end
|
80
93
|
|
94
|
+
# As #get but sends an HTTP DELETE request.
|
81
95
|
def delete(url, headers = {})
|
82
|
-
|
96
|
+
request(:delete, url, headers)
|
83
97
|
end
|
84
98
|
|
99
|
+
# Uploads the passed +data+ to the specified +url+ using HTTP PUT. +data+
|
100
|
+
# must be a string.
|
85
101
|
def put(url, data, headers = {})
|
86
|
-
|
102
|
+
request(:put, url, headers, :data => data)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Uploads the contents of a file to the specified +url+ using HTTP PUT.
|
106
|
+
def put_file(url, filename, headers = {})
|
107
|
+
request(:put, url, headers, :file => filename)
|
87
108
|
end
|
88
109
|
|
110
|
+
# Uploads the passed +data+ to the specified +url+ using HTTP POST. +data+
|
111
|
+
# must be a string.
|
89
112
|
def post(url, data, headers = {})
|
90
|
-
|
113
|
+
request(:post, url, headers, :data => data)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Uploads the contents of a file to the specified +url+ using HTTP POST.
|
117
|
+
def post_file(url, filename, headers = {})
|
118
|
+
request(:post, url, headers, :file => filename)
|
119
|
+
end
|
120
|
+
|
121
|
+
###################################################################
|
122
|
+
### WebDAV methods
|
123
|
+
###
|
124
|
+
|
125
|
+
# Sends a WebDAV COPY request to the specified +url+.
|
126
|
+
def copy(url, dest, headers = {})
|
127
|
+
headers['Destination'] = dest
|
128
|
+
request(:copy, url, headers)
|
91
129
|
end
|
92
130
|
|
93
|
-
|
131
|
+
###################################################################
|
132
|
+
### Basic API methods
|
133
|
+
###
|
94
134
|
|
95
|
-
#
|
96
|
-
def
|
135
|
+
# Send an HTTP request to the specified +url+.
|
136
|
+
def request(action, url, headers, options = {})
|
97
137
|
req = Request.new
|
98
138
|
req.action = action
|
99
139
|
req.timeout = self.timeout
|
@@ -102,7 +142,9 @@ module Patron
|
|
102
142
|
req.headers = self.headers.merge(headers)
|
103
143
|
req.username = self.username
|
104
144
|
req.password = self.password
|
105
|
-
req.upload_data = data
|
145
|
+
req.upload_data = options[:data]
|
146
|
+
req.file_name = options[:file]
|
147
|
+
req.proxy = proxy
|
106
148
|
|
107
149
|
req.url = self.base_url.to_s + url.to_s
|
108
150
|
raise ArgumentError, "Empty URL" if req.url.empty?
|
data/spec/request_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe Patron::Request do
|
|
33
33
|
describe :action do
|
34
34
|
|
35
35
|
it "should accept :get, :put, :post, :delete and :head" do
|
36
|
-
[:get, :put, :post, :delete, :head].each do |action|
|
36
|
+
[:get, :put, :post, :delete, :head, :copy].each do |action|
|
37
37
|
lambda {@request.action = action}.should_not raise_error
|
38
38
|
end
|
39
39
|
end
|
@@ -51,7 +51,7 @@ describe Patron::Request do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should raise an exception when assigned 0" do
|
54
|
-
lambda {@request.timeout =
|
54
|
+
lambda {@request.timeout = 0}.should raise_error(ArgumentError)
|
55
55
|
end
|
56
56
|
|
57
57
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
## -------------------------------------------------------------------
|
2
|
+
##
|
3
|
+
## Copyright (c) 2009 Phillip Toland <phil.toland@gmail.com>
|
4
|
+
##
|
5
|
+
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
## of this software and associated documentation files (the "Software"), to deal
|
7
|
+
## in the Software without restriction, including without limitation the rights
|
8
|
+
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
## copies of the Software, and to permit persons to whom the Software is
|
10
|
+
## furnished to do so, subject to the following conditions:
|
11
|
+
##
|
12
|
+
## The above copyright notice and this permission notice shall be included in
|
13
|
+
## all copies or substantial portions of the Software.
|
14
|
+
##
|
15
|
+
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
## THE SOFTWARE.
|
22
|
+
##
|
23
|
+
## -------------------------------------------------------------------
|
24
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
25
|
+
require 'webrick'
|
26
|
+
require 'base64'
|
27
|
+
require 'fileutils'
|
28
|
+
|
29
|
+
describe Patron::Response do
|
30
|
+
before(:each) do
|
31
|
+
@session = Patron::Session.new
|
32
|
+
@session.base_url = "http://localhost:9001"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should strip extra spaces from header values" do
|
36
|
+
response = @session.get("/test")
|
37
|
+
# All digits, no spaces
|
38
|
+
response.headers['Content-Length'].should match(/^\d+$/)
|
39
|
+
end
|
40
|
+
end
|
data/spec/session_spec.rb
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
25
25
|
require 'webrick'
|
26
26
|
require 'base64'
|
27
|
+
require 'fileutils'
|
27
28
|
|
28
29
|
describe Patron::Session do
|
29
30
|
|
@@ -39,6 +40,10 @@ describe Patron::Session do
|
|
39
40
|
unescaped.should == string
|
40
41
|
end
|
41
42
|
|
43
|
+
it "should raise an error when passed an invalid action" do
|
44
|
+
lambda { @session.request(:bogus, "/test", {}) }.should raise_error(ArgumentError)
|
45
|
+
end
|
46
|
+
|
42
47
|
it "should raise an error when no URL is provided" do
|
43
48
|
@session.base_url = nil
|
44
49
|
lambda {@session.get(nil)}.should raise_error(ArgumentError)
|
@@ -50,6 +55,15 @@ describe Patron::Session do
|
|
50
55
|
body.request_method.should == "GET"
|
51
56
|
end
|
52
57
|
|
58
|
+
it "should download content with :get and a file path" do
|
59
|
+
tmpfile = "/tmp/patron_test.yaml"
|
60
|
+
response = @session.get_file "/test", tmpfile
|
61
|
+
response.body.should be_nil
|
62
|
+
body = YAML::load_file(tmpfile)
|
63
|
+
body.request_method.should == "GET"
|
64
|
+
FileUtils.rm tmpfile
|
65
|
+
end
|
66
|
+
|
53
67
|
it "should include custom headers in a request" do
|
54
68
|
response = @session.get("/test", {"User-Agent" => "PatronTest"})
|
55
69
|
body = YAML::load(response.body)
|
@@ -103,6 +117,18 @@ describe Patron::Session do
|
|
103
117
|
body.request_method.should == "DELETE"
|
104
118
|
end
|
105
119
|
|
120
|
+
it "should send a COPY request with :copy" do
|
121
|
+
response = @session.copy("/test", "/test2")
|
122
|
+
body = YAML::load(response.body)
|
123
|
+
body.request_method.should == "COPY"
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should include a Destination header in COPY requests" do
|
127
|
+
response = @session.copy("/test", "/test2")
|
128
|
+
body = YAML::load(response.body)
|
129
|
+
body.header['destination'].first.should == "/test2"
|
130
|
+
end
|
131
|
+
|
106
132
|
it "should upload data with :put" do
|
107
133
|
data = "upload data"
|
108
134
|
response = @session.put("/test", data)
|
@@ -111,6 +137,18 @@ describe Patron::Session do
|
|
111
137
|
body.header['content-length'].should == [data.size.to_s]
|
112
138
|
end
|
113
139
|
|
140
|
+
it "should upload a file with :put" do
|
141
|
+
response = @session.put_file("/test", "VERSION.yml")
|
142
|
+
body = YAML::load(response.body)
|
143
|
+
body.request_method.should == "PUT"
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should use chunked encoding when uploading a file with :put" do
|
147
|
+
response = @session.put_file("/test", "VERSION.yml")
|
148
|
+
body = YAML::load(response.body)
|
149
|
+
body.header['transfer-encoding'].first.should == "chunked"
|
150
|
+
end
|
151
|
+
|
114
152
|
it "should upload data with :post" do
|
115
153
|
data = "upload data"
|
116
154
|
response = @session.post("/test", data)
|
@@ -119,6 +157,18 @@ describe Patron::Session do
|
|
119
157
|
body.header['content-length'].should == [data.size.to_s]
|
120
158
|
end
|
121
159
|
|
160
|
+
it "should upload a file with :post" do
|
161
|
+
response = @session.post_file("/test", "VERSION.yml")
|
162
|
+
body = YAML::load(response.body)
|
163
|
+
body.request_method.should == "POST"
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should use chunked encoding when uploading a file with :post" do
|
167
|
+
response = @session.post_file("/test", "VERSION.yml")
|
168
|
+
body = YAML::load(response.body)
|
169
|
+
body.header['transfer-encoding'].first.should == "chunked"
|
170
|
+
end
|
171
|
+
|
122
172
|
it "should pass credentials as http basic auth" do
|
123
173
|
@session.username = "foo"
|
124
174
|
@session.password = "bar"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: patron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phillip Toland
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-20 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/patron/session.rb
|
35
35
|
- spec/patron_spec.rb
|
36
36
|
- spec/request_spec.rb
|
37
|
+
- spec/response_spec.rb
|
37
38
|
- spec/session_spec.rb
|
38
39
|
- spec/spec.opts
|
39
40
|
- spec/spec_helper.rb
|
@@ -77,5 +78,6 @@ summary: Patron HTTP client
|
|
77
78
|
test_files:
|
78
79
|
- spec/patron_spec.rb
|
79
80
|
- spec/request_spec.rb
|
81
|
+
- spec/response_spec.rb
|
80
82
|
- spec/session_spec.rb
|
81
83
|
- spec/spec_helper.rb
|