Skip to content

Commit

Permalink
Merge pull request #593 from fcrepo4/content-headers
Browse files Browse the repository at this point in the history
Add Content headers to the HEAD response for a resource
  • Loading branch information
Andrew Woods committed Oct 27, 2014
2 parents 321c1b2 + 16c4e24 commit d67b0fa
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 27 deletions.
Expand Up @@ -31,6 +31,7 @@
import org.fcrepo.http.commons.responses.RangeRequestInputStream;
import org.fcrepo.kernel.Datastream;
import org.fcrepo.kernel.FedoraBinary;
import org.fcrepo.kernel.FedoraObject;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.kernel.exception.InvalidChecksumException;
import org.fcrepo.kernel.exception.MalformedRdfException;
Expand Down Expand Up @@ -92,6 +93,7 @@
import static javax.ws.rs.core.Response.status;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.jena.riot.RDFLanguages.contentTypeToLang;
import static org.fcrepo.kernel.RdfLexicon.LDP_NAMESPACE;
import static org.fcrepo.kernel.RdfLexicon.isManagedNamespace;
import static org.slf4j.LoggerFactory.getLogger;

Expand Down Expand Up @@ -123,8 +125,6 @@ public abstract class ContentExposingResource extends FedoraBaseResource {

protected abstract String externalPath();

protected abstract void addResourceHttpHeaders(FedoraResource resource);

protected Response getContent(final Prefer prefer,
final String rangeValue,
final RdfStream rdfStream) throws IOException {
Expand Down Expand Up @@ -344,16 +344,9 @@ protected Response getBinaryContent(final String rangeValue)
builder = ok(content);
}

final ContentDisposition contentDisposition = ContentDisposition.type("attachment")
.fileName(binary.getFilename())
.creationDate(binary.getCreatedDate())
.modificationDate(binary.getLastModifiedDate())
.size(binary.getContentSize())
.build();

// we set the content-type explicitly to avoid content-negotiation from getting in the way
return builder.type(binary.getMimeType())
.header("Accept-Ranges", "bytes")
.header("Content-Disposition", contentDisposition)
.cacheControl(cc)
.build();

Expand Down Expand Up @@ -384,6 +377,40 @@ protected FedoraResource resource() {
return resource;
}


/**
* Add any resource-specific headers to the response
* @param resource
*/
protected void addResourceHttpHeaders(final FedoraResource resource) {
if (resource instanceof FedoraBinary) {

final FedoraBinary binary = (FedoraBinary)resource;
final ContentDisposition contentDisposition = ContentDisposition.type("attachment")
.fileName(binary.getFilename())
.creationDate(binary.getCreatedDate())
.modificationDate(binary.getLastModifiedDate())
.size(binary.getContentSize())
.build();

servletResponse.addHeader("Content-Type", binary.getMimeType());
servletResponse.addHeader("Content-Length", String.valueOf(binary.getContentSize()));
servletResponse.addHeader("Accept-Ranges", "bytes");
servletResponse.addHeader("Content-Disposition", contentDisposition.toString());
}

servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "Resource>;rel=\"type\"");

if (resource instanceof Datastream) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\"");
} else if (resource instanceof FedoraBinary) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\"");
} else if (resource instanceof FedoraObject) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "DirectContainer>;rel=\"type\"");
}

}

/**
* Evaluate the cache control headers for the request to see if it can be served from
* the cache.
Expand Down
20 changes: 8 additions & 12 deletions fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraLdp.java
Expand Up @@ -87,7 +87,6 @@
import static org.fcrepo.http.commons.domain.RDFMediaType.TURTLE_X;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_DATASTREAM;
import static org.fcrepo.jcr.FedoraJcrTypes.FEDORA_OBJECT;
import static org.fcrepo.kernel.RdfLexicon.LDP_NAMESPACE;
import static org.fcrepo.kernel.impl.services.TransactionServiceImpl.getCurrentTransactionId;
import static org.slf4j.LoggerFactory.getLogger;

Expand Down Expand Up @@ -149,7 +148,13 @@ public Response head() {

addResourceHttpHeaders(resource());

return ok().build();
final Response.ResponseBuilder builder = ok();

if (resource() instanceof FedoraBinary) {
builder.type(((FedoraBinary) resource()).getMimeType());
}

return builder.build();
}

/**
Expand Down Expand Up @@ -439,16 +444,7 @@ && isRdfContentType(contentTypeString)) {

@Override
protected void addResourceHttpHeaders(final FedoraResource resource) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "Resource>;rel=\"type\"");

if (resource instanceof Datastream) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\"");
} else if (resource instanceof FedoraBinary) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\"");
} else if (resource instanceof FedoraObject) {
servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "DirectContainer>;rel=\"type\"");
}

super.addResourceHttpHeaders(resource);

if (getCurrentTransactionId(session) != null) {
final String canonical = translator().reverse()
Expand Down
Expand Up @@ -119,7 +119,7 @@
import org.apache.jena.riot.Lang;
import org.fcrepo.http.commons.domain.RDFMediaType;
import org.fcrepo.kernel.RdfLexicon;
import org.glassfish.grizzly.http.util.ContentType;
import org.glassfish.jersey.media.multipart.ContentDisposition;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
Expand Down Expand Up @@ -185,11 +185,19 @@ public void testHeadObject() throws Exception {
public void testHeadDatastream() throws Exception {
final String pid = getRandomUniquePid();

createDatastream(pid, "x", pid);
createDatastream(pid, "x", "123");

final String location = serverAddress + pid + "/x";
final HttpHead headObjMethod = new HttpHead(location);
assertEquals(200, getStatus(headObjMethod));
final HttpResponse response = client.execute(headObjMethod);
assertEquals(OK.getStatusCode(), response.getStatusLine().getStatusCode());

assertEquals(TEXT_PLAIN, response.getFirstHeader("Content-Type").getValue());
assertEquals("3", response.getFirstHeader("Content-Length").getValue());
assertEquals("bytes", response.getFirstHeader("Accept-Ranges").getValue());
final ContentDisposition disposition
= new ContentDisposition(response.getFirstHeader("Content-Disposition").getValue());
assertEquals("attachment", disposition.getType());
}

@Test
Expand Down Expand Up @@ -220,6 +228,8 @@ public void testOptionsBinary() throws Exception {
assertEquals(OK.getStatusCode(), optionsResponse.getStatusLine().getStatusCode());

assertResourceOptionsHeaders(optionsResponse);

assertEquals("0", optionsResponse.getFirstHeader("Content-Length").getValue());
}

@Test
Expand Down Expand Up @@ -991,8 +1001,12 @@ public void testGetDatastream() throws Exception {
assertEquals(EntityUtils.toString(response.getEntity()), 200, response
.getStatusLine().getStatusCode());

assertEquals(TEXT_PLAIN,
ContentType.newContentType(response.getFirstHeader("Content-Type").getValue()).getMimeType());
assertEquals(TEXT_PLAIN, response.getFirstHeader("Content-Type").getValue());
assertEquals("3", response.getFirstHeader("Content-Length").getValue());
assertEquals("bytes", response.getFirstHeader("Accept-Ranges").getValue());
final ContentDisposition disposition
= new ContentDisposition(response.getFirstHeader("Content-Disposition").getValue());
assertEquals("attachment", disposition.getType());

final Collection<String> links = getLinkHeaders(response);
assertTrue("Didn't find 'describedby' link header!",
Expand Down

0 comments on commit d67b0fa

Please sign in to comment.