class Midori::Request

Request class for midori @attr [String] ip client ip address @attr [Integer] port client port @attr [String] ip parsed ip address @attr [String] protocol protocol version of HTTP request @attr [Symbol] method HTTP method @attr [String] path request path @attr [Hash] query_params parameter parsed from query string @attr [String | nil] query_string request query string @attr [HTTPHeader] header request header @attr [String] body request body @attr [Hash] cookie cookie hash coming from request @attr [Boolean] parsed whether the request header parsed @attr [Boolean] body_parsed whether the request body parsed @attr [Hash] params params in the url

Attributes

body[RW]
body_parsed[RW]
header[RW]
ip[RW]
method[RW]
params[RW]
parsed[RW]
path[RW]
port[RW]
protocol[RW]
query_params[RW]
query_string[RW]
remote_ip[RW]

Public Class Methods

new() click to toggle source

Init Request

# File lib/midori/request.rb, line 23
def initialize
  @header = HTTPHeader.new
  @parsed = false
  @body_parsed = false
  @is_websocket = false
  @is_eventsource = false
  @ip = ''
  @port = 0
  @parser = Mizu::Parser.new
  @params = {}
  @query_params = Hash.new(Array.new)
  @cookie = {}
  @body = ''
  @parser.on_complete do
    @protocol = @parser.version
    @method = @parser.method
    @path = @parser.path
    # Turn header into case-insensitive due to RFC 2.6 Chapter 4.2
    # https://www.ietf.org/rfc/rfc2616.txt
    @parser.headers.each { |key, value| @header[key] = value }
    @remote_ip = parse_ip || @ip # Detect client real IP with RFC 7239

    @query_string = @path.match(/\?(.*?)$/)
    unless @query_string.nil?
      @query_string = @query_string[1]
      @query_params = CGI::parse(@query_string)
    end

    @cookie = CGI::Cookie.parse(@header['Cookie']) unless @header['Cookie'].nil?
    @path.gsub!(/\?(.*?)$/, '')
    @method = @method.to_sym
    @parsed = true
  end
end

Public Instance Methods

body_parsed?() click to toggle source

Syntactic sugar for whether a request body is parsed @return [Boolean] parsed or not

# File lib/midori/request.rb, line 137
def body_parsed?
  @body_parsed
end
eventsource?() click to toggle source

Syntactic sugar for whether a request is an eventsource request @return [Boolean] eventsource or not

# File lib/midori/request.rb, line 149
def eventsource?
  @is_eventsource
end
parse(data) click to toggle source

Init an request with String data @param [String] data @return [nil] nil

# File lib/midori/request.rb, line 74
def parse(data)
  # Call parser if header not parsed
  if @parsed
    @body += data
  else
    return nil if data.nil?
    @parser << data
    @body += data[@parser.offset..-1] if @parsed
  end

  # Set body parsed if body reaches content length
  if @parsed && (@header['Content-Length'].to_i || 0) <= @body.bytesize
    @body_parsed = true
    pre_proceed
  end
  nil
end
parse_ip() click to toggle source

Get the real user IP from headers @return [String | nil] nil when not available, otherwise, return the real IP Modified from Rack

# File lib/midori/request.rb, line 95
def parse_ip
  # Do not parse anything if not behind proxy
  return nil unless Midori::Configure.proxy
  return @header['X-Real-IP'] if Midori::Configure.trust_real_ip
  # Not enough infomation
  return nil if @header['X-Forwarded-For'].nil?
  forwarded_ips = @header['X-Forwarded-For'].split(', ')
  # Spoofing check
  trusted = forwarded_ips.reject do |ip|
    ip =~ Midori::Configure.trusted_proxies
  end
  trusted.last
end
parsed?() click to toggle source

Syntactic sugar for whether a request header is parsed @return [Boolean] parsed or not

# File lib/midori/request.rb, line 131
def parsed?
  @parsed
end
pre_proceed() click to toggle source

Preproceed the request after parsed @return [nil] nil

# File lib/midori/request.rb, line 111
def pre_proceed
  # Deal with WebSocket
  upgrade = @header['Connection']&.split(', ')&.include?('Upgrade')
  if upgrade && @header['Upgrade'] == 'websocket'
    @method = :WEBSOCKET
    @is_websocket = true
  end

  # Deal with EventSource
  if @header['Accept'] == 'text/event-stream'
    @method = :EVENTSOURCE
    @is_eventsource = true
  end

  @method = @method.to_sym
  nil
end
reset!() click to toggle source
# File lib/midori/request.rb, line 58
def reset!
  @header = HTTPHeader.new
  @parsed = false
  @body_parsed = false
  @is_websocket = false
  @is_eventsource = false
  @parser.reset!
  @params = {}
  @query_params = Hash.new(Array.new)
  @cookie = {}
  @body = ''
end
websocket?() click to toggle source

Syntactic sugar for whether a request is a websocket request @return [Boolean] websocket or not

# File lib/midori/request.rb, line 143
def websocket?
  @is_websocket
end