httpclient 2.1.5 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/bin/httpclient +77 -0
  4. data/bin/jsonclient +85 -0
  5. data/lib/hexdump.rb +50 -0
  6. data/lib/http-access2.rb +6 -4
  7. data/lib/httpclient/auth.rb +575 -173
  8. data/lib/httpclient/cacert.pem +3952 -0
  9. data/lib/httpclient/cacert1024.pem +3866 -0
  10. data/lib/httpclient/connection.rb +6 -2
  11. data/lib/httpclient/cookie.rb +162 -504
  12. data/lib/httpclient/http.rb +334 -119
  13. data/lib/httpclient/include_client.rb +85 -0
  14. data/lib/httpclient/jruby_ssl_socket.rb +588 -0
  15. data/lib/httpclient/session.rb +385 -288
  16. data/lib/httpclient/ssl_config.rb +195 -155
  17. data/lib/httpclient/ssl_socket.rb +150 -0
  18. data/lib/httpclient/timeout.rb +14 -10
  19. data/lib/httpclient/util.rb +142 -6
  20. data/lib/httpclient/version.rb +3 -0
  21. data/lib/httpclient/webagent-cookie.rb +459 -0
  22. data/lib/httpclient.rb +509 -202
  23. data/lib/jsonclient.rb +63 -0
  24. data/lib/oauthclient.rb +111 -0
  25. data/sample/async.rb +8 -0
  26. data/sample/auth.rb +11 -0
  27. data/sample/cookie.rb +18 -0
  28. data/sample/dav.rb +103 -0
  29. data/sample/howto.rb +49 -0
  30. data/sample/jsonclient.rb +67 -0
  31. data/sample/oauth_buzz.rb +57 -0
  32. data/sample/oauth_friendfeed.rb +59 -0
  33. data/sample/oauth_twitter.rb +61 -0
  34. data/sample/ssl/0cert.pem +22 -0
  35. data/sample/ssl/0key.pem +30 -0
  36. data/sample/ssl/1000cert.pem +19 -0
  37. data/sample/ssl/1000key.pem +18 -0
  38. data/sample/ssl/htdocs/index.html +10 -0
  39. data/sample/ssl/ssl_client.rb +22 -0
  40. data/sample/ssl/webrick_httpsd.rb +29 -0
  41. data/sample/stream.rb +21 -0
  42. data/sample/thread.rb +27 -0
  43. data/sample/wcat.rb +21 -0
  44. data/test/ca-chain.pem +44 -0
  45. data/test/ca.cert +23 -0
  46. data/test/client-pass.key +18 -0
  47. data/test/client.cert +19 -0
  48. data/test/client.key +15 -0
  49. data/test/helper.rb +131 -0
  50. data/test/htdigest +1 -0
  51. data/test/htpasswd +2 -0
  52. data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
  53. data/test/runner.rb +2 -0
  54. data/test/server.cert +19 -0
  55. data/test/server.key +15 -0
  56. data/test/sslsvr.rb +65 -0
  57. data/test/subca.cert +21 -0
  58. data/test/test_auth.rb +492 -0
  59. data/test/test_cookie.rb +309 -0
  60. data/test/test_hexdump.rb +14 -0
  61. data/test/test_http-access2.rb +508 -0
  62. data/test/test_httpclient.rb +2145 -0
  63. data/test/test_include_client.rb +52 -0
  64. data/test/test_jsonclient.rb +80 -0
  65. data/test/test_ssl.rb +559 -0
  66. data/test/test_webagent-cookie.rb +465 -0
  67. metadata +85 -44
  68. data/lib/httpclient/auth.rb.orig +0 -513
  69. data/lib/httpclient/cacert.p7s +0 -1579
  70. data/lib/httpclient.rb.orig +0 -1020
  71. data/lib/tags +0 -908
