annotate net/http/server/daemon.rb @ 0:1eef88068f9f tip

initial commit of maze game source
author ferencd
date Sun, 15 Sep 2019 11:46:47 +0200
parents
children
rev   line source
ferencd@0 1 require 'net/http/server/parser'
ferencd@0 2 require 'net/http/server/requests'
ferencd@0 3 require 'net/http/server/responses'
ferencd@0 4 require 'net/http/server/stream'
ferencd@0 5 require 'net/http/server/chunked_stream'
ferencd@0 6
ferencd@0 7 require 'net/protocol'
ferencd@0 8 require 'gserver'
ferencd@0 9
ferencd@0 10 module Net
ferencd@0 11 class HTTP < Protocol
ferencd@0 12 module Server
ferencd@0 13 class Daemon < GServer
ferencd@0 14
ferencd@0 15 include Requests
ferencd@0 16 include Responses
ferencd@0 17
ferencd@0 18 # Default host to bind to.
ferencd@0 19 DEFAULT_HOST = '0.0.0.0'
ferencd@0 20
ferencd@0 21 # Default port to listen on.
ferencd@0 22 DEFAULT_PORT = 8080
ferencd@0 23
ferencd@0 24 # Maximum number of simultaneous connections.
ferencd@0 25 MAX_CONNECTIONS = 256
ferencd@0 26
ferencd@0 27 # Creates a new HTTP Daemon.
ferencd@0 28 #
ferencd@0 29 # @param [Hash] options
ferencd@0 30 # Options for the daemon.
ferencd@0 31 #
ferencd@0 32 # @option options [String] :host (DEFAULT_HOST)
ferencd@0 33 # The host to run on.
ferencd@0 34 #
ferencd@0 35 # @option options [String] :port (DEFAULT_PORT)
ferencd@0 36 # The port to listen on.
ferencd@0 37 #
ferencd@0 38 # @option options [Integer] :max_connections (MAX_CONNECTIONS)
ferencd@0 39 # The maximum number of simultaneous connections.
ferencd@0 40 #
ferencd@0 41 # @option options [IO] :log ($stderr)
ferencd@0 42 # The log to write errors to.
ferencd@0 43 #
ferencd@0 44 # @option options [#call] :handler
ferencd@0 45 # The HTTP Request Handler object.
ferencd@0 46 #
ferencd@0 47 # @yield [request, socket]
ferencd@0 48 # If a block is given, it will be used to process HTTP Requests.
ferencd@0 49 #
ferencd@0 50 # @yieldparam [Hash{Symbol => String,Array,Hash}] request
ferencd@0 51 # The HTTP Request.
ferencd@0 52 #
ferencd@0 53 # @yieldparam [TCPSocket] socket
ferencd@0 54 # The TCP socket of the client.
ferencd@0 55 #
ferencd@0 56 def initialize(options={},&block)
ferencd@0 57 host = options.fetch(:host,DEFAULT_HOST)
ferencd@0 58 port = options.fetch(:port,DEFAULT_PORT).to_i
ferencd@0 59 max_connections = options.fetch(:max_connections,MAX_CONNECTIONS)
ferencd@0 60 log = options.fetch(:log,$stderr)
ferencd@0 61
ferencd@0 62 super(port,host,max_connections,log,false,true)
ferencd@0 63
ferencd@0 64 handler(options[:handler],&block)
ferencd@0 65 end
ferencd@0 66
ferencd@0 67 #
ferencd@0 68 # Sets the HTTP Request Handler.
ferencd@0 69 #
ferencd@0 70 # @param [#call, nil] object
ferencd@0 71 # The HTTP Request Handler object.
ferencd@0 72 #
ferencd@0 73 # @yield [request, stream]
ferencd@0 74 # If a block is given, it will be used to process HTTP Requests.
ferencd@0 75 #
ferencd@0 76 # @yieldparam [Hash{Symbol => String,Array,Hash}] request
ferencd@0 77 # The HTTP Request.
ferencd@0 78 #
ferencd@0 79 # @yieldparam [Stream, ChunkedStream] stream
ferencd@0 80 # The stream of the HTTP Request body.
ferencd@0 81 #
ferencd@0 82 # @raise [ArgumentError]
ferencd@0 83 # The HTTP Request Handler must respond to `#call`.
ferencd@0 84 #
ferencd@0 85 def handler(object=nil,&block)
ferencd@0 86 if object
ferencd@0 87 unless object.respond_to?(:call)
ferencd@0 88 raise(ArgumentError,"HTTP Request Handler must respond to #call")
ferencd@0 89 end
ferencd@0 90 elsif block.nil?
ferencd@0 91 raise(ArgumentError,"no HTTP Request Handler block given")
ferencd@0 92 end
ferencd@0 93
ferencd@0 94 @handler = (object || block)
ferencd@0 95 end
ferencd@0 96
ferencd@0 97 #
ferencd@0 98 # Receives HTTP Requests and handles them.
ferencd@0 99 #
ferencd@0 100 # @param [TCPSocket] socket
ferencd@0 101 # A new TCP connection.
ferencd@0 102 #
ferencd@0 103 def serve(socket)
ferencd@0 104 if (raw_request = read_request(socket))
ferencd@0 105 parser = Parser.new
ferencd@0 106
ferencd@0 107 begin
ferencd@0 108 request = parser.parse(raw_request)
ferencd@0 109 rescue Parslet::ParseFailed
ferencd@0 110 return Responses::BAD_REQUEST
ferencd@0 111 end
ferencd@0 112
ferencd@0 113 normalize_request(request)
ferencd@0 114
ferencd@0 115 stream = if request[:headers]['Transfer-Encoding'] == 'chunked'
ferencd@0 116 ChunkedStream.new(socket)
ferencd@0 117 else
ferencd@0 118 Stream.new(socket)
ferencd@0 119 end
ferencd@0 120
ferencd@0 121 # rack compliant
ferencd@0 122 status, headers, body = @handler.call(request,stream)
ferencd@0 123
ferencd@0 124 write_response(socket,status,headers,body)
ferencd@0 125 end
ferencd@0 126 end
ferencd@0 127
ferencd@0 128 end
ferencd@0 129 end
ferencd@0 130 end
ferencd@0 131 end