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