data/lib/jsonclient.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'httpclient'
2
+ require 'json'
3
+
4
+ # JSONClient auto-converts Hash <-> JSON in request and response.
5
+ # * For POST or PUT request, convert Hash body to JSON String with 'application/json; charset=utf-8' header.
6
+ # * For response, convert JSON String to Hash when content-type is '(application|text)/(x-)?json'
7
+ class JSONClient < HTTPClient
8
+ CONTENT_TYPE_JSON_REGEX = /(application|text)\/(x-)?json/i
9
+ CONTENT_TYPE_JSON = 'application/json; charset=utf-8'
10
+
11
+ attr_reader :content_type_json_request
12
+ attr_reader :content_type_json_response_regex
13
+
14
+ def initialize(*args)
15
+ super
16
+ @content_type_json_request = CONTENT_TYPE_JSON
17
+ @content_type_json_response_regex = CONTENT_TYPE_JSON_REGEX
18
+ end
19
+
20
+ def post(uri, *args, &block)
21
+ request(:post, uri, argument_to_hash_for_json(args), &block)
22
+ end
23
+
24
+ def put(uri, *args, &block)
25
+ request(:put, uri, argument_to_hash_for_json(args), &block)
26
+ end
27
+
28
+ def request(method, uri, *args, &block)
29
+ res = super
30
+ if @content_type_json_response_regex =~ res.content_type
31
+ res = wrap_json_response(res)
32
+ end
33
+ res
34
+ end
35
+
36
+ private
37
+
38
+ def argument_to_hash_for_json(args)
39
+ hash = argument_to_hash(args, :body, :header, :follow_redirect)
40
+ if hash[:body].is_a?(Hash)
41
+ hash[:header] = json_header(hash[:header])
42
+ hash[:body] = JSON.generate(hash[:body])
43
+ end
44
+ hash
45
+ end
46
+
47
+ def json_header(header)
48
+ header ||= {}
49
+ if header.is_a?(Hash)
50
+ header['Content-Type'] = @content_type_json_request
51
+ else
52
+ header << ['Content-Type', @content_type_json_request]
53
+ end
54
+ header
55
+ end
56
+
57
+ def wrap_json_response(original)
58
+ res = ::HTTP::Message.new_response(JSON.parse(original.content))
59
+ res.http_header = original.http_header
60
+ res.previous = original
61
+ res
62
+ end
63
+ end
@@ -0,0 +1,111 @@
1
+ # HTTPClient - HTTP client library.
2
+ # Copyright (C) 2000-2015 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
+ self.strict_response_size_check = true
37
+ end
38
+
39
+ # Get request token.
40
+ # uri:: URI for request token.
41
+ # callback:: callback String. This can be nil for OAuth 1.0a
42
+ # param:: Additional query parameter Hash.
43
+ #
44
+ # It returns a HTTP::Message instance as a response. When the request is made
45
+ # successfully, you can retrieve a pair of request token and secret like
46
+ # following;
47
+ # res = client.get_request_token(...)
48
+ # token = res.oauth_params['oauth_token']
49
+ # secret = res.oauth_params['oauth_token_secret']
50
+ def get_request_token(uri, callback = nil, param = nil)
51
+ oauth_config.token = nil
52
+ oauth_config.secret = nil
53
+ oauth_config.callback = callback
54
+ oauth_config.verifier = nil
55
+ res = request(oauth_config.http_method, uri, param)
56
+ filter_response(res)
57
+ res
58
+ end
59
+
60
+ # Get access token.
61
+ # uri:: URI for request token.
62
+ # request_token:: a request token String. See get_access_token.
63
+ # request_token_secret:: a request secret String. See get_access_token.
64
+ # verifier:: a verifier tag String.
65
+ #
66
+ # When the request succeeds and the server returns a pair of access token
67
+ # and secret, oauth_config.token and oauth_token.secret are updated with
68
+ # the access token. Then you can call OAuthClient#get, #post, #delete, etc.
69
+ # All requests are signed.
70
+ def get_access_token(uri, request_token, request_token_secret, verifier = nil)
71
+ oauth_config.token = request_token
72
+ oauth_config.secret = request_token_secret
73
+ oauth_config.callback = nil
74
+ oauth_config.verifier = verifier
75
+ res = request(oauth_config.http_method, uri)
76
+ filter_response(res)
77
+ oauth_config.verifier = nil
78
+ res
79
+ end
80
+
81
+ # Parse response and returns a Hash.
82
+ def get_oauth_response(res)
83
+ enc = res.header['content-encoding']
84
+ body = nil
85
+ if enc and enc[0] and enc[0].downcase == 'gzip'
86
+ body = Zlib::GzipReader.wrap(StringIO.new(res.content)) { |gz| gz.read }
87
+ else
88
+ body = res.content
89
+ end
90
+ body.split('&').inject({}) { |r, e|
91
+ key, value = e.split('=', 2)
92
+ r[unescape(key)] = unescape(value)
93
+ r
94
+ }
95
+ end
96
+
97
+ private
98
+
99
+ def unescape(escaped)
100
+ escaped ? ::HTTP::Message.unescape(escaped) : nil
101
+ end
102
+
103
+ def filter_response(res)
104
+ if res.status == 200
105
+ if res.oauth_params = get_oauth_response(res)
106
+ oauth_config.token = res.oauth_params['oauth_token']
107
+ oauth_config.secret = res.oauth_params['oauth_token_secret']
108
+ end
109
+ end
110
+ end
111
+ end
data/sample/async.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'httpclient'
2
+
3
+ c = HTTPClient.new
4
+ conn = c.get_async("http://dev.ctor.org/")
5
+ io = conn.pop.content
6
+ while str = io.read(40)
7
+ p str
8
+ end
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,67 @@
1
+ require 'httpclient'
2
+ require 'json'
3
+
4
+ module HTTP
5
+ class Message
6
+ # Returns JSON object of message body
7
+ alias original_content content
8
+ def content
9
+ if JSONClient::CONTENT_TYPE_JSON_REGEX =~ content_type
10
+ JSON.parse(original_content)
11
+ else
12
+ original_content
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+
19
+ # JSONClient provides JSON related methods in addition to HTTPClient.
20
+ class JSONClient < HTTPClient
21
+ CONTENT_TYPE_JSON_REGEX = /(application|text)\/(x-)?json/i
22
+
23
+ attr_accessor :content_type_json
24
+
25
+ class JSONRequestHeaderFilter
26
+ attr_accessor :replace
27
+
28
+ def initialize(client)
29
+ @client = client
30
+ @replace = false
31
+ end
32
+
33
+ def filter_request(req)
34
+ req.header['content-type'] = @client.content_type_json if @replace
35
+ end
36
+
37
+ def filter_response(req, res)
38
+ @replace = false
39
+ end
40
+ end
41
+
42
+ def initialize(*args)
43
+ super
44
+ @header_filter = JSONRequestHeaderFilter.new(self)
45
+ @request_filter << @header_filter
46
+ @content_type_json = 'application/json; charset=utf-8'
47
+ end
48
+
49
+ def post(uri, *args, &block)
50
+ @header_filter.replace = true
51
+ request(:post, uri, jsonify(argument_to_hash(args, :body, :header, :follow_redirect)), &block)
52
+ end
53
+
54
+ def put(uri, *args, &block)
55
+ @header_filter.replace = true
56
+ request(:put, uri, jsonify(argument_to_hash(args, :body, :header)), &block)
57
+ end
58
+
59
+ private
60
+
61
+ def jsonify(hash)
62
+ if hash[:body] && hash[:body].is_a?(Hash)
63
+ hash[:body] = JSON.generate(hash[:body])
64
+ end
65
+ hash
66
+ end
67
+ end
@@ -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 = 'https://api.twitter.com/oauth/request_token'
9
+ oob_authorize_url = 'https://api.twitter.com/oauth/authorize'
10
+ access_token_url = 'https://api.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("https://api.twitter.com/1.1/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-----
@@ -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-----