Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use message/external-body MIME type for registering 'redirect' binaries
  • Loading branch information
cbeer committed Oct 30, 2014
1 parent 3ad9b11 commit c9a435b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
Expand Up @@ -93,6 +93,7 @@
import static javax.ws.rs.core.Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE;
import static javax.ws.rs.core.Response.ok;
import static javax.ws.rs.core.Response.status;
import static javax.ws.rs.core.Response.temporaryRedirect;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.jena.riot.RDFLanguages.contentTypeToLang;
import static org.fcrepo.jcr.FedoraJcrTypes.LDP_BASIC_CONTAINER;
Expand All @@ -116,6 +117,7 @@
public abstract class ContentExposingResource extends FedoraBaseResource {

private static final Logger LOGGER = getLogger(ContentExposingResource.class);
public static final MediaType MESSAGE_EXTERNAL_BODY = MediaType.valueOf("message/external-body");

@Context protected Request request;
@Context protected HttpServletResponse servletResponse;
Expand Down Expand Up @@ -161,7 +163,20 @@ public Triple apply(final Statement input) {
}
}));
} else {
return getBinaryContent(rangeValue);

final MediaType mediaType = MediaType.valueOf(contentTypeString);
if (mediaType.isCompatible(MESSAGE_EXTERNAL_BODY)
&& mediaType.getParameters().containsKey("access-type")
&& mediaType.getParameters().get("access-type").equals("URL")
&& mediaType.getParameters().containsKey("URL") ) {
try {
return temporaryRedirect(new URI(mediaType.getParameters().get("URL"))).build();
} catch (final URISyntaxException e) {
throw new RepositoryRuntimeException(e);
}
} else {
return getBinaryContent(rangeValue);
}
}

} else {
Expand Down Expand Up @@ -553,13 +568,13 @@ protected static boolean isRdfContentType(final String contentTypeString) {
protected void replaceResourceBinaryWithStream(final FedoraBinary result,
final InputStream requestBodyStream,
final ContentDisposition contentDisposition,
final String contentTypeString,
final MediaType contentType,
final String checksum) throws InvalidChecksumException {
final URI checksumURI = checksumURI(checksum);
final String originalFileName = contentDisposition != null ? contentDisposition.getFileName() : "";

result.setContent(requestBodyStream,
contentTypeString,
contentType.toString(),
checksumURI,
originalFileName,
storagePolicyDecisionPoint);
Expand Down
Expand Up @@ -274,7 +274,7 @@ && isRdfContentType(contentType.toString())) {
}
} else if (resource instanceof FedoraBinary) {
replaceResourceBinaryWithStream((FedoraBinary) resource,
requestBodyStream, contentDisposition, contentType.toString(), checksum);
requestBodyStream, contentDisposition, requestContentType, checksum);
} else if (!resource.isNew()) {
throw new ClientErrorException("Invalid Content Type " + requestContentType, UNSUPPORTED_MEDIA_TYPE);
}
Expand Down Expand Up @@ -410,7 +410,7 @@ && isRdfContentType(contentTypeString)) {
LOGGER.trace("Created a datastream and have a binary payload.");

replaceResourceBinaryWithStream((FedoraBinary) result,
requestBodyStream, contentDisposition, contentTypeString, checksum);
requestBodyStream, contentDisposition, requestContentType, checksum);

} else if (contentTypeString.equals(contentTypeSPARQLUpdate)) {
LOGGER.trace("Found SPARQL-Update content, applying..");
Expand Down
Expand Up @@ -36,6 +36,7 @@
import static javax.ws.rs.core.Response.Status.NOT_MODIFIED;
import static javax.ws.rs.core.Response.Status.NO_CONTENT;
import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT;
import static nu.validator.htmlparser.common.DoctypeExpectation.NO_DOCTYPE_ERRORS;
import static nu.validator.htmlparser.common.XmlViolationPolicy.ALLOW;
import static org.apache.http.impl.client.cache.CacheConfig.DEFAULT;
Expand Down Expand Up @@ -106,6 +107,7 @@
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
Expand All @@ -117,6 +119,7 @@
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.cache.CachingHttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.jena.riot.Lang;
Expand Down Expand Up @@ -2190,6 +2193,32 @@ public void testGraphShouldNotBeTooLumpy() throws Exception {

}

@Test
public void testExternalMessageBody() throws Exception {

// we need a client that won't automatically follow redirects
final HttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();

final String pid = getRandomUniquePid();

final HttpPut httpPut = putObjMethod(pid);
httpPut.addHeader("Content-Type", "message/external-body; access-type=URL; " +
"URL=\"http://www.example.com/file\"");

final HttpResponse response = client.execute(httpPut);
final int status = response.getStatusLine().getStatusCode();
assertEquals("Didn't get a CREATED response!", CREATED.getStatusCode(), status);

final String subjectURI = response.getFirstHeader("Location").getValue();

final HttpGet get = new HttpGet(subjectURI);
final HttpResponse getResponse = client.execute(get);

LOGGER.error(EntityUtils.toString(getResponse.getEntity()));
assertEquals(TEMPORARY_REDIRECT.getStatusCode(), getResponse.getStatusLine().getStatusCode());
assertEquals("http://www.example.com/file", getResponse.getFirstHeader("Location").getValue());
}

private Date getDateFromModel( final Model model, final Resource subj, final Property pred ) throws Exception {
final StmtIterator stmts = model.listStatements( subj, pred, (String)null );
if ( stmts.hasNext() ) {
Expand Down

0 comments on commit c9a435b

Please sign in to comment.