Skip to content

Instantly share code, notes, and snippets.

@cpilsworth
Last active June 22, 2023 16:34
Show Gist options
  • Save cpilsworth/e0f71afd35b373354df0613fbbc1915d to your computer and use it in GitHub Desktop.
Save cpilsworth/e0f71afd35b373354df0613fbbc1915d to your computer and use it in GitHub Desktop.
Oak Direct Binary Download
package com.chrisp.rde.core.servlets;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.api.binary.BinaryDownload;
import org.apache.jackrabbit.api.binary.BinaryDownloadOptions;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.OptingServlet;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Binary;
import javax.jcr.Node;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.net.URI;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component(service = {Servlet.class})
@SlingServletResourceTypes(
resourceTypes = "dam/Asset",
methods = "GET",
selectors = "woi"
)
/**
* Returns a redirect to the cloud storage of the underlying original asset when `woi` selector added.
* e.g. https://author-p31359-e934772.adobeaemcloud.com/content/dam/xxxx/sample.jpg.woi/image.png
*/
public class ImageSignedUrlRedirectServlet extends SlingSafeMethodsServlet implements OptingServlet {
private static final Logger log = LoggerFactory.getLogger(ImageSignedUrlRedirectServlet.class);
public static final String DEFAULT_FILENAME_PATTERN = "(image|img)\\.(.+)";
private final Pattern lastSuffixPattern = Pattern.compile(DEFAULT_FILENAME_PATTERN);
/**
* Only accept requests that.
* - Are not null
* - Have a suffix that matches the image file name pattern
* @param request SlingRequest object
* @return true if the Servlet should handle the request
*/
@Override
public final boolean accepts(final SlingHttpServletRequest request) {
if (request == null) {
return false;
}
final String suffix = request.getRequestPathInfo().getSuffix();
if (StringUtils.isBlank(suffix)) {
log.info("no suffix");
return false;
}
final String lastSuffix = PathInfoUtil.getLastSuffixSegment(request);
final Matcher matcher = lastSuffixPattern.matcher(lastSuffix);
final boolean match = matcher.matches();
log.info("match {} ", match);
return match;
}
@Override
protected final void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws
ServletException, IOException {
final Resource resource = request.getResource();
if (!isAsset(resource)) {
response.setStatus(404);
log.info("not an asset");
return;
}
try {
final Resource rendition = resource.getChild("jcr:content/renditions/original");
final Node ntFile = rendition.adaptTo(Node.class);
final Node ntResource = ntFile.getNode("jcr:content");
final Binary binary = ntResource.getProperty("jcr:data").getBinary();
if (binary instanceof BinaryDownload) {
final BinaryDownload binaryDownload = (BinaryDownload) binary;
final BinaryDownloadOptions.BinaryDownloadOptionsBuilder builder = BinaryDownloadOptions.builder()
.withFileName(ntFile.getName())
.withMediaType(ntResource.getProperty("jcr:mimeType").getString());
if (ntResource.hasProperty("jcr:encoding")) {
builder.withCharacterEncoding(ntResource.getProperty("jcr:encoding").getString());
}
final URI uri = binaryDownload.getURI(builder.build());
log.info("redirect: {}", uri);
response.sendRedirect(uri.toString());
}
} catch (Throwable e) {
log.error("Exception fetching signed url", e);
response.setStatus(500);
}
}
public static boolean isAsset(Resource resource) {
return null != resource && "dam:Asset".equals(resource.getResourceType());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment