Skip to content

Commit

Permalink
fix(webSocketRoute): resolve URL against baseURL
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt committed Dec 28, 2024
1 parent 6b621ce commit 2eea1bf
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,19 @@

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;

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;
Expand All @@ -54,12 +50,17 @@ static UrlMatcher forOneOf(URL baseUrl, Object object) {
}

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;
}
}
Expand All @@ -77,21 +78,32 @@ static String resolveUrl(URL baseUrl, String spec) {
}

private UrlMatcher(URL baseURL, String glob, Pattern pattern, Predicate<String> predicate) {
this.baseURL = baseURL;
this.baseURL = baseURL.toString();
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();
}
if (predicate != null) {
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("^https?", "ws");
}
glob = resolveUrl(baseURL, glob);
}
return Pattern.compile(globToRegex(glob)).matcher(value).find();
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,38 @@ public void shouldWorkWithoutServer(Page page) {
"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) {
System.out.println("ws handler: message: " + message.text());
ws.send(message.text());
} else {
System.out.println("ws handler: message: " + message.binary());
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"));
}
}

0 comments on commit 2eea1bf

Please sign in to comment.