class AeReverseProxy::Client
Constants
- CALLBACK_METHODS
- COOKIE_PARAM_PATTERN
- COOKIE_SPLIT_PATTERN
Attributes
callbacks[RW]
uri[RW]
Public Class Methods
new(uri) { |self| ... }
click to toggle source
# File lib/ae_reverse_proxy/client.rb, line 28 def initialize(uri) self.uri = uri self.callbacks = CALLBACK_METHODS.to_h { |method| [method, proc {}] } yield(self) if block_given? end
Public Instance Methods
forward_request(env, options = {})
click to toggle source
# File lib/ae_reverse_proxy/client.rb, line 35 def forward_request(env, options = {}) # Initialize requests source_request = Rack::Request.new(env) target_request = Net::HTTP.const_get(source_request.request_method.capitalize).new(source_request.fullpath) # Setup headers for forwarding. target_request_headers = extract_http_request_headers(source_request.env).merge({ 'ORIGIN' => uri.origin, 'HOST' => uri.authority, }) target_request.initialize_http_header(target_request_headers) # Setup basic auth. target_request.basic_auth(options[:username], options[:password]) if options[:username] && options[:password] # Setup body. if target_request.request_body_permitted? && source_request.body source_request.body.rewind target_request.body_stream = source_request.body end # Setup content encoding and type. target_request.content_length = source_request.content_length || 0 target_request.content_type = source_request.content_type if source_request.content_type # Don't encode response/support compression which was # causing content length not match the actual content # length of the response which ended up causing issues # within Varnish (503) target_request['Accept-Encoding'] = nil # Setup HTTP SSL options. http_options = {} http_options[:use_ssl] = (uri.scheme == 'https') # Make the request. target_response = nil Net::HTTP.start(uri.hostname, uri.port, http_options) do |http| callbacks[:on_connect].call(http) target_response = http.request(target_request) end # Initiate callbacks. status_code = target_response.code.to_i payload = [status_code, target_response] callbacks[:on_response].call(payload) if target_response.to_hash['set-cookie'] set_cookies_hash = {} set_cookie_headers = target_response.to_hash['set-cookie'] set_cookie_headers.each do |set_cookie_header| set_cookie_hash = parse_cookie(set_cookie_header) name = set_cookie_hash[:name] set_cookies_hash[name] = set_cookie_hash end callbacks[:on_set_cookies].call(payload | [set_cookies_hash]) end case status_code when 200..299 callbacks[:on_success].call(payload) when 300..399 callbacks[:on_redirect].call(payload | [target_response['Location']]) if target_response['Location'] when 400..499 callbacks[:on_missing].call(payload) when 500..599 callbacks[:on_error].call(payload) end callbacks[:on_complete].call(payload) payload end
Private Instance Methods
extract_http_request_headers(env)
click to toggle source
# File lib/ae_reverse_proxy/client.rb, line 117 def extract_http_request_headers(env) env .reject { |k, v| !(/^HTTP_[A-Z_]+$/ === k) || k == 'HTTP_VERSION' || v.nil? } .map { |k, v| [reconstruct_header_name(k), v] } .each_with_object(Rack::Utils::HeaderHash.new) do |k_v, hash| k, v = k_v hash[k] = v end end
reconstruct_header_name(name)
click to toggle source
# File lib/ae_reverse_proxy/client.rb, line 127 def reconstruct_header_name(name) name.sub(/^HTTP_/, '').gsub('_', '-') end