Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 632888b

Browse files
author
Adam Lindenthal
committed
JERSEY-2890 Regression - relative URI resolution
Change-Id: I1664dc8a76e4ae650714f597f928e4940db4b4ea
1 parent 5924385 commit 632888b

File tree

9 files changed

+350
-49
lines changed

9 files changed

+350
-49
lines changed

core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,28 @@ public final class ServerProperties {
709709
public static final String SUBRESOURCE_LOCATOR_CACHE_JERSEY_RESOURCE_ENABLED =
710710
"jersey.config.server.subresource.cache.jersey.resource.enabled";
711711

712+
/**
713+
* If {@code true} then Jersey will resolve relative URIs in the {@code Location} http header against the
714+
* request URI according to RFC7231 (new HTTP Specification).
715+
*
716+
* <p>
717+
* This behaviour violates the JAX-RS 2.0 specification (which dates older than RFC7231).
718+
* If {@link #LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED} is set to {@code true}, value of this property is not taken
719+
* into account.
720+
* </p>
721+
*
722+
* <p>
723+
* The default value is {@code false} (JAX-RS 2.0 compliant).
724+
* </p>
725+
* <p>
726+
* The name of the configuration property is <tt>{@value}</tt>.
727+
* </p>
728+
*
729+
* @since 2.22.1
730+
*/
731+
public static final String LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231 =
732+
"jersey.config.server.headers.location.relative.resolution.rfc7231";
733+
712734
/**
713735
* If {@code true} then Jersey will not attempt to resolve relative URIs in the {@code Location} http header against the
714736
* request URI.

core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ public class ServerRuntime {
148148

149149
private final boolean processResponseErrors;
150150

151+
/** Do not resolve relative URIs in the {@code Location} header */
151152
private final boolean disableLocationHeaderRelativeUriResolution;
153+
/** Resolve relative URIs according to RFC7231 (not JAX-RS 2.0 compliant */
154+
private final boolean rfc7231LocationHeaderRelativeUriResolution;
152155

153156
/*package */ static final ExternalRequestScope<Object> NOOP_EXTERNAL_REQ_SCOPE = new ExternalRequestScope<Object>() {
154157

@@ -254,6 +257,10 @@ private ServerRuntime(final Stage<RequestProcessingContext> requestProcessingRoo
254257
this.disableLocationHeaderRelativeUriResolution = ServerProperties.getValue(configuration.getProperties(),
255258
ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED,
256259
Boolean.FALSE, Boolean.class);
260+
261+
this.rfc7231LocationHeaderRelativeUriResolution = ServerProperties.getValue(configuration.getProperties(),
262+
ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231,
263+
Boolean.FALSE, Boolean.class);
257264
}
258265

259266
/**
@@ -302,7 +309,9 @@ public void run() {
302309
// set base URI into response builder thread-local variable
303310
// for later resolving of relative location URIs
304311
if (!disableLocationHeaderRelativeUriResolution) {
305-
OutboundJaxrsResponse.Builder.setBaseUri(request.getRequestUri());
312+
final URI uriToUse =
313+
rfc7231LocationHeaderRelativeUriResolution ? request.getRequestUri() : request.getBaseUri();
314+
OutboundJaxrsResponse.Builder.setBaseUri(uriToUse);
306315
}
307316

308317
final Ref<Endpoint> endpointRef = Refs.emptyRef();
@@ -350,14 +359,17 @@ ScheduledExecutorService getBackgroundScheduler() {
350359
* @param location location URI; value of the HTTP {@value HttpHeaders#LOCATION} response header.
351360
* @param headers mutable map of response headers.
352361
* @param request container request.
362+
* @param incompatible if set to {@code true}, uri will be resolved against the request uri, not the base uri;
363+
* this is correct against RFC7231, but does violate the JAX-RS 2.0 specs
353364
*/
354365
private static void ensureAbsolute(final URI location, final MultivaluedMap<String, Object> headers,
355-
final ContainerRequest request) {
366+
final ContainerRequest request, final boolean incompatible) {
356367
if (location == null || location.isAbsolute()) {
357368
return;
358369
}
359370
// according to RFC7231 (HTTP/1.1), this field can contain one single URI reference
360-
headers.putSingle(HttpHeaders.LOCATION, request.getRequestUri().resolve(location));
371+
final URI uri = incompatible ? request.getRequestUri() : request.getBaseUri();
372+
headers.putSingle(HttpHeaders.LOCATION, uri.resolve(location));
361373
}
362374

363375
private static class AsyncResponderHolder implements Value<AsyncContext> {
@@ -466,7 +478,8 @@ public void process(final Throwable throwable) {
466478
try {
467479
response = convertResponse(exceptionResponse);
468480
if (!runtime.disableLocationHeaderRelativeUriResolution) {
469-
ensureAbsolute(response.getLocation(), response.getHeaders(), request);
481+
ensureAbsolute(response.getLocation(), response.getHeaders(), request,
482+
runtime.rfc7231LocationHeaderRelativeUriResolution);
470483
}
471484
processingContext.monitoringEventBuilder().setContainerResponse(response)
472485
.setResponseSuccessfullyMapped(true);
@@ -659,7 +672,8 @@ private ContainerResponse writeResponse(final ContainerResponse response) {
659672
final ContainerResponseWriter writer = request.getResponseWriter();
660673

661674
if (!runtime.disableLocationHeaderRelativeUriResolution) {
662-
ServerRuntime.ensureAbsolute(response.getLocation(), response.getHeaders(), response.getRequestContext());
675+
ServerRuntime.ensureAbsolute(response.getLocation(), response.getHeaders(), response.getRequestContext(),
676+
runtime.rfc7231LocationHeaderRelativeUriResolution);
663677
}
664678

665679
if (!response.hasEntity()) {
@@ -682,7 +696,7 @@ private ContainerResponse writeResponse(final ContainerResponse response) {
682696
public OutputStream getOutputStream(final int contentLength) throws IOException {
683697
if (!runtime.disableLocationHeaderRelativeUriResolution) {
684698
ServerRuntime.ensureAbsolute(response.getLocation(), response.getHeaders(),
685-
response.getRequestContext());
699+
response.getRequestContext(), runtime.rfc7231LocationHeaderRelativeUriResolution);
686700
}
687701
final OutputStream outputStream = writer.writeResponseStatusAndHeaders(contentLength, response);
688702
return isHead ? null : outputStream;
@@ -914,7 +928,8 @@ public void run() {
914928
(response instanceof Response) ? (Response) response : Response.ok(response).build();
915929
if (!responder.runtime.disableLocationHeaderRelativeUriResolution) {
916930
ServerRuntime.ensureAbsolute(jaxrsResponse.getLocation(), jaxrsResponse.getHeaders(),
917-
responder.processingContext.request());
931+
responder.processingContext.request(),
932+
responder.runtime.rfc7231LocationHeaderRelativeUriResolution);
918933
}
919934
responder.process(new ContainerResponse(responder.processingContext.request(), jaxrsResponse));
920935
} catch (final Throwable t) {

docs/src/main/docbook/jersey.ent

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@
497497
<!ENTITY jersey.server.ServerProperties.WADL_FEATURE_DISABLE "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#WADL_FEATURE_DISABLE'>ServerProperties.WADL_FEATURE_DISABLE</link>" >
498498
<!ENTITY jersey.server.ServerProperties.WADL_GENERATOR_CONFIG "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#WADL_GENERATOR_CONFIG'>ServerProperties.WADL_GENERATOR_CONFIG</link>" >
499499
<!ENTITY jersey.server.ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED'>ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED</link>" >
500+
<!ENTITY jersey.server.ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231 "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231'>ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231</link>" >
500501
<!ENTITY jersey.server.Uri "<link xlink:href='&jersey.javadoc.uri.prefix;/server/Uri.html'>Uri</link>">
501502
<!ENTITY jersey.server.UriConnegFilter "<link xlink:href='&jersey.javadoc.uri.prefix;/server/filter/UriConnegFilter.html'>UriConnegFilter</link>">
502503
<!ENTITY jersey.server.WadlFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/server/wadl/WadlFeature.html'>WadlFeature</link>">

docs/src/main/docbook/migration.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@
7878
</section>
7979
</section>
8080

81+
<section xml:id="mig-2.22.1">
82+
<title>Migrating from Jersey 2.22 to 2.22.1</title>
83+
<section xml:id="mig-2.22.1-breaking-changes">
84+
<title>Breaking Changes</title>
85+
<para>
86+
Last version contained a change in relative URI resolution in the location header. Even though the change
87+
was fixing the discrepancy between the real behaviour and RFC7231, it also caused JAX-RS spec incompatibility
88+
in some cases. Furthermore, there was no way to preserve backwards compatibility.
89+
</para>
90+
<para>
91+
Therefore, the default behaviour was rollbacked and a new configuration property was introduced to switch
92+
to the RFC7231 compliant
93+
behaviour: &jersey.server.ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231;. Also,
94+
the possibility to switch the URI resolution completely off remains with the
95+
&jersey.server.ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_DISABLED; disabled switch. Both
96+
properties are false by default.
97+
</para>
98+
</section>
99+
</section>
100+
81101
<section xml:id="mig-2.22">
82102
<title>Migrating from Jersey 2.21 to 2.22</title>
83103
<section xml:id="mig-2.22-breaking-changes">

examples/server-sent-events/src/main/java/org/glassfish/jersey/examples/sse/DomainResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public Response post(@DefaultValue("0") @QueryParam("testSources") int testSourc
8080

8181
Executors.newSingleThreadExecutor().execute(process);
8282

83-
final URI processIdUri = UriBuilder.fromUri("process/{id}").build(process.getId());
83+
final URI processIdUri = UriBuilder.fromResource(DomainResource.class).path("process/{id}").build(process.getId());
8484
return Response.created(processIdUri).build();
8585
}
8686

0 commit comments

Comments
 (0)