Skip to content

Commit a5f01f4

Browse files
committed
fix: adding prefix handling to base uri
closes: quarkusio#50293 Signed-off-by: Steve Hawkins <[email protected]>
1 parent 0075acc commit a5f01f4

File tree

5 files changed

+41
-72
lines changed

5 files changed

+41
-72
lines changed

extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/ForwardedPrefixHeaderTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void basicTest() {
3030
.get("/test")
3131
.then()
3232
.statusCode(200)
33-
.body(Matchers.equalTo("http|http://localhost:8081/test"));
33+
.body(Matchers.equalTo("absolute http|http://localhost:8081/test base http|http://localhost:8081/"));
3434

3535
given()
3636
.header("X-Forwarded-Proto", "https")
@@ -40,7 +40,8 @@ public void basicTest() {
4040
.get("/test")
4141
.then()
4242
.statusCode(200)
43-
.body(Matchers.equalTo("https|https://backend:1234/prefix/test"));
43+
.body(Matchers
44+
.equalTo("absolute https|https://backend:1234/prefix/test base https|https://backend:1234/prefix/"));
4445
}
4546

4647
@Test
@@ -73,7 +74,8 @@ public static class Resource {
7374

7475
@GET
7576
public String get(UriInfo uriInfo) {
76-
return uriInfo.getAbsolutePath().getScheme() + "|" + uriInfo.getAbsolutePath();
77+
return "absolute " + uriInfo.getAbsolutePath().getScheme() + "|" + uriInfo.getAbsolutePath() + " base "
78+
+ uriInfo.getBaseUri().getScheme() + "|" + uriInfo.getBaseUri();
7779
}
7880

7981
@GET

independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/LocationUtil.java

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,25 @@ static URI determineLocation(URI location) {
1616
// FIXME: this leaks server stuff onto the client
1717
ResteasyReactiveRequestContext request = CurrentRequestManager.get();
1818
if (request != null) {
19-
ServerHttpRequest req = request.serverRequest();
20-
try {
21-
String host = req.getRequestHost();
22-
int port = -1;
23-
int index = host.lastIndexOf(":");
24-
if (index > -1 && (host.charAt(0) != '[' || index > host.lastIndexOf("]"))) {
25-
port = Integer.parseInt(host.substring(index + 1));
26-
host = host.substring(0, index);
27-
}
28-
String prefix = determinePrefix(req, request.getDeployment());
29-
// Spec says relative to request, but TCK tests relative to Base URI, so we do that
30-
String path = location.toString();
31-
if (!path.startsWith("/")) {
32-
path = "/" + path;
33-
}
34-
URI baseUri = new URI(req.getRequestScheme(), null, host, port, null, null, null);
35-
location = baseUri.resolve(prefix + path);
36-
} catch (URISyntaxException e) {
37-
throw new RuntimeException(e);
38-
}
19+
location = getUri(location.toString(), request, true);
3920
}
4021
}
4122
return location;
4223
}
4324

25+
static URI getUri(String path, ResteasyReactiveRequestContext request, boolean usePrefix) {
26+
try {
27+
String prefix = usePrefix ? determinePrefix(request.serverRequest(), request.getDeployment()) : "";
28+
// Spec says relative to request, but TCK tests relative to Base URI, so we do that
29+
if (!path.startsWith("/")) {
30+
path = "/" + path;
31+
}
32+
return new URI(request.getScheme(), request.getAuthority(), null, null, null).resolve(prefix + path);
33+
} catch (URISyntaxException e) {
34+
throw new RuntimeException(e);
35+
}
36+
}
37+
4438
private static String determinePrefix(ServerHttpRequest serverHttpRequest, Deployment deployment) {
4539
String prefix = "";
4640
if (deployment != null) {
@@ -68,24 +62,7 @@ static URI determineContentLocation(URI location) {
6862
ResteasyReactiveRequestContext request = CurrentRequestManager.get();
6963
if (request != null) {
7064
// FIXME: this leaks server stuff onto the client
71-
ServerHttpRequest req = request.serverRequest();
72-
try {
73-
String host = req.getRequestHost();
74-
int port = -1;
75-
int index = host.lastIndexOf(":");
76-
if (index > -1 && (host.charAt(0) != '[' || index > host.lastIndexOf("]"))) {
77-
port = Integer.parseInt(host.substring(index + 1));
78-
host = host.substring(0, index);
79-
}
80-
String path = location.toString();
81-
if (!path.startsWith("/")) {
82-
path = "/" + path;
83-
}
84-
location = new URI(req.getRequestScheme(), null, host, port, null, null, null)
85-
.resolve(path);
86-
} catch (URISyntaxException e) {
87-
throw new RuntimeException(e);
88-
}
65+
location = getUri(location.toString(), request, false);
8966
}
9067
}
9168
return location;

independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/UriInfoImpl.java

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap;
1818
import org.jboss.resteasy.reactive.common.util.URIDecoder;
1919
import org.jboss.resteasy.reactive.common.util.UnmodifiableMultivaluedMap;
20-
import org.jboss.resteasy.reactive.server.core.Deployment;
2120
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;
2221
import org.jboss.resteasy.reactive.server.core.UriMatch;
2322
import org.jboss.resteasy.reactive.server.mapping.RuntimeResource;
@@ -49,14 +48,16 @@ public String getPath() {
4948

5049
@Override
5150
public String getPath(boolean decode) {
52-
if (!decode)
51+
if (!decode) {
5352
throw encodedNotSupported();
53+
}
5454
// TCK says normalized
5555
String path = URIDecoder.decodeURIComponent(currentRequest.getPath(), false);
5656
// the path must not contain the prefix
5757
String prefix = currentRequest.getDeployment().getPrefix();
58-
if (prefix.isEmpty())
58+
if (prefix.isEmpty()) {
5959
return path;
60+
}
6061
// else skip the prefix
6162
if (path.length() == prefix.length()) {
6263
return "/";
@@ -71,8 +72,9 @@ public List<PathSegment> getPathSegments() {
7172

7273
@Override
7374
public List<PathSegment> getPathSegments(boolean decode) {
74-
if (!decode)
75+
if (!decode) {
7576
throw encodedNotSupported();
77+
}
7678
return PathSegmentImpl.parseSegments(getPath(), decode);
7779
}
7880

@@ -119,24 +121,7 @@ public UriBuilder getAbsolutePathBuilder() {
119121

120122
@Override
121123
public URI getBaseUri() {
122-
try {
123-
Deployment deployment = currentRequest.getDeployment();
124-
// the TCK doesn't tell us, but Stuart and Georgios prefer dressing their base URIs with useless slashes ;)
125-
String prefix = "/";
126-
if (deployment != null) {
127-
// prefix can be empty, but if it's not it will not end with a slash
128-
prefix = deployment.getPrefix();
129-
if (prefix.isEmpty())
130-
prefix = "/";
131-
else
132-
prefix = prefix + "/";
133-
}
134-
return new URI(currentRequest.getScheme(), currentRequest.getAuthority(),
135-
prefix,
136-
null, null);
137-
} catch (URISyntaxException e) {
138-
throw new RuntimeException(e);
139-
}
124+
return LocationUtil.getUri("", currentRequest, true);
140125
}
141126

142127
@Override
@@ -151,8 +136,9 @@ public MultivaluedMap<String, String> getPathParameters() {
151136

152137
@Override
153138
public MultivaluedMap<String, String> getPathParameters(boolean decode) {
154-
if (!decode)
139+
if (!decode) {
155140
throw encodedNotSupported();
141+
}
156142
// pathParams have to be recreated when the target changes.
157143
// this happens e.g. when the ResteasyReactiveRequestContext#restart is called for sub resources
158144
// The sub resource, can have additional path params that are not present on the locator
@@ -174,8 +160,9 @@ public MultivaluedMap<String, String> getQueryParameters() {
174160

175161
@Override
176162
public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
177-
if (!decode)
163+
if (!decode) {
178164
throw encodedNotSupported();
165+
}
179166
if (queryParams == null) {
180167
queryParams = new QuarkusMultivaluedHashMap<>();
181168
Collection<String> entries = currentRequest.serverRequest().queryParamNames();
@@ -193,8 +180,9 @@ public List<String> getMatchedURIs() {
193180

194181
@Override
195182
public List<String> getMatchedURIs(boolean decode) {
196-
if (!decode)
183+
if (!decode) {
197184
throw encodedNotSupported();
185+
}
198186
if (currentRequest.getTarget() == null) {
199187
return Collections.emptyList();
200188
}

independent-projects/resteasy-reactive/server/runtime/src/test/java/org/jboss/resteasy/reactive/server/jaxrs/ResponseBuilderImplTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ public class ResponseBuilderImplTest {
1616
@Test
1717
public void shouldBuildWithNonAbsoulteLocationAndIPv6Address() {
1818
var context = Mockito.mock(ResteasyReactiveRequestContext.class, Mockito.RETURNS_DEEP_STUBS);
19-
Mockito.when(context.serverRequest().getRequestHost()).thenReturn("[0:0:0:0:0:0:0:1]");
19+
Mockito.when(context.getScheme()).thenReturn("https");
20+
Mockito.when(context.getAuthority()).thenReturn("[0:0:0:0:0:0:0:1]");
2021
Mockito.when(context.getDeployment().getPrefix()).thenReturn("/prefix");
2122
CurrentRequestManager.set(context);
2223
var response = ResponseBuilderImpl.ok().location(URI.create("/host")).build();
23-
assertEquals("//[0:0:0:0:0:0:0:1]/prefix/host", response.getLocation().toString());
24+
assertEquals("https://[0:0:0:0:0:0:0:1]/prefix/host", response.getLocation().toString());
2425

2526
response = ResponseBuilderImpl.ok().contentLocation(URI.create("/host")).build();
26-
assertEquals("//[0:0:0:0:0:0:0:1]/host", response.getHeaders().getFirst(HttpHeaders.CONTENT_LOCATION).toString());
27+
assertEquals("https://[0:0:0:0:0:0:0:1]/host", response.getHeaders().getFirst(HttpHeaders.CONTENT_LOCATION).toString());
2728
}
2829

2930
}

independent-projects/resteasy-reactive/server/runtime/src/test/java/org/jboss/resteasy/reactive/server/jaxrs/RestResponseBuilderImplTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ public class RestResponseBuilderImplTest {
1616
@Test
1717
public void shouldBuildWithNonAbsoulteLocationAndIPv6Address() {
1818
var context = Mockito.mock(ResteasyReactiveRequestContext.class, Mockito.RETURNS_DEEP_STUBS);
19-
Mockito.when(context.serverRequest().getRequestHost()).thenReturn("[0:0:0:0:0:0:0:1]");
19+
Mockito.when(context.getScheme()).thenReturn("https");
20+
Mockito.when(context.getAuthority()).thenReturn("[0:0:0:0:0:0:0:1]");
2021
Mockito.when(context.getDeployment().getPrefix()).thenReturn("/prefix");
2122
CurrentRequestManager.set(context);
2223
var response = RestResponseBuilderImpl.ok().location(URI.create("/host")).build();
23-
assertEquals("//[0:0:0:0:0:0:0:1]/prefix/host", response.getLocation().toString());
24+
assertEquals("https://[0:0:0:0:0:0:0:1]/prefix/host", response.getLocation().toString());
2425

2526
response = RestResponseBuilderImpl.ok().contentLocation(URI.create("/host")).build();
26-
assertEquals("//[0:0:0:0:0:0:0:1]/host", response.getHeaders().getFirst(HttpHeaders.CONTENT_LOCATION).toString());
27+
assertEquals("https://[0:0:0:0:0:0:0:1]/host", response.getHeaders().getFirst(HttpHeaders.CONTENT_LOCATION).toString());
2728
}
2829

2930
}

0 commit comments

Comments
 (0)