Class: Rack::Proxy

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/proxy.rb

Overview

Subclass and bring your own #rewrite_request and #rewrite_response

Constant Summary collapse

VERSION =
"0.8.2".freeze
HOP_BY_HOP_HEADERS =
{
  'connection' => true,
  'keep-alive' => true,
  'proxy-authenticate' => true,
  'proxy-authorization' => true,
  'te' => true,
  'trailer' => true,
  'transfer-encoding' => true,
  'upgrade' => true
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app = nil, opts = {}) ⇒ Proxy

Returns a new instance of Proxy.

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :backend (String, URI::HTTP)

    Backend host to proxy requests to



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rack/proxy.rb', line 65

def initialize(app = nil, opts= {})
  if app.is_a?(Hash)
    opts = app
    @app = nil
  else
    @app = app
  end

  @streaming = opts.fetch(:streaming, true)
  @backend = opts[:backend] ? URI(opts[:backend]) : nil
  @read_timeout = opts.fetch(:read_timeout, 60)
  @ssl_version = opts[:ssl_version]
  @cert = opts[:cert]
  @key = opts[:key]
  # SSL verification: defaults to VERIFY_PEER (Ruby's Net::HTTP default).
  # Pass ssl_verify_none: true to explicitly disable cert verification, or
  # pass verify_mode: <OpenSSL::SSL::VERIFY_*> for full control.
  @verify_mode = opts[:verify_mode]
  @verify_mode ||= OpenSSL::SSL::VERIFY_NONE if opts[:ssl_verify_none]

  @username = opts[:username]
  @password = opts[:password]

  # Optional logger for Net::HTTP debug output. Accepts anything with a #<< method
  # (e.g. $stdout, a StringIO, or a Ruby Logger instance).
  @logger = opts[:logger]

  @opts = opts
end

Class Method Details

.build_header_hash(pairs) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rack/proxy.rb', line 41

def build_header_hash(pairs)
  # Pass inherit: false so we only check Rack's own constants — otherwise
  # a top-level ::Headers defined by the host app would falsely match.
  if Rack.const_defined?(:Headers, false)
    # Rack::Headers is only available from Rack 3 onward
    Headers.new.tap { |headers| pairs.each { |k, v| headers[k] = v } }
  else
    # Rack::Utils::HeaderHash is deprecated from Rack 3 onward and is to be removed in 3.1
    Utils::HeaderHash.new(pairs)
  end
end

.extract_http_request_headers(env) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rack/proxy.rb', line 22

def extract_http_request_headers(env)
  headers = env.reject do |k, v|
    !(/^HTTP_[A-Z0-9_\.]+$/ === k) || v.nil?
  end.map do |k, v|
    [reconstruct_header_name(k), v]
  end.then { |pairs| build_header_hash(pairs) }

  x_forwarded_for = (headers['X-Forwarded-For'].to_s.split(/, +/) << env['REMOTE_ADDR']).join(', ')

  headers.merge!('X-Forwarded-For' => x_forwarded_for)
end

.normalize_headers(headers) ⇒ Object



34
35
36
37
38
39
# File 'lib/rack/proxy.rb', line 34

def normalize_headers(headers)
  mapped = headers.map do |k, v|
    [titleize(k), if v.is_a? Array then v.join("\n") else v end]
  end
  build_header_hash Hash[mapped]
end

Instance Method Details

#call(env) ⇒ Object



95
96
97
# File 'lib/rack/proxy.rb', line 95

def call(env)
  rewrite_response(perform_request(rewrite_env(env)))
end

#rewrite_env(env) ⇒ Object

Return modified env



100
101
102
# File 'lib/rack/proxy.rb', line 100

def rewrite_env(env)
  env
end

#rewrite_response(triplet) ⇒ Object

Return a rack triplet [status, headers, body]



105
106
107
# File 'lib/rack/proxy.rb', line 105

def rewrite_response(triplet)
  triplet
end