eventmachine-mkroman 1.3.0.dev.1

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.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +179 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +110 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +520 -0
  8. data/docs/old/ChangeLog +211 -0
  9. data/docs/old/DEFERRABLES +246 -0
  10. data/docs/old/EPOLL +141 -0
  11. data/docs/old/INSTALL +13 -0
  12. data/docs/old/KEYBOARD +42 -0
  13. data/docs/old/LEGAL +25 -0
  14. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  15. data/docs/old/PURE_RUBY +75 -0
  16. data/docs/old/RELEASE_NOTES +94 -0
  17. data/docs/old/SMTP +4 -0
  18. data/docs/old/SPAWNED_PROCESSES +148 -0
  19. data/docs/old/TODO +8 -0
  20. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  21. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  22. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  23. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  24. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  25. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  26. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  27. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  28. data/examples/old/ex_channel.rb +43 -0
  29. data/examples/old/ex_queue.rb +2 -0
  30. data/examples/old/ex_tick_loop_array.rb +15 -0
  31. data/examples/old/ex_tick_loop_counter.rb +32 -0
  32. data/examples/old/helper.rb +2 -0
  33. data/ext/binder.cpp +124 -0
  34. data/ext/binder.h +52 -0
  35. data/ext/cmain.cpp +1046 -0
  36. data/ext/ed.cpp +2243 -0
  37. data/ext/ed.h +463 -0
  38. data/ext/em.cpp +2378 -0
  39. data/ext/em.h +266 -0
  40. data/ext/eventmachine.h +152 -0
  41. data/ext/extconf.rb +291 -0
  42. data/ext/fastfilereader/extconf.rb +120 -0
  43. data/ext/fastfilereader/mapper.cpp +214 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +126 -0
  46. data/ext/kb.cpp +79 -0
  47. data/ext/page.cpp +107 -0
  48. data/ext/page.h +51 -0
  49. data/ext/pipe.cpp +354 -0
  50. data/ext/project.h +174 -0
  51. data/ext/rubymain.cpp +1643 -0
  52. data/ext/ssl.cpp +701 -0
  53. data/ext/ssl.h +103 -0
  54. data/ext/wait_for_single_fd.h +36 -0
  55. data/java/.classpath +8 -0
  56. data/java/.project +17 -0
  57. data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
  58. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  59. data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
  60. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  61. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  62. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  63. data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
  64. data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
  65. data/lib/em/buftok.rb +59 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +69 -0
  68. data/lib/em/completion.rb +307 -0
  69. data/lib/em/connection.rb +802 -0
  70. data/lib/em/deferrable/pool.rb +2 -0
  71. data/lib/em/deferrable.rb +210 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/io_streamer.rb +68 -0
  75. data/lib/em/iterator.rb +252 -0
  76. data/lib/em/messages.rb +66 -0
  77. data/lib/em/pool.rb +151 -0
  78. data/lib/em/process_watch.rb +45 -0
  79. data/lib/em/processes.rb +123 -0
  80. data/lib/em/protocols/header_and_content.rb +138 -0
  81. data/lib/em/protocols/httpclient.rb +303 -0
  82. data/lib/em/protocols/httpclient2.rb +602 -0
  83. data/lib/em/protocols/line_and_text.rb +125 -0
  84. data/lib/em/protocols/line_protocol.rb +33 -0
  85. data/lib/em/protocols/linetext2.rb +179 -0
  86. data/lib/em/protocols/memcache.rb +331 -0
  87. data/lib/em/protocols/object_protocol.rb +46 -0
  88. data/lib/em/protocols/postgres3.rb +246 -0
  89. data/lib/em/protocols/saslauth.rb +175 -0
  90. data/lib/em/protocols/smtpclient.rb +394 -0
  91. data/lib/em/protocols/smtpserver.rb +666 -0
  92. data/lib/em/protocols/socks4.rb +66 -0
  93. data/lib/em/protocols/stomp.rb +205 -0
  94. data/lib/em/protocols/tcptest.rb +54 -0
  95. data/lib/em/protocols.rb +37 -0
  96. data/lib/em/pure_ruby.rb +1300 -0
  97. data/lib/em/queue.rb +80 -0
  98. data/lib/em/resolver.rb +232 -0
  99. data/lib/em/spawnable.rb +84 -0
  100. data/lib/em/streamer.rb +118 -0
  101. data/lib/em/threaded_resource.rb +90 -0
  102. data/lib/em/tick_loop.rb +85 -0
  103. data/lib/em/timers.rb +61 -0
  104. data/lib/em/version.rb +3 -0
  105. data/lib/eventmachine.rb +1602 -0
  106. data/lib/jeventmachine.rb +319 -0
  107. data/rakelib/package.rake +120 -0
  108. data/rakelib/test.rake +6 -0
  109. data/rakelib/test_pure.rake +11 -0
  110. data/tests/client.crt +31 -0
  111. data/tests/client.key +51 -0
  112. data/tests/dhparam.pem +13 -0
  113. data/tests/em_ssl_handlers.rb +165 -0
  114. data/tests/em_test_helper.rb +198 -0
  115. data/tests/encoded_client.key +54 -0
  116. data/tests/jruby/test_jeventmachine.rb +38 -0
  117. data/tests/test_attach.rb +199 -0
  118. data/tests/test_basic.rb +321 -0
  119. data/tests/test_channel.rb +75 -0
  120. data/tests/test_completion.rb +178 -0
  121. data/tests/test_connection_count.rb +83 -0
  122. data/tests/test_connection_write.rb +35 -0
  123. data/tests/test_defer.rb +35 -0
  124. data/tests/test_deferrable.rb +35 -0
  125. data/tests/test_epoll.rb +141 -0
  126. data/tests/test_error_handler.rb +38 -0
  127. data/tests/test_exc.rb +37 -0
  128. data/tests/test_file_watch.rb +86 -0
  129. data/tests/test_fork.rb +75 -0
  130. data/tests/test_futures.rb +170 -0
  131. data/tests/test_handler_check.rb +35 -0
  132. data/tests/test_hc.rb +155 -0
  133. data/tests/test_httpclient.rb +238 -0
  134. data/tests/test_httpclient2.rb +132 -0
  135. data/tests/test_idle_connection.rb +31 -0
  136. data/tests/test_inactivity_timeout.rb +102 -0
  137. data/tests/test_io_streamer.rb +48 -0
  138. data/tests/test_ipv4.rb +96 -0
  139. data/tests/test_ipv6.rb +107 -0
  140. data/tests/test_iterator.rb +122 -0
  141. data/tests/test_kb.rb +28 -0
  142. data/tests/test_keepalive.rb +113 -0
  143. data/tests/test_line_protocol.rb +33 -0
  144. data/tests/test_ltp.rb +155 -0
  145. data/tests/test_ltp2.rb +332 -0
  146. data/tests/test_many_fds.rb +21 -0
  147. data/tests/test_next_tick.rb +104 -0
  148. data/tests/test_object_protocol.rb +36 -0
  149. data/tests/test_pause.rb +109 -0
  150. data/tests/test_pending_connect_timeout.rb +52 -0
  151. data/tests/test_pool.rb +196 -0
  152. data/tests/test_process_watch.rb +50 -0
  153. data/tests/test_processes.rb +147 -0
  154. data/tests/test_proxy_connection.rb +180 -0
  155. data/tests/test_pure.rb +156 -0
  156. data/tests/test_queue.rb +64 -0
  157. data/tests/test_resolver.rb +129 -0
  158. data/tests/test_running.rb +14 -0
  159. data/tests/test_sasl.rb +46 -0
  160. data/tests/test_send_file.rb +217 -0
  161. data/tests/test_servers.rb +32 -0
  162. data/tests/test_shutdown_hooks.rb +23 -0
  163. data/tests/test_smtpclient.rb +75 -0
  164. data/tests/test_smtpserver.rb +90 -0
  165. data/tests/test_sock_opt.rb +53 -0
  166. data/tests/test_spawn.rb +290 -0
  167. data/tests/test_ssl_args.rb +70 -0
  168. data/tests/test_ssl_dhparam.rb +57 -0
  169. data/tests/test_ssl_ecdh_curve.rb +57 -0
  170. data/tests/test_ssl_extensions.rb +24 -0
  171. data/tests/test_ssl_inline_cert.rb +222 -0
  172. data/tests/test_ssl_methods.rb +31 -0
  173. data/tests/test_ssl_protocols.rb +190 -0
  174. data/tests/test_ssl_verify.rb +108 -0
  175. data/tests/test_stomp.rb +38 -0
  176. data/tests/test_system.rb +46 -0
  177. data/tests/test_threaded_resource.rb +68 -0
  178. data/tests/test_tick_loop.rb +58 -0
  179. data/tests/test_timers.rb +150 -0
  180. data/tests/test_ud.rb +8 -0
  181. data/tests/test_unbind_reason.rb +40 -0
  182. metadata +389 -0
