rev 0.1.1 → 0.1.2
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/README +45 -9
- data/doc/rdoc/classes/Rev.html +368 -0
- data/doc/rdoc/classes/Rev.src/M000001.html +28 -0
- data/doc/rdoc/classes/Rev.src/M000002.html +35 -0
- data/doc/rdoc/classes/Rev.src/M000003.html +24 -0
- data/doc/rdoc/classes/Rev.src/M000004.html +28 -0
- data/doc/rdoc/classes/Rev.src/M000005.html +27 -0
- data/doc/rdoc/classes/Rev.src/M000006.html +33 -0
- data/doc/rdoc/classes/Rev.src/M000007.html +43 -0
- data/doc/rdoc/classes/Rev.src/M000008.html +16 -0
- data/doc/rdoc/classes/Rev/Buffer.html +354 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000019.html +17 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000020.html +29 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000021.html +27 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000022.html +27 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000023.html +31 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000024.html +31 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000025.html +30 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000026.html +50 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000027.html +22 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000028.html +24 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000029.html +24 -0
- data/doc/rdoc/classes/Rev/BufferedIO.html +397 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000095.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000096.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000097.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000098.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000099.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000100.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000101.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000102.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000103.html +20 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000104.html +24 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000105.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000106.html +22 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000107.html +29 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.html +154 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.src/M000108.html +19 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.src/M000109.html +18 -0
- data/doc/rdoc/classes/Rev/DNSResolver.html +401 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000124.html +25 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000125.html +29 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000126.html +20 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000127.html +19 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000128.html +16 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000129.html +16 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000131.html +19 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000132.html +21 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000133.html +27 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000134.html +28 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000135.html +55 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.html +154 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.src/M000136.html +20 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.src/M000137.html +22 -0
- data/doc/rdoc/classes/Rev/HttpChunkHeader.html +156 -0
- data/doc/rdoc/classes/Rev/HttpChunkHeader.src/M000031.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.html +460 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000042.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000043.html +27 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000044.html +24 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000045.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000046.html +17 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000047.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000048.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000049.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000050.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000051.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000052.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000053.html +41 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000054.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000055.html +34 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.html +310 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000009.html +20 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000010.html +20 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000011.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000012.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000013.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000014.html +19 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000015.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000016.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000017.html +22 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000018.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.html +219 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000032.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000033.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000034.html +18 -0
- data/doc/rdoc/classes/Rev/IOWatcher.html +285 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000079.html +17 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000080.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000081.html +26 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000082.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000083.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000084.html +24 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000085.html +25 -0
- data/doc/rdoc/classes/Rev/Listener.html +207 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000065.html +19 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000066.html +19 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000067.html +16 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000068.html +18 -0
- data/doc/rdoc/classes/Rev/Loop.html +395 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000070.html +25 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000071.html +45 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000072.html +18 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000073.html +23 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000074.html +19 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000075.html +17 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000076.html +27 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000077.html +32 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000078.html +32 -0
- data/doc/rdoc/classes/Rev/Server.html +164 -0
- data/doc/rdoc/classes/Rev/Server.src/M000121.html +32 -0
- data/doc/rdoc/classes/Rev/Server.src/M000122.html +20 -0
- data/doc/rdoc/classes/Rev/Socket.html +213 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000035.html +21 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000036.html +25 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000037.html +16 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000038.html +16 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.html +154 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.src/M000040.html +19 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.src/M000041.html +28 -0
- data/doc/rdoc/classes/Rev/TCPListener.html +161 -0
- data/doc/rdoc/classes/Rev/TCPListener.src/M000069.html +23 -0
- data/doc/rdoc/classes/Rev/TCPServer.html +147 -0
- data/doc/rdoc/classes/Rev/TCPServer.src/M000123.html +20 -0
- data/doc/rdoc/classes/Rev/TCPSocket.html +233 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000056.html +20 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000057.html +34 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000058.html +24 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000059.html +18 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.html +171 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000060.html +19 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000061.html +27 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000062.html +23 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.html +154 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.src/M000063.html +25 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.src/M000064.html +23 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.html +288 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000086.html +17 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000087.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000088.html +26 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000089.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000090.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000091.html +42 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000092.html +24 -0
- data/doc/rdoc/classes/Rev/UNIXListener.html +147 -0
- data/doc/rdoc/classes/Rev/UNIXListener.src/M000120.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXServer.html +147 -0
- data/doc/rdoc/classes/Rev/UNIXServer.src/M000030.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.html +175 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.src/M000093.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.src/M000094.html +21 -0
- data/doc/rdoc/classes/Rev/Watcher.html +349 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000110.html +20 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000111.html +20 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000112.html +17 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000113.html +48 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000114.html +62 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000115.html +34 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000116.html +34 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000117.html +27 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000118.html +24 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000119.html +27 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/LICENSE.html +165 -0
- data/doc/rdoc/files/README.html +297 -0
- data/doc/rdoc/files/ext/rev/rev_buffer_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_ext_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_io_watcher_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_loop_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_timer_watcher_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_watcher_c.html +101 -0
- data/doc/rdoc/files/lib/rev/buffered_io_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/dns_resolver_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/http_client_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/io_watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/listener_rb.html +108 -0
- data/doc/rdoc/files/lib/rev/loop_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/server_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/socket_rb.html +109 -0
- data/doc/rdoc/files/lib/rev/timer_watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev_rb.html +101 -0
- data/doc/rdoc/fr_class_index.html +52 -0
- data/doc/rdoc/fr_file_index.html +45 -0
- data/doc/rdoc/fr_method_index.html +163 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/ext/rev/extconf.rb +1 -1
- data/ext/rev/rev.h +0 -1
- data/ext/rev/rev_buffer.c +606 -0
- data/ext/rev/rev_ext.c +1 -0
- data/ext/rev/rev_io_watcher.c +53 -19
- data/ext/rev/rev_loop.c +12 -35
- data/ext/rev/rev_timer_watcher.c +45 -3
- data/ext/rev/rev_watcher.c +13 -1
- data/lib/http11_client.bundle +0 -0
- data/lib/rev.rb +1 -1
- data/lib/rev/buffered_io.rb +25 -22
- data/lib/rev/dns_resolver.rb +31 -14
- data/lib/rev/http_client.rb +88 -91
- data/lib/rev/listener.rb +22 -5
- data/lib/rev/loop.rb +13 -0
- data/lib/rev/server.rb +10 -3
- data/lib/rev/socket.rb +30 -9
- data/lib/rev/watcher.rb +4 -2
- data/lib/rev_ext.bundle +0 -0
- metadata +230 -2
data/lib/rev/http_client.rb
CHANGED
|
@@ -146,7 +146,7 @@ module Rev
|
|
|
146
146
|
@parser_nbytes = 0
|
|
147
147
|
|
|
148
148
|
@state = :response_header
|
|
149
|
-
@data =
|
|
149
|
+
@data = Rev::Buffer.new
|
|
150
150
|
|
|
151
151
|
@response_header = HttpResponseHeader.new
|
|
152
152
|
@chunk_header = HttpChunkHeader.new
|
|
@@ -224,9 +224,8 @@ module Rev
|
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
def on_read(data)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
end
|
|
227
|
+
@data << data
|
|
228
|
+
dispatch
|
|
230
229
|
end
|
|
231
230
|
|
|
232
231
|
#
|
|
@@ -273,147 +272,145 @@ module Rev
|
|
|
273
272
|
# Response processing
|
|
274
273
|
#
|
|
275
274
|
|
|
276
|
-
def
|
|
277
|
-
case state
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
275
|
+
def dispatch
|
|
276
|
+
while case @state
|
|
277
|
+
when :response_header
|
|
278
|
+
parse_response_header
|
|
279
|
+
when :chunk_header
|
|
280
|
+
parse_chunk_header
|
|
281
|
+
when :chunk_body
|
|
282
|
+
process_chunk_body
|
|
283
|
+
when :chunk_footer
|
|
284
|
+
process_chunk_footer
|
|
285
|
+
when :response_footer
|
|
286
|
+
process_response_footer
|
|
287
|
+
when :body
|
|
288
|
+
process_body
|
|
289
|
+
when :finished, :invalid
|
|
290
|
+
break
|
|
291
|
+
else raise RuntimeError, "invalid state: #{@state}"
|
|
292
|
+
end
|
|
291
293
|
end
|
|
292
294
|
end
|
|
293
295
|
|
|
294
|
-
def parse_header(header
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
def parse_header(header)
|
|
297
|
+
return false if @data.empty?
|
|
298
|
+
|
|
299
|
+
@parser_nbytes = @parser.execute(header, @data.to_str, @parser_nbytes)
|
|
300
|
+
return false unless @parser.finished?
|
|
298
301
|
|
|
299
|
-
|
|
300
|
-
@data
|
|
302
|
+
# Clear parsed data from the buffer
|
|
303
|
+
@data.read(@parser_nbytes)
|
|
301
304
|
@parser.reset
|
|
302
305
|
@parser_nbytes = 0
|
|
303
|
-
|
|
304
|
-
|
|
306
|
+
|
|
307
|
+
true
|
|
305
308
|
end
|
|
306
309
|
|
|
307
|
-
def parse_response_header
|
|
308
|
-
|
|
309
|
-
return :response_header, '' if data.nil?
|
|
310
|
+
def parse_response_header
|
|
311
|
+
return false unless parse_header(@response_header)
|
|
310
312
|
|
|
311
313
|
unless @response_header.http_status and @response_header.http_reason
|
|
312
314
|
on_error "no HTTP response"
|
|
313
|
-
|
|
315
|
+
@state = :invalid
|
|
316
|
+
return false
|
|
314
317
|
end
|
|
315
318
|
|
|
316
319
|
on_response_header(@response_header)
|
|
317
320
|
|
|
318
321
|
if @response_header.chunked_encoding?
|
|
319
|
-
|
|
322
|
+
@state = :chunk_header
|
|
320
323
|
else
|
|
324
|
+
@state = :body
|
|
321
325
|
@bytes_remaining = @response_header.content_length
|
|
322
|
-
return :body, data
|
|
323
326
|
end
|
|
327
|
+
|
|
328
|
+
true
|
|
324
329
|
end
|
|
325
330
|
|
|
326
|
-
def parse_chunk_header
|
|
327
|
-
|
|
328
|
-
return :chunk_header, '' if data.nil?
|
|
331
|
+
def parse_chunk_header
|
|
332
|
+
return false unless parse_header(@chunk_header)
|
|
329
333
|
|
|
330
334
|
@bytes_remaining = @chunk_header.chunk_size
|
|
331
335
|
@chunk_header = HttpChunkHeader.new
|
|
332
336
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
else
|
|
336
|
-
@bytes_remaining = 2
|
|
337
|
-
return :response_footer, data
|
|
338
|
-
end
|
|
337
|
+
@state = @bytes_remaining > 0 ? :chunk_body : :response_footer
|
|
338
|
+
true
|
|
339
339
|
end
|
|
340
340
|
|
|
341
|
-
def process_chunk_body
|
|
342
|
-
if data.size < @bytes_remaining
|
|
343
|
-
@bytes_remaining -= data.size
|
|
344
|
-
on_body_data data
|
|
345
|
-
return
|
|
341
|
+
def process_chunk_body
|
|
342
|
+
if @data.size < @bytes_remaining
|
|
343
|
+
@bytes_remaining -= @data.size
|
|
344
|
+
on_body_data @data.read
|
|
345
|
+
return false
|
|
346
346
|
end
|
|
347
347
|
|
|
348
|
-
on_body_data data.
|
|
349
|
-
@bytes_remaining =
|
|
350
|
-
|
|
348
|
+
on_body_data @data.read(@bytes_remaining)
|
|
349
|
+
@bytes_remaining = 0
|
|
350
|
+
|
|
351
|
+
@state = :chunk_footer
|
|
352
|
+
true
|
|
351
353
|
end
|
|
352
354
|
|
|
353
|
-
def
|
|
354
|
-
|
|
355
|
-
@bytes_remaining = 2 - @data.size
|
|
356
|
-
return unless @bytes_remaining == 0
|
|
355
|
+
def process_chunk_footer
|
|
356
|
+
return false if @data.size < 2
|
|
357
357
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return matches_crlf, data
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
def process_chunk_footer(data)
|
|
365
|
-
result, data = process_crlf(data)
|
|
366
|
-
return :chunk_footer, '' if result.nil?
|
|
367
|
-
|
|
368
|
-
if result
|
|
369
|
-
return :chunk_header, data
|
|
358
|
+
if @data.read(2) == CRLF
|
|
359
|
+
@state = :chunk_header
|
|
370
360
|
else
|
|
371
361
|
on_error "non-CRLF chunk footer"
|
|
372
|
-
|
|
362
|
+
@state = :invalid
|
|
373
363
|
end
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if
|
|
380
|
-
|
|
364
|
+
|
|
365
|
+
true
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def process_response_footer
|
|
369
|
+
return false if @data.size < 2
|
|
370
|
+
|
|
371
|
+
if @data.read(2) == CRLF
|
|
372
|
+
if @data.empty?
|
|
373
|
+
on_request_complete
|
|
374
|
+
@state = :finished
|
|
375
|
+
else
|
|
381
376
|
on_error "garbage at end of chunked response"
|
|
382
|
-
|
|
377
|
+
@state = :invalid
|
|
383
378
|
end
|
|
384
|
-
|
|
385
|
-
on_request_complete
|
|
386
|
-
return :finished
|
|
387
379
|
else
|
|
388
380
|
on_error "non-CRLF response footer"
|
|
389
|
-
|
|
381
|
+
@state = :invalid
|
|
390
382
|
end
|
|
383
|
+
|
|
384
|
+
false
|
|
391
385
|
end
|
|
392
386
|
|
|
393
|
-
def process_body
|
|
387
|
+
def process_body
|
|
394
388
|
# FIXME the proper thing to do here is probably to keep reading until
|
|
395
389
|
# the socket closes, then assume that's the end of the body, provided
|
|
396
390
|
# the server has specified Connection: close
|
|
397
391
|
if @bytes_remaining.nil?
|
|
398
392
|
on_error "no content length specified"
|
|
399
|
-
|
|
393
|
+
@state = :invalid
|
|
400
394
|
end
|
|
401
395
|
|
|
402
|
-
if data.size < @bytes_remaining
|
|
403
|
-
@bytes_remaining -= data.size
|
|
404
|
-
on_body_data data
|
|
405
|
-
return
|
|
396
|
+
if @data.size < @bytes_remaining
|
|
397
|
+
@bytes_remaining -= @data.size
|
|
398
|
+
on_body_data @data.read
|
|
399
|
+
return false
|
|
406
400
|
end
|
|
407
401
|
|
|
408
|
-
on_body_data data.
|
|
402
|
+
on_body_data @data.read(@bytes_remaining)
|
|
403
|
+
@bytes_remaining = 0
|
|
409
404
|
|
|
410
|
-
|
|
405
|
+
if @data.empty?
|
|
406
|
+
on_request_complete
|
|
407
|
+
@state = :finished
|
|
408
|
+
else
|
|
411
409
|
on_error "garbage at end of body"
|
|
412
|
-
|
|
410
|
+
@state = :invalid
|
|
413
411
|
end
|
|
414
412
|
|
|
415
|
-
|
|
416
|
-
return :finished
|
|
413
|
+
false
|
|
417
414
|
end
|
|
418
415
|
end
|
|
419
|
-
end
|
|
416
|
+
end
|
data/lib/rev/listener.rb
CHANGED
|
@@ -8,11 +8,20 @@ require 'socket'
|
|
|
8
8
|
require File.dirname(__FILE__) + '/../rev'
|
|
9
9
|
|
|
10
10
|
module Rev
|
|
11
|
+
# Listeners wait for incoming connections. When a listener receives a
|
|
12
|
+
# connection it fires the on_connection event with the newly accepted
|
|
13
|
+
# socket as a parameter.
|
|
11
14
|
class Listener < IOWatcher
|
|
12
15
|
def initialize(listen_socket)
|
|
13
16
|
@listen_socket = listen_socket
|
|
14
17
|
super(@listen_socket)
|
|
15
18
|
end
|
|
19
|
+
|
|
20
|
+
# Close the listener
|
|
21
|
+
def close
|
|
22
|
+
detach if attached?
|
|
23
|
+
@listen_socket.close
|
|
24
|
+
end
|
|
16
25
|
|
|
17
26
|
# Called whenever the server receives a new connection
|
|
18
27
|
def on_connection(socket); end
|
|
@@ -29,12 +38,20 @@ module Rev
|
|
|
29
38
|
end
|
|
30
39
|
|
|
31
40
|
class TCPListener < Listener
|
|
32
|
-
|
|
41
|
+
DEFAULT_BACKLOG = 1024
|
|
42
|
+
|
|
43
|
+
# Create a new Rev::TCPListener on the specified address and port.
|
|
44
|
+
# Accepts the following options:
|
|
33
45
|
#
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
# :backlog - Max size of the pending connection queue (default 1024)
|
|
47
|
+
# :reverse_lookup - Retain BasicSocket's reverse DNS functionality (default false)
|
|
48
|
+
#
|
|
49
|
+
def initialize(addr, port, options = {})
|
|
50
|
+
BasicSocket.do_not_reverse_lookup = true unless options[:reverse_lookup]
|
|
51
|
+
options[:backlog] ||= DEFAULT_BACKLOG
|
|
52
|
+
|
|
53
|
+
listen_socket = ::TCPServer.new(addr, port)
|
|
54
|
+
listen_socket.instance_eval { listen(options[:backlog]) }
|
|
38
55
|
super(listen_socket)
|
|
39
56
|
end
|
|
40
57
|
end
|
data/lib/rev/loop.rb
CHANGED
|
@@ -8,7 +8,20 @@ require File.dirname(__FILE__) + '/../rev'
|
|
|
8
8
|
|
|
9
9
|
module Rev
|
|
10
10
|
class Loop
|
|
11
|
+
@@default_loop = {}
|
|
11
12
|
attr_reader :watchers
|
|
13
|
+
|
|
14
|
+
# Retrieve the default event loop for the current thread
|
|
15
|
+
def self.default
|
|
16
|
+
# Well awesome, variables stashed in Thread.current[]
|
|
17
|
+
# are only accessible in the context of the Fiber where
|
|
18
|
+
# they were stored. Soo... we need to make our own
|
|
19
|
+
# thread-local store if we want Fiber compatibility
|
|
20
|
+
#
|
|
21
|
+
# I think this should be sufficient... but it may need
|
|
22
|
+
# a mutex or something, got me.
|
|
23
|
+
@@default_loop[Thread.current] ||= Loop.new
|
|
24
|
+
end
|
|
12
25
|
|
|
13
26
|
# Create a new Rev::Loop
|
|
14
27
|
#
|
data/lib/rev/server.rb
CHANGED
|
@@ -8,10 +8,13 @@ require File.dirname(__FILE__) + '/../rev'
|
|
|
8
8
|
|
|
9
9
|
module Rev
|
|
10
10
|
class Server < Listener
|
|
11
|
+
# Servers listen for incoming connections and create new connection objects
|
|
12
|
+
# whenever incoming connections are received. The default class for new
|
|
13
|
+
# connections is a Socket, but any subclass of IOWatcher is acceptable.
|
|
11
14
|
def initialize(listen_socket, klass = Socket, *args, &block)
|
|
12
15
|
# Ensure the provided class responds to attach
|
|
13
|
-
unless
|
|
14
|
-
raise ArgumentError, "provided class must
|
|
16
|
+
unless klass.allocate.is_a? IOWatcher
|
|
17
|
+
raise ArgumentError, "provided class must descend from IOWatcher"
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
# Verify the arity of the provided arguments
|
|
@@ -37,6 +40,8 @@ module Rev
|
|
|
37
40
|
end
|
|
38
41
|
end
|
|
39
42
|
|
|
43
|
+
# TCP server class. Listens on the specified host and port and creates
|
|
44
|
+
# new connection objects of the given class.
|
|
40
45
|
class TCPServer < Server
|
|
41
46
|
def initialize(host, port, klass = TCPSocket, *args, &block)
|
|
42
47
|
listen_socket = ::TCPServer.new(host, port)
|
|
@@ -45,9 +50,11 @@ module Rev
|
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
|
|
53
|
+
# UNIX server class. Listens on the specified UNIX domain socket and
|
|
54
|
+
# creates new connection objects of the given class.
|
|
48
55
|
class UNIXServer < Server
|
|
49
56
|
def initialize(path, klass = UNIXSocket, *args, &block)
|
|
50
57
|
super(::UNIXServer.new(*args), klass, *args, &block)
|
|
51
58
|
end
|
|
52
59
|
end
|
|
53
|
-
end
|
|
60
|
+
end
|
data/lib/rev/socket.rb
CHANGED
|
@@ -9,7 +9,7 @@ require 'resolv'
|
|
|
9
9
|
require File.dirname(__FILE__) + '/../rev'
|
|
10
10
|
|
|
11
11
|
module Rev
|
|
12
|
-
class Socket < BufferedIO
|
|
12
|
+
class Socket < BufferedIO
|
|
13
13
|
def self.connect(socket, *args)
|
|
14
14
|
new(socket, *args).instance_eval {
|
|
15
15
|
@connector = Connector.new(self, socket)
|
|
@@ -38,6 +38,10 @@ module Rev
|
|
|
38
38
|
def on_connect_failed; end
|
|
39
39
|
event_callback :on_connect_failed
|
|
40
40
|
|
|
41
|
+
# Called if a hostname failed to resolve when connecting
|
|
42
|
+
# Defaults to being aliased to on_connect_failed
|
|
43
|
+
alias_method :on_resolve_failed, :on_connect_failed
|
|
44
|
+
|
|
41
45
|
#########
|
|
42
46
|
protected
|
|
43
47
|
#########
|
|
@@ -76,6 +80,17 @@ module Rev
|
|
|
76
80
|
attr_reader :remote_host, :remote_addr, :remote_port, :address_family
|
|
77
81
|
watcher_delegate :@resolver
|
|
78
82
|
|
|
83
|
+
# Similar to .new, but used in cases where the resulting object is in a
|
|
84
|
+
# "half-open" state. This is primarily used for when asynchronous
|
|
85
|
+
# DNS resolution is taking place. We don't actually have a handle to
|
|
86
|
+
# the socket we want to use to create the watcher yet, since we don't
|
|
87
|
+
# know the IP address to connect to.
|
|
88
|
+
def self.precreate(*args, &block)
|
|
89
|
+
obj = allocate
|
|
90
|
+
obj.__send__(:preinitialize, *args, &block)
|
|
91
|
+
obj
|
|
92
|
+
end
|
|
93
|
+
|
|
79
94
|
# Perform a non-blocking connect to the given host and port
|
|
80
95
|
def self.connect(addr, port, *args)
|
|
81
96
|
family = nil
|
|
@@ -94,13 +109,17 @@ module Rev
|
|
|
94
109
|
return connect(host, port, *args)
|
|
95
110
|
end
|
|
96
111
|
|
|
97
|
-
|
|
98
|
-
@remote_host, @remote_addr, @remote_port = addr, addr, port
|
|
99
|
-
@resolver = TCPConnectResolver.new(self, addr, port, *args)
|
|
100
|
-
self
|
|
101
|
-
}
|
|
112
|
+
precreate(addr, port, *args)
|
|
102
113
|
end
|
|
103
114
|
|
|
115
|
+
# Called by precreate during asyncronous DNS resolution
|
|
116
|
+
def preinitialize(addr, port, *args)
|
|
117
|
+
@remote_host, @remote_addr, @remote_port = addr, addr, port
|
|
118
|
+
@resolver = TCPConnectResolver.new(self, addr, port, *args)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private :preinitialize
|
|
122
|
+
|
|
104
123
|
def initialize(socket)
|
|
105
124
|
unless socket.is_a?(::TCPSocket) or socket.is_a?(TCPConnectSocket)
|
|
106
125
|
raise TypeError, "socket must be a TCPSocket"
|
|
@@ -111,6 +130,10 @@ module Rev
|
|
|
111
130
|
@address_family, @remote_port, @remote_host, @remote_addr = socket.peeraddr
|
|
112
131
|
end
|
|
113
132
|
|
|
133
|
+
def peeraddr
|
|
134
|
+
[@address_family, @remote_port, @remote_host, @remote_addr]
|
|
135
|
+
end
|
|
136
|
+
|
|
114
137
|
#########
|
|
115
138
|
protected
|
|
116
139
|
#########
|
|
@@ -157,15 +180,13 @@ module Rev
|
|
|
157
180
|
end
|
|
158
181
|
|
|
159
182
|
def on_failure
|
|
160
|
-
@sock.
|
|
183
|
+
@sock.__send__(:on_resolve_failed)
|
|
161
184
|
@sock.instance_eval {
|
|
162
185
|
@resolver = nil
|
|
163
186
|
@failed = true
|
|
164
187
|
}
|
|
165
188
|
return
|
|
166
189
|
end
|
|
167
|
-
|
|
168
|
-
alias_method :on_timeout, :on_failure
|
|
169
190
|
end
|
|
170
191
|
end
|
|
171
192
|
|
data/lib/rev/watcher.rb
CHANGED