Skip to content

Commit fcd0444

Browse files
authored
fix(webSocketRoute): resolve URL against baseURL (#1722)
1 parent 067e69f commit fcd0444

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed

playwright/src/main/java/com/microsoft/playwright/impl/UrlMatcher.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,19 @@
1616

1717
package com.microsoft.playwright.impl;
1818

19-
import com.google.gson.JsonArray;
20-
import com.google.gson.JsonObject;
2119
import com.microsoft.playwright.PlaywrightException;
2220

23-
import java.net.MalformedURLException;
21+
import java.net.URI;
22+
import java.net.URISyntaxException;
2423
import java.net.URL;
25-
import java.util.ArrayList;
26-
import java.util.List;
27-
import java.util.Objects;
2824
import java.util.function.Predicate;
2925
import java.util.regex.Pattern;
3026

3127
import static com.microsoft.playwright.impl.Utils.globToRegex;
3228
import static com.microsoft.playwright.impl.Utils.toJsRegexFlags;
3329

3430
class UrlMatcher {
35-
private final URL baseURL;
31+
private final String baseURL;
3632
public final String glob;
3733
public final Pattern pattern;
3834
public final Predicate<String> predicate;
@@ -54,12 +50,17 @@ static UrlMatcher forOneOf(URL baseUrl, Object object) {
5450
}
5551

5652
static String resolveUrl(URL baseUrl, String spec) {
53+
return resolveUrl(baseUrl.toString(), spec);
54+
}
55+
56+
private static String resolveUrl(String baseUrl, String spec) {
5757
if (baseUrl == null) {
5858
return spec;
5959
}
6060
try {
61-
return new URL(baseUrl, spec).toString();
62-
} catch (MalformedURLException e) {
61+
// Join using URI instead of URL since URL doesn't handle ws(s) protocols.
62+
return new URI(baseUrl).resolve(spec).toString();
63+
} catch (URISyntaxException e) {
6364
return spec;
6465
}
6566
}
@@ -77,21 +78,32 @@ static String resolveUrl(URL baseUrl, String spec) {
7778
}
7879

7980
private UrlMatcher(URL baseURL, String glob, Pattern pattern, Predicate<String> predicate) {
80-
this.baseURL = baseURL;
81+
this.baseURL = baseURL != null ? baseURL.toString() : null;
8182
this.glob = glob;
8283
this.pattern = pattern;
8384
this.predicate = predicate;
8485
}
8586

8687
boolean test(String value) {
88+
return testImpl(baseURL, pattern, predicate, glob, value);
89+
}
90+
91+
private static boolean testImpl(String baseURL, Pattern pattern, Predicate<String> predicate, String glob, String value) {
8792
if (pattern != null) {
8893
return pattern.matcher(value).find();
8994
}
9095
if (predicate != null) {
9196
return predicate.test(value);
9297
}
9398
if (glob != null) {
94-
return Pattern.compile(globToRegex(resolveUrl(baseURL, glob))).matcher(value).find();
99+
if (!glob.startsWith("*")) {
100+
// Allow http(s) baseURL to match ws(s) urls.
101+
if (baseURL != null && Pattern.compile("^https?://").matcher(baseURL).find() && Pattern.compile("^wss?://").matcher(value).find()) {
102+
baseURL = baseURL.replaceFirst("^http", "ws");
103+
}
104+
glob = resolveUrl(baseURL, glob);
105+
}
106+
return Pattern.compile(globToRegex(glob)).matcher(value).find();
95107
}
96108
return true;
97109
}

playwright/src/test/java/com/microsoft/playwright/TestRouteWebSocket.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,36 @@ public void shouldWorkWithoutServer(Page page) {
317317
"close code=3008 reason=oops"),
318318
page.evaluate("window.log"));
319319
}
320+
321+
@Test
322+
public void shouldWorkWithBaseURL(Browser browser) throws Exception {
323+
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setBaseURL("http://localhost:" + webSocketServer.getPort()));
324+
Page newPage = context.newPage();
325+
326+
newPage.routeWebSocket("/ws", ws -> {
327+
ws.onMessage(message -> {
328+
if (message.text() != null) {
329+
ws.send(message.text());
330+
} else {
331+
ws.send(message.binary());
332+
}
333+
});
334+
});
335+
336+
setupWS(newPage, webSocketServer.getPort(), "blob");
337+
338+
newPage.evaluate("async () => {\n" +
339+
" await window.wsOpened;\n" +
340+
" window.ws.send('echo');\n" +
341+
" }");
342+
343+
newPage.waitForCondition(() -> {
344+
Boolean result = (Boolean) newPage.evaluate("() => window.log.length >= 2");
345+
return result;
346+
});
347+
348+
assertEquals(
349+
asList("open", "message: data=echo origin=ws://localhost:" + webSocketServer.getPort() + " lastEventId="),
350+
newPage.evaluate("window.log"));
351+
}
320352
}

0 commit comments

Comments
 (0)