Mercurial > maze-src
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/net/http/server/responses.rb Sun Sep 15 11:46:47 2019 +0200 @@ -0,0 +1,182 @@ +require 'net/http/server/chunked_stream' + +require 'net/protocol' +require 'time' + +module Net + class HTTP < Protocol + module Server + module Responses + # The supported HTTP Protocol. + HTTP_VERSION = '1.1' + + # The known HTTP Status codes and messages + HTTP_STATUSES = { + # 1xx + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + # 2xx + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + # 3xx + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + # 4xx + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Time-out', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Large', + 415 => 'Unsupported Media Type', + 416 => 'Requested range not satisfiable', + 417 => 'Expectation Failed', + # 5xx + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Time-out', + 505 => 'HTTP Version not supported extension-code' + } + + # Generic Bad Request response + BAD_REQUEST = [400, {}, ['Bad Request']] + + protected + + # + # Writes the status of an HTTP Response to a stream. + # + # @param [IO] stream + # The stream to write the headers back to. + # + # @param [Integer] status + # The status of the HTTP Response. + # + def write_status(stream,status) + status = status.to_i + + reason = HTTP_STATUSES[status] + stream.write("HTTP/#{HTTP_VERSION} #{status} #{reason}\r\n") + end + + # + # Write the headers of an HTTP Response to a stream. + # + # @param [IO] stream + # The stream to write the headers back to. + # + # @param [Hash{String => String,Time,Array<String>}] headers + # The headers of the HTTP Response. + # + def write_headers(stream,headers) + headers.each do |name,values| + case values + when String + values.each_line("\n") do |value| + stream.write("#{name}: #{value.chomp}\r\n") + end + when Time + stream.write("#{name}: #{values.httpdate}\r\n") + when Array + values.each do |value| + stream.write("#{name}: #{value}\r\n") + end + end + end + + stream.write("\r\n") + stream.flush + end + + # + # Writes the body of a HTTP Response to a stream. + # + # @param [IO] stream + # The stream to write the headers back to. + # + # @param [#each] body + # The body of the HTTP Response. + # + def write_body(stream,body) + body.each do |chunk| + stream.write(chunk) + stream.flush + end + end + + # + # Writes the body of a HTTP Response to a stream, using Chunked + # Transfer-Encoding. + # + # @param [IO] stream + # The stream to write the headers back to. + # + # @param [#each] body + # The body of the HTTP Response. + # + # @since 0.2.0 + # + def write_body_streamed(stream,body) + chunked_stream = ChunkedStream.new(stream) + + body.each { |chunk| chunked_stream.write(chunk) } + + chunked_stream.close + end + + # + # Writes a HTTP Response to a stream. + # + # @param [IO] stream + # The stream to write the HTTP Response to. + # + # @param [Integer] status + # The status of the HTTP Response. + # + # @param [Hash{String => String,Time,Array<String>}] headers + # The headers of the HTTP Response. + # + # @param [#each] body + # The body of the HTTP Response. + # + def write_response(stream,status,headers,body) + write_status stream, status + write_headers stream, headers + + if headers['Transfer-Encoding'] == 'chunked' + write_body_streamed stream, body + else + write_body stream, body + + # if neither `Content-Length` or `Transfer-Encoding` + # were specified, close the stream after writing the response. + stream.close unless headers['Content-Length'] + end + end + + end + end + end +end
