iodine 0.0.1 → 0.0.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.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +86 -8
- data/lib/iodine.rb +45 -2
- data/lib/iodine/core.rb +9 -37
- data/lib/iodine/http.rb +135 -0
- data/lib/iodine/http/hpack.rb +543 -0
- data/lib/iodine/http/http1.rb +217 -0
- data/lib/iodine/http/http2.rb +465 -0
- data/lib/iodine/http/rack_support.rb +105 -0
- data/lib/iodine/http/request.rb +413 -0
- data/lib/iodine/http/response.rb +355 -0
- data/lib/iodine/http/session.rb +110 -0
- data/lib/iodine/http/websocket_client.rb +224 -0
- data/lib/iodine/http/websocket_handler.rb +40 -0
- data/lib/iodine/http/websockets.rb +319 -0
- data/lib/iodine/io.rb +71 -28
- data/lib/iodine/protocol.rb +74 -25
- data/lib/iodine/settings.rb +44 -3
- data/lib/iodine/ssl_connector.rb +47 -0
- data/lib/iodine/timers.rb +5 -21
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +3 -0
- data/{bin/http_test → manual tests/core_http_test } +6 -2
- data/bin/echo b/data/manual → tests/echo +0 -0
- data/bin/em playground b/data/manual tests/em → playground +0 -0
- data/manual tests/hello_world +56 -0
- metadata +20 -6
- data/lib/iodine/ssl_protocol.rb +0 -108
    
        data/lib/iodine/timers.rb
    CHANGED
    
    | @@ -24,7 +24,7 @@ module Iodine | |
| 24 24 | 
             
            		end
         | 
| 25 25 |  | 
| 26 26 | 
             
            		# stops a timed event.
         | 
| 27 | 
            -
            		# @return [ | 
| 27 | 
            +
            		# @return [Iodine::TimedEvent] returns the TimedEvent object.
         | 
| 28 28 | 
             
            		def stop!
         | 
| 29 29 | 
             
            			@repeat_limit = 0
         | 
| 30 30 | 
             
            			self
         | 
| @@ -38,7 +38,7 @@ module Iodine | |
| 38 38 | 
             
            			return false unless @next <= Iodine.time
         | 
| 39 39 | 
             
            			return true if @repeat_limit == 0
         | 
| 40 40 | 
             
            			@repeat_limit -= 1 if @repeat_limit.to_i > 0
         | 
| 41 | 
            -
            			Iodine. | 
| 41 | 
            +
            			Iodine.run *@args, &@job
         | 
| 42 42 | 
             
            			@next = Iodine.time + @interval
         | 
| 43 43 | 
             
            			@repeat_limit == 0
         | 
| 44 44 | 
             
            		end
         | 
| @@ -59,28 +59,11 @@ module Iodine | |
| 59 59 | 
             
            	#
         | 
| 60 60 | 
             
            	# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent).
         | 
| 61 61 | 
             
            	#
         | 
| 62 | 
            -
            	# @return [ | 
| 62 | 
            +
            	# @return [Iodine::TimedEvent] returns the new TimedEvent object.
         | 
| 63 63 | 
             
            	def run_after seconds, *args, &block
         | 
| 64 64 | 
             
            		timed_job seconds, 1, args, block
         | 
| 65 65 | 
             
            	end
         | 
| 66 66 |  | 
| 67 | 
            -
            	# pushes a timed event to the timers's stack
         | 
| 68 | 
            -
            	#
         | 
| 69 | 
            -
            	# accepts:
         | 
| 70 | 
            -
            	# time:: the time at which the job should be executed.
         | 
| 71 | 
            -
            	# *arg:: any arguments that will be passed to the handler's `call` method.
         | 
| 72 | 
            -
            	# &block:: the block to execute.
         | 
| 73 | 
            -
            	#
         | 
| 74 | 
            -
            	# A block is required.
         | 
| 75 | 
            -
            	#
         | 
| 76 | 
            -
            	# On top of the arguments passed to the `run_after` method, the timer object will be passed as the last agrument to the receiving block.
         | 
| 77 | 
            -
            	#
         | 
| 78 | 
            -
            	# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent).
         | 
| 79 | 
            -
            	#
         | 
| 80 | 
            -
            	# @return [GReactor::TimedEvent] returns the new TimedEvent object.
         | 
| 81 | 
            -
            	def run_at run_time, *args, &block
         | 
| 82 | 
            -
            		timed_job( (@time - run_time), 1, args, block)
         | 
| 83 | 
            -
            	end
         | 
| 84 67 | 
             
            	# pushes a repeated timed event to the timers's stack
         | 
| 85 68 | 
             
            	#
         | 
