glebtv-httpclient 3.0.0
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.
- checksums.yaml +7 -0
- data/README.rdoc +108 -0
- data/bin/httpclient +65 -0
- data/lib/glebtv-httpclient.rb +1 -0
- data/lib/hexdump.rb +50 -0
- data/lib/http-access2/cookie.rb +1 -0
- data/lib/http-access2/http.rb +1 -0
- data/lib/http-access2.rb +55 -0
- data/lib/httpclient/auth.rb +899 -0
- data/lib/httpclient/cacert.p7s +1912 -0
- data/lib/httpclient/connection.rb +88 -0
- data/lib/httpclient/cookie.rb +438 -0
- data/lib/httpclient/http.rb +1050 -0
- data/lib/httpclient/include_client.rb +83 -0
- data/lib/httpclient/session.rb +1031 -0
- data/lib/httpclient/ssl_config.rb +403 -0
- data/lib/httpclient/timeout.rb +140 -0
- data/lib/httpclient/util.rb +186 -0
- data/lib/httpclient/version.rb +3 -0
- data/lib/httpclient.rb +1157 -0
- data/lib/oauthclient.rb +110 -0
- 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-chain.cert +44 -0
- data/test/ca.cert +23 -0
- data/test/client.cert +19 -0
- data/test/client.key +15 -0
- data/test/helper.rb +129 -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 +321 -0
- data/test/test_cookie.rb +412 -0
- data/test/test_hexdump.rb +14 -0
- data/test/test_http-access2.rb +507 -0
- data/test/test_httpclient.rb +1801 -0
- data/test/test_include_client.rb +52 -0
- data/test/test_ssl.rb +235 -0
- metadata +102 -0
data/lib/oauthclient.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# HTTPClient - HTTP client library.
|
2
|
+
# Copyright (C) 2000-2009 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
#
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
require 'httpclient'
|
10
|
+
|
11
|
+
module HTTP
|
12
|
+
class Message
|
13
|
+
attr_accessor :oauth_params
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# OAuthClient provides OAuth related methods in addition to HTTPClient.
|
19
|
+
#
|
20
|
+
# See sample/ dir how to use OAuthClient. There are sample clients for Twitter,
|
21
|
+
# FriendFeed and Google Buzz.
|
22
|
+
class OAuthClient < HTTPClient
|
23
|
+
|
24
|
+
# HTTPClient::OAuth::Config:: OAuth configurator.
|
25
|
+
attr_accessor :oauth_config
|
26
|
+
|
27
|
+
# Creates a OAuthClient instance which provides OAuth related methods in
|
28
|
+
# addition to HTTPClient.
|
29
|
+
#
|
30
|
+
# Method signature is as same as HTTPClient. See HTTPClient.new
|
31
|
+
def initialize(*arg)
|
32
|
+
super
|
33
|
+
@oauth_config = HTTPClient::OAuth::Config.new
|
34
|
+
self.www_auth.oauth.set_config(nil, @oauth_config)
|
35
|
+
self.www_auth.oauth.challenge(nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get request token.
|
39
|
+
# uri:: URI for request token.
|
40
|
+
# callback:: callback String. This can be nil for OAuth 1.0a
|
41
|
+
# param:: Additional query parameter Hash.
|
42
|
+
#
|
43
|
+
# It returns a HTTP::Message instance as a response. When the request is made
|
44
|
+
# successfully, you can retrieve a pair of request token and secret like
|
45
|
+
# following;
|
46
|
+
# res = client.get_request_token(...)
|
47
|
+
# token = res.oauth_params['oauth_token']
|
48
|
+
# secret = res.oauth_params['oauth_token_secret']
|
49
|
+
def get_request_token(uri, callback = nil, param = nil)
|
50
|
+
oauth_config.token = nil
|
51
|
+
oauth_config.secret = nil
|
52
|
+
oauth_config.callback = callback
|
53
|
+
oauth_config.verifier = nil
|
54
|
+
res = request(oauth_config.http_method, uri, param)
|
55
|
+
filter_response(res)
|
56
|
+
res
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get access token.
|
60
|
+
# uri:: URI for request token.
|
61
|
+
# request_token:: a request token String. See get_access_token.
|
62
|
+
# request_token_secret:: a request secret String. See get_access_token.
|
63
|
+
# verifier:: a verifier tag String.
|
64
|
+
#
|
65
|
+
# When the request succeeds and the server returns a pair of access token
|
66
|
+
# and secret, oauth_config.token and oauth_token.secret are updated with
|
67
|
+
# the access token. Then you can call OAuthClient#get, #post, #delete, etc.
|
68
|
+
# All requests are signed.
|
69
|
+
def get_access_token(uri, request_token, request_token_secret, verifier = nil)
|
70
|
+
oauth_config.token = request_token
|
71
|
+
oauth_config.secret = request_token_secret
|
72
|
+
oauth_config.callback = nil
|
73
|
+
oauth_config.verifier = verifier
|
74
|
+
res = request(oauth_config.http_method, uri)
|
75
|
+
filter_response(res)
|
76
|
+
oauth_config.verifier = nil
|
77
|
+
res
|
78
|
+
end
|
79
|
+
|
80
|
+
# Parse response and returns a Hash.
|
81
|
+
def get_oauth_response(res)
|
82
|
+
enc = res.header['content-encoding']
|
83
|
+
body = nil
|
84
|
+
if enc and enc[0] and enc[0].downcase == 'gzip'
|
85
|
+
body = Zlib::GzipReader.wrap(StringIO.new(res.content)) { |gz| gz.read }
|
86
|
+
else
|
87
|
+
body = res.content
|
88
|
+
end
|
89
|
+
body.split('&').inject({}) { |r, e|
|
90
|
+
key, value = e.split('=', 2)
|
91
|
+
r[unescape(key)] = unescape(value)
|
92
|
+
r
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def unescape(escaped)
|
99
|
+
escaped ? ::HTTP::Message.unescape(escaped) : nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def filter_response(res)
|
103
|
+
if res.status == 200
|
104
|
+
if res.oauth_params = get_oauth_response(res)
|
105
|
+
oauth_config.token = res.oauth_params['oauth_token']
|
106
|
+
oauth_config.secret = res.oauth_params['oauth_token_secret']
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
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
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'oauthclient'
|
2
|
+
require 'zlib'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
# Get your own consumer token from http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
|
6
|
+
consumer_key = nil
|
7
|
+
consumer_secret = nil
|
8
|
+
|
9
|
+
callback = 'http://localhost/' # should point somewhere else...
|
10
|
+
scope = 'https://www.googleapis.com/auth/buzz'
|
11
|
+
request_token_url = 'https://www.google.com/accounts/OAuthGetRequestToken'
|
12
|
+
access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken'
|
13
|
+
|
14
|
+
STDOUT.sync = true
|
15
|
+
|
16
|
+
# create OAuth client.
|
17
|
+
client = OAuthClient.new
|
18
|
+
client.oauth_config.consumer_key = consumer_key
|
19
|
+
client.oauth_config.consumer_secret = consumer_secret
|
20
|
+
client.oauth_config.signature_method = 'HMAC-SHA1'
|
21
|
+
client.oauth_config.http_method = :get # Twitter does not allow :post
|
22
|
+
client.debug_dev = STDERR if $DEBUG
|
23
|
+
|
24
|
+
# Get request token.
|
25
|
+
res = client.get_request_token(request_token_url, callback, :scope => scope)
|
26
|
+
p res.status
|
27
|
+
p res.oauth_params
|
28
|
+
p res.content
|
29
|
+
p client.oauth_config
|
30
|
+
token = res.oauth_params['oauth_token']
|
31
|
+
secret = res.oauth_params['oauth_token_secret']
|
32
|
+
raise if token.nil? or secret.nil?
|
33
|
+
|
34
|
+
# You need to confirm authorization out of band.
|
35
|
+
puts
|
36
|
+
puts "Go here and do confirm: https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?oauth_token=#{token}&domain=#{consumer_key}&scope=#{scope}"
|
37
|
+
puts "Type oauth_verifier (if given) and hit [enter] to go"
|
38
|
+
require 'cgi'
|
39
|
+
verifier = CGI.unescape(gets.chomp)
|
40
|
+
verifier = nil if verifier.empty?
|
41
|
+
|
42
|
+
# Get access token.
|
43
|
+
res = client.get_access_token(access_token_url, token, secret, verifier)
|
44
|
+
p res.status
|
45
|
+
p res.oauth_params
|
46
|
+
p res.content
|
47
|
+
p client.oauth_config
|
48
|
+
id = res.oauth_params['user_id']
|
49
|
+
|
50
|
+
puts
|
51
|
+
puts "Access token usage example"
|
52
|
+
puts "Hit [enter] to go"
|
53
|
+
gets
|
54
|
+
|
55
|
+
# Access to a protected resource.
|
56
|
+
# @consumption requires Buzz API
|
57
|
+
puts client.get_content("https://www.googleapis.com/buzz/v1/activities/@me/@consumption", :alt => :json, :prettyprint => true)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'oauthclient'
|
2
|
+
|
3
|
+
# Get your own consumer token from http://friendfeed.com/api/applications
|
4
|
+
consumer_key = 'EDIT HERE'
|
5
|
+
consumer_secret = 'EDIT HERE'
|
6
|
+
|
7
|
+
request_token_url = 'https://friendfeed.com/account/oauth/request_token'
|
8
|
+
oob_authorize_url = 'https://friendfeed.com/account/oauth/authorize'
|
9
|
+
access_token_url = 'https://friendfeed.com/account/oauth/access_token'
|
10
|
+
|
11
|
+
STDOUT.sync = true
|
12
|
+
|
13
|
+
# create OAuth client.
|
14
|
+
client = OAuthClient.new
|
15
|
+
client.oauth_config.consumer_key = consumer_key
|
16
|
+
client.oauth_config.consumer_secret = consumer_secret
|
17
|
+
client.oauth_config.signature_method = 'HMAC-SHA1'
|
18
|
+
client.oauth_config.http_method = :get # FriendFeed does not allow :post
|
19
|
+
client.debug_dev = STDERR if $DEBUG
|
20
|
+
|
21
|
+
# Get request token.
|
22
|
+
res = client.get_request_token(request_token_url)
|
23
|
+
p res.status
|
24
|
+
p res.oauth_params
|
25
|
+
p res.content
|
26
|
+
p client.oauth_config
|
27
|
+
token = res.oauth_params['oauth_token']
|
28
|
+
secret = res.oauth_params['oauth_token_secret']
|
29
|
+
raise if token.nil? or secret.nil?
|
30
|
+
|
31
|
+
# You need to confirm authorization out of band.
|
32
|
+
puts
|
33
|
+
puts "Go here and do confirm: #{oob_authorize_url}?oauth_token=#{token}"
|
34
|
+
puts "Hit [enter] to go"
|
35
|
+
gets
|
36
|
+
|
37
|
+
# Get access token.
|
38
|
+
# FYI: You may need to re-construct OAuthClient instance here.
|
39
|
+
# In normal web app flow, getting access token and getting request token
|
40
|
+
# must be done in different HTTP requests.
|
41
|
+
# client = OAuthClient.new
|
42
|
+
# client.oauth_config.consumer_key = consumer_key
|
43
|
+
# client.oauth_config.consumer_secret = consumer_secret
|
44
|
+
# client.oauth_config.signature_method = 'HMAC-SHA1'
|
45
|
+
# client.oauth_config.http_method = :get # Twitter does not allow :post
|
46
|
+
res = client.get_access_token(access_token_url, token, secret)
|
47
|
+
p res.status
|
48
|
+
p res.oauth_params
|
49
|
+
p res.content
|
50
|
+
p client.oauth_config
|
51
|
+
username = res.oauth_params['username']
|
52
|
+
|
53
|
+
puts
|
54
|
+
puts "Access token usage example"
|
55
|
+
puts "Hit [enter] to go"
|
56
|
+
gets
|
57
|
+
|
58
|
+
# Access to a protected resource. (user profile)
|
59
|
+
puts client.get("http://friendfeed-api.com/v2/feedinfo/#{username}?format=json")
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'oauthclient'
|
2
|
+
|
3
|
+
# Get your own consumer token from http://twitter.com/apps
|
4
|
+
consumer_key = 'EDIT HERE'
|
5
|
+
consumer_secret = 'EDIT HERE'
|
6
|
+
|
7
|
+
callback = ARGV.shift # can be nil for OAuth 1.0. (not 1.0a)
|
8
|
+
request_token_url = 'http://twitter.com/oauth/request_token'
|
9
|
+
oob_authorize_url = 'http://twitter.com/oauth/authorize'
|
10
|
+
access_token_url = 'http://twitter.com/oauth/access_token'
|
11
|
+
|
12
|
+
STDOUT.sync = true
|
13
|
+
|
14
|
+
# create OAuth client.
|
15
|
+
client = OAuthClient.new
|
16
|
+
client.oauth_config.consumer_key = consumer_key
|
17
|
+
client.oauth_config.consumer_secret = consumer_secret
|
18
|
+
client.oauth_config.signature_method = 'HMAC-SHA1'
|
19
|
+
client.oauth_config.http_method = :get # Twitter does not allow :post
|
20
|
+
client.debug_dev = STDERR if $DEBUG
|
21
|
+
|
22
|
+
# Get request token.
|
23
|
+
res = client.get_request_token(request_token_url, callback)
|
24
|
+
p res.status
|
25
|
+
p res.oauth_params
|
26
|
+
p res.content
|
27
|
+
p client.oauth_config
|
28
|
+
token = res.oauth_params['oauth_token']
|
29
|
+
secret = res.oauth_params['oauth_token_secret']
|
30
|
+
raise if token.nil? or secret.nil?
|
31
|
+
|
32
|
+
# You need to confirm authorization out of band.
|
33
|
+
puts
|
34
|
+
puts "Go here and do confirm: #{oob_authorize_url}?oauth_token=#{token}"
|
35
|
+
puts "Type oauth_verifier/PIN (if given) and hit [enter] to go"
|
36
|
+
verifier = gets.chomp
|
37
|
+
verifier = nil if verifier.empty?
|
38
|
+
|
39
|
+
# Get access token.
|
40
|
+
# FYI: You may need to re-construct OAuthClient instance here.
|
41
|
+
# In normal web app flow, getting access token and getting request token
|
42
|
+
# must be done in different HTTP requests.
|
43
|
+
# client = OAuthClient.new
|
44
|
+
# client.oauth_config.consumer_key = consumer_key
|
45
|
+
# client.oauth_config.consumer_secret = consumer_secret
|
46
|
+
# client.oauth_config.signature_method = 'HMAC-SHA1'
|
47
|
+
# client.oauth_config.http_method = :get # Twitter does not allow :post
|
48
|
+
res = client.get_access_token(access_token_url, token, secret, verifier)
|
49
|
+
p res.status
|
50
|
+
p res.oauth_params
|
51
|
+
p res.content
|
52
|
+
p client.oauth_config
|
53
|
+
id = res.oauth_params['user_id']
|
54
|
+
|
55
|
+
puts
|
56
|
+
puts "Access token usage example"
|
57
|
+
puts "Hit [enter] to go"
|
58
|
+
gets
|
59
|
+
|
60
|
+
# Access to a protected resource. (DM)
|
61
|
+
puts client.get("http://twitter.com/direct_messages.json")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDjzCCAnegAwIBAgIBADANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJDWjEN
|
3
|
+
MAsGA1UEChMEUnVieTEPMA0GA1UEAxMGUnVieUNBMB4XDTAzMDUzMTAyNDcyOFoX
|
4
|
+
DTA1MDUzMDAyNDcyOFowLTELMAkGA1UEBhMCQ1oxDTALBgNVBAoTBFJ1YnkxDzAN
|
5
|
+
BgNVBAMTBlJ1YnlDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANfw
|
6
|
+
JSR2OxME6WBRYekhvN1M7uZwJLC3qHhRtBm583x7MS3yzF/HwFNH1oAmOmzUcDSz
|
7
|
+
Y9OmTDVIMU9b0bSYHuu8KswrRWmx/iEhgU/hODS1MQKi+uHoMTtY/dVXwTLAfw5d
|
8
|
+
UMPQ9F5EhiV57sKWrS7vIVBtpxUNgfJW61FP+Ru3Lr8uhUgXPECHck8fjFu8w2Sw
|
9
|
+
JQBQ8ePrfKBiTHpOzKmDVXXWzVYzIQN0zQfpu/FSjOJ4xWV3wmfltN4FK+UkpALW
|
10
|
+
3RKsNFx+Pmji0fr2/PeEPhzKkhWk5b+pYrIlTNkagS7u8EoeLtY1y3LSZvopbcPI
|
11
|
+
l0QFQHCMtxS7ngC6wsECAwEAAaOBuTCBtjAPBgNVHRMECDAGAQH/AgEAMC0GCWCG
|
12
|
+
SAGG+EIBDQQgFh5HZW5lcmF0ZWQgYnkgT3BlblNTTCBmb3IgUnVieS4wHQYDVR0O
|
13
|
+
BBYEFA2IpXrgDnpJ9p6bfBmtM6j0IejmMFUGA1UdIwROMEyAFA2IpXrgDnpJ9p6b
|
14
|
+
fBmtM6j0IejmoTGkLzAtMQswCQYDVQQGEwJDWjENMAsGA1UEChMEUnVieTEPMA0G
|
15
|
+
A1UEAxMGUnVieUNBggEAMA0GCSqGSIb3DQEBBQUAA4IBAQB1b4iTezqgZj6FhcAc
|
16
|
+
0AtleAc8TpUn8YOX6zSlHG6I7tKcLfnWen9eFs4Jx73Bup5wHvcrHF6U+/nAdpb5
|
17
|
+
R7lkNbjWFWwoi5cQC36mh4ym8GWhUZUf8362yPzimbdKMBIiDoIBY8NyIBBORU2m
|
18
|
+
BlXsHr0dqGpeTmNnFhgi1FCN+F/VitplOUP9E8NzsgLS/GY9HO160HbPXoZc4yp5
|
19
|
+
KFweqmyhbxZvkrrD6LanvB23cJP+TeHzA5mLJtIBciFq+AJe+cDTlJYjtLcsxkAy
|
20
|
+
Evojd//5gePjgSz3gbzU5Zq0/tI2T0rQYnmySoSQ1u2+i5FrMvEjh/H6tZtQ6nO0
|
21
|
+
ROTL
|
22
|
+
-----END CERTIFICATE-----
|
data/sample/ssl/0key.pem
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,BC9A85421E11A052
|
4
|
+
|
5
|
+
dlFN8woboqu1mLWHSe6HnBCzrJUFw1NLv4sJM8MFPcSGkPEJoqceRQ5XFFlwnhwT
|
6
|
+
WStidVQLAaCqWxPlQbvKs/eW2yEZRX3JhNHlGkuZUbAuqC7FGcIPCFtXmshmR3/K
|
7
|
+
wSxM3DuEBA31kHoyH/DGPEOcp/L9M95fU2w/1Zz895nXgECdlYfMB7KEXJ7S0TVD
|
8
|
+
NvcH6dcNS2I56ikUfRd9MA+tTtJTDsolBii3HpNkI+i8GeAAznfuyhCa+RasbMnR
|
9
|
+
3SRHSgiZpK01JkepKEumG1iyGXBE4GMlF3dK9TL4UTfK7PjbW1BRGVdmGayA5L8X
|
10
|
+
vpn9uIMbpFUD7nU/cSs6+ECYy9Fdq/d8oE7YRVpqGA2mX+Vvjzc6ZByiW8eH8uYW
|
11
|
+
d1YCySAzttQUcDFx4YlpbQN+NSE67amGY/nkXn3CnQuB2uDiUm6818p1jjhEbIj6
|
12
|
+
SQpNgpuhHPhyawMuC98BvxEXoSTFRmXx5h+Qgo8nfCBUpGUCA8STuJG+EebIXMHH
|
13
|
+
yNdZGYMdkkuzow1G+bcHaIV4pgD0hOX6D+AzhO8/11gsJNiZHWAkxRtXres0B7JQ
|
14
|
+
BTv6mrpmRsr1TbY7K55y5QePkvroiqI4BX2//RgAcUw+aBzPCSt87YU55pPxxDCv
|
15
|
+
KnoMQJapUIlXgYBs+2GBiFQlr3dAnzduXrXkZa/TuE0853QDDnKWN3aWapW0EieH
|
16
|
+
sDxYz6kZ6c/vjDJtNjjgysKvi2ZFnJMk92fi1sNd2MrH9w1vSmjHw6+b9REH+r6K
|
17
|
+
YCcMzCUnIV5Y5jgbnrY5jWlB5Jt5PlU+QDFTBNsdctyoES3h5yQh48hcpnJOy4YT
|
18
|
+
tn9jEmIAYM7QZtGZrY5yiZRZbM5tLL7VeXA0M7N0ivjZUVP4NBUV1IFhLpeus3Yo
|
19
|
+
yXB99Sib/M8fqlmnRlyKKaRseB9a80/LJdLJC7Q1aJG9JYTTpumydppDzvwwUFV/
|
20
|
+
yHQibPzWhnHTElyXSGeWWQ/4gKJXJFkSyrBeKt/DcDggEnpsVw7kAeo0KJLWvBq2
|
21
|
+
0CwnWxPsseIYSLdwE0wOZTnWvHC6viCCqxaFwROa+bHsgCtRR8xwOKVg0RQRexQi
|
22
|
+
SKsCEyq4hfKH3Kd7KkI5c4iCHrNDxQiYVAHGo0kuVWPNP9PH8XrRuP7f2Aq6ObEU
|
23
|
+
cGLN+OKlzChKJQZZzdthGTjO52cZERokS7etLs5yPNM27CUZIy2gUsWwANG700ov
|
24
|
+
DYi4S9j4y2fK9qVFGuNmZ7nNQ6juHIN8ZpZObmzGz/GEsVy8zYGV7jH2bC8fhCg1
|
25
|
+
wiTn0CHyfI0AfJ5zQMQ48z/ATI5+/pP5DuJ4kPLYU90EdIlIQ/9zQDRxVPvUalas
|
26
|
+
kskX8qdsbILaLqKzqvPa6jkhncV7SVQPhxIrs6vU2RWrsU1Qw9wHhzaITu9yb1l1
|
27
|
+
s8uialiJWnWOwkhIAUULOoGRnBB7U6sseFh7LcYHc2sZYJzQQO3g14ANvtsu/ILT
|
28
|
+
abUPXtGHSUlI4kUjI82NEkyQz/pDD9VkhTefiFHNymIkUaZBulmR5QdcEcQn6bku
|
29
|
+
J/P3M/T7CtsCPdBUrzDI71eAYqXPjikg+8unKWk9c/p+V7wXtvsdgJf3+xht/YUQ
|
30
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,19 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDCTCCAfGgAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwLTELMAkGA1UEBhMCQ1ox
|
3
|
+
DTALBgNVBAoTBFJ1YnkxDzANBgNVBAMTBlJ1YnlDQTAeFw0wMzA1MzEwMzUwNDFa
|
4
|
+
Fw0wNDA1MzAwMzUwNDFaMDAxCzAJBgNVBAYTAkNaMQ0wCwYDVQQKEwRSdWJ5MRIw
|
5
|
+
EAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALhs
|
6
|
+
fh4i1c+K57vFG7SUDfdxuSlbPUqaV0sbiuvWb0f7B2T7bHicaIRsDYW7PQRLLwwR
|
7
|
+
Pd+aKg3KuwhWN47faRam19Z3yWCD7Tg+BhXDqlXnz6snnr4APpAxc22kJKjzuil6
|
8
|
+
sp+QTkl/EFKI3+ocDur1UB+kSOmTzsDmepaWUZwTAgMBAAGjgbMwgbAwCQYDVR0T
|
9
|
+
BAIwADAtBglghkgBhvhCAQ0EIBYeR2VuZXJhdGVkIGJ5IE9wZW5TU0wgZm9yIFJ1
|
10
|
+
YnkuMB0GA1UdDgQWBBQlYESgTYdkTOYy02+/jGSqa+OpzjBVBgNVHSMETjBMgBQN
|
11
|
+
iKV64A56Sfaem3wZrTOo9CHo5qExpC8wLTELMAkGA1UEBhMCQ1oxDTALBgNVBAoT
|
12
|
+
BFJ1YnkxDzANBgNVBAMTBlJ1YnlDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAJh9v
|
13
|
+
ehhUv69oilVWGvGB6xCr8LgErnO9QdAyqJE2xBhbNaB3crjWDdQTz4UNvCQoJG/4
|
14
|
+
Oa9Vp10vM8E0ZMVHer87WM9tPEOg09r38U/1c7gSYBkPSGQfeWtZNjQ1YOm6RDx4
|
15
|
+
JJp9sp9v/CdBlVXaBQQd+MQFny7E+EkMHRfiv89KTfOs0wYdirLrM1C90CZUEj0i
|
16
|
+
cMcBdHzH5XcNpWB1ag4cNiUn2ljsaWlUpEg48gLe2FLJVPBio+iZnOm/C6KIwBMO
|
17
|
+
BCVxkZ6oIR87JT4xbr8SxRS9d/irhVU9MtGYwMe4MPSztefASdmEyj59ZFCLKQHV
|
18
|
+
+ltGb7/b7DetoT1spA==
|
19
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,18 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,5E9A9AC8F0F62A4A
|
4
|
+
|
5
|
+
3/VDlc8E13xKZr+MXt+HVZCiuWN1gsVx1bTZE5fN5FVoJ45Bgy2zAegnqZiP1NNy
|
6
|
+
j/76Vy9Ru/G9HPh5QPbIPl+md+tOyJV2M23a+5jESk1tLuWt5lRqmTtHN000844l
|
7
|
+
uCgZPPhRV7nhYPC5f6Gqw/xDl/EZsElqJM/hl2JbqiVKfT5/1i0STU8LNkoaLWrJ
|
8
|
+
kQhc7hOR5ihmDPeD8mA99bmGD+UyyqzzLTtKvRbBObyi9dy7cQ5Q+iptQWTUuEKI
|
9
|
+
+W7b8f8/Iiin4JJZGpFuhQSx0ARjT0fuYNXddmz1L3Gu3sjzN1GvT2T3GlpiF4/7
|
10
|
+
ERS8Q43zjoCP8nC2MTSvdNRRoPMBg2SDS2ZIq4GSiKsKjeN+GnPCycAMeZSr5yG6
|
11
|
+
VMBJLoAJ7XIcl3se8gF6hH1AfhCzDaK/2pKLP9jH/W4g6VvUBazKEQCNbZXSTpQ4
|
12
|
+
8EfvJBPpplFs3Zid6iwC/WjKhFBuBBfycwNJjXG9x1fMPkBM8HeiZXgrXoUXJMEP
|
13
|
+
RF05Beo0HPPEOPIxcG6EVmnpDvs8uC+xIQ6UE6DrLGK5TnR6kdz3BDpeAehujSss
|
14
|
+
wfZiOvuJQZQl+oovOH54pcwAwhicgRcNdIX47kHrXNL1vQMYTXte+ZzDGyoOXd0W
|
15
|
+
qf1CZbrjULT9nfJFWMMicTnLM/6iQx+3bTkXXvk0qP0qAoIPqtY4rwt6yHgq937A
|
16
|
+
LubDxudMWV0hqcnH8cBCPHfWdE4HELw4RcVXmQH43yHs1gwShyG9rTS+PCKoRr8u
|
17
|
+
bpssW6J0xJmilf1KprbNWJyof9i0CtSVOlUt6ttoinwqj8Me01dHqQ==
|
18
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join('..', '..', 'lib'))
|
4
|
+
require 'httpclient'
|
5
|
+
|
6
|
+
url = ARGV.shift || 'https://localhost:8808/'
|
7
|
+
uri = URI.parse(url)
|
8
|
+
|
9
|
+
#ca_file = "0cert.pem"
|
10
|
+
#crl_file = '0crl.pem'
|
11
|
+
|
12
|
+
# create CA's cert in pem format and run 'c_rehash' in trust_certs dir. before
|
13
|
+
# using this.
|
14
|
+
ca_path = File.join(File.dirname(File.expand_path(__FILE__)), "trust_certs")
|
15
|
+
|
16
|
+
proxy = ENV['HTTP_PROXY'] || ENV['http_proxy'] || nil
|
17
|
+
h = HTTPClient.new(proxy)
|
18
|
+
#h.ssl_config.add_trust_ca(ca_file)
|
19
|
+
#h.ssl_config.add_crl(crl_file)
|
20
|
+
h.ssl_config.add_trust_ca(ca_path)
|
21
|
+
|
22
|
+
print h.get_content(url)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'webrick/https'
|
4
|
+
require 'getopts'
|
5
|
+
|
6
|
+
getopts nil, 'r:', 'p:8808'
|
7
|
+
|
8
|
+
dir = File::dirname(File::expand_path(__FILE__))
|
9
|
+
|
10
|
+
# Pass phrase of '1000key.pem' is '1000'.
|
11
|
+
data = open(File::join(dir, "1000key.pem")){|io| io.read }
|
12
|
+
pkey = OpenSSL::PKey::RSA.new(data)
|
13
|
+
data = open(File::join(dir, "1000cert.pem")){|io| io.read }
|
14
|
+
cert = OpenSSL::X509::Certificate.new(data)
|
15
|
+
|
16
|
+
s = WEBrick::HTTPServer.new(
|
17
|
+
:BindAddress => "localhost",
|
18
|
+
:Port => $OPT_p.to_i,
|
19
|
+
:Logger => nil,
|
20
|
+
:DocumentRoot => $OPT_r || File::join(dir, "/htdocs"),
|
21
|
+
:SSLEnable => true,
|
22
|
+
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
23
|
+
:SSLCertificate => cert,
|
24
|
+
:SSLPrivateKey => pkey,
|
25
|
+
:SSLCertName => nil,
|
26
|
+
:SSLCACertificateFile => "all.pem"
|
27
|
+
)
|
28
|
+
trap("INT"){ s.shutdown }
|
29
|
+
s.start
|
data/sample/stream.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift(File.join('..', 'lib'))
|
2
|
+
require "httpclient"
|
3
|
+
|
4
|
+
c = HTTPClient.new
|
5
|
+
|
6
|
+
piper, pipew = IO.pipe
|
7
|
+
conn = c.post_async("http://localhost:8080/stream", piper)
|
8
|
+
|
9
|
+
Thread.new do
|
10
|
+
res = conn.pop
|
11
|
+
while str = res.content.read(10)
|
12
|
+
p str
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
p "type here"
|
17
|
+
while line = STDIN.gets
|
18
|
+
pipew << line
|
19
|
+
end
|
20
|
+
pipew.close
|
21
|
+
sleep 5
|