fix(proxy): proxy protocol check (#5474)
* fix(proxy): proxy protocol check * Clarify docs
This commit is contained in:
6
.changeset/famous-hornets-know.md
Normal file
6
.changeset/famous-hornets-know.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'@verdaccio/proxy': patch
|
||||||
|
'@verdaccio/website': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(proxy): proxy protocol check
|
||||||
@@ -15,7 +15,9 @@ class CustomAgents {
|
|||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.agentOptions = agentOptions;
|
this.agentOptions = agentOptions;
|
||||||
const { protocol } = this.getParsedUrl();
|
// Type of agent depends on the protocol of the server URL (no on the proxy)
|
||||||
|
// See https://www.npmjs.com/package/hpagent
|
||||||
|
const { protocol } = new URL(this.url);
|
||||||
this.agent = this.getAgent(protocol);
|
this.agent = this.getAgent(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,10 +43,6 @@ class CustomAgents {
|
|||||||
: { http: new HttpAgent(this.agentOptions) };
|
: { http: new HttpAgent(this.agentOptions) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getParsedUrl() {
|
|
||||||
return this.proxy ? new URL(this.proxy) : new URL(this.url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CustomAgents;
|
export default CustomAgents;
|
||||||
|
|||||||
@@ -632,20 +632,6 @@ class ProxyStorage implements IProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate proxy protocol matches the proxy_key type
|
|
||||||
if (this.proxy) {
|
|
||||||
const proxyUrl = new URL(this.proxy);
|
|
||||||
const expectedProtocol = isHTTPS ? 'https:' : 'http:';
|
|
||||||
if (proxyUrl.protocol !== expectedProtocol) {
|
|
||||||
this.logger.error(
|
|
||||||
{ proxy: this.proxy, expectedProtocol },
|
|
||||||
`invalid protocol for ${proxy_key} - must be ${expectedProtocol}`
|
|
||||||
);
|
|
||||||
this.proxy = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof this.proxy === 'string') {
|
if (typeof this.proxy === 'string') {
|
||||||
debug('using proxy @{proxy} for @{url}', this.proxy, this.url.href);
|
debug('using proxy @{proxy} for @{url}', this.proxy, this.url.href);
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
|
|||||||
@@ -28,60 +28,47 @@ describe('Check protocol of proxy', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
test('validate main config protocol - http', () => {
|
test('main config - http registry, http proxy', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance(
|
getProxyInstance('http://registry.domain.org', { http_proxy: 'http://proxy.local' }, {}).proxy
|
||||||
'http://registry.domain.org',
|
).toEqual('http://proxy.local');
|
||||||
{ http_proxy: 'http://registry.local.org' },
|
|
||||||
{}
|
|
||||||
).proxy
|
|
||||||
).toEqual('http://registry.local.org');
|
|
||||||
});
|
});
|
||||||
test('main config invalid protocol - http', () => {
|
test('main config - http registry, https proxy', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance(
|
getProxyInstance('http://registry.domain.org', { http_proxy: 'https://proxy.local' }, {})
|
||||||
'http://registry.domain.org',
|
.proxy
|
||||||
{ http_proxy: 'https://registry.local.org' },
|
).toEqual('https://proxy.local');
|
||||||
{}
|
|
||||||
).proxy
|
|
||||||
).toEqual(undefined);
|
|
||||||
expect(mockError).toHaveBeenCalledOnce();
|
|
||||||
});
|
});
|
||||||
test('main config invalid protocol - https', () => {
|
test('main config invalid config key - http registry', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance(
|
getProxyInstance('http://registry.domain.org', { https_proxy: 'anything' }, {}).proxy
|
||||||
'https://registry.domain.org',
|
).toEqual(undefined);
|
||||||
{ https_proxy: 'http://registry.local.org' },
|
});
|
||||||
{}
|
test('main config invalid config key - https registry', () => {
|
||||||
).proxy
|
expect(
|
||||||
|
getProxyInstance('https://registry.domain.org', { http_proxy: 'anything' }, {}).proxy
|
||||||
).toEqual(undefined);
|
).toEqual(undefined);
|
||||||
expect(mockError).toHaveBeenCalledOnce();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('validate uplink config protocol - http', () => {
|
test('uplink config - http registry, http proxy', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance(
|
getProxyInstance('http://registry.domain.org', {}, { http_proxy: 'http://proxy.local' }).proxy
|
||||||
'https://registry.domain.org',
|
).toEqual('http://proxy.local');
|
||||||
{},
|
|
||||||
{ https_proxy: 'https://proxy.domain.org' }
|
|
||||||
).proxy
|
|
||||||
).toEqual('https://proxy.domain.org');
|
|
||||||
});
|
});
|
||||||
test('uplink config invalid protocol - http', () => {
|
test('uplink config - http registry, https proxy', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance('http://registry.domain.org', {}, { http_proxy: 'https://proxy.domain.org' })
|
getProxyInstance('http://registry.domain.org', {}, { http_proxy: 'https://proxy.local' })
|
||||||
.proxy
|
.proxy
|
||||||
).toEqual(undefined);
|
).toEqual('https://proxy.local');
|
||||||
expect(mockError).toHaveBeenCalledOnce();
|
|
||||||
});
|
});
|
||||||
test('uplink config invalid protocol - https', () => {
|
test('uplink config invalid config key - http registry', () => {
|
||||||
expect(
|
expect(
|
||||||
getProxyInstance(
|
getProxyInstance('http://registry.domain.org', {}, { https_proxy: 'anything' }).proxy
|
||||||
'https://registry.domain.org',
|
).toEqual(undefined);
|
||||||
{},
|
});
|
||||||
{ https_proxy: 'http://proxy.domain.org' }
|
test('uplink config invalid config key - https registry', () => {
|
||||||
).proxy
|
expect(
|
||||||
|
getProxyInstance('https://registry.domain.org', {}, { http_proxy: 'anything' }).proxy
|
||||||
).toEqual(undefined);
|
).toEqual(undefined);
|
||||||
expect(mockError).toHaveBeenCalledOnce();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -322,7 +322,22 @@ https:
|
|||||||
|
|
||||||
### Proxy {#proxy}
|
### Proxy {#proxy}
|
||||||
|
|
||||||
Proxies are special-purpose HTTP servers designed to transfer data from remote servers to local clients. You can define a HTTP or HTTPS proxy in the main configuration or separately for each uplink. The definition for uplinks have higher priority. The proxy protocol (http or https) has to match the protocol of the registry or uplink URLs.
|
Proxies are special-purpose HTTP servers designed to transfer data from remote servers to local clients. You can define a HTTP or HTTPS proxy in the main configuration or separately for each uplink. The definition for uplinks have higher priority.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
The proxy configuration key (`http_proxy` or `https_proxy`) has to match the protocol of the uplink URL!
|
||||||
|
|
||||||
|
For example, to use a proxy for npm i.e. `https://registry.npmjs.com`, then you have to use `https_proxy` in your configuration to specify you proxy URL (no matter if the proxy uses `http` or `https`).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
uplinks:
|
||||||
|
npmjs:
|
||||||
|
url: https://registry.npmjs.org/
|
||||||
|
https_proxy: http://my.proxy.local/
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
#### http_proxy and https_proxy {#http_proxy-and-https_proxy}
|
#### http_proxy and https_proxy {#http_proxy-and-https_proxy}
|
||||||
|
|
||||||
|
|||||||
@@ -330,7 +330,22 @@ https:
|
|||||||
|
|
||||||
### Proxy {#proxy}
|
### Proxy {#proxy}
|
||||||
|
|
||||||
Proxies are special-purpose HTTP servers designed to transfer data from remote servers to local clients. You can define a HTTP or HTTPS proxy in the main configuration or separately for each uplink. The definition for uplinks have higher priority. The proxy protocol (http or https) has to match the protocol of the registry URL.
|
Proxies are special-purpose HTTP servers designed to transfer data from remote servers to local clients. You can define a HTTP or HTTPS proxy in the main configuration or separately for each uplink. The definition for uplinks have higher priority.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
The proxy configuration key (`http_proxy` or `https_proxy`) has to match the protocol of the uplink URL!
|
||||||
|
|
||||||
|
For example, to use a proxy for npm i.e. `https://registry.npmjs.com`, then you have to use `https_proxy` in your configuration to specify you proxy URL (no matter if the proxy uses `http` or `https`).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
uplinks:
|
||||||
|
npmjs:
|
||||||
|
url: https://registry.npmjs.org/
|
||||||
|
https_proxy: http://my.proxy.local/
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
#### http_proxy and https_proxy {#http_proxy-and-https_proxy}
|
#### http_proxy and https_proxy {#http_proxy-and-https_proxy}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user