浏览代码

Fix gitea-origin-url with default ports (#29085) (#29088)

Backport #29085 by @silverwind

When setting `url.host` on a URL object with no port specified (like is
the case of default port), the resulting URL's port will not change.
Workaround this quirk in the URL standard by explicitely setting port
for the http and https protocols.

Extracted the logic to a function for the purpose of testing. Initially
I wanted to have the function in utils.js, but it turns out esbuild can
not treeshake the unused functions which would result in the
webcomponents chunk having all 2kB utils.js inlined, so it seemed not
worth.

Fixes: https://github.com/go-gitea/gitea/issues/29084

Co-authored-by: silverwind <me@silverwind.io>
tags/v1.21.6
Giteabot 3 个月前
父节点
当前提交
fb7f28e9a7
没有帐户链接到提交者的电子邮件
共有 3 个文件被更改,包括 34 次插入13 次删除
  1. 1
    1
      .eslintrc.yaml
  2. 16
    12
      web_src/js/webcomponents/GiteaOriginUrl.js
  3. 17
    0
      web_src/js/webcomponents/GiteaOriginUrl.test.js

+ 1
- 1
.eslintrc.yaml 查看文件

@@ -743,7 +743,7 @@ rules:
wc/no-constructor-params: [2]
wc/no-constructor: [2]
wc/no-customized-built-in-elements: [2]
wc/no-exports-with-element: [2]
wc/no-exports-with-element: [0]
wc/no-invalid-element-name: [2]
wc/no-invalid-extends: [2]
wc/no-method-prefixed-with-on: [2]

+ 16
- 12
web_src/js/webcomponents/GiteaOriginUrl.js 查看文件

@@ -1,17 +1,21 @@
// Convert an absolute or relative URL to an absolute URL with the current origin
export function toOriginUrl(urlStr) {
try {
// only process absolute HTTP/HTTPS URL or relative URLs ('/xxx' or '//host/xxx')
if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
const {origin, protocol, hostname, port} = window.location;
const url = new URL(urlStr, origin);
url.protocol = protocol;
url.hostname = hostname;
url.port = port || (protocol === 'https:' ? '443' : '80');
return url.toString();
}
} catch {}
return urlStr;
}

window.customElements.define('gitea-origin-url', class extends HTMLElement {
connectedCallback() {
const urlStr = this.getAttribute('data-url');
try {
// only process absolute HTTP/HTTPS URL or relative URLs ('/xxx' or '//host/xxx')
if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
const url = new URL(urlStr, window.origin);
url.protocol = window.location.protocol;
url.host = window.location.host;
this.textContent = url.toString();
return;
}
} catch {}
this.textContent = urlStr;
this.textContent = toOriginUrl(this.getAttribute('data-url'));
}
});

+ 17
- 0
web_src/js/webcomponents/GiteaOriginUrl.test.js 查看文件

@@ -0,0 +1,17 @@
import {toOriginUrl} from './GiteaOriginUrl.js';

test('toOriginUrl', () => {
const oldLocation = window.location;
for (const origin of ['https://example.com', 'https://example.com:3000']) {
window.location = new URL(`${origin}/`);
expect(toOriginUrl('/')).toEqual(`${origin}/`);
expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
expect(toOriginUrl('https://another.com/')).toEqual(`${origin}/`);
expect(toOriginUrl('https://another.com/org/repo.git')).toEqual(`${origin}/org/repo.git`);
expect(toOriginUrl('https://another.com:4000')).toEqual(`${origin}/`);
expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
}
window.location = oldLocation;
});

正在加载...
取消
保存