Skip to content

Commit

Permalink
fix(urlMatcher): normalize URLs to align with Node.js parser behavior (
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt authored Jan 27, 2025
1 parent fcd0444 commit 4820088
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -65,6 +66,21 @@ private static String resolveUrl(String baseUrl, String spec) {
}
}

private static String normaliseUrl(String spec) {
try {
// Align with the Node.js URL parser which automatically adds a slash to the path if it is empty.
URI url = new URI(spec);
if (url.getScheme() != null &&
Arrays.asList("http", "https", "ws", "wss").contains(url.getScheme()) &&
url.getPath().isEmpty()) {
return new URI(url.getScheme(), url.getAuthority(), "/", url.getQuery(), url.getFragment()).toString();
}
return url.toString();
} catch (URISyntaxException e) {
return spec;
}
}

UrlMatcher(URL baseURL, String glob) {
this(baseURL, glob, null, null);
}
Expand Down Expand Up @@ -101,7 +117,7 @@ private static boolean testImpl(String baseURL, Pattern pattern, Predicate<Strin
if (baseURL != null && Pattern.compile("^https?://").matcher(baseURL).find() && Pattern.compile("^wss?://").matcher(value).find()) {
baseURL = baseURL.replaceFirst("^http", "ws");
}
glob = resolveUrl(baseURL, glob);
glob = normaliseUrl(resolveUrl(baseURL, glob));
}
return Pattern.compile(globToRegex(glob)).matcher(value).find();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -349,4 +351,44 @@ public void shouldWorkWithBaseURL(Browser browser) throws Exception {
asList("open", "message: data=echo origin=ws://localhost:" + webSocketServer.getPort() + " lastEventId="),
newPage.evaluate("window.log"));
}

@Test
public void shouldWorkWithNoTrailingSlash(Page page) throws Exception {
List<String> log = new ArrayList<>();

// No trailing slash in the route pattern
page.routeWebSocket("ws://localhost:" + webSocketServer.getPort(), ws -> {
ws.onMessage(message -> {
log.add(message.text());
ws.send("response");
});
});

page.navigate("about:blank");
page.evaluate("({ port }) => {\n" +
" window.log = [];\n" +
" // No trailing slash in WebSocket URL\n" +
" window.ws = new WebSocket('ws://localhost:' + port);\n" +
" window.ws.addEventListener('message', event => window.log.push(event.data));\n" +
"}", mapOf("port", webSocketServer.getPort()));

// Wait for WebSocket to be ready (readyState === 1)
page.waitForCondition(() -> {
Integer result = (Integer) page.evaluate("() => window.ws.readyState");
return result == 1;
});

page.evaluate("() => window.ws.send('query')");

// Wait and verify server received message
page.waitForCondition(() -> log.size() >= 1);
assertEquals(asList("query"), log);

// Wait and verify client received response
page.waitForCondition(() -> {
Boolean result = (Boolean) page.evaluate("() => window.log.length >= 1");
return result;
});
assertEquals(asList("response"), page.evaluate("window.log"));
}
}

0 comments on commit 4820088

Please sign in to comment.