Skip to content

Commit 1031036

Browse files
authored
fix: fix init location computation (#22225)
Flow client computes the initial location to be sent to the server by getting the current location and removing the document base URI part. However, the process performs an URL decode only for the location causing replacement to fail if the web application context path contains URL encodable characters. This change makes sure that both texts are URL decoded before performing the replacement. It also ensure that the regex based on document baseURI is correctly escaped. Fixes #22211
1 parent 38964af commit 1031036

File tree

8 files changed

+271
-4
lines changed

8 files changed

+271
-4
lines changed

flow-client/src/main/frontend/Flow.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ function sendEvent(eventName: string, data: any) {
7979
getClients().forEach((client) => client.sendEventMessage(ROOT_NODE_ID, eventName, data));
8080
}
8181

82+
// In the future could be replaced with RegExp.escape()
83+
function escapeRegExp(pattern: string) {
84+
return pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
85+
}
8286
/**
8387
* Client API for flow UI operations.
8488
*/
@@ -116,7 +120,9 @@ export class Flow {
116120
this.baseRegex = new RegExp(
117121
`^${
118122
// IE11 does not support document.baseURI
119-
(document.baseURI || (elm && elm.href) || '/').replace(/^https?:\/\/[^/]+/i, '')
123+
escapeRegExp(
124+
decodeURIComponent((document.baseURI || (elm && elm.href) || '/').replace(/^https?:\/\/[^/]+/i, ''))
125+
)
120126
}`
121127
);
122128
this.appShellTitle = document.title;

flow-tests/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@
295295
<module>test-pwa-disabled-offline</module>
296296
<module>test-pwa-disabled-offline/pom-production.xml</module>
297297
<module>test-router-custom-context</module>
298+
<module>test-router-custom-context-encoded</module>
299+
<module>test-router-custom-context-encoded-prod</module>
298300
<module>test-live-reload</module>
299301
<module>test-live-reload-multimodule</module>
300302
<module>test-live-reload-multimodule-devbundle</module>
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.vaadin</groupId>
7+
<artifactId>flow-tests</artifactId>
8+
<version>25.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>test-router-custom-context-encoded-production</artifactId>
11+
<name>Flow Router on custom context with encoded chars test (Production Mode)</name>
12+
<packaging>war</packaging>
13+
14+
<properties>
15+
<maven.deploy.skip>true</maven.deploy.skip>
16+
<jetty.skip>${maven.test.skip}</jetty.skip>
17+
<!--
18+
Uses both URL encodable chars (e.g. space => %20) and chars that should be escaped
19+
in a regex ($ { *) to verify that the Flow client correctly computes location
20+
-->
21+
<jettyContextPath>/custom con$t{ext*rou}ter</jettyContextPath>
22+
</properties>
23+
24+
<dependencies>
25+
<dependency>
26+
<groupId>com.vaadin</groupId>
27+
<artifactId>flow-test-resources</artifactId>
28+
<version>${project.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.vaadin</groupId>
32+
<artifactId>vaadin-dev-server</artifactId>
33+
<version>${project.version}</version>
34+
</dependency>
35+
<!--
36+
Jetty Maven plugin automatically merges war dependencies with the current archive
37+
https://jetty.org/docs/jetty/12.1/programming-guide/maven-jetty/jetty-maven-plugin.html#using-overlaid-wars
38+
-->
39+
<dependency>
40+
<groupId>com.vaadin</groupId>
41+
<artifactId>test-router-custom-context</artifactId>
42+
<version>${project.version}</version>
43+
<type>war</type>
44+
</dependency>
45+
<!-- build-frontend needs WAR classes as JAR to scan for frontend resources -->
46+
<dependency>
47+
<groupId>com.vaadin</groupId>
48+
<artifactId>test-router-custom-context</artifactId>
49+
<version>${project.version}</version>
50+
<classifier>classes</classifier>
51+
<scope>provided</scope>
52+
</dependency>
53+
<dependency>
54+
<groupId>com.vaadin</groupId>
55+
<artifactId>test-router-custom-context</artifactId>
56+
<version>${project.version}</version>
57+
<classifier>tests</classifier>
58+
<type>test-jar</type>
59+
<scope>test</scope>
60+
</dependency>
61+
</dependencies>
62+
63+
<build>
64+
<plugins>
65+
<!-- The Jetty plugin allows us to easily test the development
66+
build by running jetty:run -->
67+
<plugin>
68+
<groupId>org.eclipse.jetty.ee10</groupId>
69+
<artifactId>jetty-ee10-maven-plugin</artifactId>
70+
<version>${jetty.version}</version>
71+
<executions>
72+
<!-- start and stop jetty (running our app) when running
73+
integration tests -->
74+
<execution>
75+
<id>start-jetty</id>
76+
<phase>pre-integration-test</phase>
77+
<goals>
78+
<goal>start</goal>
79+
</goals>
80+
</execution>
81+
<execution>
82+
<id>stop-jetty</id>
83+
<phase>post-integration-test</phase>
84+
<goals>
85+
<goal>stop</goal>
86+
</goals>
87+
</execution>
88+
</executions>
89+
<configuration>
90+
<webApp>
91+
<contextPath>${jettyContextPath}</contextPath>
92+
</webApp>
93+
</configuration>
94+
</plugin>
95+
<plugin>
96+
<groupId>com.vaadin</groupId>
97+
<artifactId>flow-maven-plugin</artifactId>
98+
<executions>
99+
<execution>
100+
<phase>compile</phase>
101+
<goals>
102+
<goal>prepare-frontend</goal>
103+
<goal>build-frontend</goal>
104+
</goals>
105+
</execution>
106+
</executions>
107+
</plugin>
108+
<plugin>
109+
<groupId>org.apache.maven.plugins</groupId>
110+
<artifactId>maven-failsafe-plugin</artifactId>
111+
<configuration>
112+
<systemPropertyVariables>
113+
<vaadin.test.jettyContextPath>${jettyContextPath}</vaadin.test.jettyContextPath>
114+
</systemPropertyVariables>
115+
<dependenciesToScan>
116+
<dependency>com.vaadin:test-router-custom-context:test-jar:tests</dependency>
117+
</dependenciesToScan>
118+
</configuration>
119+
</plugin>
120+
</plugins>
121+
</build>
122+
123+
124+
</project>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.vaadin</groupId>
7+
<artifactId>flow-tests</artifactId>
8+
<version>25.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>test-router-custom-context-encoded</artifactId>
11+
<name>Flow Router on custom context with encoded chars test</name>
12+
<packaging>war</packaging>
13+
14+
<properties>
15+
<maven.deploy.skip>true</maven.deploy.skip>
16+
<jetty.skip>${maven.test.skip}</jetty.skip>
17+
<!--
18+
Uses both URL encodable chars (e.g. space => %20) and chars that should be escaped
19+
in a regex ($ { *) to verify that the Flow client correctly computes location
20+
-->
21+
<jettyContextPath>/custom con$t{ext*rou}ter</jettyContextPath>
22+
</properties>
23+
24+
<dependencies>
25+
<dependency>
26+
<groupId>com.vaadin</groupId>
27+
<artifactId>flow-test-resources</artifactId>
28+
<version>${project.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.vaadin</groupId>
32+
<artifactId>vaadin-dev-server</artifactId>
33+
<version>${project.version}</version>
34+
</dependency>
35+
<!--
36+
Jetty Maven plugin automatically merges war dependencies with the current archive
37+
https://jetty.org/docs/jetty/12.1/programming-guide/maven-jetty/jetty-maven-plugin.html#using-overlaid-wars
38+
-->
39+
<dependency>
40+
<groupId>com.vaadin</groupId>
41+
<artifactId>test-router-custom-context</artifactId>
42+
<version>${project.version}</version>
43+
<type>war</type>
44+
</dependency>
45+
<dependency>
46+
<groupId>com.vaadin</groupId>
47+
<artifactId>test-router-custom-context</artifactId>
48+
<version>${project.version}</version>
49+
<classifier>tests</classifier>
50+
<type>test-jar</type>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
55+
<build>
56+
<plugins>
57+
<!-- The Jetty plugin allows us to easily test the development
58+
build by running jetty:run -->
59+
<plugin>
60+
<groupId>org.eclipse.jetty.ee10</groupId>
61+
<artifactId>jetty-ee10-maven-plugin</artifactId>
62+
<version>${jetty.version}</version>
63+
<executions>
64+
<!-- start and stop jetty (running our app) when running
65+
integration tests -->
66+
<execution>
67+
<id>start-jetty</id>
68+
<phase>pre-integration-test</phase>
69+
<goals>
70+
<goal>start</goal>
71+
</goals>
72+
</execution>
73+
<execution>
74+
<id>stop-jetty</id>
75+
<phase>post-integration-test</phase>
76+
<goals>
77+
<goal>stop</goal>
78+
</goals>
79+
</execution>
80+
</executions>
81+
<configuration>
82+
<webApp>
83+
<contextPath>${jettyContextPath}</contextPath>
84+
</webApp>
85+
</configuration>
86+
</plugin>
87+
<plugin>
88+
<groupId>com.vaadin</groupId>
89+
<artifactId>flow-maven-plugin</artifactId>
90+
</plugin>
91+
<plugin>
92+
<groupId>org.apache.maven.plugins</groupId>
93+
<artifactId>maven-failsafe-plugin</artifactId>
94+
<configuration>
95+
<systemPropertyVariables>
96+
<vaadin.test.jettyContextPath>${jettyContextPath}</vaadin.test.jettyContextPath>
97+
</systemPropertyVariables>
98+
<dependenciesToScan>
99+
<dependency>com.vaadin:test-router-custom-context:test-jar:tests</dependency>
100+
</dependenciesToScan>
101+
</configuration>
102+
</plugin>
103+
</plugins>
104+
</build>
105+
106+
107+
</project>

flow-tests/test-router-custom-context/pom.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@
6464
<groupId>com.vaadin</groupId>
6565
<artifactId>flow-maven-plugin</artifactId>
6666
</plugin>
67+
<!-- Export classes as jar so it can be used by other modules -->
68+
<plugin>
69+
<groupId>org.apache.maven.plugins</groupId>
70+
<artifactId>maven-war-plugin</artifactId>
71+
<configuration>
72+
<attachClasses>true</attachClasses>
73+
</configuration>
74+
</plugin>
75+
<!-- Export the test-jar so it can be used by other modules -->
76+
<plugin>
77+
<groupId>org.apache.maven.plugins</groupId>
78+
<artifactId>maven-jar-plugin</artifactId>
79+
<configuration>
80+
<finalName>${project.artifactId}</finalName>
81+
</configuration>
82+
<executions>
83+
<execution>
84+
<goals>
85+
<goal>test-jar</goal>
86+
</goals>
87+
</execution>
88+
</executions>
89+
</plugin>
6790
</plugins>
6891
</build>
6992

flow-tests/test-router-custom-context/src/test/java/com/vaadin/flow/contexttest/ui/AbstractContextIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
public abstract class AbstractContextIT extends ChromeBrowserTest {
1010

11-
static final String JETTY_CONTEXT = "/custom-context-router";
11+
static final String JETTY_CONTEXT = System.getProperty(
12+
"vaadin.test.jettyContextPath", "/custom-context-router");
1213

1314
private static final String RED = "rgba(255, 0, 0, 1)";
1415
private static final String BLUE = "rgba(0, 0, 255, 1)";

flow-tests/test-router-custom-context/src/test/java/com/vaadin/flow/contexttest/ui/PushIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ public void testRoutedSubContextLongPolling() throws InterruptedException {
7373

7474
private void doTest(final String subContext, Transport transport,
7575
boolean pushMustWork) throws InterruptedException {
76-
String url = getRootURL() + "/custom-context-router/" + subContext;
76+
String contextPath = System.getProperty("vaadin.test.jettyContextPath",
77+
"/custom-context-router");
78+
String url = getRootURL() + contextPath + "/" + subContext;
7779
if (transport != null) {
7880
url += "?transport=" + transport.getIdentifier();
7981
}

scripts/computeMatrix.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ const moduleWeights = {
130130
'flow-tests/test-eager-bootstrap': { weight: 6 },
131131
'flow-tests/test-ccdm-flow-navigation': { weight: 5 },
132132
'flow-tests/test-custom-frontend-directory/test-themes-custom-frontend-directory/pom-generatedTsDir.xml': { weight: 5 },
133-
'flow-tests/test-router-custom-context': { weight: 5 },
133+
'flow-tests/test-router-custom-context': { pos: 8 },
134+
'flow-tests/test-router-custom-context-encoded': { pos: 8 },
135+
'flow-tests/test-router-custom-context-encoded-prod': { pos: 8 },
134136
'flow-tests/test-frontend/vite-embedded': { weight: 5 },
135137
'flow-tests/test-dev-mode': { weight: 5 },
136138
'flow-tests/test-custom-frontend-directory/test-themes-custom-frontend-directory': { weight: 5 },

0 commit comments

Comments
 (0)