patron 0.4.14 → 0.4.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
|