| 86 69 | 
             
            	# accepts:
         | 
| @@ -95,7 +78,7 @@ module Iodine | |
| 95 78 | 
             
            	#
         | 
| 96 79 | 
             
            	# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent unless you save and reload them yourself).
         | 
| 97 80 | 
             
            	#
         | 
| 98 | 
            -
            	# @return [ | 
| 81 | 
            +
            	# @return [Iodine::TimedEvent] returns the new TimedEvent object.
         | 
| 99 82 | 
             
            	def run_every seconds, limit = -1, *args, &block
         | 
| 100 83 | 
             
            		timed_job seconds, limit, args, block
         | 
| 101 84 | 
             
            	end
         | 
| @@ -112,5 +95,6 @@ module Iodine | |
| 112 95 | 
             
            	@check_timers = Proc.new do
         | 
| 113 96 | 
             
            		@timer_locker.synchronize { @timers.delete_if {|t| t.done? } }
         | 
| 114 97 | 
             
            	end
         | 
| 98 | 
            +
            	@check_timers = [@check_timers]
         | 
| 115 99 |  | 
| 116 100 | 
             
            end
         | 
    
        data/lib/iodine/version.rb
    CHANGED
    
    
| @@ -14,7 +14,7 @@ require 'stringio' | |
| 14 14 |  | 
| 15 15 |  | 
| 16 16 |  | 
| 17 | 
            -
            class MiniServer < Iodine:: | 
| 17 | 
            +
            class MiniServer < Iodine::Protocol
         | 
| 18 18 | 
             
            	def on_open
         | 
| 19 19 | 
             
            		@headers = {}
         | 
| 20 20 | 
             
            		set_timeout 1
         | 
| @@ -46,4 +46,8 @@ class MiniServer < Iodine::SSLProtocol | |
| 46 46 |  | 
| 47 47 | 
             
            end
         | 
| 48 48 |  | 
| 49 | 
            -
            Iodine. | 
| 49 | 
            +
            Iodine.threads = 1
         | 
| 50 | 
            +
            # Iodine.ssl = 1
         | 
| 51 | 
            +
            Iodine.protocol = MiniServer
         | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'pathname'
         | 
| 4 | 
            +
            Root ||= Pathname.new(File.dirname(__FILE__)).expand_path
         | 
| 5 | 
            +
            Dir.chdir Root.join('..').to_s
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require "bundler/setup"
         | 
| 8 | 
            +
            require "iodine/http"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            # Iodine.ssl = true
         | 
| 11 | 
            +
            # Iodine.treads = 8
         | 
| 12 | 
            +
            # Iodine.protocol.on_http do |req, res|
         | 
| 13 | 
            +
            # 	res.session[:count] ||= 0
         | 
| 14 | 
            +
            # 	res.session[:count] += 1
         | 
| 15 | 
            +
            # 	res << "Visits: #{res.session[:count]}\n\nRequest object:\n\n#{req.to_s}"
         | 
| 16 | 
            +
            # end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # Iodine.processes = 4
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            Iodine.protocol.on_http { "Hello World!" }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
            class WSChatServer
         | 
| 24 | 
            +
            	def initialize nickname
         | 
| 25 | 
            +
            		@nickname = nickname || "unknown"
         | 
| 26 | 
            +
            	end
         | 
| 27 | 
            +
            	def on_open protocol
         | 
| 28 | 
            +
            		@io = protocol
         | 
| 29 | 
            +
            		@io.broadcast "#{@nickname} has joined the chat!"
         | 
| 30 | 
            +
            		@io << "Welcome #{@nickname}, you have joined the chat!"
         | 
| 31 | 
            +
            	end
         | 
| 32 | 
            +
            	def on_message data
         | 
| 33 | 
            +
            		@io.broadcast "#{@nickname} >> #{data}"
         | 
| 34 | 
            +
            		@io << ">> #{data}"
         | 
| 35 | 
            +
            	end
         | 
| 36 | 
            +
            	def on_broadcast data
         | 
| 37 | 
            +
            		@io << data
         | 
| 38 | 
            +
            	end
         | 
| 39 | 
            +
            	def on_close
         | 
| 40 | 
            +
            		@io.broadcast "#{@nickname} has left the chat!"
         | 
| 41 | 
            +
            	end
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            Iodine::Http.on_websocket { |request, response| WSChatServer.new request.params[:name]}
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            Process.fork do
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            	Iodine.ssl = true
         | 
| 49 | 
            +
            	Iodine.port = 3030
         | 
| 50 | 
            +
            	Iodine.protocol.on_http do |req, res|
         | 
| 51 | 
            +
            		res.session[:count] ||= 0
         | 
