httpclient 2.2.4 → 2.2.5
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/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
|