Skip to content

Commit 9f3e9fa

Browse files
authored
4.x: double-slash URI issue helidon-io#7474 (helidon-io#7657)
* Double-slash URI issue helidon-io#7474 * Flaky test fix * Review issues 2
1 parent a0d4a50 commit 9f3e9fa

3 files changed

Lines changed: 30 additions & 9 deletions

File tree

common/uri/src/main/java/io/helidon/common/uri/UriPathNoParam.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public String rawPathNoParams() {
7373
@Override
7474
public String path() {
7575
if (decodedPath == null) {
76-
decodedPath = decode(rawPath);
76+
decodedPath = decode(rawPath, false);
7777
}
7878
return decodedPath;
7979
}
@@ -104,11 +104,11 @@ public String toString() {
104104
@Override
105105
public void validate() {
106106
if (decodedPath == null) {
107-
this.decodedPath = URI.create(rawPath).normalize().getPath();
107+
this.decodedPath = decode(rawPath, true);
108108
}
109109
}
110110

111-
private static String decode(String rawPath) {
111+
private static String decode(String rawPath, boolean validate) {
112112
/*
113113
Raw path may:
114114
- be encoded (%20)
@@ -121,10 +121,18 @@ private static String decode(String rawPath) {
121121
int dot = rawPath.indexOf(".");
122122
int doubleSlash = rawPath.indexOf("//");
123123

124-
if (percent == -1 && doubleSlash == -1 && dot == -1) {
124+
if (!validate && percent == -1 && doubleSlash == -1 && dot == -1) {
125125
return rawPath;
126126
}
127127

128+
if (doubleSlash == 0) {
129+
/*
130+
RFC2396 - net_path starts with //, that would lead to loosing first path segment.
131+
example: URI.create("//foo/bar").getPath() --> "/bar"
132+
*/
133+
rawPath = rawPath.substring(1);
134+
}
135+
128136
return URI.create(rawPath).normalize().getPath();
129137
}
130138
}

common/uri/src/test/java/io/helidon/common/uri/UriPathTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package io.helidon.common.uri;
1818

1919
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.params.ParameterizedTest;
21+
import org.junit.jupiter.params.provider.ValueSource;
2022

2123
import static org.hamcrest.CoreMatchers.is;
2224
import static org.hamcrest.MatcherAssert.assertThat;
@@ -37,4 +39,16 @@ void testEncodeSpace() {
3739
assertThat(path.path(), is("/my path"));
3840
assertThat(path.rawPath(), is("/my%20path"));
3941
}
42+
43+
@ParameterizedTest
44+
@ValueSource(strings = {
45+
"//foo/bar",
46+
"//foo//bar",
47+
"/foo//bar",
48+
"/foo/bar",
49+
})
50+
void testDoubleSlash(String rawPath) {
51+
UriPath path = UriPath.create(rawPath);
52+
assertThat(path.path(), is("/foo/bar"));
53+
}
4054
}

webclient/tests/webclient/src/test/java/io/helidon/webclient/tests/TracingPropagationTest.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
class TracingPropagationTest {
6060
private static final Duration TIMEOUT = Duration.ofSeconds(15);
6161
private static final AtomicReference<CountDownLatch> SPAN_COUNT_LATCH = new AtomicReference<>();
62+
// 2+1 after re-introduction of content-write span
63+
private static final int EXPECTED_NUMBER_OF_SPANS = 3;
6264
private static MockTracer tracer;
6365
private final Http1Client client;
6466
private final URI uri;
@@ -92,7 +94,7 @@ protected void onSpanFinished(MockSpan mockSpan) {
9294

9395
@Test
9496
void testTracingSuccess() throws InterruptedException {
95-
SPAN_COUNT_LATCH.set(new CountDownLatch(2));
97+
SPAN_COUNT_LATCH.set(new CountDownLatch(EXPECTED_NUMBER_OF_SPANS));
9698
Context context = Context.builder().id("tracing-unit-test").build();
9799
context.register(tracer);
98100

@@ -110,10 +112,7 @@ void testTracingSuccess() throws InterruptedException {
110112
List<MockSpan> mockSpans = tracer.finishedSpans();
111113

112114
// the server traces asynchronously, some spans may be written after we receive the response.
113-
// we need to try to wait for such spans
114-
// re-introduced content-write span
115-
assertThat("There should be 3 spans reported", tracer.finishedSpans(), hasSize(3));
116-
115+
assertThat("There should be 3 spans reported", tracer.finishedSpans(), hasSize(EXPECTED_NUMBER_OF_SPANS));
117116

118117
// we need the first span - parentId 0
119118
MockSpan clientSpan = findSpanWithParentId(mockSpans, 0);

0 commit comments

Comments
 (0)