1
0
mirror of synced 2026-05-22 18:53:15 +00:00

fix(webSocketRoute): resolve URL against baseURL (#1722)

This commit is contained in:
Max Schmitt
2025-01-27 15:43:47 +01:00
committed by GitHub
parent 067e69f339
commit fcd0444c57
2 changed files with 55 additions and 11 deletions
@@ -16,15 +16,11 @@
package com.microsoft.playwright.impl;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.microsoft.playwright.PlaywrightException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.regex.Pattern;
@@ -32,7 +28,7 @@ import static com.microsoft.playwright.impl.Utils.globToRegex;
import static com.microsoft.playwright.impl.Utils.toJsRegexFlags;
class UrlMatcher {
private final URL baseURL;
private final String baseURL;
public final String glob;
public final Pattern pattern;
public final Predicate<String> predicate;
@@ -54,12 +50,17 @@ class UrlMatcher {
}
static String resolveUrl(URL baseUrl, String spec) {
return resolveUrl(baseUrl.toString(), spec);
}
private static String resolveUrl(String baseUrl, String spec) {
if (baseUrl == null) {
return spec;
}
try {
return new URL(baseUrl, spec).toString();
} catch (MalformedURLException e) {
// Join using URI instead of URL since URL doesn't handle ws(s) protocols.
return new URI(baseUrl).resolve(spec).toString();
} catch (URISyntaxException e) {
return spec;
}
}
@@ -77,13 +78,17 @@ class UrlMatcher {
}
private UrlMatcher(URL baseURL, String glob, Pattern pattern, Predicate<String> predicate) {
this.baseURL = baseURL;
this.baseURL = baseURL != null ? baseURL.toString() : null;
this.glob = glob;
this.pattern = pattern;
this.predicate = predicate;
}
boolean test(String value) {
return testImpl(baseURL, pattern, predicate, glob, value);
}
private static boolean testImpl(String baseURL, Pattern pattern, Predicate<String> predicate, String glob, String value) {
if (pattern != null) {
return pattern.matcher(value).find();
}
@@ -91,7 +96,14 @@ class UrlMatcher {
return predicate.test(value);
}
if (glob != null) {
return Pattern.compile(globToRegex(resolveUrl(baseURL, glob))).matcher(value).find();
if (!glob.startsWith("*")) {
// Allow http(s) baseURL to match ws(s) urls.
if (baseURL != null && Pattern.compile("^https?://").matcher(baseURL).find() && Pattern.compile("^wss?://").matcher(value).find()) {
baseURL = baseURL.replaceFirst("^http", "ws");
}
glob = resolveUrl(baseURL, glob);
}
return Pattern.compile(globToRegex(glob)).matcher(value).find();
}
return true;
}
@@ -317,4 +317,36 @@ public class TestRouteWebSocket {
"close code=3008 reason=oops"),
page.evaluate("window.log"));
}
@Test
public void shouldWorkWithBaseURL(Browser browser) throws Exception {
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setBaseURL("http://localhost:" + webSocketServer.getPort()));
Page newPage = context.newPage();
newPage.routeWebSocket("/ws", ws -> {
ws.onMessage(message -> {
if (message.text() != null) {
ws.send(message.text());
} else {
ws.send(message.binary());
}
});
});
setupWS(newPage, webSocketServer.getPort(), "blob");
newPage.evaluate("async () => {\n" +
" await window.wsOpened;\n" +
" window.ws.send('echo');\n" +
" }");
newPage.waitForCondition(() -> {
Boolean result = (Boolean) newPage.evaluate("() => window.log.length >= 2");
return result;
});
assertEquals(
asList("open", "message: data=echo origin=ws://localhost:" + webSocketServer.getPort() + " lastEventId="),
newPage.evaluate("window.log"));
}
}