Path: blob/main/extensions/json-language-features/client/src/utils/urlMatch.ts
5237 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Uri } from 'vscode';67/**8* Check whether a URL matches the list of trusted domains or URIs.9*10* trustedDomains is an object where:11* - Keys are full domains (https://www.microsoft.com) or full URIs (https://www.test.com/schemas/mySchema.json)12* - Keys can include wildcards (https://*.microsoft.com) or glob patterns13* - Values are booleans indicating if the domain/URI is trusted (true) or blocked (false)14*15* @param url The URL to check16* @param trustedDomains Object mapping domain patterns to boolean trust values17*/18export function matchesUrlPattern(url: Uri, trustedDomains: Record<string, boolean>): boolean {19// Check localhost20if (isLocalhostAuthority(url.authority)) {21return true;22}2324for (const [pattern, isTrusted] of Object.entries(trustedDomains)) {25if (typeof pattern !== 'string' || pattern.trim() === '') {26continue;27}2829// Wildcard matches everything30if (pattern === '*') {31return isTrusted;32}3334try {35const patternUri = Uri.parse(pattern);3637// Scheme must match38if (url.scheme !== patternUri.scheme) {39continue;40}4142// Check authority (host:port)43if (!matchesAuthority(url.authority, patternUri.authority)) {44continue;45}4647// Check path48if (!matchesPath(url.path, patternUri.path)) {49continue;50}5152return isTrusted;53} catch {54// Invalid pattern, skip55continue;56}57}5859return false;60}6162function matchesAuthority(urlAuthority: string, patternAuthority: string): boolean {63urlAuthority = urlAuthority.toLowerCase();64patternAuthority = patternAuthority.toLowerCase();6566if (patternAuthority === urlAuthority) {67return true;68}69// Handle wildcard subdomains (e.g., *.github.com)70if (patternAuthority.startsWith('*.')) {71const patternDomain = patternAuthority.substring(2);72// Exact match or subdomain match73return urlAuthority === patternDomain || urlAuthority.endsWith('.' + patternDomain);74}7576return false;77}7879function matchesPath(urlPath: string, patternPath: string): boolean {80// Empty pattern path or just "/" matches any path81if (!patternPath || patternPath === '/') {82return true;83}8485// Exact match86if (urlPath === patternPath) {87return true;88}8990// If pattern ends with '/', it matches any path starting with it91if (patternPath.endsWith('/')) {92return urlPath.startsWith(patternPath);93}9495// Otherwise, pattern must be a prefix96return urlPath.startsWith(patternPath + '/') || urlPath === patternPath;97}9899100const rLocalhost = /^(.+\.)?localhost(:\d+)?$/i;101const r127 = /^127\.0\.0\.1(:\d+)?$/;102const rIPv6Localhost = /^\[::1\](:\d+)?$/;103104function isLocalhostAuthority(authority: string): boolean {105return rLocalhost.test(authority) || r127.test(authority) || rIPv6Localhost.test(authority);106}107108109