Skip to content

Commit a1c4eaa

Browse files
authored
feat: CORS proxying (#94)
1 parent aca8452 commit a1c4eaa

File tree

5 files changed

+81
-5
lines changed

5 files changed

+81
-5
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,4 @@
132132
"utf-8-validate": "^5.0.4",
133133
"uuid": "^8.3.2"
134134
}
135-
}
135+
}

src/client.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ zitiFetch = async ( url, opts ) => {
619619
throw err;
620620
});
621621

622-
var newUrl = new URL( 'https://' + zitiConfig.httpAgent.target.host + ':' + zitiConfig.httpAgent.target.port + url );
622+
let newUrl = new URL( 'https://' + zitiConfig.httpAgent.target.host + ':' + zitiConfig.httpAgent.target.port + url );
623623
ziti._ctx.logger.trace( 'zitiFetch: transformed URL: ', newUrl.toString());
624624

625625
serviceName = await ziti._ctx.shouldRouteOverZiti( newUrl );
@@ -633,8 +633,44 @@ zitiFetch = async ( url, opts ) => {
633633

634634
} else { // the request is targeting the raw internet
635635

636-
ziti._ctx.logger.warn('zitiFetch(): no http agent url match, bypassing intercept of [%s]', url);
637-
return window.realFetch(url, opts);
636+
serviceName = await ziti._ctx.shouldRouteOverZiti( url );
637+
638+
if (isUndefined(serviceName)) { // If we have no serviceConfig associated with the hostname:port
639+
640+
let routeOverCORSProxy = await ziti._ctx.shouldRouteOverCORSProxy( url );
641+
642+
if (routeOverCORSProxy) { // If we hostname:port is something we need to CORS Proxy
643+
644+
ziti._ctx.logger.warn('zitiFetch(): doing CORS Proxying of [%s]', url);
645+
646+
let newUrl = new URL( url );
647+
let corsTargetHostname = newUrl.hostname;
648+
let corsTargetPort = newUrl.port;
649+
if (corsTargetPort === '') {
650+
if (newUrl.protocol === 'https:') {
651+
corsTargetPort = '443';
652+
} else {
653+
corsTargetPort = '80';
654+
}
655+
}
656+
657+
let corsTargetPathname = newUrl.pathname;
658+
newUrl.hostname = zitiConfig.httpAgent.self.host;
659+
newUrl.port = 443;
660+
newUrl.pathname = '/ziti-cors-proxy/' + corsTargetHostname + ':' + corsTargetPort + corsTargetPathname;
661+
// newUrl.pathname = '/ziti-cors-proxy/' + corsTargetHostname + corsTargetPathname;
662+
ziti._ctx.logger.warn( 'zitiFetch: transformed URL: ', newUrl.toString());
663+
664+
return window.realFetch(newUrl, opts); // Send special request to HTTP Agent
665+
666+
} else {
667+
668+
ziti._ctx.logger.warn('zitiFetch(): no associated serviceConfig, bypassing intercept of [%s]', url);
669+
return window.realFetch(url, opts);
670+
671+
}
672+
673+
}
638674
}
639675

640676
/**

src/context/context.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,40 @@ ZitiContext.prototype.shouldRouteOverZiti = async function(url) {
897897
}
898898

899899

900+
/**
901+
* Determine if the given URL should be handled via CORS Proxy.
902+
*
903+
* @returns {bool}
904+
*/
905+
ZitiContext.prototype.shouldRouteOverCORSProxy = async function(url) {
906+
let parsedURL = new URL(url);
907+
908+
let hostname = parsedURL.hostname;
909+
let port = parsedURL.port;
910+
911+
if (port === '') {
912+
if ((parsedURL.protocol === 'https:') || (parsedURL.protocol === 'wss:')) {
913+
port = 443;
914+
} else {
915+
port = 80;
916+
}
917+
}
918+
919+
let corsHostsArray = zitiConfig.httpAgent.corsProxy.hosts.split(',');
920+
921+
return new Promise( async (resolve, reject) => {
922+
let routeOverCORSProxy = false;
923+
forEach(corsHostsArray, function( corsHost ) {
924+
let corsHostSplit = corsHost.split(':');
925+
if ((hostname === corsHostSplit[0]) && (port === parseInt(corsHostSplit[1], 10))) {
926+
routeOverCORSProxy = true;
927+
}
928+
});
929+
return resolve( routeOverCORSProxy );
930+
});
931+
}
932+
933+
900934
/**
901935
* Return current value of the ztAPI
902936
*

src/http/request.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ HttpRequest.prototype.getRequestOptions = async function() {
196196
const parsedURL = this[INTERNALS].parsedURL;
197197
const headers = this[INTERNALS].headers;
198198

199+
// Transform all occurances of the HTTP Agent hostname back to the target hostname
200+
var replace = zitiConfig.httpAgent.self.host;
201+
var re = new RegExp(replace,"gi");
202+
parsedURL.href = parsedURL.href.replace(re, zitiConfig.httpAgent.target.host);
203+
parsedURL.search = parsedURL.search.replace(re, zitiConfig.httpAgent.target.host);
204+
199205
// fetch step 1.3
200206
if (!headers.has('Accept')) {
201207
headers.set('Accept', '*/*');

0 commit comments

Comments
 (0)