Skip to content

Improved support for Link header handling #1129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.trellisldp.common;

import static java.util.Collections.emptyList;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.HttpHeaders.LINK;
import static org.trellisldp.common.HttpConstants.ACCEPT_DATETIME;
Expand All @@ -34,6 +35,8 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.trellisldp.vocabulary.LDP;

/**
* A class representing an HTTP request with various LDP-related headers and query parameters.
*
Expand Down Expand Up @@ -110,14 +113,19 @@ public String getSlug() {
}

/**
* Get the Link header.
* Get the first LDP Link header.
*
* @return the Link header
* @return the first LDP Link header
*/
public Link getLink() {
final String link = headers.getFirst(LINK);
if (link != null) {
return Link.valueOf(link);
for (final String header : headers.getOrDefault(LINK, emptyList())) {
final Link link = Link.valueOf(header);
if (Link.TYPE.equals(link.getRel())) {
final String uri = link.getUri().toString();
if (uri.startsWith(LDP.getNamespace()) && !uri.equals(LDP.Resource.getIRIString())) {
return link;
}
}
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ void testLinkHeader() {
final URI uri = create("http://example.com/");
final MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
final MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
headers.add("Link", "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"");
headers.add("Link", "<http://example.com/SomeType>; rel=\"type\"");
headers.add("Link", "<http://www.w3.org/ns/ldp#BasicContainer>; rel=\"about\"");
final String rawLink = "<http://www.w3.org/ns/ldp#BasicContainer>; rel=\"type\"";
headers.add("Link", rawLink);
final MultivaluedMap<String, String> pathParams = new MultivaluedHashMap<>();
Expand All @@ -224,4 +227,27 @@ void testLinkHeader() {
final TrellisRequest req = new TrellisRequest(mockRequest, mockUriInfo, mockHeaders);
assertEquals(Link.valueOf(rawLink), req.getLink());
}

@Test
void testSkippedLinkHeaders() {
final URI uri = create("http://example.com/");
final MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
final MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
headers.add("Link", "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"");
headers.add("Link", "<http://example.com/SomeType>; rel=\"type\"");
headers.add("Link", "<http://www.w3.org/ns/ldp#BasicContainer>; rel=\"about\"");
final MultivaluedMap<String, String> pathParams = new MultivaluedHashMap<>();
pathParams.add("path", "resource");

when(mockUriInfo.getPath()).thenReturn("resource");
when(mockUriInfo.getPathParameters()).thenReturn(pathParams);
when(mockUriInfo.getQueryParameters()).thenReturn(queryParams);
when(mockUriInfo.getBaseUri()).thenReturn(uri);
when(mockHeaders.getRequestHeaders()).thenReturn(headers);
when(mockRequest.getMethod()).thenReturn(GET);
when(mockHeaders.getAcceptableMediaTypes()).thenReturn(singletonList(RdfMediaType.TEXT_TURTLE_TYPE));

final TrellisRequest req = new TrellisRequest(mockRequest, mockUriInfo, mockHeaders);
assertNull(req.getLink());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,8 @@ private static RDFSyntax getRdfSyntax(final String contentType, final List<RDFSy
}

private static IRI getLdpType(final Link link, final RDFSyntax syntax, final String contentType) {
if (link != null && Link.TYPE.equals(link.getRel())) {
final String uri = link.getUri().toString();
if (uri.startsWith(LDP.getNamespace())) {
final IRI iri = rdf.createIRI(uri);
if (!LDP.Resource.equals(iri)) {
return iri;
}
}
if (link != null) {
return rdf.createIRI(link.getUri().toString());
}
return contentType != null && syntax == null ? LDP.NonRDFSource : LDP.RDFSource;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,8 @@ private IRI getLdpType() {
return getResource().getInteractionModel();
}
final Link link = getRequest().getLink();
if (link != null && Link.TYPE.equals(link.getRel())) {
final String uri = link.getUri().toString();
if (uri.startsWith(LDP.getNamespace()) && !uri.equals(LDP.Resource.getIRIString())) {
return rdf.createIRI(uri);
}
if (link != null) {
return rdf.createIRI(link.getUri().toString());
}
if (getResource() != null) {
return getResource().getInteractionModel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void testDefaultType2() throws IOException {

@Test
void testDefaultType3() throws IOException {
when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.Resource.getIRIString()).rel(TYPE).build());
when(mockTrellisRequest.getLink()).thenReturn(null);

final PostHandler handler = buildPostHandler(RESOURCE_EMPTY, NEW_RESOURCE, null);
try (final Response res = handler.createResource(handler.initialize(mockParent, MISSING_RESOURCE))
Expand All @@ -144,7 +144,7 @@ void testDefaultType3() throws IOException {
@Test
void testDefaultType4() throws IOException {
when(mockTrellisRequest.getContentType()).thenReturn(TEXT_PLAIN);
when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.Resource.getIRIString()).rel(TYPE).build());
when(mockTrellisRequest.getLink()).thenReturn(null);

final PostHandler handler = buildPostHandler(RESOURCE_SIMPLE, NEW_RESOURCE, null);
try (final Response res = handler.createResource(handler.initialize(mockParent, MISSING_RESOURCE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ void testNoVersioning() {
}

@Test
void testPutLdpResourceDefaultType() {
void testPutNoLdpLinkType() {
when(mockTrellisRequest.getPath()).thenReturn(RESOURCE_NAME);
when(mockTrellisRequest.getContentType()).thenReturn(TEXT_TURTLE);
when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.Resource.getIRIString()).rel(TYPE).build());
when(mockTrellisRequest.getLink()).thenReturn(null);

final PutHandler handler = buildPutHandler(RESOURCE_TURTLE, null, false);
try (final Response res = handler.setResource(handler.initialize(mockParent, mockResource))
Expand Down Expand Up @@ -214,10 +214,10 @@ void testPutLdpResourceContainerUncontained() throws IOException {
}

@Test
void testPutLdpBinaryResourceWithLdprLink() {
void testPutLdpBinaryResourceNoLdpLink() {
when(mockResource.getInteractionModel()).thenReturn(LDP.NonRDFSource);
when(mockTrellisRequest.getContentType()).thenReturn(TEXT_PLAIN);
when(mockTrellisRequest.getLink()).thenReturn(fromUri(LDP.Resource.getIRIString()).rel(TYPE).build());
when(mockTrellisRequest.getLink()).thenReturn(null);

final PutHandler handler = buildPutHandler(RESOURCE_SIMPLE, null);
try (final Response res = handler.setResource(handler.initialize(mockParent, mockResource))
Expand Down