httpclient 2.2.0.2 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/httpclient.rb +5 -5
- data/lib/httpclient/cacert.p7s +12 -12
- data/lib/httpclient/cacert_sha1.p7s +12 -12
- data/lib/httpclient/http.rb +15 -8
- data/lib/httpclient/session.rb +6 -1
- data/lib/httpclient/ssl_config.rb +18 -14
- data/sample/async.rb +8 -0
- data/sample/auth.rb +11 -0
- data/sample/cookie.rb +18 -0
- data/sample/dav.rb +103 -0
- data/sample/howto.rb +49 -0
- data/sample/oauth_buzz.rb +57 -0
- data/sample/oauth_friendfeed.rb +59 -0
- data/sample/oauth_twitter.rb +61 -0
- data/sample/ssl/0cert.pem +22 -0
- data/sample/ssl/0key.pem +30 -0
- data/sample/ssl/1000cert.pem +19 -0
- data/sample/ssl/1000key.pem +18 -0
- data/sample/ssl/htdocs/index.html +10 -0
- data/sample/ssl/ssl_client.rb +22 -0
- data/sample/ssl/webrick_httpsd.rb +29 -0
- data/sample/stream.rb +21 -0
- data/sample/thread.rb +27 -0
- data/sample/wcat.rb +21 -0
- data/test/ca.cert +23 -0
- data/test/client.cert +19 -0
- data/test/client.key +15 -0
- data/test/helper.rb +99 -0
- data/test/htdigest +1 -0
- data/test/htpasswd +2 -0
- data/test/runner.rb +2 -0
- data/test/server.cert +19 -0
- data/test/server.key +15 -0
- data/test/sslsvr.rb +65 -0
- data/test/subca.cert +21 -0
- data/test/test_auth.rb +196 -0
- data/test/test_cookie.rb +398 -0
- data/test/test_http-access2.rb +497 -0
- data/test/test_httpclient.rb +1544 -0
- data/test/test_ssl.rb +215 -0
- metadata +53 -38
- data/lib/http-access2.rbc +0 -732
- data/lib/httpclient.rbc +0 -13559
- data/lib/httpclient/auth.rbc +0 -13772
- data/lib/httpclient/connection.rbc +0 -767
- data/lib/httpclient/cookie.rbc +0 -8442
- data/lib/httpclient/http.rbc +0 -14163
- data/lib/httpclient/session.rbc +0 -15846
- data/lib/httpclient/ssl_config.rbc +0 -5575
- data/lib/httpclient/timeout.rbc +0 -2411
- data/lib/httpclient/util.rbc +0 -1278
data/lib/httpclient.rb
CHANGED
@@ -229,7 +229,7 @@ require 'httpclient/cookie'
|
|
229
229
|
# ruby -rhttpclient -e 'p HTTPClient.head(ARGV.shift).header["last-modified"]' http://dev.ctor.org/
|
230
230
|
#
|
231
231
|
class HTTPClient
|
232
|
-
VERSION = '2.2.
|
232
|
+
VERSION = '2.2.1'
|
233
233
|
RUBY_VERSION_STRING = "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
234
234
|
/: (\S+) (\S+)/ =~ %q$Id$
|
235
235
|
LIB_NAME = "(#{$1}/#{$2}, #{RUBY_VERSION_STRING})"
|
@@ -438,7 +438,7 @@ class HTTPClient
|
|
438
438
|
#
|
439
439
|
# Calling this method resets all existing sessions.
|
440
440
|
def proxy=(proxy)
|
441
|
-
if proxy.nil?
|
441
|
+
if proxy.nil? || proxy.to_s.empty?
|
442
442
|
@proxy = nil
|
443
443
|
@proxy_auth.reset_challenge
|
444
444
|
else
|
@@ -728,9 +728,9 @@ class HTTPClient
|
|
728
728
|
# a HTTP request message body.
|
729
729
|
#
|
730
730
|
# When you pass an IO as a body, HTTPClient sends it as a HTTP request with
|
731
|
-
# chunked encoding (Transfer-Encoding: chunked in HTTP header)
|
732
|
-
# that some server application does not support
|
733
|
-
# cgi.rb does not support it.
|
731
|
+
# chunked encoding (Transfer-Encoding: chunked in HTTP header) if IO does not
|
732
|
+
# respond to :read. Bear in mind that some server application does not support
|
733
|
+
# chunked request. At least cgi.rb does not support it.
|
734
734
|
def request(method, uri, *args, &block)
|
735
735
|
query, body, header, follow_redirect = keyword_argument(args, :query, :body, :header, :follow_redirect)
|
736
736
|
if [:post, :put].include?(method)
|
data/lib/httpclient/cacert.p7s
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
MIME-Version: 1.0
|
2
|
-
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha1"; boundary="----
|
2
|
+
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha1"; boundary="----FC1E47CA462F4279D20B7F02AEA7E734"
|
3
3
|
|
4
4
|
This is an S/MIME signed message
|
5
5
|
|
6
|
-
------
|
6
|
+
------FC1E47CA462F4279D20B7F02AEA7E734
|
7
7
|
-----BEGIN CERTIFICATE-----
|
8
8
|
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
|
9
9
|
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
|
@@ -1813,7 +1813,7 @@ lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
|
|
1813
1813
|
7M2CYfE45k+XmCpajQ==
|
1814
1814
|
-----END CERTIFICATE-----
|
1815
1815
|
|
1816
|
-
------
|
1816
|
+
------FC1E47CA462F4279D20B7F02AEA7E734
|
1817
1817
|
Content-Type: application/pkcs7-signature; name="smime.p7s"
|
1818
1818
|
Content-Transfer-Encoding: base64
|
1819
1819
|
Content-Disposition: attachment; filename="smime.p7s"
|
@@ -1843,16 +1843,16 @@ BO7mpwMLMIdsjTvnkx2b/WEokIPiXr2Hcnc6FEgRQ8l8ec+8znC2LILZ1wT2K3AT
|
|
1843
1843
|
o3whsSOELB++JcWKxWsM3/6llkYx/rtlpjGCAiswggInAgEBMFAwSzELMAkGA1UE
|
1844
1844
|
BhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9wbWVudDET
|
1845
1845
|
MBEGA1UEAwwKaHR0cGNsaWVudAIBATAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJ
|
1846
|
-
|
1846
|
+
AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDUyMjA4NTEyMFowIwYJ
|
1847
1847
|
KoZIhvcNAQkEMRYEFB6px2QzZcvvEHTjt2rAmZJQzfDEMFIGCSqGSIb3DQEJDzFF
|
1848
1848
|
MEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcG
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1849
|
+
BSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIIBAL1U0w4bM8Qr
|
1850
|
+
qYow95JP8oCG/ObfF6vFgo3h50kC/iXuKz9092VcUxleieiRHNf4fdv0snWmZD6H
|
1851
|
+
aOdxaKaJYdx0ZX6nEnPIYpIZ7w7M3RQhd/BLajIHft4sl0MG5AoDBhp1xLicuHUA
|
1852
|
+
EN0a0Zcv2cqHAxu/EiaVfNHyNL1lWPu0MlpNEOh6tBc9kjKplhaZgX7yqzkGXiJj
|
1853
|
+
pTyyJ2W+iUUyD4qH2bLGVjXeruK8SKmbsOsS/EbDH/pibY7GyY+UlMyeNo9LmVcH
|
1854
|
+
hX93iPwUHfNQLfUDrjVcdx7okIQvSJrg9X3brv4NccRFa/PtqH9RkG5tFH3xnoQq
|
1855
|
+
/Q1ATdBt6C4=
|
1856
1856
|
|
1857
|
-
------
|
1857
|
+
------FC1E47CA462F4279D20B7F02AEA7E734--
|
1858
1858
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
MIME-Version: 1.0
|
2
|
-
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha1"; boundary="----
|
2
|
+
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha1"; boundary="----C57026F268CF9C1DB42129AC956CD0BC"
|
3
3
|
|
4
4
|
This is an S/MIME signed message
|
5
5
|
|
6
|
-
------
|
6
|
+
------C57026F268CF9C1DB42129AC956CD0BC
|
7
7
|
-----BEGIN CERTIFICATE-----
|
8
8
|
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
|
9
9
|
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
|
@@ -1813,7 +1813,7 @@ lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
|
|
1813
1813
|
7M2CYfE45k+XmCpajQ==
|
1814
1814
|
-----END CERTIFICATE-----
|
1815
1815
|
|
1816
|
-
------
|
1816
|
+
------C57026F268CF9C1DB42129AC956CD0BC
|
1817
1817
|
Content-Type: application/pkcs7-signature; name="smime.p7s"
|
1818
1818
|
Content-Transfer-Encoding: base64
|
1819
1819
|
Content-Disposition: attachment; filename="smime.p7s"
|
@@ -1843,16 +1843,16 @@ YMEtiMT3acFCZEjamCfXIcfLu6Jr7dYc6bvZqLd8tKkKFy01dOSEXIgHtDsthHbv
|
|
1843
1843
|
t9v4ZZy8AJlYcuqOLLbIs9nL0lnCcKLjITGCAiswggInAgEBMFAwSzELMAkGA1UE
|
1844
1844
|
BhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9wbWVudDET
|
1845
1845
|
MBEGA1UEAwwKaHR0cGNsaWVudAIBAjAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJ
|
1846
|
-
|
1846
|
+
AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDUyMjA4NTE0M1owIwYJ
|
1847
1847
|
KoZIhvcNAQkEMRYEFB6px2QzZcvvEHTjt2rAmZJQzfDEMFIGCSqGSIb3DQEJDzFF
|
1848
1848
|
MEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcG
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1849
|
+
BSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIIBAEFfFngL8sd6
|
1850
|
+
+P5CqVUuK7XCov5ALywlJJiDnk8LWaFmoM8oQldYOgUE7+Incryzku2XQXQqVXVM
|
1851
|
+
TAXSOOsvoJTCHeNopBpJzUEImrm3Cwc7gSS4Zss9l7JtrI+vnWm1DUbmicWkUB+1
|
1852
|
+
UDkIGLhRpTdlzIoa/aJi2Di2BMfQ374ej//nYQIOc4GsyDmRyR+Q07P2DLTkQfTF
|
1853
|
+
1F88F+mduib+pz3+BsqGLERONSZOEfiNOZFTfNlc77EzgUk/XcXfFohCVSXXjNRJ
|
1854
|
+
oPM4EGs9fZpt8t3f8NG4qiGb6HM/mt1FQhjUrlzXh8VHKW7zYWFSS64I2lml4x82
|
1855
|
+
xlt2BAWZwnE=
|
1856
1856
|
|
1857
|
-
------
|
1857
|
+
------C57026F268CF9C1DB42129AC956CD0BC--
|
1858
1858
|
|
data/lib/httpclient/http.rb
CHANGED
@@ -442,18 +442,18 @@ module HTTP
|
|
442
442
|
def dump(header = '', dev = '')
|
443
443
|
if @body.is_a?(Parts)
|
444
444
|
dev << header
|
445
|
-
buf = ''
|
446
445
|
@body.parts.each do |part|
|
447
446
|
if Message.file?(part)
|
448
447
|
reset_pos(part)
|
449
|
-
|
450
|
-
dev << buf
|
451
|
-
end
|
452
|
-
part.rewind
|
448
|
+
dump_file(part, dev)
|
453
449
|
else
|
454
450
|
dev << part
|
455
451
|
end
|
456
452
|
end
|
453
|
+
elsif Message.file?(@body)
|
454
|
+
dev << header
|
455
|
+
reset_pos(@body)
|
456
|
+
dump_file(@body, dev)
|
457
457
|
elsif @body
|
458
458
|
dev << header + @body
|
459
459
|
else
|
@@ -498,11 +498,11 @@ module HTTP
|
|
498
498
|
|
499
499
|
def set_content(body, boundary = nil)
|
500
500
|
if body.respond_to?(:read)
|
501
|
-
# uses Transfer-Encoding: chunked
|
502
|
-
# support it.
|
501
|
+
# uses Transfer-Encoding: chunked if body does not respond to :size.
|
502
|
+
# bear in mind that server may not support it. at least ruby's CGI doesn't.
|
503
503
|
@body = body
|
504
504
|
remember_pos(@body)
|
505
|
-
@size = nil
|
505
|
+
@size = body.respond_to?(:size) ? body.size - body.pos : nil
|
506
506
|
elsif boundary and Message.multiparam_query?(body)
|
507
507
|
@body = build_query_multipart_str(body, boundary)
|
508
508
|
@size = @body.size
|
@@ -521,6 +521,13 @@ module HTTP
|
|
521
521
|
io.pos = @positions[io] if @positions.key?(io)
|
522
522
|
end
|
523
523
|
|
524
|
+
def dump_file(io, dev)
|
525
|
+
buf = ''
|
526
|
+
while !io.read(@chunk_size, buf).nil?
|
527
|
+
dev << buf
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
524
531
|
def dump_chunks(io, dev)
|
525
532
|
buf = ''
|
526
533
|
while !io.read(@chunk_size, buf).nil?
|
data/lib/httpclient/session.rb
CHANGED
@@ -124,7 +124,7 @@ class HTTPClient
|
|
124
124
|
@protocol_version = nil
|
125
125
|
@debug_dev = client.debug_dev
|
126
126
|
@socket_sync = true
|
127
|
-
@chunk_size =
|
127
|
+
@chunk_size = ::HTTP::Message::Body::DEFAULT_CHUNK_SIZE
|
128
128
|
|
129
129
|
@connect_timeout = 60
|
130
130
|
@connect_retry = 1
|
@@ -899,6 +899,7 @@ class HTTPClient
|
|
899
899
|
begin
|
900
900
|
@socket.readpartial(maxbytes, buf)
|
901
901
|
rescue EOFError
|
902
|
+
close
|
902
903
|
buf = nil
|
903
904
|
end
|
904
905
|
end
|
@@ -917,6 +918,10 @@ class HTTPClient
|
|
917
918
|
buf = ''
|
918
919
|
while true
|
919
920
|
len = @socket.gets(RS)
|
921
|
+
if len.nil? # EOF
|
922
|
+
close
|
923
|
+
return
|
924
|
+
end
|
920
925
|
@chunk_length = len.hex
|
921
926
|
if @chunk_length == 0
|
922
927
|
@content_length = 0
|
@@ -146,19 +146,23 @@ class HTTPClient
|
|
146
146
|
# Calling this method resets all existing sessions.
|
147
147
|
def add_trust_ca(trust_ca_file_or_hashed_dir)
|
148
148
|
@cacerts_loaded = true # avoid lazy override
|
149
|
+
add_trust_ca_to_store(@cert_store, trust_ca_file_or_hashed_dir)
|
150
|
+
change_notify
|
151
|
+
end
|
152
|
+
alias set_trust_ca add_trust_ca
|
153
|
+
|
154
|
+
def add_trust_ca_to_store(cert_store, trust_ca_file_or_hashed_dir)
|
149
155
|
if FileTest.directory?(trust_ca_file_or_hashed_dir)
|
150
|
-
|
156
|
+
cert_store.add_path(trust_ca_file_or_hashed_dir)
|
151
157
|
else
|
152
|
-
|
158
|
+
cert_store.add_file(trust_ca_file_or_hashed_dir)
|
153
159
|
end
|
154
|
-
change_notify
|
155
160
|
end
|
156
|
-
alias set_trust_ca add_trust_ca
|
157
161
|
|
158
162
|
# Loads default trust anchors.
|
159
163
|
# Calling this method resets all existing sessions.
|
160
164
|
def load_trust_ca
|
161
|
-
load_cacerts
|
165
|
+
load_cacerts(@cert_store)
|
162
166
|
change_notify
|
163
167
|
end
|
164
168
|
|
@@ -283,13 +287,13 @@ class HTTPClient
|
|
283
287
|
# Default callback for verification: only dumps error.
|
284
288
|
def default_verify_callback(is_ok, ctx)
|
285
289
|
if $DEBUG
|
286
|
-
|
290
|
+
warn("#{ is_ok ? 'ok' : 'ng' }: #{ctx.current_cert.subject}")
|
287
291
|
end
|
288
292
|
if !is_ok
|
289
293
|
depth = ctx.error_depth
|
290
294
|
code = ctx.error
|
291
295
|
msg = ctx.error_string
|
292
|
-
|
296
|
+
warn("at depth #{depth} - #{code}: #{msg}")
|
293
297
|
end
|
294
298
|
is_ok
|
295
299
|
end
|
@@ -300,7 +304,7 @@ class HTTPClient
|
|
300
304
|
depth = ctx.error_depth
|
301
305
|
code = ctx.error
|
302
306
|
msg = ctx.error_string
|
303
|
-
|
307
|
+
warn("at depth #{depth} - #{code}: #{msg}") if $DEBUG
|
304
308
|
return false
|
305
309
|
end
|
306
310
|
|
@@ -333,13 +337,13 @@ class HTTPClient
|
|
333
337
|
end
|
334
338
|
|
335
339
|
if self_signed
|
336
|
-
|
340
|
+
warn('self signing CA') if $DEBUG
|
337
341
|
return true
|
338
342
|
elsif ca
|
339
|
-
|
343
|
+
warn('middle level CA') if $DEBUG
|
340
344
|
return true
|
341
345
|
elsif server_auth
|
342
|
-
|
346
|
+
warn('for server authentication') if $DEBUG
|
343
347
|
return true
|
344
348
|
end
|
345
349
|
|
@@ -352,7 +356,7 @@ class HTTPClient
|
|
352
356
|
@client.reset_all
|
353
357
|
end
|
354
358
|
|
355
|
-
def load_cacerts
|
359
|
+
def load_cacerts(cert_store)
|
356
360
|
[
|
357
361
|
[DIST_CERT, 'cacert.p7s'],
|
358
362
|
[DIST_CERT_SHA1, 'cacert_sha1.p7s']
|
@@ -364,12 +368,12 @@ class HTTPClient
|
|
364
368
|
store = X509::Store.new
|
365
369
|
store.add_cert(selfcert)
|
366
370
|
if (p7.verify(nil, store, p7.data, 0))
|
367
|
-
|
371
|
+
add_trust_ca_to_store(cert_store, file)
|
368
372
|
return
|
369
373
|
end
|
370
374
|
end
|
371
375
|
end
|
372
|
-
|
376
|
+
warn("cacerts loading failed")
|
373
377
|
end
|
374
378
|
|
375
379
|
DIST_CERT =<<__DIST_CERT__
|
data/sample/async.rb
ADDED
data/sample/auth.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
|
3
|
+
c = HTTPClient.new
|
4
|
+
c.debug_dev = STDOUT
|
5
|
+
|
6
|
+
# for Proxy authentication: supports Basic, Negotiate and NTLM.
|
7
|
+
#c.set_proxy_auth("admin", "admin")
|
8
|
+
|
9
|
+
# for WWW authentication: supports Basic, Digest and Negotiate.
|
10
|
+
c.set_auth("http://dev.ctor.org/http-access2/", "user", "user")
|
11
|
+
p c.get("http://dev.ctor.org/http-access2/login")
|
data/sample/cookie.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join('..', 'lib'))
|
4
|
+
require 'httpclient'
|
5
|
+
|
6
|
+
proxy = ENV['HTTP_PROXY']
|
7
|
+
clnt = HTTPClient.new(proxy)
|
8
|
+
clnt.set_cookie_store("cookie.dat")
|
9
|
+
clnt.debug_dev = STDOUT if $DEBUG
|
10
|
+
|
11
|
+
while urlstr = ARGV.shift
|
12
|
+
response = clnt.get(urlstr){ |data|
|
13
|
+
print data
|
14
|
+
}
|
15
|
+
p response.contenttype
|
16
|
+
end
|
17
|
+
|
18
|
+
clnt.save_cookie_store
|
data/sample/dav.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'httpclient'
|
3
|
+
|
4
|
+
class DAV
|
5
|
+
attr_reader :headers
|
6
|
+
|
7
|
+
def initialize(uri = nil)
|
8
|
+
@uri = nil
|
9
|
+
@headers = {}
|
10
|
+
open(uri) if uri
|
11
|
+
proxy = ENV['HTTP_PROXY'] || ENV['http_proxy'] || nil
|
12
|
+
@client = HTTPClient.new(proxy)
|
13
|
+
end
|
14
|
+
|
15
|
+
def open(uri)
|
16
|
+
@uri = if uri.is_a?(URI)
|
17
|
+
uri
|
18
|
+
else
|
19
|
+
URI.parse(uri)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_basic_auth(user_id, passwd)
|
24
|
+
@client.set_basic_auth(@uri, user_id, passwd)
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: propget/propset support
|
28
|
+
|
29
|
+
def propfind(target)
|
30
|
+
target_uri = @uri + target
|
31
|
+
res = @client.propfind(target_uri)
|
32
|
+
res.body.content
|
33
|
+
end
|
34
|
+
|
35
|
+
def get(target, local = nil)
|
36
|
+
local ||= target
|
37
|
+
target_uri = @uri + target
|
38
|
+
if FileTest.exist?(local)
|
39
|
+
raise RuntimeError.new("File #{ local } exists.")
|
40
|
+
end
|
41
|
+
f = File.open(local, "wb")
|
42
|
+
res = @client.get(target_uri, nil, @headers) do |data|
|
43
|
+
f << data
|
44
|
+
end
|
45
|
+
f.close
|
46
|
+
STDOUT.puts("#{ res.header['content-length'][0] } bytes saved to file #{ target }.")
|
47
|
+
end
|
48
|
+
|
49
|
+
def debug_dev=(dev)
|
50
|
+
@client.debug_dev = dev
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_content(target)
|
54
|
+
target_uri = @uri + target
|
55
|
+
@client.get_content(target_uri, nil, @headers)
|
56
|
+
end
|
57
|
+
|
58
|
+
def put_content(target, content)
|
59
|
+
target_uri = @uri + target
|
60
|
+
res = @client.put(target_uri, content, @headers)
|
61
|
+
if res.status < 200 or res.status >= 300
|
62
|
+
raise "HTTP PUT failed: #{res.inspect}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Mock
|
67
|
+
attr_reader :headers
|
68
|
+
|
69
|
+
def initialize(uri = nil)
|
70
|
+
@uri = nil
|
71
|
+
@headers = {}
|
72
|
+
open(uri) if uri
|
73
|
+
|
74
|
+
@cache = {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def open(uri)
|
78
|
+
@uri = uri.is_a?(URI) ? uri : URI.parse(uri)
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_basic_auth(user_id, passwd)
|
82
|
+
# ignore
|
83
|
+
end
|
84
|
+
|
85
|
+
def propfind(target)
|
86
|
+
# not found
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def get(target, local = nil)
|
91
|
+
# ignore
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_content(target)
|
95
|
+
@cache[target]
|
96
|
+
end
|
97
|
+
|
98
|
+
def put_content(target, content)
|
99
|
+
@cache[target] = content
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/sample/howto.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join('..', 'lib'))
|
4
|
+
require 'httpclient'
|
5
|
+
|
6
|
+
proxy = ENV['HTTP_PROXY']
|
7
|
+
clnt = HTTPClient.new(proxy)
|
8
|
+
clnt.set_cookie_store("cookie.dat")
|
9
|
+
target = ARGV.shift || "http://localhost/foo.cgi"
|
10
|
+
|
11
|
+
puts
|
12
|
+
puts '= GET content directly'
|
13
|
+
puts clnt.get_content(target)
|
14
|
+
|
15
|
+
puts '= GET result object'
|
16
|
+
result = clnt.get(target)
|
17
|
+
puts '== Header object'
|
18
|
+
p result.header
|
19
|
+
puts "== Content-type"
|
20
|
+
p result.contenttype
|
21
|
+
puts '== Body object'
|
22
|
+
p result.body
|
23
|
+
puts '== Content'
|
24
|
+
print result.content
|
25
|
+
puts '== GET with Block'
|
26
|
+
clnt.get(target) do |str|
|
27
|
+
puts str
|
28
|
+
end
|
29
|
+
|
30
|
+
puts
|
31
|
+
puts '= GET with query'
|
32
|
+
puts clnt.get(target, { "foo" => "bar", "baz" => "quz" }).content
|
33
|
+
|
34
|
+
puts
|
35
|
+
puts '= GET with query 2'
|
36
|
+
puts clnt.get(target, [["foo", "bar1"], ["foo", "bar2"]]).content
|
37
|
+
|
38
|
+
clnt.debug_dev = STDERR
|
39
|
+
puts
|
40
|
+
puts '= GET with extra header'
|
41
|
+
puts clnt.get(target, nil, { "SOAPAction" => "HelloWorld" }).content
|
42
|
+
|
43
|
+
puts
|
44
|
+
puts '= GET with extra header 2'
|
45
|
+
puts clnt.get(target, nil, [["Accept", "text/plain"], ["Accept", "text/html"]]).content
|
46
|
+
|
47
|
+
clnt.debug_dev = nil
|
48
|
+
|
49
|
+
clnt.save_cookie_store
|