| 52 | 
            +
            		res.session[:count] += 1
         | 
| 53 | 
            +
            		res << "Visits: #{res.session[:count]}\n\nRequest object:\n\n#{req.to_s}"
         | 
| 54 | 
            +
            	end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: iodine
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Boaz Segev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-10- | 
| 11 | 
            +
            date: 2015-10-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -66,20 +66,33 @@ files: | |
| 66 66 | 
             
            - README.md
         | 
| 67 67 | 
             
            - Rakefile
         | 
| 68 68 | 
             
            - bin/console
         | 
| 69 | 
            -
            - bin/echo
         | 
| 70 | 
            -
            - bin/em playground
         | 
| 71 | 
            -
            - bin/http_test
         | 
| 72 69 | 
             
            - bin/setup
         | 
| 73 70 | 
             
            - iodine.gemspec
         | 
| 74 71 | 
             
            - lib/iodine.rb
         | 
| 75 72 | 
             
            - lib/iodine/core.rb
         | 
| 73 | 
            +
            - lib/iodine/http.rb
         | 
| 74 | 
            +
            - lib/iodine/http/hpack.rb
         | 
| 75 | 
            +
            - lib/iodine/http/http1.rb
         | 
| 76 | 
            +
            - lib/iodine/http/http2.rb
         | 
| 77 | 
            +
            - lib/iodine/http/rack_support.rb
         | 
| 78 | 
            +
            - lib/iodine/http/request.rb
         | 
| 79 | 
            +
            - lib/iodine/http/response.rb
         | 
| 80 | 
            +
            - lib/iodine/http/session.rb
         | 
| 81 | 
            +
            - lib/iodine/http/websocket_client.rb
         | 
| 82 | 
            +
            - lib/iodine/http/websocket_handler.rb
         | 
| 83 | 
            +
            - lib/iodine/http/websockets.rb
         | 
| 76 84 | 
             
            - lib/iodine/io.rb
         | 
| 77 85 | 
             
            - lib/iodine/logging.rb
         | 
| 78 86 | 
             
            - lib/iodine/protocol.rb
         | 
| 79 87 | 
             
            - lib/iodine/settings.rb
         | 
| 80 | 
            -
            - lib/iodine/ | 
| 88 | 
            +
            - lib/iodine/ssl_connector.rb
         | 
| 81 89 | 
             
            - lib/iodine/timers.rb
         | 
| 82 90 | 
             
            - lib/iodine/version.rb
         | 
| 91 | 
            +
            - lib/rack/handler/iodine.rb
         | 
| 92 | 
            +
            - manual tests/core_http_test
         | 
| 93 | 
            +
            - manual tests/echo
         | 
| 94 | 
            +
            - manual tests/em playground
         | 
| 95 | 
            +
            - manual tests/hello_world
         | 
| 83 96 | 
             
            homepage: https://github.com/boazsegev/iodine
         | 
| 84 97 | 
             
            licenses:
         | 
| 85 98 | 
             
            - MIT
         | 
| @@ -106,3 +119,4 @@ signing_key: | |
| 106 119 | 
             
            specification_version: 4
         | 
| 107 120 | 
             
            summary: IOdine makes writing evented server applications easy to write.
         | 
| 108 121 | 
             
            test_files: []
         | 
| 122 | 
            +
            has_rdoc: 
         | 
    
        data/lib/iodine/ssl_protocol.rb
    DELETED
    
    | @@ -1,108 +0,0 @@ | |
| 1 | 
            -
            module Iodine
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            	# This class inherits from Protocol, but it includes some adjustments related to SSL connection handling.
         | 
| 4 | 
            -
            	class SSLProtocol < Protocol
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            		# This is a mini-protocol used only to implement the SSL Handshake in a non-blocking manner,
         | 
| 7 | 
            -
            		# allowing for a hardcoded timeout (which you can monkey patch) of 3 seconds.
         | 
| 8 | 
            -
            		class SSLWait < Protocol
         | 
| 9 | 
            -
            			TIMEOUT = 3 # hardcoded SSL/TLS handshake timeout
         | 
| 10 | 
            -
            			def on_open
         | 
| 11 | 
            -
            				timeout = TIMEOUT
         | 
| 12 | 
            -
            				@ssl_socket = OpenSSL::SSL::SSLSocket.new(@io, Iodine.ssl_context)
         | 
| 13 | 
            -
            				@ssl_socket.sync_close = true
         | 
| 14 | 
            -
            			end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            			# atempt an SSL Handshale
         | 
| 17 | 
            -
            			def call
         | 
| 18 | 
            -
            				return if @locker.locked?
         | 
| 19 | 
            -
            				return unless @locker.try_lock
         | 
