httpclient 2.2.0.2 → 2.2.1
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/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
|