@@ -2,19 +2,18 @@ var url = require('url');
22var httpProxy = require ( 'http-proxy' ) ;
33
44var log = require ( '../logger' ) . create ( 'proxy' ) ;
5+ var _ = require ( '../helper' ) . _ ;
56
67var parseProxyConfig = function ( proxies , config ) {
7- var proxyConfig = { } ;
88 var endsWithSlash = function ( str ) {
99 return str . substr ( - 1 ) === '/' ;
1010 } ;
1111
1212 if ( ! proxies ) {
13- return proxyConfig ;
13+ return [ ] ;
1414 }
1515
16- Object . keys ( proxies ) . forEach ( function ( proxyPath ) {
17- var proxyUrl = proxies [ proxyPath ] ;
16+ return _ . sortBy ( _ . map ( proxies , function ( proxyUrl , proxyPath ) {
1817 var proxyDetails = url . parse ( proxyUrl ) ;
1918 var pathname = proxyDetails . pathname ;
2019
@@ -31,75 +30,74 @@ var parseProxyConfig = function(proxies, config) {
3130 proxyPath += '/' ;
3231 }
3332
34- if ( pathname === '/' && ! endsWithSlash ( proxyUrl ) ) {
33+ if ( pathname === '/' && ! endsWithSlash ( proxyUrl ) ) {
3534 pathname = '' ;
3635 }
3736
38- proxyConfig [ proxyPath ] = {
39- host : proxyDetails . hostname ,
40- port : proxyDetails . port ,
41- baseProxyUrl : pathname ,
42- https : proxyDetails . protocol === 'https:'
43- } ;
44-
45- if ( ! proxyConfig [ proxyPath ] . port ) {
46- if ( ! proxyConfig [ proxyPath ] . host ) {
47- proxyConfig [ proxyPath ] . host = config . hostname ;
48- proxyConfig [ proxyPath ] . port = config . port ;
37+ var hostname = proxyDetails . hostname || config . hostname ;
38+ var port = proxyDetails . port || config . port ||
39+ ( proxyDetails . protocol === 'https:' ? '443' : '80' ) ;
40+ var https = proxyDetails . protocol === 'https:' ;
41+
42+ var proxy = new httpProxy . createProxyServer ( {
43+ target : {
44+ host : hostname ,
45+ port : port ,
46+ https : https
47+ } ,
48+ xfwd : true ,
49+ secure : config . proxyValidateSSL
50+ } ) ;
51+
52+ proxy . on ( 'error' , function proxyError ( err , req , res ) {
53+ if ( err . code === 'ECONNRESET' && req . socket . destroyed ) {
54+ log . debug ( 'failed to proxy %s (browser hung up the socket)' , req . url ) ;
4955 } else {
50- proxyConfig [ proxyPath ] . port = proxyConfig [ proxyPath ] . https ? '443' : '80' ;
56+ log . warn ( 'failed to proxy %s (%s)' , req . url , err . message ) ;
5157 }
52- }
53- } ) ;
5458
55- return proxyConfig ;
59+ res . destroy ( ) ;
60+ } ) ;
61+
62+ return {
63+ path : proxyPath ,
64+ baseUrl : pathname ,
65+ host : hostname ,
66+ port : port ,
67+ https : https ,
68+ proxy : proxy
69+ } ;
70+ } ) , 'path' ) . reverse ( ) ;
5671} ;
5772
5873
5974/**
6075 * Returns a handler which understands the proxies and its redirects, along with the proxy to use
61- * @param proxy A http-proxy.RoutingProxy object with the proxyRequest method
62- * @param proxies a map of routes to proxy url
76+ * @param proxies An array of proxy record objects
77+ * @param urlRoot The URL root that karma is mounted on
6378 * @return {Function } handler function
6479 */
65- var createProxyHandler = function ( proxy , proxyConfig , proxyValidateSSL , urlRoot , config ) {
66- var proxies = parseProxyConfig ( proxyConfig , config ) ;
67- var proxiesList = Object . keys ( proxies ) . sort ( ) . reverse ( ) ;
68-
69- if ( ! proxiesList . length ) {
80+ var createProxyHandler = function ( proxies , urlRoot ) {
81+ if ( ! proxies . length ) {
7082 var nullProxy = function createNullProxy ( request , response , next ) {
7183 return next ( ) ;
7284 } ;
73- nullProxy . upgrade = function upgradeNullProxy ( ) {
74- } ;
85+ nullProxy . upgrade = function upgradeNullProxy ( ) { } ;
7586 return nullProxy ;
7687 }
7788
78- proxy . on ( 'proxyError' , function ( err , req ) {
79- if ( err . code === 'ECONNRESET' && req . socket . destroyed ) {
80- log . debug ( 'failed to proxy %s (browser hung up the socket)' , req . url ) ;
81- } else {
82- log . warn ( 'failed to proxy %s (%s)' , req . url , err . message ) ;
83- }
84- } ) ;
85-
8689 var middleware = function createProxy ( request , response , next ) {
87- for ( var i = 0 ; i < proxiesList . length ; i ++ ) {
88- if ( request . url . indexOf ( proxiesList [ i ] ) === 0 ) {
89- var proxiedUrl = proxies [ proxiesList [ i ] ] ;
90-
91- log . debug ( 'proxying request - %s to %s:%s' , request . url , proxiedUrl . host , proxiedUrl . port ) ;
92- request . url = request . url . replace ( proxiesList [ i ] , proxiedUrl . baseProxyUrl ) ;
93- proxy . proxyRequest ( request , response , {
94- host : proxiedUrl . host ,
95- port : proxiedUrl . port ,
96- target : { https : proxiedUrl . https , rejectUnauthorized : proxyValidateSSL }
97- } ) ;
98- return ;
99- }
90+ var proxyRecord = _ . find ( proxies , function ( p ) {
91+ return request . url . indexOf ( p . path ) === 0 ;
92+ } ) ;
93+
94+ if ( ! proxyRecord ) {
95+ return next ( ) ;
10096 }
10197
102- return next ( ) ;
98+ log . debug ( 'proxying request - %s to %s:%s' , request . url , proxyRecord . host , proxyRecord . port ) ;
99+ request . url = request . url . replace ( proxyRecord . path , proxyRecord . baseUrl ) ;
100+ proxyRecord . proxy . web ( request , response ) ;
103101 } ;
104102
105103 middleware . upgrade = function upgradeProxy ( request , socket , head ) {
@@ -108,22 +106,24 @@ var createProxyHandler = function(proxy, proxyConfig, proxyValidateSSL, urlRoot,
108106 log . debug ( 'NOT upgrading proxyWebSocketRequest %s' , request . url ) ;
109107 return ;
110108 }
111- for ( var i = 0 ; i < proxiesList . length ; i ++ ) {
112- if ( request . url . indexOf ( proxiesList [ i ] ) === 0 ) {
113- var proxiedUrl = proxies [ proxiesList [ i ] ] ;
114- log . debug ( 'upgrade proxyWebSocketRequest %s to %s:%s' ,
115- request . url , proxiedUrl . host , proxiedUrl . port ) ;
116- proxy . proxyWebSocketRequest ( request , socket , head ,
117- { host : proxiedUrl . host , port : proxiedUrl . port } ) ;
118- }
109+
110+ var proxyRecord = _ . find ( proxies , function ( p ) {
111+ return request . url . indexOf ( p . path ) === 0 ;
112+ } ) ;
113+
114+ if ( ! proxyRecord ) {
115+ return ;
119116 }
117+
118+ log . debug ( 'upgrade proxyWebSocketRequest %s to %s:%s' ,
119+ request . url , proxyRecord . host , proxyRecord . port ) ;
120+ request . url = request . url . replace ( proxyRecord . path , proxyRecord . baseUrl ) ;
121+ proxyRecord . proxy . ws ( request , socket , head ) ;
120122 } ;
121123
122124 return middleware ;
123125} ;
124126
125- exports . create = function ( /* config */ config , /* config.proxies */ proxies ,
126- /* config.proxyValidateSSL */ validateSSL ) {
127- return createProxyHandler ( new httpProxy . RoutingProxy ( { changeOrigin : true } ) ,
128- proxies , validateSSL , config . urlRoot , config ) ;
127+ exports . create = function ( /* config */ config , /* config.proxies */ proxies ) {
128+ return createProxyHandler ( parseProxyConfig ( proxies , config ) , config . urlRoot ) ;
129129} ;
0 commit comments