@@ -0,0 +1,303 @@
1
+ #--
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 July 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ module EventMachine
28
+ module Protocols
29
+
30
+ #
31
+ # @example
32
+ #
33
+ # EventMachine.run {
34
+ # http = EventMachine::Protocols::HttpClient.request(
35
+ # :host => server,
36
+ # :port => 80,
37
+ # :request => "/index.html",
38
+ # :query_string => "parm1=value1&parm2=value2"
39
+ # )
40
+ # http.callback {|response|
41
+ # puts response[:status]
42
+ # puts response[:headers]
43
+ # puts response[:content]
44
+ # }
45
+ # }
46
+ #--
47
+ # @todo Add streaming so we can support enormous POSTs. Current max is 20meg.
48
+ # Timeout for connections that run too long or hang somewhere in the middle.
49
+ # Persistent connections (HTTP/1.1), may need a associated delegate object.
50
+ # DNS: Some way to cache DNS lookups for hostnames we connect to. Ruby's
51
+ # DNS lookups are unbelievably slow.
52
+ # HEAD requests.
53
+ # Convenience methods for requests. get, post, url, etc.
54
+ # SSL.
55
+ # Handle status codes like 304, 100, etc.
56
+ # Refactor this code so that protocol errors all get handled one way (an exception?),
57
+ # instead of sprinkling set_deferred_status :failed calls everywhere.
58
+ #
59
+ # @deprecated Please use [EM-HTTP-Request](https://github.com/igrigorik/em-http-request) instead.
60
+ #
61
+ class HttpClient < Connection
62
+ include EventMachine::Deferrable
63
+
64
+ MaxPostContentLength = 20 * 1024 * 1024
65
+
66
+ def initialize
67
+ warn "HttpClient is deprecated and will be removed. EM-Http-Request should be used instead."
68
+ @connected = false
69
+ end
70
+
71
+ # @param args [Hash] The request arguments
72
+ # @option args [String] :host The host IP/DNS name
73
+ # @option args [Integer] :port The port to connect too
74
+ # @option args [String] :verb The request type [GET | POST | DELETE | PUT]
75
+ # @option args [String] :request The request path
76
+ # @option args [Hash] :basic_auth The basic auth credentials (:username and :password)
77
+ # @option args [String] :content The request content
78
+ # @option args [String] :contenttype The content type (e.g. text/plain)
79
+ # @option args [String] :query_string The query string
80
+ # @option args [String] :host_header The host header to set
81
+ # @option args [String] :cookie Cookies to set
82
+ def self.request( args = {} )
83
+ args[:port] ||= 80
84
+ EventMachine.connect( args[:host], args[:port], self ) {|c|
85
+ # According to the docs, we will get here AFTER post_init is called.
86
+ c.instance_eval {@args = args}
87
+ }
88
+ end
89
+
90
+ def post_init
91
+ @start_time = Time.now
92
+ @data = ""
93
+ @read_state = :base
94
+ end
95
+
96
+ # We send the request when we get a connection.
97
+ # AND, we set an instance variable to indicate we passed through here.
98
+ # That allows #unbind to know whether there was a successful connection.
99
+ # NB: This naive technique won't work when we have to support multiple
100
+ # requests on a single connection.
101
+ def connection_completed
102
+ @connected = true
103
+ send_request @args
104
+ end
105
+
106
+ def send_request args
107
+ args[:verb] ||= args[:method] # Support :method as an alternative to :verb.
108
+ args[:verb] ||= :get # IS THIS A GOOD IDEA, to default to GET if nothing was specified?
109
+
110
+ verb = args[:verb].to_s.upcase
111
+ unless ["GET", "POST", "PUT", "DELETE", "HEAD"].include?(verb)
112
+ set_deferred_status :failed, {:status => 0} # TODO, not signalling the error type
113
+ return # NOTE THE EARLY RETURN, we're not sending any data.
114
+ end
115
+
116
+ request = args[:request] || "/"
117
+ unless request[0,1] == "/"
118
+ request = "/" + request
119
+ end
120
+
121
+ qs = args[:query_string] || ""
122
+ if qs.length > 0 and qs[0,1] != '?'
123
+ qs = "?" + qs
124
+ end
125
+
126
+ version = args[:version] || "1.1"
127
+
128
+ # Allow an override for the host header if it's not the connect-string.
129
+ host = args[:host_header] || args[:host] || "_"
130
+ # For now, ALWAYS tuck in the port string, although we may want to omit it if it's the default.
131
+ port = args[:port].to_i != 80 ? ":#{args[:port]}" : ""
132
+
133
+ # POST items.
134
+ postcontenttype = args[:contenttype] || "application/octet-stream"
135
+ postcontent = args[:content] || ""
136
+ raise "oversized content in HTTP POST" if postcontent.length > MaxPostContentLength
137
+
138
+ # ESSENTIAL for the request's line-endings to be CRLF, not LF. Some servers misbehave otherwise.
139
+ # TODO: We ASSUME the caller wants to send a 1.1 request. May not be a good assumption.
140
+ req = [
141
+ "#{verb} #{request}#{qs} HTTP/#{version}",
142
+ "Host: #{host}#{port}",
143
+ "User-agent: Ruby EventMachine",
144
+ ]
145
+
146
+ if verb == "POST" || verb == "PUT"
147
+ req << "Content-type: #{postcontenttype}"
148
+ req << "Content-length: #{postcontent.length}"
149
+ end
150
+
151
+ # TODO, this cookie handler assumes it's getting a single, semicolon-delimited string.
152
+ # Eventually we will want to deal intelligently with arrays and hashes.
153
+ if args[:cookie]
154
+ req << "Cookie: #{args[:cookie]}"
155
+ end
156
+
157
+ # Allow custom HTTP headers, e.g. SOAPAction
158
+ args[:custom_headers].each do |k,v|
159
+ req << "#{k}: #{v}"
160
+ end if args[:custom_headers]
161
+
162
+ # Basic-auth stanza contributed by Matt Murphy.
163
+ if args[:basic_auth]
164
+ basic_auth_string = ["#{args[:basic_auth][:username]}:#{args[:basic_auth][:password]}"].pack('m').strip.gsub(/\n/,'')
165
+ req << "Authorization: Basic #{basic_auth_string}"
166
+ end
167
+
168
+ req << ""
169
+ reqstring = req.map {|l| "#{l}\r\n"}.join
170
+ send_data reqstring
171
+
172
+ if verb == "POST" || verb == "PUT"
173
+ send_data postcontent
174
+ end
175
+ end
176
+
177
+
178
+ def receive_data data
179
+ while data and data.length > 0
180
+ case @read_state
181
+ when :base
182
+ # Perform any per-request initialization here and don't consume any data.
183
+ @data = ""
184
+ @headers = []
185
+ @content_length = nil # not zero
186
+ @content = ""
187
+ @status = nil
188
+ @chunked = false
189
+ @chunk_length = nil
190
+ @read_state = :header
191
+ @connection_close = nil
192
+ when :header
193
+ ary = data.split( /\r?\n/m, 2 )
194
+ if ary.length == 2
195
+ data = ary.last
196
+ if ary.first == ""
197
+ if (@content_length and @content_length > 0) || @chunked || @connection_close
198
+ @read_state = :content
199
+ else
200
+ dispatch_response
201
+ @read_state = :base
202
+ end
203
+ else
204
+ @headers << ary.first
205
+ if @headers.length == 1
206
+ parse_response_line
207
+ elsif ary.first =~ /\Acontent-length:\s*/i
208
+ # Only take the FIRST content-length header that appears,
209
+ # which we can distinguish because @content_length is nil.
210
+ # TODO, it's actually a fatal error if there is more than one
211
+ # content-length header, because the caller is presumptively
212
+ # a bad guy. (There is an exploit that depends on multiple
213
+ # content-length headers.)
214
+ @content_length ||= $'.to_i
215
+ elsif ary.first =~ /\Aconnection:\s*close/i
216
+ @connection_close = true
217
+ elsif ary.first =~ /\Atransfer-encoding:\s*chunked/i
218
+ @chunked = true
219
+ end
220
+ end
221
+ else
222
+ @data << data
223
+ data = ""
224
+ end
225
+ when :content
226
+ if @chunked && @chunk_length
227
+ bytes_needed = @chunk_length - @chunk_read
228
+ new_data = data[0, bytes_needed]
229
+ @chunk_read += new_data.length
230
+ @content += new_data
231
+ data = data[bytes_needed..-1] || ""
232
+ if @chunk_length == @chunk_read && data[0,2] == "\r\n"
233
+ @chunk_length = nil
234
+ data = data[2..-1]
235
+ end
236
+ elsif @chunked
237
+ if (m = data.match(/\A(\S*)\r\n/m))
238
+ data = data[m[0].length..-1]
239
+ @chunk_length = m[1].to_i(16)
240
+ @chunk_read = 0
241
+ if @chunk_length == 0
242
+ dispatch_response
243
+ @read_state = :base
244
+ end
245
+ end
246
+ elsif @content_length
247
+ # If there was no content-length header, we have to wait until the connection
248
+ # closes. Everything we get until that point is content.
249
+ # TODO: Must impose a content-size limit, and also must implement chunking.
250
+ # Also, must support either temporary files for large content, or calling
251
+ # a content-consumer block supplied by the user.
252
+ bytes_needed = @content_length - @content.length
253
+ @content += data[0, bytes_needed]
254
+ data = data[bytes_needed..-1] || ""
255
+ if @content_length == @content.length
256
+ dispatch_response
257
+ @read_state = :base
258
+ end
259
+ else
260
+ @content << data
261
+ data = ""
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+
268
+ # We get called here when we have received an HTTP response line.
269
+ # It's an opportunity to throw an exception or trigger other exceptional
270
+ # handling.
271
+ def parse_response_line
272
+ if @headers.first =~ /\AHTTP\/1\.[01] ([\d]{3})/
273
+ @status = $1.to_i
274
+ else
275
+ set_deferred_status :failed, {
276
+ :status => 0 # crappy way of signifying an unrecognized response. TODO, find a better way to do this.
277
+ }
278
+ close_connection
279
+ end
280
+ end
281
+ private :parse_response_line
282
+
283
+ def dispatch_response
284
+ @read_state = :base
285
+ set_deferred_status :succeeded, {
286
+ :content => @content,
287
+ :headers => @headers,
288
+ :status => @status
289
+ }
290
+ # TODO, we close the connection for now, but this is wrong for persistent clients.
291
+ close_connection
292
+ end
293
+
294
+ def unbind
295
+ if !@connected
296
+ set_deferred_status :failed, {:status => 0} # YECCCCH. Find a better way to signal no-connect/network error.
297
+ elsif (@read_state == :content and @content_length == nil)
298
+ dispatch_response
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end