Mercurial > maze-src
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/net/http/server/daemon.rb Sun Sep 15 11:46:47 2019 +0200 @@ -0,0 +1,131 @@ +require 'net/http/server/parser' +require 'net/http/server/requests' +require 'net/http/server/responses' +require 'net/http/server/stream' +require 'net/http/server/chunked_stream' + +require 'net/protocol' +require 'gserver' + +module Net + class HTTP < Protocol + module Server + class Daemon < GServer + + include Requests + include Responses + + # Default host to bind to. + DEFAULT_HOST = '0.0.0.0' + + # Default port to listen on. + DEFAULT_PORT = 8080 + + # Maximum number of simultaneous connections. + MAX_CONNECTIONS = 256 + + # Creates a new HTTP Daemon. + # + # @param [Hash] options + # Options for the daemon. + # + # @option options [String] :host (DEFAULT_HOST) + # The host to run on. + # + # @option options [String] :port (DEFAULT_PORT) + # The port to listen on. + # + # @option options [Integer] :max_connections (MAX_CONNECTIONS) + # The maximum number of simultaneous connections. + # + # @option options [IO] :log ($stderr) + # The log to write errors to. + # + # @option options [#call] :handler + # The HTTP Request Handler object. + # + # @yield [request, socket] + # If a block is given, it will be used to process HTTP Requests. + # + # @yieldparam [Hash{Symbol => String,Array,Hash}] request + # The HTTP Request. + # + # @yieldparam [TCPSocket] socket + # The TCP socket of the client. + # + def initialize(options={},&block) + host = options.fetch(:host,DEFAULT_HOST) + port = options.fetch(:port,DEFAULT_PORT).to_i + max_connections = options.fetch(:max_connections,MAX_CONNECTIONS) + log = options.fetch(:log,$stderr) + + super(port,host,max_connections,log,false,true) + + handler(options[:handler],&block) + end + + # + # Sets the HTTP Request Handler. + # + # @param [#call, nil] object + # The HTTP Request Handler object. + # + # @yield [request, stream] + # If a block is given, it will be used to process HTTP Requests. + # + # @yieldparam [Hash{Symbol => String,Array,Hash}] request + # The HTTP Request. + # + # @yieldparam [Stream, ChunkedStream] stream + # The stream of the HTTP Request body. + # + # @raise [ArgumentError] + # The HTTP Request Handler must respond to `#call`. + # + def handler(object=nil,&block) + if object + unless object.respond_to?(:call) + raise(ArgumentError,"HTTP Request Handler must respond to #call") + end + elsif block.nil? + raise(ArgumentError,"no HTTP Request Handler block given") + end + + @handler = (object || block) + end + + # + # Receives HTTP Requests and handles them. + # + # @param [TCPSocket] socket + # A new TCP connection. + # + def serve(socket) + if (raw_request = read_request(socket)) + parser = Parser.new + + begin + request = parser.parse(raw_request) + rescue Parslet::ParseFailed + return Responses::BAD_REQUEST + end + + normalize_request(request) + + stream = if request[:headers]['Transfer-Encoding'] == 'chunked' + ChunkedStream.new(socket) + else + Stream.new(socket) + end + + # rack compliant + status, headers, body = @handler.call(request,stream) + + write_response(socket,status,headers,body) + end + end + + end + end + end +end
