comparison net/http/server/responses.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/chunked_stream'
2
3 require 'net/protocol'
4 require 'time'
5
6 module Net
7 class HTTP < Protocol
8 module Server
9 module Responses
10 # The supported HTTP Protocol.
11 HTTP_VERSION = '1.1'
12
13 # The known HTTP Status codes and messages
14 HTTP_STATUSES = {
15 # 1xx
16 100 => 'Continue',
17 101 => 'Switching Protocols',
18 102 => 'Processing',
19 # 2xx
20 200 => 'OK',
21 201 => 'Created',
22 202 => 'Accepted',
23 203 => 'Non-Authoritative Information',
24 204 => 'No Content',
25 205 => 'Reset Content',
26 206 => 'Partial Content',
27 # 3xx
28 300 => 'Multiple Choices',
29 301 => 'Moved Permanently',
30 302 => 'Found',
31 303 => 'See Other',
32 304 => 'Not Modified',
33 305 => 'Use Proxy',
34 307 => 'Temporary Redirect',
35 # 4xx
36 400 => 'Bad Request',
37 401 => 'Unauthorized',
38 402 => 'Payment Required',
39 403 => 'Forbidden',
40 404 => 'Not Found',
41 405 => 'Method Not Allowed',
42 406 => 'Not Acceptable',
43 407 => 'Proxy Authentication Required',
44 408 => 'Request Time-out',
45 409 => 'Conflict',
46 410 => 'Gone',
47 411 => 'Length Required',
48 412 => 'Precondition Failed',
49 413 => 'Request Entity Too Large',
50 414 => 'Request-URI Too Large',
51 415 => 'Unsupported Media Type',
52 416 => 'Requested range not satisfiable',
53 417 => 'Expectation Failed',
54 # 5xx
55 500 => 'Internal Server Error',
56 501 => 'Not Implemented',
57 502 => 'Bad Gateway',
58 503 => 'Service Unavailable',
59 504 => 'Gateway Time-out',
60 505 => 'HTTP Version not supported extension-code'
61 }
62
63 # Generic Bad Request response
64 BAD_REQUEST = [400, {}, ['Bad Request']]
65
66 protected
67
68 #
69 # Writes the status of an HTTP Response to a stream.
70 #
71 # @param [IO] stream
72 # The stream to write the headers back to.
73 #
74 # @param [Integer] status
75 # The status of the HTTP Response.
76 #
77 def write_status(stream,status)
78 status = status.to_i
79
80 reason = HTTP_STATUSES[status]
81 stream.write("HTTP/#{HTTP_VERSION} #{status} #{reason}\r\n")
82 end
83
84 #
85 # Write the headers of an HTTP Response to a stream.
86 #
87 # @param [IO] stream
88 # The stream to write the headers back to.
89 #
90 # @param [Hash{String => String,Time,Array<String>}] headers
91 # The headers of the HTTP Response.
92 #
93 def write_headers(stream,headers)
94 headers.each do |name,values|
95 case values
96 when String
97 values.each_line("\n") do |value|
98 stream.write("#{name}: #{value.chomp}\r\n")
99 end
100 when Time
101 stream.write("#{name}: #{values.httpdate}\r\n")
102 when Array
103 values.each do |value|
104 stream.write("#{name}: #{value}\r\n")
105 end
106 end
107 end
108
109 stream.write("\r\n")
110 stream.flush
111 end
112
113 #
114 # Writes the body of a HTTP Response to a stream.
115 #
116 # @param [IO] stream
117 # The stream to write the headers back to.
118 #
119 # @param [#each] body
120 # The body of the HTTP Response.
121 #
122 def write_body(stream,body)
123 body.each do |chunk|
124 stream.write(chunk)
125 stream.flush
126 end
127 end
128
129 #
130 # Writes the body of a HTTP Response to a stream, using Chunked
131 # Transfer-Encoding.
132 #
133 # @param [IO] stream
134 # The stream to write the headers back to.
135 #
136 # @param [#each] body
137 # The body of the HTTP Response.
138 #
139 # @since 0.2.0
140 #
141 def write_body_streamed(stream,body)
142 chunked_stream = ChunkedStream.new(stream)
143
144 body.each { |chunk| chunked_stream.write(chunk) }
145
146 chunked_stream.close
147 end
148
149 #
150 # Writes a HTTP Response to a stream.
151 #
152 # @param [IO] stream
153 # The stream to write the HTTP Response to.
154 #
155 # @param [Integer] status
156 # The status of the HTTP Response.
157 #
158 # @param [Hash{String => String,Time,Array<String>}] headers
159 # The headers of the HTTP Response.
160 #
161 # @param [#each] body
162 # The body of the HTTP Response.
163 #
164 def write_response(stream,status,headers,body)
165 write_status stream, status
166 write_headers stream, headers
167
168 if headers['Transfer-Encoding'] == 'chunked'
169 write_body_streamed stream, body
170 else
171 write_body stream, body
172
173 # if neither `Content-Length` or `Transfer-Encoding`
174 # were specified, close the stream after writing the response.
175 stream.close unless headers['Content-Length']
176 end
177 end
178
179 end
180 end
181 end
182 end