@@ -42,6 +42,7 @@ var ProxyTable = exports.ProxyTable = function (options) {
42
42
events . EventEmitter . call ( this ) ;
43
43
44
44
this . silent = options . silent || options . silent !== true ;
45
+ this . target = options . target || { } ;
45
46
this . hostnameOnly = options . hostnameOnly === true ;
46
47
47
48
if ( typeof options . router === 'object' ) {
@@ -91,19 +92,62 @@ ProxyTable.prototype.setRoutes = function (router) {
91
92
throw new Error ( 'Cannot update ProxyTable routes without router.' ) ;
92
93
}
93
94
95
+ var self = this ;
94
96
this . router = router ;
95
97
96
98
if ( this . hostnameOnly === false ) {
97
- var self = this ;
98
99
this . routes = [ ] ;
99
100
100
101
Object . keys ( router ) . forEach ( function ( path ) {
101
- var route = new RegExp ( '^' + path , 'i' ) ;
102
+ if ( ! / h t t p [ s ] ? / . test ( router [ path ] ) ) {
103
+ router [ path ] = ( self . target . https ? 'https://' : 'http://' )
104
+ + router [ path ] ;
105
+ }
102
106
107
+ var target = url . parse ( router [ path ] ) ,
108
+ defaultPort = self . target . https ? 443 : 80 ;
109
+
110
+ //
111
+ // Setup a robust lookup table for the route:
112
+ //
113
+ // {
114
+ // source: {
115
+ // regexp: /^foo.com/i,
116
+ // sref: 'foo.com',
117
+ // url: {
118
+ // protocol: 'http:',
119
+ // slashes: true,
120
+ // host: 'foo.com',
121
+ // hostname: 'foo.com',
122
+ // href: 'http://foo.com/',
123
+ // pathname: '/',
124
+ // path: '/'
125
+ // }
126
+ // },
127
+ // {
128
+ // target: {
129
+ // sref: '127.0.0.1:8000/',
130
+ // url: {
131
+ // protocol: 'http:',
132
+ // slashes: true,
133
+ // host: '127.0.0.1:8000',
134
+ // hostname: '127.0.0.1',
135
+ // href: 'http://127.0.0.1:8000/',
136
+ // pathname: '/',
137
+ // path: '/'
138
+ // }
139
+ // },
140
+ //
103
141
self . routes . push ( {
104
- route : route ,
105
- target : router [ path ] ,
106
- path : path
142
+ source : {
143
+ regexp : new RegExp ( '^' + path , 'i' ) ,
144
+ sref : path ,
145
+ url : url . parse ( 'http://' + path )
146
+ } ,
147
+ target : {
148
+ sref : target . hostname + ':' + ( target . port || defaultPort ) + target . path ,
149
+ url : target
150
+ }
107
151
} ) ;
108
152
} ) ;
109
153
}
@@ -137,22 +181,30 @@ ProxyTable.prototype.getProxyLocation = function (req) {
137
181
target += req . url ;
138
182
for ( var i in this . routes ) {
139
183
var route = this . routes [ i ] ;
140
- if ( target . match ( route . route ) ) {
141
- var requrl = url . parse ( req . url ) ;
142
- //add the 'http://'' to get around a url.parse bug, it won't actually be used.
143
- var targeturl = url . parse ( 'http://' + route . target ) ;
144
- var pathurl = url . parse ( 'http://' + route . path ) ;
145
-
146
- //This replaces the path's part of the URL to the target's part of the URL.
147
- requrl . pathname = requrl . pathname . replace ( pathurl . pathname , targeturl . pathname ) ;
148
- req . url = url . format ( requrl ) ;
149
-
150
- var host = targeturl . hostname ,
151
- port = targeturl . port || 80 ;
184
+ if ( target . match ( route . source . regexp ) ) {
185
+ //
186
+ // Attempt to perform any path replacement for differences
187
+ // between the source path and the target path. This replaces the
188
+ // path's part of the URL to the target's part of the URL.
189
+ //
190
+ // 1. Parse the request URL
191
+ // 2. Replace any portions of the source path with the target path
192
+ // 3. Set the request URL to the formatted URL with replacements.
193
+ //
194
+ var parsed = url . parse ( req . url ) ;
195
+
196
+ parsed . pathname = parsed . pathname . replace (
197
+ route . source . url . pathname ,
198
+ route . target . url . pathname
199
+ ) ;
200
+
201
+ req . url = url . format ( parsed ) ;
152
202
153
203
return {
154
- port : port ,
155
- host : host
204
+ protocol : route . target . url . protocol . replace ( ':' , '' ) ,
205
+ host : route . target . url . hostname ,
206
+ port : route . target . url . port
207
+ || ( this . target . https ? 443 : 80 )
156
208
} ;
157
209
}
158
210
}
0 commit comments