| 20 | 
            -
            				begin
         | 
| 21 | 
            -
            					@ssl_socket.accept_nonblock
         | 
| 22 | 
            -
            					@locker.unlock
         | 
| 23 | 
            -
            				rescue IO::WaitReadable, IO::WaitWritable
         | 
| 24 | 
            -
            					@locker.unlock
         | 
| 25 | 
            -
            					return
         | 
| 26 | 
            -
            				rescue OpenSSL::SSL::SSLError
         | 
| 27 | 
            -
            					@e = Exception.new "Self-signed Certificate?".freeze
         | 
| 28 | 
            -
            					@locker.unlock
         | 
| 29 | 
            -
            					return
         | 
| 30 | 
            -
            				rescue => e
         | 
| 31 | 
            -
            					Iodine.warn "SSL Handshake failed with: #{e.message}".freeze
         | 
| 32 | 
            -
            					@e = e
         | 
| 33 | 
            -
            					close
         | 
| 34 | 
            -
            					@locker.unlock
         | 
| 35 | 
            -
            					return
         | 
| 36 | 
            -
            				end
         | 
| 37 | 
            -
            				Iodine.protocol.new @ssl_socket
         | 
| 38 | 
            -
            			end
         | 
| 39 | 
            -
            			def on_close
         | 
| 40 | 
            -
            				# inform
         | 
| 41 | 
            -
            				Iodine.warn "SSL Handshake #{@e ? "failed with: #{@e.message} (#{@e.class.name})" : 'timed-out.'}".freeze
         | 
| 42 | 
            -
            				# the core @io is already closed, but let's make sure the SSL object is closed as well.
         | 
| 43 | 
            -
            				@ssl_socket.close unless @ssl_socket.closed?
         | 
| 44 | 
            -
            			end
         | 
| 45 | 
            -
            		end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
            		attr_reader :ssl_socket
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
            		# reads from the IO up to the specified number of bytes (defaults to ~1Mb).
         | 
| 53 | 
            -
            		def read size = 1048576
         | 
| 54 | 
            -
            			@send_locker.synchronize do
         | 
| 55 | 
            -
            				data = ''
         | 
| 56 | 
            -
            				begin
         | 
| 57 | 
            -
            					 (data << @ssl_socket.read_nonblock(size).to_s) until data.bytesize >= size
         | 
| 58 | 
            -
            				rescue OpenSSL::SSL::SSLErrorWaitReadable, IO::WaitReadable, IO::WaitWritable
         | 
| 59 | 
            -
             | 
| 60 | 
            -
            				rescue IOError
         | 
| 61 | 
            -
            					close
         | 
| 62 | 
            -
            				rescue => e
         | 
| 63 | 
            -
            					Iodine.warn "SSL Protocol read error: #{e.class.name} #{e.message} (closing connection)"
         | 
| 64 | 
            -
            					close
         | 
| 65 | 
            -
            				end
         | 
| 66 | 
            -
            				return false if data.to_s.empty?
         | 
| 67 | 
            -
            				touch
         | 
| 68 | 
            -
            				data
         | 
| 69 | 
            -
            			end
         | 
| 70 | 
            -
            		end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
            		def write data
         | 
| 73 | 
            -
            			begin
         | 
| 74 | 
            -
            				@send_locker.synchronize do
         | 
| 75 | 
            -
            					r = @ssl_socket.write data
         | 
| 76 | 
            -
            					touch
         | 
| 77 | 
            -
            					r
         | 
| 78 | 
            -
            				end				
         | 
| 79 | 
            -
            			rescue => e
         | 
| 80 | 
            -
            				close
         | 
| 81 | 
            -
            				false
         | 
| 82 | 
            -
            			end
         | 
| 83 | 
            -
            		end
         | 
| 84 | 
            -
            		alias :send :write
         | 
| 85 | 
            -
            		alias :<< :write
         | 
| 86 | 
            -
             | 
| 87 | 
            -
            		def on_close
         | 
| 88 | 
            -
            			@ssl_socket.close unless @ssl_socket.closed?
         | 
| 89 | 
            -
            			super
         | 
| 90 | 
            -
            		end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
            		# This method initializes the SSL Protocol
         | 
| 97 | 
            -
            		def initialize ssl_socket
         | 
| 98 | 
            -
            			@ssl_socket = ssl_socket
         | 
| 99 | 
            -
            			super(ssl_socket.io)
         | 
| 100 | 
            -
            		end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
            		def self.accept io
         | 
| 103 | 
            -
            			SSLWait.new(io)
         | 
| 104 | 
            -
            		end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
            	end
         | 
| 108 | 
            -
            end
         |