Class: WrapItRuby::Middleware::ProxyMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/wrap_it_ruby/middleware/proxy_middleware.rb

Overview

Rack middleware that proxies /_proxy/host/path to the upstream host.

Header strategy (both request and response):

1. Whitelist 

Constant Summary collapse

PATTERN =
%r{\A/_proxy/(?<host>[^/]+)(?<path>/.*)?\z}
REQUEST_WHITELIST =

── Request headers whitelisted for forwarding to upstream ──

Everything not on this list is dropped. This prevents leaking proxy-internal headers, browser metadata, and hop-by-hop headers.

%w[
  accept
  accept-language
  authorization
  cache-control
  content-type
  content-length
  cookie
  if-match
  if-modified-since
  if-none-match
  if-range
  if-unmodified-since
  pragma
  range
  x-requested-with
].to_set.freeze
RESPONSE_WHITELIST =

── Response headers whitelisted for forwarding to browser ──

Everything not on this list is dropped. This prevents frame- blocking headers, CSP, HSTS, and hop-by-hop headers from reaching the browser inside the iframe.

%w[
  accept-ranges
  age
  cache-control
  content-disposition
  content-language
  content-length
  content-range
  content-type
  date
  etag
  expires
  last-modified
  location
  pragma
  retry-after
  set-cookie
  vary
  x-content-type-options
  x-xss-protection
].to_set.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ ProxyMiddleware

Returns a new instance of ProxyMiddleware.



70
71
72
73
74
75
# File 'lib/wrap_it_ruby/middleware/proxy_middleware.rb', line 70

def initialize(app)
  @app          = app
  @clients      = {}
  @proxy_host   = ENV['WRAP_IT_PROXY_HOST']
  @cookie_domain = ENV.fetch('WRAP_IT_COOKIE_DOMAIN', '.cia.net')
end

Instance Method Details

#call(env) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/wrap_it_ruby/middleware/proxy_middleware.rb', line 77

def call(env)
  PATTERN.match(env['PATH_INFO'].to_s).then do |match|
    if match
      host = match[:host].delete_suffix('.')
      path = match[:path] || '/'

      if websocket?(env)
        proxy_websocket(env, host, path)
      else
        proxy_http(env, host, path)
      end
    else
      @app.call(env)
    end
  end
end