patron 0.4.14 → 0.4.15
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.
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/ext/patron/session_ext.c +13 -16
- data/lib/patron/response.rb +32 -3
- data/lib/patron/session.rb +31 -17
- data/lib/patron/version.rb +1 -1
- data/script/test_server +17 -1
- data/spec/session_spec.rb +10 -0
- metadata +45 -55
- data/.rvmrc +0 -1
data/Gemfile.lock
CHANGED
data/ext/patron/session_ext.c
CHANGED
@@ -355,23 +355,25 @@ static void set_options_from_request(VALUE self, VALUE request) {
|
|
355
355
|
}
|
356
356
|
|
357
357
|
// Use the info in a Curl handle to create a new Response object.
|
358
|
-
static VALUE create_response(CURL* curl) {
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
char* url = NULL;
|
363
|
-
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
|
364
|
-
rb_iv_set(response, "@url", rb_str_new2(url));
|
358
|
+
static VALUE create_response(VALUE self, CURL* curl, VALUE header_buffer, VALUE body_buffer) {
|
359
|
+
char* effective_url = NULL;
|
360
|
+
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
|
361
|
+
VALUE url = rb_str_new2(effective_url);
|
365
362
|
|
366
363
|
long code = 0;
|
367
364
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
|
368
|
-
|
365
|
+
VALUE status = INT2NUM(code);
|
369
366
|
|
370
367
|
long count = 0;
|
371
368
|
curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &count);
|
372
|
-
|
369
|
+
VALUE redirect_count = INT2NUM(count);
|
370
|
+
|
371
|
+
VALUE default_charset = rb_iv_get(self, "@default_response_charset");
|
373
372
|
|
374
|
-
|
373
|
+
VALUE args[6] = { url, status, redirect_count, header_buffer, body_buffer, default_charset };
|
374
|
+
|
375
|
+
return rb_class_new_instance(6, args,
|
376
|
+
rb_const_get(mPatron, rb_intern("Response")));
|
375
377
|
}
|
376
378
|
|
377
379
|
// Raise an exception based on the Curl error code.
|
@@ -419,12 +421,7 @@ static VALUE perform_request(VALUE self) {
|
|
419
421
|
#endif
|
420
422
|
|
421
423
|
if (CURLE_OK == ret) {
|
422
|
-
|
423
|
-
if (!NIL_P(body_buffer)) {
|
424
|
-
rb_iv_set(response, "@body", body_buffer);
|
425
|
-
}
|
426
|
-
rb_funcall(response, rb_intern("parse_headers"), 1, header_buffer);
|
427
|
-
return response;
|
424
|
+
return create_response(self, curl, header_buffer, body_buffer);
|
428
425
|
} else {
|
429
426
|
rb_raise(select_error(ret), "%s", state->error_buf);
|
430
427
|
}
|
data/lib/patron/response.rb
CHANGED
@@ -28,11 +28,22 @@ module Patron
|
|
28
28
|
# Represents the response from the HTTP server.
|
29
29
|
class Response
|
30
30
|
|
31
|
-
def initialize
|
32
|
-
@
|
31
|
+
def initialize(url, status, redirect_count, header_data, body, default_charset = "ASCII-8BIT")
|
32
|
+
@url = url
|
33
|
+
@status = status
|
34
|
+
@redirect_count = redirect_count
|
35
|
+
@body = body
|
36
|
+
|
37
|
+
@charset = determine_charset(header_data, body) || default_charset
|
38
|
+
|
39
|
+
[url, header_data, body].each do |attr|
|
40
|
+
convert_to_default_encoding!(attr)
|
41
|
+
end
|
42
|
+
|
43
|
+
parse_headers(header_data)
|
33
44
|
end
|
34
45
|
|
35
|
-
attr_reader :url, :status, :status_line, :redirect_count, :body, :headers
|
46
|
+
attr_reader :url, :status, :status_line, :redirect_count, :body, :headers, :charset
|
36
47
|
|
37
48
|
def inspect
|
38
49
|
# Avoid spamming the console with the header and body data
|
@@ -41,8 +52,26 @@ module Patron
|
|
41
52
|
|
42
53
|
private
|
43
54
|
|
55
|
+
def determine_charset(header_data, body)
|
56
|
+
header_data.match(charset_regex) || (body && body.match(charset_regex))
|
57
|
+
|
58
|
+
$1
|
59
|
+
end
|
60
|
+
|
61
|
+
def charset_regex
|
62
|
+
/(?:charset|encoding)="?([a-z0-9-]+)"?/i
|
63
|
+
end
|
64
|
+
|
65
|
+
def convert_to_default_encoding!(str)
|
66
|
+
if str.respond_to?(:encode) && Encoding.default_internal
|
67
|
+
str.force_encoding(charset).encode!(Encoding.default_internal)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
44
71
|
# Called by the C code to parse and set the headers
|
45
72
|
def parse_headers(header_data)
|
73
|
+
@headers = {}
|
74
|
+
|
46
75
|
header_data.split(/\r\n/).each do |header|
|
47
76
|
if header =~ %r|^HTTP/1.[01]|
|
48
77
|
@status_line = header.strip
|
data/lib/patron/session.rb
CHANGED
@@ -75,6 +75,9 @@ module Patron
|
|
75
75
|
# only be set if buffer_size is non-nil
|
76
76
|
attr_accessor :buffer_size
|
77
77
|
|
78
|
+
# Default encoding of responses. Used if no charset is provided by the host.
|
79
|
+
attr_accessor :default_response_charset
|
80
|
+
|
78
81
|
private :ext_initialize, :handle_request, :enable_cookie_session, :set_debug_file
|
79
82
|
|
80
83
|
# Create a new Session object.
|
@@ -150,8 +153,12 @@ module Patron
|
|
150
153
|
end
|
151
154
|
|
152
155
|
# Uploads the passed +data+ to the specified +url+ using HTTP POST. +data+
|
153
|
-
#
|
156
|
+
# can be a string or a hash.
|
154
157
|
def post(url, data, headers = {})
|
158
|
+
if data.is_a?(Hash)
|
159
|
+
data = data.map {|k,v| urlencode(k.to_s) + '=' + urlencode(v.to_s) }.join('&')
|
160
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
161
|
+
end
|
155
162
|
request(:post, url, headers, :data => data)
|
156
163
|
end
|
157
164
|
|
@@ -185,22 +192,22 @@ module Patron
|
|
185
192
|
headers['Expect'] ||= ''
|
186
193
|
|
187
194
|
req = Request.new
|
188
|
-
req.action
|
189
|
-
req.
|
190
|
-
req.
|
191
|
-
req.
|
192
|
-
req.
|
193
|
-
req.username
|
194
|
-
req.password
|
195
|
-
req.
|
196
|
-
req.
|
197
|
-
req.
|
198
|
-
req.
|
199
|
-
req.
|
200
|
-
req.
|
201
|
-
req.
|
202
|
-
req.
|
203
|
-
req.
|
195
|
+
req.action = action
|
196
|
+
req.headers = self.headers.merge headers
|
197
|
+
req.timeout = options.fetch :timeout, self.timeout
|
198
|
+
req.connect_timeout = options.fetch :connect_timeout, self.connect_timeout
|
199
|
+
req.max_redirects = options.fetch :max_redirects, self.max_redirects
|
200
|
+
req.username = options.fetch :username, self.username
|
201
|
+
req.password = options.fetch :password, self.password
|
202
|
+
req.proxy = options.fetch :proxy, self.proxy
|
203
|
+
req.proxy_type = options.fetch :proxy_type, self.proxy_type
|
204
|
+
req.auth_type = options.fetch :auth_type, self.auth_type
|
205
|
+
req.insecure = options.fetch :insecure, self.insecure
|
206
|
+
req.ignore_content_length = options.fetch :ignore_content_length, self.ignore_content_length
|
207
|
+
req.buffer_size = options.fetch :buffer_size, self.buffer_size
|
208
|
+
req.multipart = options[:multipart]
|
209
|
+
req.upload_data = options[:data]
|
210
|
+
req.file_name = options[:file]
|
204
211
|
|
205
212
|
url = self.base_url.to_s + url.to_s
|
206
213
|
uri = URI.parse(url)
|
@@ -214,5 +221,12 @@ module Patron
|
|
214
221
|
|
215
222
|
handle_request(req)
|
216
223
|
end
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
def urlencode(str)
|
228
|
+
str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0].ord) }
|
229
|
+
end
|
230
|
+
|
217
231
|
end
|
218
232
|
end
|
data/lib/patron/version.rb
CHANGED
data/script/test_server
CHANGED
@@ -36,11 +36,16 @@ class URI::Parser
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
module RespondWith
|
40
40
|
def respond_with(method, req, res)
|
41
41
|
res.body = req.to_yaml
|
42
42
|
res['Content-Type'] = "text/plain"
|
43
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class TestServlet < HTTPServlet::AbstractServlet
|
47
|
+
|
48
|
+
include RespondWith
|
44
49
|
|
45
50
|
def do_GET(req,res)
|
46
51
|
respond_with(:GET, req, res)
|
@@ -76,6 +81,16 @@ class RedirectServlet < HTTPServlet::AbstractServlet
|
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
84
|
+
|
85
|
+
class TestPostBodyServlet < HTTPServlet::AbstractServlet
|
86
|
+
include RespondWith
|
87
|
+
def do_POST(req, res)
|
88
|
+
respond_with(:POST, {'body' => req.body, 'content_type' => req.content_type}, res)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
79
94
|
class SetCookieServlet < HTTPServlet::AbstractServlet
|
80
95
|
def do_GET(req, res)
|
81
96
|
res['Set-Cookie'] = "session_id=foo123"
|
@@ -104,6 +119,7 @@ end
|
|
104
119
|
|
105
120
|
server = WEBrick::HTTPServer.new :Port => 9001
|
106
121
|
server.mount("/test", TestServlet)
|
122
|
+
server.mount("/testpost", TestPostBodyServlet)
|
107
123
|
server.mount("/timeout", TimeoutServlet)
|
108
124
|
server.mount("/redirect", RedirectServlet)
|
109
125
|
server.mount("/setcookie", SetCookieServlet)
|
data/spec/session_spec.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
## -------------------------------------------------------------------
|
24
24
|
require File.expand_path("./spec") + '/spec_helper.rb'
|
25
25
|
require 'webrick'
|
26
|
+
require 'yaml'
|
26
27
|
require 'base64'
|
27
28
|
require 'fileutils'
|
28
29
|
|
@@ -165,6 +166,15 @@ describe Patron::Session do
|
|
165
166
|
body.header['content-length'].should == [data.size.to_s]
|
166
167
|
end
|
167
168
|
|
169
|
+
it "should post a hash of arguments as a urlencoded form" do
|
170
|
+
data = {:foo => 123, 'baz' => '++hello world++'}
|
171
|
+
response = @session.post("/testpost", data)
|
172
|
+
body = YAML::load(response.body)
|
173
|
+
body['content_type'].should == "application/x-www-form-urlencoded"
|
174
|
+
body['body'].should match(/baz=%2b%2bhello%20world%2b%2b/)
|
175
|
+
body['body'].should match(/foo=123/)
|
176
|
+
end
|
177
|
+
|
168
178
|
it "should raise when no data is provided to :post" do
|
169
179
|
lambda { @session.post("/test", nil) }.should raise_error(ArgumentError)
|
170
180
|
end
|
metadata
CHANGED
@@ -1,76 +1,71 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: patron
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.15
|
4
5
|
prerelease:
|
5
|
-
version: 0.4.14
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Phillip Toland
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-08-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: bundler
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &2157493740 !ruby/object:Gem::Requirement
|
20
17
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
24
21
|
version: 1.0.0
|
25
22
|
type: :development
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake-compiler
|
29
23
|
prerelease: false
|
30
|
-
|
24
|
+
version_requirements: *2157493740
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake-compiler
|
27
|
+
requirement: &2157493280 !ruby/object:Gem::Requirement
|
31
28
|
none: false
|
32
|
-
requirements:
|
29
|
+
requirements:
|
33
30
|
- - ~>
|
34
|
-
- !ruby/object:Gem::Version
|
31
|
+
- !ruby/object:Gem::Version
|
35
32
|
version: 0.7.5
|
36
33
|
type: :development
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rspec
|
40
34
|
prerelease: false
|
41
|
-
|
35
|
+
version_requirements: *2157493280
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &2157492820 !ruby/object:Gem::Requirement
|
42
39
|
none: false
|
43
|
-
requirements:
|
40
|
+
requirements:
|
44
41
|
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
42
|
+
- !ruby/object:Gem::Version
|
46
43
|
version: 2.3.0
|
47
44
|
type: :development
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: rcov
|
51
45
|
prerelease: false
|
52
|
-
|
46
|
+
version_requirements: *2157492820
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rcov
|
49
|
+
requirement: &2157492360 !ruby/object:Gem::Requirement
|
53
50
|
none: false
|
54
|
-
requirements:
|
51
|
+
requirements:
|
55
52
|
- - ~>
|
56
|
-
- !ruby/object:Gem::Version
|
53
|
+
- !ruby/object:Gem::Version
|
57
54
|
version: 0.9.9
|
58
55
|
type: :development
|
59
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2157492360
|
60
58
|
description: Ruby HTTP client library based on libcurl
|
61
|
-
email:
|
59
|
+
email:
|
62
60
|
- phil.toland@gmail.com
|
63
61
|
executables: []
|
64
|
-
|
65
|
-
extensions:
|
62
|
+
extensions:
|
66
63
|
- ext/patron/extconf.rb
|
67
64
|
extra_rdoc_files: []
|
68
|
-
|
69
|
-
files:
|
65
|
+
files:
|
70
66
|
- .autotest
|
71
67
|
- .gitignore
|
72
68
|
- .rspec
|
73
|
-
- .rvmrc
|
74
69
|
- Gemfile
|
75
70
|
- Gemfile.lock
|
76
71
|
- LICENSE
|
@@ -96,34 +91,29 @@ files:
|
|
96
91
|
- spec/session_spec.rb
|
97
92
|
- spec/spec_helper.rb
|
98
93
|
- spec/util_spec.rb
|
99
|
-
has_rdoc: true
|
100
94
|
homepage: https://github.com/toland/patron
|
101
95
|
licenses: []
|
102
|
-
|
103
96
|
post_install_message:
|
104
97
|
rdoc_options: []
|
105
|
-
|
106
|
-
require_paths:
|
98
|
+
require_paths:
|
107
99
|
- lib
|
108
100
|
- ext
|
109
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
102
|
none: false
|
111
|
-
requirements:
|
112
|
-
- -
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
version:
|
115
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
108
|
none: false
|
117
|
-
requirements:
|
118
|
-
- -
|
119
|
-
- !ruby/object:Gem::Version
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
120
112
|
version: 1.2.0
|
121
113
|
requirements: []
|
122
|
-
|
123
114
|
rubyforge_project: patron
|
124
|
-
rubygems_version: 1.
|
115
|
+
rubygems_version: 1.8.7
|
125
116
|
signing_key:
|
126
117
|
specification_version: 3
|
127
118
|
summary: Patron HTTP Client
|
128
119
|
test_files: []
|
129
|
-
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm gemset use patron
|