Skip to content

Commit b96d153

Browse files
committed
fix(webSocketRoute): resolve URL against baseURL
1 parent 6b621ce commit b96d153

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-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: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,38 @@ 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+
System.out.println("ws handler: message: " + message.text());
330+
ws.send(message.text());
331+
} else {
332+
System.out.println("ws handler: message: " + message.binary());
333+
ws.send(message.binary());
334+
}
335+
});
336+
});
337+
338+
setupWS(newPage, webSocketServer.getPort(), "blob");
339+
340+
newPage.evaluate("async () => {\n" +
341+
" await window.wsOpened;\n" +
342+
" window.ws.send('echo');\n" +
343+
" }");
344+
345+
newPage.waitForCondition(() -> {
346+
Boolean result = (Boolean) newPage.evaluate("() => window.log.length >= 2");
347+
return result;
348+
});
349+
350+
assertEquals(
351+
asList("open", "message: data=echo origin=ws://localhost:" + webSocketServer.getPort() + " lastEventId="),
352+
newPage.evaluate("window.log"));
353+
}
320354
}

0 commit comments

Comments
 (0)