Skip to content

Commit

Permalink
core: properly handle localhost uris on Electron (#10590)
Browse files Browse the repository at this point in the history
When running Electron `window.location` is not a standard HTTP(S) URL,
so we cannot use it to determine the host where the backend is running.

Resolve the remote host to `localhost` when running Electron.
  • Loading branch information
paul-marechal authored Jan 12, 2022
1 parent a11c163 commit fb74ef0
Showing 1 changed file with 31 additions and 16 deletions.
47 changes: 31 additions & 16 deletions packages/core/src/browser/external-uri-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { environment } from '@theia/application-package/lib/environment';
import { injectable } from 'inversify';
import URI from '../common/uri';
import { MaybePromise } from '../common/types';
import URI from '../common/uri';
import { Endpoint } from './endpoint';

export interface AddressPort {
address: string
port: number
}

@injectable()
export class ExternalUriService {

Expand All @@ -31,34 +37,43 @@ export class ExternalUriService {
* Use `parseLocalhost` to retrieve localhost address and port information.
*/
resolve(uri: URI): MaybePromise<URI> {
const localhost = this.parseLocalhost(uri);
if (localhost) {
return this.toRemoteUrl(uri, localhost);
const address = this.parseLocalhost(uri);
if (address) {
return this.toRemoteUrl(uri, address);
}
return uri;
}

protected toRemoteUrl(uri: URI, localhost: { address: string, port: number }): URI {
const host = this.toRemoteHost(localhost);
return new Endpoint({ host }).getRestUrl().withPath(uri.path).withFragment(uri.fragment).withQuery(uri.query);
}

protected toRemoteHost(localhost: { address: string, port: number }): string {
return `${window.location.hostname}:${localhost.port}`;
}

parseLocalhost(uri: URI): { address: string, port: number } | undefined {
parseLocalhost(uri: URI): AddressPort | undefined {
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
return undefined;
return;
}
const localhostMatch = /^(localhost|127\.0\.0\.1|0\.0\.0\.0):(\d+)$/.exec(uri.authority);
if (!localhostMatch) {
return undefined;
return;
}
return {
address: localhostMatch[1],
port: +localhostMatch[2],
};
}

protected toRemoteUrl(uri: URI, address: AddressPort): URI {
return new Endpoint({ host: this.toRemoteHost(address) })
.getRestUrl()
.withPath(uri.path)
.withFragment(uri.fragment)
.withQuery(uri.query);
}

protected toRemoteHost(address: AddressPort): string {
return `${this.getRemoteHost()}:${address.port}`;
}

/**
* @returns The remote host (where the backend is running).
*/
protected getRemoteHost(): string {
return environment.electron.is() ? 'localhost' : window.location.hostname;
}
}

0 comments on commit fb74ef0

Please sign in to comment.