httpclient 2.2.4 → 2.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +614 -0
- data/lib/hexdump.rb +15 -1
- data/lib/httpclient.rb +8 -8
- data/lib/httpclient/http.rb +13 -6
- data/lib/httpclient/session.rb +7 -2
- data/lib/httpclient/ssl_config.rb +39 -2
- data/lib/httpclient/version.rb +1 -1
- data/test/ca-chain.cert +44 -0
- data/test/helper.rb +27 -0
- data/test/test_auth.rb +5 -2
- data/test/test_hexdump.rb +14 -0
- data/test/test_http-access2.rb +24 -17
- data/test/test_httpclient.rb +100 -53
- data/test/test_ssl.rb +12 -1
- metadata +12 -3
data/lib/hexdump.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
|
1
3
|
# This was written by Arai-san and published at
|
2
4
|
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/31987
|
3
5
|
|
4
6
|
|
5
7
|
module HexDump
|
8
|
+
# str must be in BINARY encoding in 1.9
|
6
9
|
def encode(str)
|
7
10
|
offset = 0
|
8
11
|
result = []
|
@@ -21,7 +24,7 @@ module HexDump
|
|
21
24
|
result << sprintf("%08x %-36s %s", offset, data, text)
|
22
25
|
offset += 16
|
23
26
|
# omit duplicate line
|
24
|
-
if /^(#{
|
27
|
+
if /^(#{regex_quote_n(raw)})+/n =~ str[offset .. -1]
|
25
28
|
result << sprintf("%08x ...", offset)
|
26
29
|
offset += $&.length
|
27
30
|
# should print at the end
|
@@ -33,4 +36,15 @@ module HexDump
|
|
33
36
|
result
|
34
37
|
end
|
35
38
|
module_function :encode
|
39
|
+
|
40
|
+
if RUBY_VERSION >= "1.9"
|
41
|
+
# raw must be in BINARY encoding in 1.9
|
42
|
+
def self.regex_quote_n(raw)
|
43
|
+
Regexp.quote(raw)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
def self.regex_quote_n(raw)
|
47
|
+
Regexp.quote(raw, 'n')
|
48
|
+
end
|
49
|
+
end
|
36
50
|
end
|
data/lib/httpclient.rb
CHANGED
@@ -65,7 +65,7 @@ require 'httpclient/cookie'
|
|
65
65
|
#
|
66
66
|
# 3. You can pass :follow_redirect option to follow redirect response in get.
|
67
67
|
#
|
68
|
-
# puts clnt.get('http://dev.ctor.org/', :
|
68
|
+
# puts clnt.get('http://dev.ctor.org/', :follow_redirect => true)
|
69
69
|
#
|
70
70
|
# 4. Get content as chunks of String. It yields chunks of String.
|
71
71
|
#
|
@@ -198,7 +198,7 @@ require 'httpclient/cookie'
|
|
198
198
|
#
|
199
199
|
# Pass a Hash or an Array for header argument.
|
200
200
|
#
|
201
|
-
# header = { 'Accept' => '
|
201
|
+
# header = { 'Accept' => 'text/html' }
|
202
202
|
# clnt.get(uri, query, header)
|
203
203
|
#
|
204
204
|
# header = [['Accept', 'image/jpeg'], ['Accept', 'image/png']]
|
@@ -562,7 +562,7 @@ class HTTPClient
|
|
562
562
|
# Give an array to pass multiple value like
|
563
563
|
# [["a", "b"], ["a", "c"]] => 'http://host/part?a=b&a=c'.
|
564
564
|
# header:: a Hash or an Array of extra headers. e.g.
|
565
|
-
# { 'Accept' => '
|
565
|
+
# { 'Accept' => 'text/html' } or
|
566
566
|
# [['Accept', 'image/jpeg'], ['Accept', 'image/png']].
|
567
567
|
# &block:: Give a block to get chunked message-body of response like
|
568
568
|
# get_content(uri) { |chunked_body| ... }.
|
@@ -597,7 +597,7 @@ class HTTPClient
|
|
597
597
|
# { 'Content-Type' => 'video/mp4', :content => File.new('video.mp4') }]
|
598
598
|
# => <Two parts with custom Content-Type header>
|
599
599
|
# header:: a Hash or an Array of extra headers. e.g.
|
600
|
-
# { 'Accept' => '
|
600
|
+
# { 'Accept' => 'text/html' }
|
601
601
|
# or
|
602
602
|
# [['Accept', 'image/jpeg'], ['Accept', 'image/png']].
|
603
603
|
# &block:: Give a block to get chunked message-body of response like
|
@@ -641,8 +641,8 @@ class HTTPClient
|
|
641
641
|
newuri = URI.parse(res.header['location'][0])
|
642
642
|
unless newuri.is_a?(URI::HTTP)
|
643
643
|
newuri = uri + newuri
|
644
|
-
|
645
|
-
|
644
|
+
warn("could be a relative URI in location header which is not recommended")
|
645
|
+
warn("'The field value consists of a single absolute URI' in HTTP spec")
|
646
646
|
end
|
647
647
|
if https?(uri) && !https?(newuri)
|
648
648
|
raise BadResponseError.new("redirecting to non-https resource")
|
@@ -721,7 +721,7 @@ class HTTPClient
|
|
721
721
|
# => <Two parts with custom Content-Type header>
|
722
722
|
# See HTTP::Message.file? for actual condition of 'a file'.
|
723
723
|
# header:: a Hash or an Array of extra headers. e.g.
|
724
|
-
# { 'Accept' => '
|
724
|
+
# { 'Accept' => 'text/html' } or
|
725
725
|
# [['Accept', 'image/jpeg'], ['Accept', 'image/png']].
|
726
726
|
# &block:: Give a block to get chunked message-body of response like
|
727
727
|
# get(uri) { |chunked_body| ... }.
|
@@ -996,7 +996,7 @@ private
|
|
996
996
|
end
|
997
997
|
req = HTTP::Message.new_request(method, uri, query, body, boundary)
|
998
998
|
header.each do |key, value|
|
999
|
-
req.header.add(key, value)
|
999
|
+
req.header.add(key.to_s, value)
|
1000
1000
|
end
|
1001
1001
|
if @cookie_manager && cookie = @cookie_manager.find(uri)
|
1002
1002
|
req.header.add('Cookie', cookie)
|
data/lib/httpclient/http.rb
CHANGED
@@ -7,7 +7,9 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
require 'time'
|
10
|
-
|
10
|
+
if defined?(Encoding::ASCII_8BIT)
|
11
|
+
require 'open-uri' # for encoding
|
12
|
+
end
|
11
13
|
|
12
14
|
|
13
15
|
# A namespace module for HTTP Message definitions used by HTTPClient.
|
@@ -256,6 +258,11 @@ module HTTP
|
|
256
258
|
}.join
|
257
259
|
end
|
258
260
|
|
261
|
+
# Set Date header
|
262
|
+
def set_date_header
|
263
|
+
set('Date', Time.now.httpdate)
|
264
|
+
end
|
265
|
+
|
259
266
|
# Adds a header. Addition order is preserved.
|
260
267
|
def add(key, value)
|
261
268
|
if value.is_a?(Array)
|
@@ -392,7 +399,7 @@ module HTTP
|
|
392
399
|
return if @dumped
|
393
400
|
@dumped = true
|
394
401
|
if defined?(Apache) && self['Date'].empty?
|
395
|
-
|
402
|
+
set_date_header
|
396
403
|
end
|
397
404
|
keep_alive = Message.keep_alive_enabled?(@http_version)
|
398
405
|
if @chunked
|
@@ -525,7 +532,7 @@ module HTTP
|
|
525
532
|
private
|
526
533
|
|
527
534
|
def set_content(body, boundary = nil)
|
528
|
-
if
|
535
|
+
if Message.file?(body)
|
529
536
|
# uses Transfer-Encoding: chunked if body does not respond to :size.
|
530
537
|
# bear in mind that server may not support it. at least ruby's CGI doesn't.
|
531
538
|
@body = body
|
@@ -588,14 +595,14 @@ module HTTP
|
|
588
595
|
if Message.file?(part)
|
589
596
|
@as_stream = true
|
590
597
|
@body << part
|
591
|
-
if part.respond_to?(:
|
598
|
+
if part.respond_to?(:lstat)
|
599
|
+
@size += part.lstat.size
|
600
|
+
elsif part.respond_to?(:size)
|
592
601
|
if sz = part.size
|
593
602
|
@size += sz
|
594
603
|
else
|
595
604
|
@size = nil
|
596
605
|
end
|
597
|
-
elsif part.respond_to?(:lstat)
|
598
|
-
@size += part.lstat.size
|
599
606
|
else
|
600
607
|
# use chunked upload
|
601
608
|
@size = nil
|
data/lib/httpclient/session.rb
CHANGED
@@ -717,10 +717,15 @@ class HTTPClient
|
|
717
717
|
if @from
|
718
718
|
req.header.set('From', @from)
|
719
719
|
end
|
720
|
+
if req.header.get('Accept').empty?
|
721
|
+
req.header.set('Accept', '*/*')
|
722
|
+
end
|
720
723
|
if @transparent_gzip_decompression
|
721
724
|
req.header.set('Accept-Encoding', 'gzip,deflate')
|
722
725
|
end
|
723
|
-
req.header.
|
726
|
+
if req.header.get('Date').empty?
|
727
|
+
req.header.set_date_header
|
728
|
+
end
|
724
729
|
end
|
725
730
|
|
726
731
|
# Connect to the server
|
@@ -808,7 +813,7 @@ class HTTPClient
|
|
808
813
|
parse_header
|
809
814
|
res.http_version, res.status, res.reason = @version, @status, @reason
|
810
815
|
@headers.each do |key, value|
|
811
|
-
res.header.set(key, value)
|
816
|
+
res.header.set(key.to_s, value)
|
812
817
|
end
|
813
818
|
commands = @client.request_filter.collect { |filter|
|
814
819
|
filter.filter_response(req, res)
|
@@ -33,6 +33,8 @@ class HTTPClient
|
|
33
33
|
class SSLConfig
|
34
34
|
include OpenSSL if SSLEnabled
|
35
35
|
|
36
|
+
# String name of OpenSSL's SSL version method name: SSLv2, SSLv23 or SSLv3
|
37
|
+
attr_reader :ssl_version
|
36
38
|
# OpenSSL::X509::Certificate:: certificate for SSL client authenticateion.
|
37
39
|
# nil by default. (no client authenticateion)
|
38
40
|
attr_reader :client_cert
|
@@ -80,11 +82,21 @@ class HTTPClient
|
|
80
82
|
@verify_callback = nil
|
81
83
|
@dest = nil
|
82
84
|
@timeout = nil
|
85
|
+
# TODO: change to "SSLv3" in future versions to make harder to use SSLv2.
|
86
|
+
@ssl_version = "SSLv23"
|
83
87
|
@options = defined?(SSL::OP_ALL) ? SSL::OP_ALL | SSL::OP_NO_SSLv2 : nil
|
84
|
-
|
88
|
+
# OpenSSL 0.9.8 default: "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH"
|
89
|
+
@ciphers = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
|
85
90
|
@cacerts_loaded = false
|
86
91
|
end
|
87
92
|
|
93
|
+
# Sets SSL version method String. Possible values: "SSLv2" for SSL2,
|
94
|
+
# "SSLv3" for SSL3 and TLS1.x, "SSLv23" for SSL3 with fallback to SSL2.
|
95
|
+
def ssl_version=(ssl_version)
|
96
|
+
@ssl_version = ssl_version
|
97
|
+
change_notify
|
98
|
+
end
|
99
|
+
|
88
100
|
# Sets certificate (OpenSSL::X509::Certificate) for SSL client
|
89
101
|
# authentication.
|
90
102
|
# client_key and client_cert must be a pair.
|
@@ -117,6 +129,24 @@ class HTTPClient
|
|
117
129
|
change_notify
|
118
130
|
end
|
119
131
|
|
132
|
+
# Sets OpenSSL's default trusted CA certificates. Generally, OpenSSL is
|
133
|
+
# configured to use OS's trusted CA certificates located at
|
134
|
+
# /etc/pki/certs or /etc/ssl/certs. Unfortunately OpenSSL's Windows build
|
135
|
+
# does not work with Windows Certificate Storage.
|
136
|
+
#
|
137
|
+
# On Windows or when you build OpenSSL manually, you can set the
|
138
|
+
# CA certificates directory by SSL_CERT_DIR env variable at runtime.
|
139
|
+
#
|
140
|
+
# SSL_CERT_DIR=/etc/ssl/certs ruby -rhttpclient -e "..."
|
141
|
+
#
|
142
|
+
# Calling this method resets all existing sessions.
|
143
|
+
def set_default_paths
|
144
|
+
@cacerts_loaded = true # avoid lazy override
|
145
|
+
@cert_store = X509::Store.new
|
146
|
+
@cert_store.set_default_paths
|
147
|
+
change_notify
|
148
|
+
end
|
149
|
+
|
120
150
|
# Drops current certificate store (OpenSSL::X509::Store) for SSL and create
|
121
151
|
# new one for the next session.
|
122
152
|
#
|
@@ -253,6 +283,7 @@ class HTTPClient
|
|
253
283
|
ctx.timeout = @timeout
|
254
284
|
ctx.options = @options
|
255
285
|
ctx.ciphers = @ciphers
|
286
|
+
ctx.ssl_version = @ssl_version
|
256
287
|
end
|
257
288
|
|
258
289
|
# post connection check proc for ruby < 1.8.5.
|
@@ -287,7 +318,13 @@ class HTTPClient
|
|
287
318
|
# Default callback for verification: only dumps error.
|
288
319
|
def default_verify_callback(is_ok, ctx)
|
289
320
|
if $DEBUG
|
290
|
-
|
321
|
+
if is_ok
|
322
|
+
warn("ok: #{ctx.current_cert.subject.to_s.dump}")
|
323
|
+
else
|
324
|
+
warn("ng: #{ctx.current_cert.subject.to_s.dump} at depth #{ctx.error_depth} - #{ctx.error}: #{ctx.error_string} in #{ctx.chain.inspect}")
|
325
|
+
end
|
326
|
+
warn(ctx.current_cert.to_text)
|
327
|
+
warn(ctx.current_cert.to_pem)
|
291
328
|
end
|
292
329
|
if !is_ok
|
293
330
|
depth = ctx.error_depth
|
data/lib/httpclient/version.rb
CHANGED
data/test/ca-chain.cert
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
3
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
+
DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
|
5
|
+
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
|
6
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
|
7
|
+
wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
|
8
|
+
L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
|
9
|
+
bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
|
10
|
+
JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
|
11
|
+
dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
|
12
|
+
AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
|
13
|
+
ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
|
14
|
+
USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
|
15
|
+
31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
|
16
|
+
SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
|
17
|
+
ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
|
18
|
+
r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
|
19
|
+
MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
|
20
|
+
PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
|
21
|
+
PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
|
22
|
+
d/xgcK06UVQRL/HbEYGiQL056mc=
|
23
|
+
-----END CERTIFICATE-----
|
24
|
+
-----BEGIN CERTIFICATE-----
|
25
|
+
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
26
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
27
|
+
DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
|
28
|
+
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
|
29
|
+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
|
30
|
+
ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
|
31
|
+
d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
|
32
|
+
kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
|
33
|
+
3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
|
34
|
+
4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
|
35
|
+
AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
|
36
|
+
cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
|
37
|
+
LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
|
38
|
+
rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
|
39
|
+
c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
|
40
|
+
LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
|
41
|
+
ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
|
42
|
+
SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
|
43
|
+
uY/bPeOBYiVsOYVe
|
44
|
+
-----END CERTIFICATE-----
|
data/test/helper.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
require 'test/unit'
|
3
|
+
require 'simplecov'
|
4
|
+
require 'simplecov-rcov'
|
5
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
6
|
+
SimpleCov.start
|
7
|
+
|
3
8
|
require 'httpclient'
|
4
9
|
require 'webrick'
|
5
10
|
require 'webrick/httpproxy.rb'
|
@@ -96,4 +101,26 @@ module Helper
|
|
96
101
|
end
|
97
102
|
t
|
98
103
|
end
|
104
|
+
|
105
|
+
def params(str)
|
106
|
+
HTTP::Message.parse(str).inject({}) { |r, (k, v)| r[k] = v.first; r }
|
107
|
+
end
|
108
|
+
|
109
|
+
def silent
|
110
|
+
begin
|
111
|
+
back, $VERBOSE = $VERBOSE, nil
|
112
|
+
yield
|
113
|
+
ensure
|
114
|
+
$VERBOSE = back
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def escape_env
|
119
|
+
env = {}
|
120
|
+
env.update(ENV)
|
121
|
+
yield
|
122
|
+
ensure
|
123
|
+
ENV.clear
|
124
|
+
ENV.update(env)
|
125
|
+
end
|
99
126
|
end
|
data/test/test_auth.rb
CHANGED
@@ -39,15 +39,18 @@ class TestAuth < Test::Unit::TestCase
|
|
39
39
|
htdigest = File.join(File.dirname(__FILE__), 'htdigest')
|
40
40
|
htdigest_userdb = WEBrick::HTTPAuth::Htdigest.new(htdigest)
|
41
41
|
@basic_auth = WEBrick::HTTPAuth::BasicAuth.new(
|
42
|
+
:Logger => @logger,
|
42
43
|
:Realm => 'auth',
|
43
44
|
:UserDB => htpasswd_userdb
|
44
45
|
)
|
45
46
|
@digest_auth = WEBrick::HTTPAuth::DigestAuth.new(
|
47
|
+
:Logger => @logger,
|
46
48
|
:Algorithm => 'MD5',
|
47
49
|
:Realm => 'auth',
|
48
50
|
:UserDB => htdigest_userdb
|
49
51
|
)
|
50
52
|
@digest_sess_auth = WEBrick::HTTPAuth::DigestAuth.new(
|
53
|
+
:Logger => @logger,
|
51
54
|
:Algorithm => 'MD5-sess',
|
52
55
|
:Realm => 'auth',
|
53
56
|
:UserDB => htdigest_userdb
|
@@ -177,7 +180,7 @@ class TestAuth < Test::Unit::TestCase
|
|
177
180
|
c.www_auth.oauth.challenge('http://photos.example.net/')
|
178
181
|
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
179
182
|
c.debug_dev = str = ''
|
180
|
-
c.get_content('http://photos.example.net/photos', :file
|
183
|
+
c.get_content('http://photos.example.net/photos', [[:file, 'vacation.jpg'], [:size, 'original']])
|
181
184
|
assert(str.index(%q(GET /photos?file=vacation.jpg&size=original)))
|
182
185
|
assert(str.index(%q(Authorization: OAuth realm="http://photos.example.net/", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="kllo9940pd9333jh", oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d00sl2jdk", oauth_version="1.0")))
|
183
186
|
#
|
@@ -189,7 +192,7 @@ class TestAuth < Test::Unit::TestCase
|
|
189
192
|
#
|
190
193
|
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
191
194
|
c.debug_dev = str = ''
|
192
|
-
c.post_content('http://photos.example.net/photos', :file
|
195
|
+
c.post_content('http://photos.example.net/photos', [[:file, 'vacation.jpg'], [:size, 'original']])
|
193
196
|
assert(str.index(%q(POST /photos)))
|
194
197
|
assert(str.index(%q(Authorization: OAuth realm="http://photos.example.net/", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="kllo9940pd9333jh", oauth_signature="wPkvxykrw%2BBTdCcGqKr%2B3I%2BPsiM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d00sl2jdk", oauth_version="1.0")))
|
195
198
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
3
|
+
require 'hexdump'
|
4
|
+
|
5
|
+
|
6
|
+
class TestHexDump < Test::Unit::TestCase
|
7
|
+
def test_encode
|
8
|
+
str = "\032l\277\370\2429\216\236\351[{\{\262\350\274\376"
|
9
|
+
str.force_encoding('BINARY') if str.respond_to?(:force_encoding)
|
10
|
+
assert_equal(["00000000 1a6cbff8 a2398e9e e95b7b7b b2e8bcfe .l...9...[{{...."], HexDump.encode(str))
|
11
|
+
end
|
12
|
+
end if defined?(RUBY_ENGINE) && RUBY_ENGINE != "rbx" && RUBY_VERSION >= "1.9.0"
|
13
|
+
# Rubinius 1.8 mode does not support Regexp.quote(raw, 'n') I don't want put
|
14
|
+
# a pressure on supporting it because 1.9 mode works fine.
|
data/test/test_http-access2.rb
CHANGED
@@ -80,8 +80,8 @@ class TestClient < Test::Unit::TestCase
|
|
80
80
|
assert_equal("= Request", lines[0])
|
81
81
|
assert_equal("! CONNECTION ESTABLISHED", lines[2])
|
82
82
|
assert_equal("GET /hello HTTP/1.0", lines[3])
|
83
|
-
assert_equal("Connection: close", lines[
|
84
|
-
assert_equal("= Response", lines[
|
83
|
+
assert_equal("Connection: close", lines[6])
|
84
|
+
assert_equal("= Response", lines[7])
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_protocol_version_http11
|
@@ -92,7 +92,7 @@ class TestClient < Test::Unit::TestCase
|
|
92
92
|
assert_equal("= Request", lines[0])
|
93
93
|
assert_equal("! CONNECTION ESTABLISHED", lines[2])
|
94
94
|
assert_equal("GET / HTTP/1.1", lines[3])
|
95
|
-
assert_equal("Host: localhost:#{serverport}", lines[
|
95
|
+
assert_equal("Host: localhost:#{serverport}", lines[6])
|
96
96
|
@client.protocol_version = 'HTTP/1.1'
|
97
97
|
str = ""
|
98
98
|
@client.debug_dev = str
|
@@ -227,44 +227,51 @@ class TestClient < Test::Unit::TestCase
|
|
227
227
|
|
228
228
|
def test_head
|
229
229
|
assert_equal("head", @client.head(serverurl + 'servlet').header["x-head"][0])
|
230
|
-
|
231
|
-
|
230
|
+
param = {'1'=>'2', '3'=>'4'}
|
231
|
+
res = @client.head(serverurl + 'servlet', param)
|
232
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
232
233
|
end
|
233
234
|
|
234
235
|
def test_get
|
235
236
|
assert_equal("get", @client.get(serverurl + 'servlet').content)
|
236
|
-
|
237
|
-
|
237
|
+
param = {'1'=>'2', '3'=>'4'}
|
238
|
+
res = @client.get(serverurl + 'servlet', param)
|
239
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
238
240
|
end
|
239
241
|
|
240
242
|
def test_post
|
241
243
|
assert_equal("post", @client.post(serverurl + 'servlet').content)
|
242
|
-
|
243
|
-
|
244
|
+
param = {'1'=>'2', '3'=>'4'}
|
245
|
+
res = @client.get(serverurl + 'servlet', param)
|
246
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
244
247
|
end
|
245
248
|
|
246
249
|
def test_put
|
247
250
|
assert_equal("put", @client.put(serverurl + 'servlet').content)
|
248
|
-
|
249
|
-
|
251
|
+
param = {'1'=>'2', '3'=>'4'}
|
252
|
+
res = @client.get(serverurl + 'servlet', param)
|
253
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
250
254
|
end
|
251
255
|
|
252
256
|
def test_delete
|
253
257
|
assert_equal("delete", @client.delete(serverurl + 'servlet').content)
|
254
|
-
|
255
|
-
|
258
|
+
param = {'1'=>'2', '3'=>'4'}
|
259
|
+
res = @client.get(serverurl + 'servlet', param)
|
260
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
256
261
|
end
|
257
262
|
|
258
263
|
def test_options
|
259
264
|
assert_equal("options", @client.options(serverurl + 'servlet').content)
|
260
|
-
|
261
|
-
|
265
|
+
param = {'1'=>'2', '3'=>'4'}
|
266
|
+
res = @client.get(serverurl + 'servlet', param)
|
267
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
262
268
|
end
|
263
269
|
|
264
270
|
def test_trace
|
265
271
|
assert_equal("trace", @client.trace(serverurl + 'servlet').content)
|
266
|
-
|
267
|
-
|
272
|
+
param = {'1'=>'2', '3'=>'4'}
|
273
|
+
res = @client.get(serverurl + 'servlet', param)
|
274
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
268
275
|
end
|
269
276
|
|
270
277
|
def test_get_query
|