aeden-jruby-http-reactor 0.0.1 → 0.1.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.
- data/.gitignore +2 -0
- data/VERSION +1 -1
- data/examples/opml.rb +30 -0
- data/jruby-http-reactor.gemspec +51 -0
- data/lib/http_reactor.rb +1 -0
- data/lib/http_reactor/client.rb +62 -18
- data/lib/http_reactor/request.rb +13 -0
- data/test/client_test.rb +13 -5
- metadata +8 -4
data/.gitignore
ADDED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/examples/opml.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Usage: jruby examples/opml.rb opml.xml
|
4
|
+
#
|
5
|
+
# Dependencies:
|
6
|
+
#
|
7
|
+
# hpricot (0.6.164)
|
8
|
+
# threadify (1.1.0) (optional, uncomment in code)
|
9
|
+
|
10
|
+
require 'uri'
|
11
|
+
require 'rubygems'
|
12
|
+
require 'hpricot'
|
13
|
+
#require 'threadify'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/http_reactor'
|
15
|
+
|
16
|
+
def requests
|
17
|
+
@requests ||= begin
|
18
|
+
xml = File.read(ARGV.pop)
|
19
|
+
doc = Hpricot::XML(xml)
|
20
|
+
urls = (doc/'outline').map { |outline| outline['xmlUrl'] }
|
21
|
+
urls.map { |url_string| HttpReactor::Request.new(URI.parse(url_string)) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
#uris.threadify(:each_slice, 1) do |slice|
|
26
|
+
HttpReactor::Client.new(requests) do |response, context|
|
27
|
+
puts "Response: #{response.status_line.status_code}"
|
28
|
+
end
|
29
|
+
#end
|
30
|
+
puts "Processed #{requests.length} feeds"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{jruby-http-reactor}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Anthony Eden"]
|
9
|
+
s.date = %q{2009-09-12}
|
10
|
+
s.description = %q{}
|
11
|
+
s.email = %q{anthonyeden@gmail.com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".gitignore",
|
17
|
+
"README.rdoc",
|
18
|
+
"Rakefile",
|
19
|
+
"VERSION",
|
20
|
+
"examples/opml.rb",
|
21
|
+
"jruby-http-reactor.gemspec",
|
22
|
+
"lib/http_reactor.rb",
|
23
|
+
"lib/http_reactor/client.rb",
|
24
|
+
"lib/http_reactor/request.rb",
|
25
|
+
"test/client_test.rb",
|
26
|
+
"test/test_helper.rb",
|
27
|
+
"vendor/httpcore-4.0.1.jar",
|
28
|
+
"vendor/httpcore-nio-4.0.1.jar"
|
29
|
+
]
|
30
|
+
s.has_rdoc = true
|
31
|
+
s.homepage = %q{http://github.com/aeden/jruby-http-reactor}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.1}
|
35
|
+
s.summary = %q{JRuby NIO HTTP client.}
|
36
|
+
s.test_files = [
|
37
|
+
"test/client_test.rb",
|
38
|
+
"test/test_helper.rb",
|
39
|
+
"examples/opml.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 2
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
else
|
48
|
+
end
|
49
|
+
else
|
50
|
+
end
|
51
|
+
end
|
data/lib/http_reactor.rb
CHANGED
data/lib/http_reactor/client.rb
CHANGED
@@ -8,6 +8,7 @@ module HttpReactor #:nodoc:
|
|
8
8
|
RESPONSE_RECEIVED = "response-received"
|
9
9
|
|
10
10
|
HTTP_TARGET_PATH = 'http_target_path'
|
11
|
+
HTTP_TARGET_REQUEST = 'http_target_request'
|
11
12
|
|
12
13
|
def initialize(request_count, handler_proc)
|
13
14
|
@request_count = request_count
|
@@ -15,8 +16,9 @@ module HttpReactor #:nodoc:
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def initalize_context(context, attachment)
|
18
|
-
context.set_attribute(ExecutionContext.HTTP_TARGET_HOST, attachment[:host])
|
19
|
+
context.set_attribute(ExecutionContext.HTTP_TARGET_HOST, attachment[:host])
|
19
20
|
context.set_attribute(HTTP_TARGET_PATH, attachment[:path])
|
21
|
+
context.set_attribute(HTTP_TARGET_REQUEST, attachment[:request])
|
20
22
|
end
|
21
23
|
|
22
24
|
def finalize_context(context)
|
@@ -27,6 +29,7 @@ module HttpReactor #:nodoc:
|
|
27
29
|
def submit_request(context)
|
28
30
|
target_host = context.get_attribute(ExecutionContext.HTTP_TARGET_HOST);
|
29
31
|
target_path = context.get_attribute(HTTP_TARGET_PATH)
|
32
|
+
target_request = context.get_attribute(HTTP_TARGET_REQUEST)
|
30
33
|
flag = context.get_attribute(REQUEST_SENT);
|
31
34
|
if flag.nil?
|
32
35
|
# Stick some object into the context
|
@@ -36,7 +39,9 @@ module HttpReactor #:nodoc:
|
|
36
39
|
puts "Sending request to #{target_host}#{target_path}"
|
37
40
|
puts "--------------"
|
38
41
|
|
39
|
-
org.apache.http.message.
|
42
|
+
org.apache.http.message.BasicHttpEntityEnclosingRequest.new(
|
43
|
+
target_request.method, target_path
|
44
|
+
)
|
40
45
|
else
|
41
46
|
# No new request to submit
|
42
47
|
end
|
@@ -89,7 +94,7 @@ module HttpReactor #:nodoc:
|
|
89
94
|
def connection_closed(conn)
|
90
95
|
puts "Connection closed: #{conn}"
|
91
96
|
end
|
92
|
-
def
|
97
|
+
def fatal_i_o_exception(ex, conn)
|
93
98
|
puts "Fatal I/O error: #{ex.message}"
|
94
99
|
end
|
95
100
|
def fatal_protocol_exception(ex, conn)
|
@@ -113,16 +118,23 @@ module HttpReactor #:nodoc:
|
|
113
118
|
# * <tt>handler_proc</tt>: A Proc that will be called with the response and context
|
114
119
|
# * <tt>session_request_callback</tt>: A class that implements the session request
|
115
120
|
# callback interface found in the HttpCore library.
|
116
|
-
|
121
|
+
# * <tt>options: A hash of configuration options. See below.
|
122
|
+
#
|
123
|
+
# The options hash may include the following options
|
124
|
+
# * <tt>:so_timeout</tt>: (default = 5 seconds)
|
125
|
+
# * <tt>:connection_timeout</tt>: The HTTP connection timeout (default = 10 seconds)
|
126
|
+
# * <tt>:socket_buffer_size</tt>: The buffer size (defaults to 8Kb)
|
127
|
+
# * <tt>:stale_connection_check</tt>: (defaults to false)
|
128
|
+
# * <tt>:tcp_nodelay</tt>: (defaults to true)
|
129
|
+
# * <tt>:user_agent</tt>: The user agent string to send (defaults to "JRubyHttpReactor")
|
130
|
+
# * <tt>:event_listener</tt>: A class that implements the org.apache.http.nio.protocol interface
|
131
|
+
def initialize(requests=[], handler_proc=nil, options={})
|
117
132
|
handler_proc ||= default_handler_proc
|
133
|
+
session_request_callback = SessionRequestCallback
|
118
134
|
|
119
|
-
|
120
|
-
|
121
|
-
params
|
122
|
-
params.set_int_parameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
|
123
|
-
params.set_boolean_parameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
|
124
|
-
params.set_boolean_parameter(CoreConnectionPNames.TCP_NODELAY, true)
|
125
|
-
params.set_parameter(CoreProtocolPNames.USER_AGENT, "JRubyHttpReactor/0.0.1")
|
135
|
+
initialize_options(options)
|
136
|
+
|
137
|
+
params = build_params(options)
|
126
138
|
|
127
139
|
io_reactor = DefaultConnectingIOReactor.new(2, params);
|
128
140
|
|
@@ -135,7 +147,7 @@ module HttpReactor #:nodoc:
|
|
135
147
|
|
136
148
|
# We are going to use this object to synchronize between the
|
137
149
|
# I/O event and main threads
|
138
|
-
request_count = java.util.concurrent.CountDownLatch.new(
|
150
|
+
request_count = java.util.concurrent.CountDownLatch.new(requests.length);
|
139
151
|
|
140
152
|
handler = BufferingHttpClientHandler.new(
|
141
153
|
httpproc,
|
@@ -143,8 +155,8 @@ module HttpReactor #:nodoc:
|
|
143
155
|
org.apache.http.impl.DefaultConnectionReuseStrategy.new,
|
144
156
|
params
|
145
157
|
)
|
146
|
-
|
147
|
-
handler.event_listener =
|
158
|
+
|
159
|
+
handler.event_listener = options[:event_listener].new if options[:event_listener]
|
148
160
|
|
149
161
|
io_event_dispatch = DefaultClientIOEventDispatch.new(handler, params)
|
150
162
|
|
@@ -161,11 +173,17 @@ module HttpReactor #:nodoc:
|
|
161
173
|
puts "Shutdown"
|
162
174
|
end
|
163
175
|
|
164
|
-
|
176
|
+
requests.each do |request|
|
177
|
+
uri = request.uri
|
178
|
+
attachment = {
|
179
|
+
:host => HttpHost.new(uri.host),
|
180
|
+
:path => uri.path,
|
181
|
+
:request => request
|
182
|
+
}
|
165
183
|
io_reactor.connect(
|
166
184
|
java.net.InetSocketAddress.new(uri.host, uri.port),
|
167
185
|
nil,
|
168
|
-
|
186
|
+
attachment,
|
169
187
|
session_request_callback.new(request_count)
|
170
188
|
)
|
171
189
|
end
|
@@ -182,6 +200,34 @@ module HttpReactor #:nodoc:
|
|
182
200
|
end
|
183
201
|
|
184
202
|
private
|
203
|
+
|
204
|
+
def initialize_options(options)
|
205
|
+
options[:so_timeout] ||= 5000
|
206
|
+
options[:connection_timeout] ||= 10000
|
207
|
+
options[:socket_buffer_size] ||= 8 * 1024
|
208
|
+
options[:stale_connection_check] ||= false
|
209
|
+
options[:tcp_nodelay] ||= true
|
210
|
+
options[:user_agent] ||= "JRubyHttpReactor"
|
211
|
+
#options[:event_listener] ||= EventLogger
|
212
|
+
end
|
213
|
+
|
214
|
+
def build_params(options)
|
215
|
+
params = BasicHttpParams.new
|
216
|
+
params.set_int_parameter(
|
217
|
+
CoreConnectionPNames.SO_TIMEOUT, options[:so_timeout])
|
218
|
+
params.set_int_parameter(
|
219
|
+
CoreConnectionPNames.CONNECTION_TIMEOUT, options[:connection_timeout])
|
220
|
+
params.set_int_parameter(
|
221
|
+
CoreConnectionPNames.SOCKET_BUFFER_SIZE, options[:socket_buffer_size])
|
222
|
+
params.set_boolean_parameter(
|
223
|
+
CoreConnectionPNames.STALE_CONNECTION_CHECK, options[:stale_connection_check])
|
224
|
+
params.set_boolean_parameter(
|
225
|
+
CoreConnectionPNames.TCP_NODELAY, options[:tcp_nodelay])
|
226
|
+
params.set_parameter(
|
227
|
+
CoreProtocolPNames.USER_AGENT, options[:user_agent])
|
228
|
+
params
|
229
|
+
end
|
230
|
+
|
185
231
|
def default_handler_proc
|
186
232
|
Proc.new { |response, context|
|
187
233
|
target_host = context.get_attribute(ExecutionContext.HTTP_TARGET_HOST);
|
@@ -193,9 +239,7 @@ module HttpReactor #:nodoc:
|
|
193
239
|
|
194
240
|
puts "--------------"
|
195
241
|
puts "Response from #{target_host}#{target_path}"
|
196
|
-
puts "--------------"
|
197
242
|
puts response.status_line
|
198
|
-
puts "--------------"
|
199
243
|
puts "Document length: #{content.length}"
|
200
244
|
puts "--------------"
|
201
245
|
rescue java.io.IOException => ex
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module HttpReactor
|
2
|
+
# A class that represents an HTTP request.
|
3
|
+
class Request
|
4
|
+
attr_reader :uri, :method, :payload
|
5
|
+
|
6
|
+
# Initialize the request object.
|
7
|
+
def initialize(uri, method='GET', payload=nil)
|
8
|
+
@uri = uri
|
9
|
+
@method = method
|
10
|
+
@payload = payload
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/test/client_test.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'uri'
|
2
3
|
|
3
4
|
class ClientTest < Test::Unit::TestCase
|
4
|
-
def
|
5
|
-
@
|
5
|
+
def requests
|
6
|
+
@requests ||= [
|
6
7
|
'http://www.yahoo.com/',
|
7
8
|
'http://www.google.com/',
|
8
9
|
'http://www.apache.org/',
|
9
10
|
'http://anthony.mp/about_me'
|
10
|
-
].map { |url_string| URI.parse(url_string) }
|
11
|
+
].map { |url_string| HttpReactor::Request.new(URI.parse(url_string)) }
|
11
12
|
end
|
12
13
|
|
13
14
|
def test_new
|
14
15
|
assert_nothing_raised do
|
15
|
-
HttpReactor::Client.new(
|
16
|
+
HttpReactor::Client.new(requests)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -20,6 +21,13 @@ class ClientTest < Test::Unit::TestCase
|
|
20
21
|
handler = Proc.new { |response, context|
|
21
22
|
puts "Response: #{response.status_line.status_code}"
|
22
23
|
}
|
23
|
-
HttpReactor::Client.new(
|
24
|
+
HttpReactor::Client.new(requests, handler)
|
24
25
|
end
|
26
|
+
|
27
|
+
def test_block
|
28
|
+
HttpReactor::Client.new(requests) do |response, context|
|
29
|
+
puts "Response: #{response.status_line.status_code}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aeden-jruby-http-reactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Eden
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-12 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -22,18 +22,21 @@ extensions: []
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README.rdoc
|
24
24
|
files:
|
25
|
+
- .gitignore
|
25
26
|
- README.rdoc
|
26
27
|
- Rakefile
|
27
28
|
- VERSION
|
29
|
+
- examples/opml.rb
|
30
|
+
- jruby-http-reactor.gemspec
|
28
31
|
- lib/http_reactor.rb
|
29
32
|
- lib/http_reactor/client.rb
|
33
|
+
- lib/http_reactor/request.rb
|
30
34
|
- test/client_test.rb
|
31
35
|
- test/test_helper.rb
|
32
36
|
- vendor/httpcore-4.0.1.jar
|
33
37
|
- vendor/httpcore-nio-4.0.1.jar
|
34
38
|
has_rdoc: true
|
35
39
|
homepage: http://github.com/aeden/jruby-http-reactor
|
36
|
-
licenses:
|
37
40
|
post_install_message:
|
38
41
|
rdoc_options:
|
39
42
|
- --charset=UTF-8
|
@@ -54,10 +57,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
57
|
requirements: []
|
55
58
|
|
56
59
|
rubyforge_project:
|
57
|
-
rubygems_version: 1.
|
60
|
+
rubygems_version: 1.2.0
|
58
61
|
signing_key:
|
59
62
|
specification_version: 2
|
60
63
|
summary: JRuby NIO HTTP client.
|
61
64
|
test_files:
|
62
65
|
- test/client_test.rb
|
63
66
|
- test/test_helper.rb
|
67
|
+
- examples/opml.rb
|