cool.io 0.9.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 +25 -0
- data/CHANGES +199 -0
- data/LICENSE +20 -0
- data/README.markdown +4 -0
- data/Rakefile +98 -0
- data/VERSION +1 -0
- data/examples/echo_client.rb +38 -0
- data/examples/echo_server.rb +27 -0
- data/examples/google.rb +9 -0
- data/examples/httpclient.rb +38 -0
- data/ext/cool.io/.gitignore +5 -0
- data/ext/cool.io/cool.io.h +58 -0
- data/ext/cool.io/cool.io_ext.c +25 -0
- data/ext/cool.io/ev_wrap.h +8 -0
- data/ext/cool.io/extconf.rb +69 -0
- data/ext/cool.io/iowatcher.c +189 -0
- data/ext/cool.io/libev.c +8 -0
- data/ext/cool.io/loop.c +303 -0
- data/ext/cool.io/stat_watcher.c +191 -0
- data/ext/cool.io/timer_watcher.c +219 -0
- data/ext/cool.io/utils.c +122 -0
- data/ext/cool.io/watcher.c +264 -0
- data/ext/cool.io/watcher.h +71 -0
- data/ext/http11_client/.gitignore +5 -0
- data/ext/http11_client/ext_help.h +14 -0
- data/ext/http11_client/extconf.rb +6 -0
- data/ext/http11_client/http11_client.c +300 -0
- data/ext/http11_client/http11_parser.c +403 -0
- data/ext/http11_client/http11_parser.h +48 -0
- data/ext/http11_client/http11_parser.rl +173 -0
- data/ext/libev/Changes +364 -0
- data/ext/libev/LICENSE +36 -0
- data/ext/libev/README +58 -0
- data/ext/libev/README.embed +3 -0
- data/ext/libev/ev.c +3867 -0
- data/ext/libev/ev.h +826 -0
- data/ext/libev/ev_epoll.c +234 -0
- data/ext/libev/ev_kqueue.c +198 -0
- data/ext/libev/ev_poll.c +148 -0
- data/ext/libev/ev_port.c +164 -0
- data/ext/libev/ev_select.c +307 -0
- data/ext/libev/ev_vars.h +197 -0
- data/ext/libev/ev_win32.c +153 -0
- data/ext/libev/ev_wrap.h +186 -0
- data/ext/libev/test_libev_win32.c +123 -0
- data/ext/libev/update_ev_wrap +19 -0
- data/lib/.gitignore +2 -0
- data/lib/cool.io.rb +30 -0
- data/lib/cool.io/async_watcher.rb +43 -0
- data/lib/cool.io/dns_resolver.rb +220 -0
- data/lib/cool.io/eventmachine.rb +234 -0
- data/lib/cool.io/http_client.rb +419 -0
- data/lib/cool.io/io.rb +174 -0
- data/lib/cool.io/iowatcher.rb +17 -0
- data/lib/cool.io/listener.rb +93 -0
- data/lib/cool.io/loop.rb +130 -0
- data/lib/cool.io/meta.rb +49 -0
- data/lib/cool.io/server.rb +74 -0
- data/lib/cool.io/socket.rb +224 -0
- data/lib/cool.io/timer_watcher.rb +17 -0
- data/lib/coolio.rb +2 -0
- data/lib/rev.rb +4 -0
- data/spec/async_watcher_spec.rb +57 -0
- data/spec/possible_tests/schedules_other_threads.rb +48 -0
- data/spec/possible_tests/test_on_resolve_failed.rb +9 -0
- data/spec/possible_tests/test_resolves.rb +27 -0
- data/spec/possible_tests/test_write_during_resolve.rb +27 -0
- data/spec/possible_tests/works_straight.rb +71 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/timer_watcher_spec.rb +55 -0
- data/spec/unix_listener_spec.rb +25 -0
- data/spec/unix_server_spec.rb +25 -0
- metadata +184 -0
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
coverage
|
18
|
+
rdoc
|
19
|
+
pkg
|
20
|
+
|
21
|
+
## RUBINIUS
|
22
|
+
*.rbc
|
23
|
+
|
24
|
+
## PROJECT::SPECIFIC
|
25
|
+
conftest.dSYM
|
data/CHANGES
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
0.9.0:
|
2
|
+
|
3
|
+
* Rename the project to cool.io
|
4
|
+
|
5
|
+
* Bump the version all the way to 0.9! Hell yeah! 1.0 soon!
|
6
|
+
|
7
|
+
* Rename the main module from Rev to Coolio, with deprecation warnings for Rev
|
8
|
+
|
9
|
+
* Use Jeweler to manage the gem
|
10
|
+
|
11
|
+
* Update to RSpec 2.0
|
12
|
+
|
13
|
+
* Update to libev 4.01
|
14
|
+
|
15
|
+
0.3.2:
|
16
|
+
|
17
|
+
* Perform a blocking system call if we're the only thread running (1.8 only)
|
18
|
+
|
19
|
+
* Run in non-blocking mode if we're the only thread in the process (1.8 only)
|
20
|
+
|
21
|
+
* Make Rev::Loop#run_nonblock signal-safe
|
22
|
+
|
23
|
+
* Fix spurious firing of Rev::AsyncWatchers
|
24
|
+
|
25
|
+
0.3.1:
|
26
|
+
|
27
|
+
* Configurable intervals for Rev::StatWatcher
|
28
|
+
|
29
|
+
* Fix broken version number :(
|
30
|
+
|
31
|
+
* Removed warning about spuriously readable sockets from Rev::Listener
|
32
|
+
|
33
|
+
* Rev::Listener ignores ECONNABORTED from accept_nonblock
|
34
|
+
|
35
|
+
* Document rationale for EAGAIN/ECONNABORTED handling in Rev::Listener
|
36
|
+
|
37
|
+
0.3.0:
|
38
|
+
|
39
|
+
* Add Rev::StatWatcher to monitor filesystem changes
|
40
|
+
|
41
|
+
* Add Rev::Listener#fileno for accessing the underlying file descriptor
|
42
|
+
|
43
|
+
* Support for creating Rev::Listeners from existing TCPServers/UNIXServers
|
44
|
+
|
45
|
+
* Upgrade to libev 3.8
|
46
|
+
|
47
|
+
* Simplified code loading
|
48
|
+
|
49
|
+
* Pull in iobuffer gem and change outstanding uses of Rev::Buffer to IO::Buffer
|
50
|
+
|
51
|
+
* Fix memory leaks resulting from strange semantics of Ruby's xrealloc
|
52
|
+
|
53
|
+
* Rev::UNIXServer: use path instead of the first argument
|
54
|
+
|
55
|
+
* Rev::Server-based classes can build off ::*Server objects
|
56
|
+
|
57
|
+
0.2.4:
|
58
|
+
|
59
|
+
* Ugh, botched my first release from the git repo. Oh well. Try, try again.
|
60
|
+
|
61
|
+
0.2.3:
|
62
|
+
|
63
|
+
* Initial Windows support
|
64
|
+
|
65
|
+
* Initial Ruby 1.8.7 and 1.9.1 support
|
66
|
+
|
67
|
+
* Upgrade to libev 3.52
|
68
|
+
|
69
|
+
* Add checks for sys/resource.h and don't allow getting/setting maxfds if it
|
70
|
+
isn't present
|
71
|
+
|
72
|
+
0.2.2:
|
73
|
+
|
74
|
+
* Correct a pointer arithmetic error in the buffering code that could result
|
75
|
+
in data corruption.
|
76
|
+
|
77
|
+
* Upgrade to libev 3.41
|
78
|
+
|
79
|
+
* Relax HTTP/1.1 reponse parser to allow the "reason" portion of the response
|
80
|
+
header to be omitted
|
81
|
+
|
82
|
+
0.2.1:
|
83
|
+
|
84
|
+
* Upgrade to libev 3.31
|
85
|
+
|
86
|
+
* Rev::Loop#run_once and Rev::Loop#run_nonblock now return the number of events
|
87
|
+
received when they were running
|
88
|
+
|
89
|
+
* Remove inheritence relationship between Rev::IO and Rev::IOWatcher
|
90
|
+
|
91
|
+
* Loosen HTTP/1.1 response parser to accept a common malformation in HTTP/1.1
|
92
|
+
chunk headers
|
93
|
+
|
94
|
+
* Add underscore prefix to instance variables to avoid conflicts in subclasses
|
95
|
+
|
96
|
+
* Remove Rev::SSLServer until it can be made more useful
|
97
|
+
|
98
|
+
0.2.0:
|
99
|
+
|
100
|
+
* Initial Ruby 1.8.6 support
|
101
|
+
|
102
|
+
* Omit Rev::LIBEV_VERSION constant
|
103
|
+
|
104
|
+
* Catch Errno::ECONNRESET when writing to sockets
|
105
|
+
|
106
|
+
* SSL support via Rev::SSL, with a small C extension subclassing Ruby's
|
107
|
+
OpenSSL::SSL::SSLSocket allowing for non-blocking SSL handshakes
|
108
|
+
|
109
|
+
* Initial Rev::Utils implementation with #ncpus and methods to query and
|
110
|
+
change the maximum number of file descriptors for the current process.
|
111
|
+
|
112
|
+
* Initial Rev::AsyncWatcher implementation for cross-thread signaling
|
113
|
+
|
114
|
+
* Handle unspecified Content-Length when encoding is identity in HttpClient
|
115
|
+
|
116
|
+
* Fix bug in HttpClient processing zero Content-Length
|
117
|
+
|
118
|
+
* Get rid of method_missing stuff in Rev::HttpClient
|
119
|
+
|
120
|
+
* Have Rev::HttpClient close the connection on error
|
121
|
+
|
122
|
+
* Allow Rev::TCPSocket#on_connect to be private when accepting connections
|
123
|
+
from a Rev::TCPServer
|
124
|
+
|
125
|
+
0.1.4:
|
126
|
+
|
127
|
+
* Calibrate Rev::TimerWatchers against ev_time() and ev_now() when the watcher
|
128
|
+
is attached to the loop to ensure that the timeout interval is correct.
|
129
|
+
|
130
|
+
* Add check to ensure that a Rev::Loop cannot be run from within a callback
|
131
|
+
|
132
|
+
* Store Rev::Loop.default in a Thread-specific instance variable
|
133
|
+
|
134
|
+
* Upgrade libev to 0.3.0
|
135
|
+
|
136
|
+
* Rename BufferedIO to IO
|
137
|
+
|
138
|
+
* Fixed bug in BufferedIO#write_output_buffer causing it to spin endlessly on
|
139
|
+
an empty buffer.
|
140
|
+
|
141
|
+
* Added has_active_watchers? to Rev::Loop to check for active watchers
|
142
|
+
|
143
|
+
0.1.3:
|
144
|
+
|
145
|
+
* Fixed bug in Rev::Buffer read_from and write_to: now rb_sys_fail on failed
|
146
|
+
reads/writes.
|
147
|
+
|
148
|
+
* Change Rev::Buffer memory pools to purge on a periodic interval, rather than
|
149
|
+
whenever the GC marks the object.
|
150
|
+
|
151
|
+
* Fix bug in tracking the active watcher count. Factor shared watcher behavior
|
152
|
+
from rev_watcher.h to rev_watcher.c.
|
153
|
+
|
154
|
+
0.1.2:
|
155
|
+
|
156
|
+
* Commit initial specs
|
157
|
+
|
158
|
+
* Improve RDoc for the library
|
159
|
+
|
160
|
+
* Eliminate "zero copy" writes as they bypass the event loop
|
161
|
+
|
162
|
+
* Added Rev::Buffer C extension to provide high speed buffered writes
|
163
|
+
|
164
|
+
* Implement Rev::TCPSocket#peeraddr to improve compatibility with Ruby sockets
|
165
|
+
|
166
|
+
* Added Rev::Listener.close for clean shutdown of a listener
|
167
|
+
|
168
|
+
* Rev::Loop.default used to call ev_loop_default() (in C). However, this
|
169
|
+
registers signal handlers which conflict with Ruby's own. Now the behavior
|
170
|
+
has been changed to return a thread-local singleton of Rev::Loop.
|
171
|
+
|
172
|
+
* Creating a new Rev::TCPListener will disable reverse lookups in BasicSocket
|
173
|
+
|
174
|
+
* Made backlog for Rev::TCPListener user-definable
|
175
|
+
|
176
|
+
* Rev::TCPSocket now implements an on_resolve_failed callback for failed DNS
|
177
|
+
resolution. By default it's aliased to on_connect_failed.
|
178
|
+
|
179
|
+
* Changed event_callbacks to use instance_exec rather than passing the
|
180
|
+
watcher object as an argument. Documented use of defining an event
|
181
|
+
callback as a block
|
182
|
+
|
183
|
+
* Subsecond precision for Rev::TimerWatchers
|
184
|
+
|
185
|
+
0.1.1:
|
186
|
+
|
187
|
+
* Added Rev::HttpClient, an asynchronous HTTP/1.1 client written on top of
|
188
|
+
the Rev::TCPSocket class
|
189
|
+
|
190
|
+
* Imported HTTP response parser from the RFuzz project
|
191
|
+
|
192
|
+
* Added exception handling for Errno::ECONNRESET and Errno::EAGAIN
|
193
|
+
|
194
|
+
* Fixed bugs in buffered writer which resulted in exceptions if all data
|
195
|
+
couldn't be written with a nonblocking write.
|
196
|
+
|
197
|
+
0.1.0:
|
198
|
+
|
199
|
+
* Initial public release
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007-10 Tony Arcieri
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = "cool.io"
|
9
|
+
gem.summary = "The cool event framework for Ruby"
|
10
|
+
gem.description = "A Ruby wrapper around the libev high performance event library"
|
11
|
+
gem.email = "tony@medioh.com"
|
12
|
+
gem.homepage = "http://github.com/tarcieri/cool.io"
|
13
|
+
gem.authors = ["Tony Arcieri"]
|
14
|
+
gem.add_dependency "iobuffer", ">= 0.1.3"
|
15
|
+
gem.add_development_dependency "rspec", "~> 2.0.0"
|
16
|
+
gem.extensions = FileList["ext/**/extconf.rb"].to_a
|
17
|
+
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rspec_opts = %w[-fs -c -b]
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.rcov = true
|
34
|
+
spec.rspec_opts = %w[-fs -c -b]
|
35
|
+
end
|
36
|
+
|
37
|
+
task :default => %w(compile spec)
|
38
|
+
task :spec => :check_dependencies
|
39
|
+
|
40
|
+
require 'rake/rdoctask'
|
41
|
+
Rake::RDocTask.new do |rdoc|
|
42
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "cool.io #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
49
|
+
|
50
|
+
def make(makedir)
|
51
|
+
Dir.chdir(makedir) { sh 'make' }
|
52
|
+
end
|
53
|
+
|
54
|
+
def extconf(dir)
|
55
|
+
Dir.chdir(dir) { ruby "extconf.rb" }
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup_extension(dir, extension)
|
59
|
+
ext = "ext/#{dir}"
|
60
|
+
ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
|
61
|
+
ext_files = FileList[
|
62
|
+
"#{ext}/*.c",
|
63
|
+
"#{ext}/*.h",
|
64
|
+
"#{ext}/extconf.rb",
|
65
|
+
"#{ext}/Makefile",
|
66
|
+
]
|
67
|
+
|
68
|
+
desc "Builds just the #{extension} extension"
|
69
|
+
task extension.to_sym => ["#{ext}/Makefile", ext_so ]
|
70
|
+
|
71
|
+
file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
|
72
|
+
extconf "#{ext}"
|
73
|
+
end
|
74
|
+
|
75
|
+
file ext_so => ext_files do
|
76
|
+
make "#{ext}"
|
77
|
+
cp ext_so, "lib"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
setup_extension("cool.io", "cool.io_ext")
|
82
|
+
setup_extension("http11_client", "http11_client")
|
83
|
+
|
84
|
+
task :compile => %w(cool.io_ext http11_client)
|
85
|
+
|
86
|
+
# Rebuild parser Ragel
|
87
|
+
task :http11_parser do
|
88
|
+
Dir.chdir "ext/http11_client" do
|
89
|
+
target = "http11_parser.c"
|
90
|
+
File.unlink target if File.exist? target
|
91
|
+
sh "ragel http11_parser.rl | rlgen-cd -G2 -o #{target}"
|
92
|
+
raise "Failed to build C source" unless File.exist? target
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
CLEAN.include ["build/*", "**/*.o", "**/*.so", "**/*.a", "**/*.log", "pkg"]
|
97
|
+
CLEAN.include ["ext/**/Makefile", "lib/cool.io_ext.*", "lib/http11_client.*"]
|
98
|
+
CLEAN.include ["ext/**/*.#{Config::CONFIG["DLEXT"]}"]
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.0
|
@@ -0,0 +1,38 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'cool.io'
|
5
|
+
|
6
|
+
ADDR = '127.0.0.1'
|
7
|
+
PORT = 4321
|
8
|
+
|
9
|
+
class ClientConnection < Coolio::TCPSocket
|
10
|
+
def on_connect
|
11
|
+
puts "#{remote_addr}:#{remote_port} connected"
|
12
|
+
write "bounce this back to me"
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_close
|
16
|
+
puts "#{remote_addr}:#{remote_port} disconnected"
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_read(data)
|
20
|
+
print "got #{data}"
|
21
|
+
close
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_resolve_failed
|
25
|
+
print "DNS resolve failed"
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_connect_failed
|
29
|
+
print "connect failed, meaning our connection to their port was rejected"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
event_loop = Coolio::Loop.default
|
35
|
+
client = ClientConnection.connect(ADDR, PORT)
|
36
|
+
client.attach(event_loop)
|
37
|
+
puts "Echo client connecting to #{ADDR}:#{PORT}..."
|
38
|
+
event_loop.run
|
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'cool.io'
|
5
|
+
|
6
|
+
ADDR = '127.0.0.1'
|
7
|
+
PORT = 4321
|
8
|
+
|
9
|
+
class EchoServerConnection < Coolio::TCPSocket
|
10
|
+
def on_connect
|
11
|
+
puts "#{remote_addr}:#{remote_port} connected"
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_close
|
15
|
+
puts "#{remote_addr}:#{remote_port} disconnected"
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_read(data)
|
19
|
+
write data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
event_loop = Coolio::Loop.default
|
24
|
+
Coolio::TCPServer.new(ADDR, PORT, EchoServerConnection).attach(event_loop)
|
25
|
+
|
26
|
+
puts "Echo server listening on #{ADDR}:#{PORT}"
|
27
|
+
event_loop.run
|
data/examples/google.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'cool.io'
|
5
|
+
|
6
|
+
class MyHttpClient < Coolio::HttpClient
|
7
|
+
def on_connect
|
8
|
+
super
|
9
|
+
STDERR.puts "Connected to #{remote_host}:#{remote_port}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_connect_failed
|
13
|
+
super
|
14
|
+
STDERR.puts "Connection failed"
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_response_header(header)
|
18
|
+
STDERR.puts "Response: #{header.http_version} #{header.status} #{header.http_reason}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_body_data(data)
|
22
|
+
STDOUT.write data
|
23
|
+
STDOUT.flush
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_request_complete
|
27
|
+
STDERR.puts "Request complete!"
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_error(reason)
|
31
|
+
STDERR.puts "Error: #{reason}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
l = Coolio::Loop.default
|
36
|
+
c = MyHttpClient.connect("www.google.com", 80).attach(l)
|
37
|
+
c.request('GET', '/search', :query => { :q => 'foobar' })
|
38
|
+
l.run
|