annotate net/http/server/requests.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/protocol'
ferencd@0 2
ferencd@0 3 module Net
ferencd@0 4 class HTTP < Protocol
ferencd@0 5 module Server
ferencd@0 6 module Requests
ferencd@0 7 # Default ports for common URI schemes
ferencd@0 8 DEFAULT_PORTS = {
ferencd@0 9 'https' => 443,
ferencd@0 10 'http' => 80
ferencd@0 11 }
ferencd@0 12
ferencd@0 13 protected
ferencd@0 14
ferencd@0 15 #
ferencd@0 16 # Reads a HTTP Request from the stream.
ferencd@0 17 #
ferencd@0 18 # @param [IO] stream
ferencd@0 19 # The stream to read from.
ferencd@0 20 #
ferencd@0 21 # @return [String, nil]
ferencd@0 22 # The raw HTTP Request or `nil` if the Request was malformed.
ferencd@0 23 #
ferencd@0 24 def read_request(stream)
ferencd@0 25 buffer = ''
ferencd@0 26
ferencd@0 27 begin
ferencd@0 28 request_line = stream.readline("\r\n")
ferencd@0 29 post_req = false
ferencd@0 30 if request_line.start_with? 'POST'
ferencd@0 31 post_req = true
ferencd@0 32 end
ferencd@0 33 # the request line must contain 'HTTP/'
ferencd@0 34 return unless request_line.include?('HTTP/')
ferencd@0 35
ferencd@0 36 buffer << request_line
ferencd@0 37
ferencd@0 38 stream.each_line("\r\n") do |header|
ferencd@0 39 buffer << header
ferencd@0 40 # a header line must contain a ':' character followed by
ferencd@0 41 # linear-white-space (either ' ' or "\t").
ferencd@0 42 unless (header.include?(': ') || header.include?(":\t"))
ferencd@0 43 # if this is not a header line, check if it is the end
ferencd@0 44 # of the request
ferencd@0 45 if header == "\r\n"
ferencd@0 46 if post_req
ferencd@0 47 # end of the request, what comes here is the possible POST data
ferencd@0 48 extra = ''
ferencd@0 49 begin
ferencd@0 50 extra = stream.read_nonblock(256)
ferencd@0 51 rescue
ferencd@0 52 extra = ''
ferencd@0 53 end
ferencd@0 54 buffer = buffer.strip
ferencd@0 55 buffer << "\r\nX-Extra: #{extra}"
ferencd@0 56 buffer += "\r\n\r\n"
ferencd@0 57 end
ferencd@0 58 break
ferencd@0 59 else
ferencd@0 60 # invalid header line
ferencd@0 61 return
ferencd@0 62 end
ferencd@0 63 end
ferencd@0 64 end
ferencd@0 65
ferencd@0 66 rescue IOError, SystemCallError
ferencd@0 67 return
ferencd@0 68 end
ferencd@0 69
ferencd@0 70 return buffer
ferencd@0 71
ferencd@0 72 end
ferencd@0 73
ferencd@0 74 #
ferencd@0 75 # Normalizes the `:uri` part of the request.
ferencd@0 76 #
ferencd@0 77 # @param [Hash] request
ferencd@0 78 # The unnormalized HTTP request.
ferencd@0 79 #
ferencd@0 80 def normalize_uri(request)
ferencd@0 81 uri = request[:uri]
ferencd@0 82
ferencd@0 83 case uri
ferencd@0 84 when Hash
ferencd@0 85 if uri[:scheme]
ferencd@0 86 uri[:port] = unless uri[:port]
ferencd@0 87 DEFAULT_PORTS[uri[:scheme]]
ferencd@0 88 else
ferencd@0 89 uri[:port].to_i
ferencd@0 90 end
ferencd@0 91 end
ferencd@0 92 when '*'
ferencd@0 93 request[:uri] = {}
ferencd@0 94 end
ferencd@0 95 end
ferencd@0 96
ferencd@0 97 #
ferencd@0 98 # Normalizes the `:headers` part of the request.
ferencd@0 99 #
ferencd@0 100 # @param [Hash] request
ferencd@0 101 # The unnormalized HTTP request.
ferencd@0 102 #
ferencd@0 103 def normalize_headers(request)
ferencd@0 104 headers = request[:headers]
ferencd@0 105 normalized_headers = {}
ferencd@0 106
ferencd@0 107 unless headers.empty?
ferencd@0 108 headers.each do |header|
ferencd@0 109 name = header[:name].to_s
ferencd@0 110 value = header[:value].to_s
ferencd@0 111
ferencd@0 112 if normalized_headers.has_key?(name)
ferencd@0 113 previous_value = normalized_headers[name]
ferencd@0 114
ferencd@0 115 if previous_value.kind_of?(Array)
ferencd@0 116 previous_value << value
ferencd@0 117 else
ferencd@0 118 normalized_headers[name] = [previous_value, value]
ferencd@0 119 end
ferencd@0 120 else
ferencd@0 121 normalized_headers[name] = value
ferencd@0 122 end
ferencd@0 123 end
ferencd@0 124 end
ferencd@0 125
ferencd@0 126 request[:headers] = normalized_headers
ferencd@0 127 end
ferencd@0 128
ferencd@0 129 #
ferencd@0 130 # Normalizes a HTTP request.
ferencd@0 131 #
ferencd@0 132 # @param [Hash] request
ferencd@0 133 # The unnormalized HTTP request.
ferencd@0 134 #
ferencd@0 135 def normalize_request(request)
ferencd@0 136 normalize_uri(request)
ferencd@0 137 normalize_headers(request)
ferencd@0 138 end
ferencd@0 139
ferencd@0 140 end
ferencd@0 141 end
ferencd@0 142 end
ferencd@0 143 end