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