httpclient-fixcerts 2.8.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.
- checksums.yaml +7 -0
- data/README.md +98 -0
- data/bin/httpclient +77 -0
- data/bin/jsonclient +85 -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 +924 -0
- data/lib/httpclient/cacert.pem +3952 -0
- data/lib/httpclient/cacert1024.pem +3866 -0
- data/lib/httpclient/connection.rb +88 -0
- data/lib/httpclient/cookie.rb +220 -0
- data/lib/httpclient/http.rb +1082 -0
- data/lib/httpclient/include_client.rb +85 -0
- data/lib/httpclient/jruby_ssl_socket.rb +594 -0
- data/lib/httpclient/session.rb +960 -0
- data/lib/httpclient/ssl_config.rb +433 -0
- data/lib/httpclient/ssl_socket.rb +150 -0
- data/lib/httpclient/timeout.rb +140 -0
- data/lib/httpclient/util.rb +222 -0
- data/lib/httpclient/version.rb +3 -0
- data/lib/httpclient/webagent-cookie.rb +459 -0
- data/lib/httpclient.rb +1332 -0
- data/lib/jsonclient.rb +66 -0
- data/lib/oauthclient.rb +111 -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/jsonclient.rb +67 -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.pem +44 -0
- data/test/ca.cert +23 -0
- data/test/client-pass.key +18 -0
- data/test/client.cert +19 -0
- data/test/client.key +15 -0
- data/test/helper.rb +131 -0
- data/test/htdigest +1 -0
- data/test/htpasswd +2 -0
- data/test/jruby_ssl_socket/test_pemutils.rb +32 -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 +492 -0
- data/test/test_cookie.rb +309 -0
- data/test/test_hexdump.rb +14 -0
- data/test/test_http-access2.rb +508 -0
- data/test/test_httpclient.rb +2145 -0
- data/test/test_include_client.rb +52 -0
- data/test/test_jsonclient.rb +98 -0
- data/test/test_ssl.rb +562 -0
- data/test/test_webagent-cookie.rb +465 -0
- metadata +124 -0
@@ -0,0 +1,88 @@
|
|
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
|
+
class HTTPClient
|
10
|
+
|
11
|
+
|
12
|
+
# Represents a HTTP response to an asynchronous request. Async methods of
|
13
|
+
# HTTPClient such as get_async, post_async, etc. returns an instance of
|
14
|
+
# Connection.
|
15
|
+
#
|
16
|
+
# == How to use
|
17
|
+
#
|
18
|
+
# 1. Invoke HTTP method asynchronously and check if it's been finished
|
19
|
+
# periodically.
|
20
|
+
#
|
21
|
+
# connection = clnt.post_async(url, body)
|
22
|
+
# print 'posting.'
|
23
|
+
# while true
|
24
|
+
# break if connection.finished?
|
25
|
+
# print '.'
|
26
|
+
# sleep 1
|
27
|
+
# end
|
28
|
+
# puts '.'
|
29
|
+
# res = connection.pop
|
30
|
+
# p res.status
|
31
|
+
#
|
32
|
+
# 2. Read the response as an IO.
|
33
|
+
#
|
34
|
+
# connection = clnt.get_async('http://dev.ctor.org/')
|
35
|
+
# io = connection.pop.content
|
36
|
+
# while str = io.read(40)
|
37
|
+
# p str
|
38
|
+
# end
|
39
|
+
class Connection
|
40
|
+
attr_accessor :async_thread
|
41
|
+
|
42
|
+
def initialize(header_queue = [], body_queue = []) # :nodoc:
|
43
|
+
@headers = header_queue
|
44
|
+
@body = body_queue
|
45
|
+
@async_thread = nil
|
46
|
+
@queue = Queue.new
|
47
|
+
end
|
48
|
+
|
49
|
+
# Checks if the asynchronous invocation has been finished or not.
|
50
|
+
def finished?
|
51
|
+
if !@async_thread
|
52
|
+
# Not in async mode.
|
53
|
+
true
|
54
|
+
elsif @async_thread.alive?
|
55
|
+
# Working...
|
56
|
+
false
|
57
|
+
else
|
58
|
+
# Async thread have been finished.
|
59
|
+
join
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Retrieves a HTTP::Message instance of HTTP response. Do not invoke this
|
65
|
+
# method twice for now. The second invocation will be blocked.
|
66
|
+
def pop
|
67
|
+
response_or_exception = @queue.pop
|
68
|
+
if response_or_exception.is_a? Exception
|
69
|
+
raise response_or_exception
|
70
|
+
end
|
71
|
+
response_or_exception
|
72
|
+
end
|
73
|
+
|
74
|
+
def push(result) # :nodoc:
|
75
|
+
@queue.push(result)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Waits the completion of the asynchronous invocation.
|
79
|
+
def join
|
80
|
+
if @async_thread
|
81
|
+
@async_thread.join
|
82
|
+
end
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# do not override if httpclient/webagent-cookie is loaded already
|
2
|
+
unless defined?(HTTPClient::CookieManager)
|
3
|
+
begin # for catching LoadError and load webagent-cookie instead
|
4
|
+
|
5
|
+
require 'http-cookie'
|
6
|
+
require 'httpclient/util'
|
7
|
+
|
8
|
+
class HTTPClient
|
9
|
+
class CookieManager
|
10
|
+
include HTTPClient::Util
|
11
|
+
|
12
|
+
attr_reader :format, :jar
|
13
|
+
attr_accessor :cookies_file
|
14
|
+
|
15
|
+
def initialize(cookies_file = nil, format = WebAgentSaver, jar = HTTP::CookieJar.new)
|
16
|
+
@cookies_file = cookies_file
|
17
|
+
@format = format
|
18
|
+
@jar = jar
|
19
|
+
load_cookies if @cookies_file
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_cookies
|
23
|
+
check_cookies_file
|
24
|
+
@jar.clear
|
25
|
+
@jar.load(@cookies_file, :format => @format)
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_cookies(session = false)
|
29
|
+
check_cookies_file
|
30
|
+
@jar.save(@cookies_file, :format => @format, :session => session)
|
31
|
+
end
|
32
|
+
|
33
|
+
def cookies(uri = nil)
|
34
|
+
cookies = @jar.cookies(uri)
|
35
|
+
# TODO: return HTTP::Cookie in the future
|
36
|
+
cookies.map { |cookie|
|
37
|
+
WebAgent::Cookie.new(
|
38
|
+
:name => cookie.name,
|
39
|
+
:value => cookie.value,
|
40
|
+
:domain => cookie.domain,
|
41
|
+
:path => cookie.path,
|
42
|
+
:origin => cookie.origin,
|
43
|
+
:for_domain => cookie.for_domain,
|
44
|
+
:expires => cookie.expires,
|
45
|
+
:httponly => cookie.httponly,
|
46
|
+
:secure => cookie.secure
|
47
|
+
)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def cookie_value(uri)
|
52
|
+
cookies = self.cookies(uri)
|
53
|
+
unless cookies.empty?
|
54
|
+
HTTP::Cookie.cookie_value(cookies)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse(value, uri)
|
59
|
+
@jar.parse(value, uri)
|
60
|
+
end
|
61
|
+
|
62
|
+
def cookies=(cookies)
|
63
|
+
@jar.clear
|
64
|
+
cookies.each do |cookie|
|
65
|
+
add(cookie)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add(cookie)
|
70
|
+
@jar.add(cookie)
|
71
|
+
end
|
72
|
+
|
73
|
+
def find(uri)
|
74
|
+
warning('CookieManager#find is deprecated and will be removed in near future. Use HTTP::Cookie.cookie_value(CookieManager#cookies) instead')
|
75
|
+
if cookie = cookies(uri)
|
76
|
+
HTTP::Cookie.cookie_value(cookie)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def check_cookies_file
|
83
|
+
unless @cookies_file
|
84
|
+
raise ArgumentError.new('Cookies file not specified')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class WebAgentSaver < HTTP::CookieJar::AbstractSaver
|
90
|
+
# no option
|
91
|
+
def default_options
|
92
|
+
{}
|
93
|
+
end
|
94
|
+
|
95
|
+
# same as HTTP::CookieJar::CookiestxtSaver
|
96
|
+
def save(io, jar)
|
97
|
+
jar.each { |cookie|
|
98
|
+
next if !@session && cookie.session?
|
99
|
+
io.print cookie_to_record(cookie)
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
# same as HTTP::CookieJar::CookiestxtSaver
|
104
|
+
def load(io, jar)
|
105
|
+
io.each_line { |line|
|
106
|
+
cookie = parse_record(line) and jar.add(cookie)
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def cookie_to_record(cookie)
|
113
|
+
[
|
114
|
+
cookie.origin,
|
115
|
+
cookie.name,
|
116
|
+
cookie.value,
|
117
|
+
cookie.expires.to_i,
|
118
|
+
cookie.dot_domain,
|
119
|
+
cookie.path,
|
120
|
+
self.class.flag(cookie)
|
121
|
+
].join("\t") + "\n"
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse_record(line)
|
125
|
+
return nil if /\A#/ =~ line
|
126
|
+
col = line.chomp.split(/\t/)
|
127
|
+
|
128
|
+
origin = col[0]
|
129
|
+
name = col[1]
|
130
|
+
value = col[2]
|
131
|
+
value.chomp!
|
132
|
+
if col[3].empty? or col[3] == '0'
|
133
|
+
expires = nil
|
134
|
+
else
|
135
|
+
expires = Time.at(col[3].to_i)
|
136
|
+
return nil if expires < Time.now
|
137
|
+
end
|
138
|
+
domain = col[4]
|
139
|
+
path = col[5]
|
140
|
+
|
141
|
+
cookie = WebAgent::Cookie.new(name, value,
|
142
|
+
:origin => origin,
|
143
|
+
:domain => domain,
|
144
|
+
:path => path,
|
145
|
+
:expires => expires
|
146
|
+
)
|
147
|
+
self.class.set_flag(cookie, col[6].to_i)
|
148
|
+
cookie
|
149
|
+
end
|
150
|
+
|
151
|
+
USE = 1
|
152
|
+
SECURE = 2
|
153
|
+
DOMAIN = 4
|
154
|
+
PATH = 8
|
155
|
+
HTTP_ONLY = 64
|
156
|
+
|
157
|
+
def self.flag(cookie)
|
158
|
+
flg = 0
|
159
|
+
flg += USE # not used
|
160
|
+
flg += SECURE if cookie.secure?
|
161
|
+
flg += DOMAIN if cookie.for_domain?
|
162
|
+
flg += HTTP_ONLY if cookie.httponly?
|
163
|
+
flg += PATH if cookie.path # not used
|
164
|
+
flg
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.set_flag(cookie, flag)
|
168
|
+
cookie.secure = true if flag & SECURE > 0
|
169
|
+
cookie.for_domain = true if flag & DOMAIN > 0
|
170
|
+
cookie.httponly = true if flag & HTTP_ONLY > 0
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# for backward compatibility
|
176
|
+
class WebAgent
|
177
|
+
CookieManager = ::HTTPClient::CookieManager
|
178
|
+
|
179
|
+
class Cookie < HTTP::Cookie
|
180
|
+
include HTTPClient::Util
|
181
|
+
|
182
|
+
def url
|
183
|
+
deprecated('url', 'origin')
|
184
|
+
self.origin
|
185
|
+
end
|
186
|
+
|
187
|
+
def url=(url)
|
188
|
+
deprecated('url=', 'origin=')
|
189
|
+
self.origin = url
|
190
|
+
end
|
191
|
+
|
192
|
+
def http_only?
|
193
|
+
deprecated('http_only?', 'httponly?')
|
194
|
+
self.httponly?
|
195
|
+
end
|
196
|
+
|
197
|
+
alias original_domain domain
|
198
|
+
|
199
|
+
def domain
|
200
|
+
warning('Cookie#domain returns dot-less domain name now. Use Cookie#dot_domain if you need "." at the beginning.')
|
201
|
+
self.original_domain
|
202
|
+
end
|
203
|
+
|
204
|
+
def flag
|
205
|
+
deprecated('flag', 'secure, for_domain, etc.')
|
206
|
+
HTTPClient::WebAgentSaver.flag(self)
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
|
211
|
+
def deprecated(old, new)
|
212
|
+
warning("WebAgent::Cookie is deprecated and will be replaced with HTTP::Cookie in the near future. Please use Cookie##{new} instead of Cookie##{old} for the replacement.")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
rescue LoadError
|
218
|
+
require 'httpclient/webagent-cookie'
|
219
|
+
end
|
220
|
+
end
|