1
- require ' net/http'
2
- require ' net/https'
1
+ require " net/http"
2
+ require " net/https"
3
3
require "rack-proxy"
4
4
5
5
module RackReverseProxy
6
+ # FIXME: Enable them and fix issues during refactoring
7
+ # rubocop:disable Metrics/ClassLength
8
+ # rubocop:disable Metrics/MethodLength
9
+ # rubocop:disable Metrics/CyclomaticComplexity
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ # rubocop:disable Metrics/AbcSize
12
+
13
+ # Rack middleware for handling reverse proxying
6
14
class Middleware
7
15
include NewRelic ::Agent ::Instrumentation ::ControllerInstrumentation if defined? NewRelic
8
16
9
17
def initialize ( app = nil , &b )
10
- @app = app || lambda { | env | [ 404 , [ ] , [ ] ] }
18
+ @app = app || lambda { | _ | [ 404 , [ ] , [ ] ] }
11
19
@matchers = [ ]
12
- @global_options = { :preserve_host => true , :x_forwarded_host => true , :matching => :all , :replace_response_host => false }
20
+ @global_options = {
21
+ :preserve_host => true ,
22
+ :x_forwarded_host => true ,
23
+ :matching => :all ,
24
+ :replace_response_host => false ,
25
+ }
13
26
instance_eval ( &b ) if block_given?
14
27
end
15
28
16
29
def call ( env )
17
30
rackreq = Rack ::Request . new ( env )
18
- matcher = get_matcher ( rackreq . fullpath , Rack ::Proxy . extract_http_request_headers ( rackreq . env ) , rackreq )
31
+ matcher = get_matcher (
32
+ rackreq . fullpath ,
33
+ Rack ::Proxy . extract_http_request_headers ( rackreq . env ) ,
34
+ rackreq ,
35
+ )
19
36
return @app . call ( env ) if matcher . nil?
20
37
21
38
if @global_options [ :newrelic_instrumentation ]
22
- action_name = "#{ rackreq . path . gsub ( /\/ \d +/ , '/:id' ) . gsub ( /^\/ / , '' ) } /#{ rackreq . request_method } " # Rack::ReverseProxy/foo/bar#GET
39
+ # Rack::ReverseProxy/foo/bar#GET
40
+ action_path = rackreq . path . gsub ( %r{/\d +} , "/:id" ) . gsub ( %r{^/} , "" )
41
+ action_name = "#{ action_path } /#{ rackreq . request_method } "
23
42
perform_action_with_newrelic_trace ( :name => action_name , :request => rackreq ) do
24
43
proxy ( env , rackreq , matcher )
25
44
end
@@ -31,40 +50,43 @@ def call(env)
31
50
private
32
51
33
52
def proxy ( env , source_request , matcher )
34
- uri = matcher . get_uri ( source_request . fullpath , env )
35
- if uri . nil?
36
- return @app . call ( env )
37
- end
53
+ uri = matcher . get_uri ( source_request . fullpath , env )
54
+ return @app . call ( env ) if uri . nil?
55
+
38
56
options = @global_options . dup . merge ( matcher . options )
39
57
40
58
# Initialize request
41
- target_request = Net ::HTTP . const_get ( source_request . request_method . capitalize ) . new ( uri . request_uri )
59
+ target_request = Net ::HTTP . const_get (
60
+ source_request . request_method . capitalize ,
61
+ ) . new ( uri . request_uri )
42
62
43
63
# Setup headers
44
64
target_request_headers = Rack ::Proxy . extract_http_request_headers ( source_request . env )
45
65
46
66
if options [ :preserve_host ]
47
67
if uri . port == uri . default_port
48
- target_request_headers [ ' HOST' ] = uri . host
68
+ target_request_headers [ " HOST" ] = uri . host
49
69
else
50
- target_request_headers [ ' HOST' ] = "#{ uri . host } :#{ uri . port } "
70
+ target_request_headers [ " HOST" ] = "#{ uri . host } :#{ uri . port } "
51
71
end
52
72
end
53
73
54
74
if options [ :x_forwarded_host ]
55
- target_request_headers [ ' X-Forwarded-Host' ] = source_request . host
56
- target_request_headers [ ' X-Forwarded-Port' ] = "#{ source_request . port } "
75
+ target_request_headers [ " X-Forwarded-Host" ] = source_request . host
76
+ target_request_headers [ " X-Forwarded-Port" ] = "#{ source_request . port } "
57
77
end
58
78
59
79
target_request . initialize_http_header ( target_request_headers )
60
80
61
81
# Basic auth
62
- target_request . basic_auth options [ :username ] , options [ :password ] if options [ :username ] and options [ :password ]
82
+ if options [ :username ] && options [ :password ]
83
+ target_request . basic_auth options [ :username ] , options [ :password ]
84
+ end
63
85
64
86
# Setup body
65
87
if target_request . request_body_permitted? && source_request . body
66
88
source_request . body . rewind
67
- target_request . body_stream = source_request . body
89
+ target_request . body_stream = source_request . body
68
90
end
69
91
70
92
target_request . content_length = source_request . content_length || 0
@@ -79,16 +101,18 @@ def proxy(env, source_request, matcher)
79
101
target_response . use_ssl = "https" == uri . scheme
80
102
81
103
# Let rack set the transfer-encoding header
82
- response_headers = Rack ::Utils ::HeaderHash . new Rack ::Proxy . normalize_headers ( format_headers ( target_response . headers ) )
83
- response_headers . delete ( 'Transfer-Encoding' )
84
- response_headers . delete ( 'Status' )
104
+ response_headers = Rack ::Utils ::HeaderHash . new (
105
+ Rack ::Proxy . normalize_headers ( format_headers ( target_response . headers ) ) ,
106
+ )
107
+ response_headers . delete ( "Transfer-Encoding" )
108
+ response_headers . delete ( "Status" )
85
109
86
110
# Replace the location header with the proxy domain
87
- if response_headers [ ' Location' ] && options [ :replace_response_host ]
88
- response_location = URI ( response_headers [ ' location' ] )
111
+ if response_headers [ " Location" ] && options [ :replace_response_host ]
112
+ response_location = URI ( response_headers [ " location" ] )
89
113
response_location . host = source_request . host
90
114
response_location . port = source_request . port
91
- response_headers [ ' Location' ] = response_location . to_s
115
+ response_headers [ " Location" ] = response_location . to_s
92
116
end
93
117
94
118
[ target_response . status , response_headers , target_response . body ]
@@ -102,26 +126,27 @@ def get_matcher(path, headers, rackreq)
102
126
if matches . length < 1
103
127
nil
104
128
elsif matches . length > 1 && @global_options [ :matching ] != :first
105
- raise Errors ::AmbiguousMatch . new ( path , matches )
129
+ fail Errors ::AmbiguousMatch . new ( path , matches )
106
130
else
107
131
matches . first
108
132
end
109
133
end
110
134
111
135
def reverse_proxy_options ( options )
112
- @global_options = options
136
+ @global_options = options
113
137
end
114
138
115
- def reverse_proxy ( matcher , url = nil , opts = { } )
116
- raise Errors ::GenericURI . new ( url ) if matcher . is_a? ( String ) && url . is_a? ( String ) && URI ( url ) . class == URI ::Generic
117
- @matchers << Matcher . new ( matcher , url , opts )
139
+ def reverse_proxy ( matcher , url = nil , opts = { } )
140
+ if matcher . is_a? ( String ) && url . is_a? ( String ) && URI ( url ) . class == URI ::Generic
141
+ fail Errors ::GenericURI . new , url
142
+ end
143
+ @matchers << Matcher . new ( matcher , url , opts )
118
144
end
119
145
120
146
def format_headers ( headers )
121
- headers . reduce ( { } ) do |acc , ( key , val ) |
122
- formated_key = key . split ( '-' ) . map ( &:capitalize ) . join ( '-' )
147
+ headers . each_with_object ( { } ) do |( key , val ) , acc |
148
+ formated_key = key . split ( "-" ) . map ( &:capitalize ) . join ( "-" )
123
149
acc [ formated_key ] = Array ( val )
124
- acc
125
150
end
126
151
end
127
152
end
0 commit comments