Commit 79337d9d authored by Matija Obreza's avatar Matija Obreza

Repository API: Better error handling for downloads

parent 341c11f5
......@@ -206,7 +206,7 @@ public class ApiExceptionHandler {
* @return the api error
*/
@ResponseStatus(code = HttpStatus.NOT_FOUND)
@ExceptionHandler(value = { NoSuchRepositoryFileException.class, NotFoundElement.class, org.genesys2.server.exception.NotFoundElement.class })
@ExceptionHandler(value = { NoSuchRepositoryFileException.class, NotFoundElement.class })
@ResponseBody
public ApiError<Exception> handleNotFound(final Exception e, final HttpServletRequest request) {
LOG.warn("Element not found {} {}", request.getMethod(), request.getRequestURL());
......
......@@ -220,19 +220,22 @@ public class RepositoryController {
response.flushBuffer();
return;
}
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=86400, s-maxage=86400, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setHeader(HttpHeaders.ETAG, eTag);
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
final byte[] data = repositoryService.getFileBytes(repositoryFile);
if (data != null) {
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=86400, s-maxage=86400, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setHeader(HttpHeaders.ETAG, eTag);
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
response.setContentLength(data.length);
response.getOutputStream().write(data);
} else {
throw new NoSuchRepositoryFileException("Bytes not available");
}
response.flushBuffer();
}
......
......@@ -37,10 +37,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.HandlerMapping;
/**
......@@ -48,7 +47,7 @@ import org.springframework.web.servlet.HandlerMapping;
*
* @author Matija Obreza
*/
@Controller("repositoryDownload1")
@RestController("repositoryDownload1")
public class RepositoryDownloadController {
public static final Logger LOG = LoggerFactory.getLogger(RepositoryDownloadController.class);
......@@ -59,7 +58,7 @@ public class RepositoryDownloadController {
@Autowired
private BytesStorageService byteStorageService;
private void downloadFile(final Path path, final String name, final String ext, final HttpServletResponse response, HttpServletRequest request) throws IOException {
private void downloadFile(final Path path, final String name, final String ext, final HttpServletResponse response, HttpServletRequest request) throws IOException, NotFoundElement, NoSuchRepositoryFileException {
byte[] data;
boolean noCache = "no-cache".equalsIgnoreCase(request.getHeader(HttpHeaders.CACHE_CONTROL))
......@@ -115,6 +114,9 @@ public class RepositoryDownloadController {
}
data = this.repositoryService.getFileBytes(repositoryFile);
if (data == null) {
throw new NotFoundElement("No such thing");
}
// Cache for 24hrs
if (SecurityContextUtil.anyoneHasPermission(repositoryFile, "READ")) {
......@@ -137,14 +139,9 @@ public class RepositoryDownloadController {
}
}
if (data != null) {
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.flushBuffer();
} else {
throw new NotFoundElement("No such thing. Sorry");
}
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.flushBuffer();
}
private boolean clientCacheValid(RepositoryFile repositoryFile, HttpServletRequest request, HttpServletResponse response) throws IOException {
......@@ -179,8 +176,8 @@ public class RepositoryDownloadController {
/**
* Serve the bytes of the repository object
*/
@RequestMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**", method = RequestMethod.GET)
public void downloadFile(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
@GetMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**")
public void downloadFile(final HttpServletRequest request, final HttpServletResponse response) throws IOException, NotFoundElement, NoSuchRepositoryFileException {
final String fullpath = ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).substring((RepositoryController.CONTROLLER_URL + "/download/d").length());
if (LOG.isTraceEnabled()) {
LOG.trace("Fullname: {}", fullpath);
......@@ -206,8 +203,8 @@ public class RepositoryDownloadController {
/**
* Return repository object metadata
*/
@RequestMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**", method = RequestMethod.GET, params = { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody RepositoryFile getMetadata(final HttpServletRequest request) throws IOException, NoSuchRepositoryFileException {
@GetMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**", params = { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody RepositoryFile getMetadata(final HttpServletRequest request) throws IOException, NotFoundElement, NoSuchRepositoryFileException {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
LOG.debug("Fullname: {}", fullpath);
......
......@@ -145,19 +145,22 @@ public class RepositoryController extends ApiBaseController {
response.flushBuffer();
return;
}
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=86400, s-maxage=86400, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setHeader(HttpHeaders.ETAG, eTag);
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
final byte[] data = repositoryService.getFileBytes(repositoryFile);
if (data != null) {
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=86400, s-maxage=86400, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setHeader(HttpHeaders.ETAG, eTag);
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
response.setContentLength(data.length);
response.getOutputStream().write(data);
} else {
throw new NoSuchRepositoryFileException("Bytes not available");
}
response.flushBuffer();
}
......
......@@ -16,14 +16,15 @@
package org.genesys2.server.api.v2;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.genesys.blocks.security.SecurityContextUtil;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryFile;
......@@ -34,8 +35,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.HandlerMapping;
......@@ -58,7 +59,7 @@ public class RepositoryDownloadController extends ApiBaseController {
/**
* Serve the bytes of the repository object
*/
@RequestMapping(value = "/download/d/**", method = RequestMethod.GET)
@GetMapping(value = "/download/d/**")
public void downloadFile(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final String fullpath = ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).substring((RepositoryController.CONTROLLER_URL + "/download/d").length());
if (LOG.isTraceEnabled()) {
......@@ -79,7 +80,7 @@ public class RepositoryDownloadController extends ApiBaseController {
/**
* Return repository object metadata
*/
@RequestMapping(value = "/download/d/**", method = RequestMethod.GET, params = { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = "/download/d/**", params = { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
public RepositoryFile getMetadata(final HttpServletRequest request) throws NoSuchRepositoryFileException {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
......@@ -164,6 +165,10 @@ public class RepositoryDownloadController extends ApiBaseController {
data = this.repositoryService.getFileBytes(repositoryFile);
if (data == null) {
throw new NotFoundElement("No such thing. Sorry");
}
// Cache for 24hrs
if (SecurityContextUtil.anyoneHasPermission(repositoryFile, "READ")) {
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=2592000, s-maxage=2592000, public, no-transform");
......@@ -185,14 +190,10 @@ public class RepositoryDownloadController extends ApiBaseController {
}
}
if (data != null) {
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.flushBuffer();
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.flushBuffer();
} else {
throw new NotFoundElement("No such thing. Sorry");
}
}
private boolean clientCacheValid(RepositoryFile repositoryFile, HttpServletRequest request, HttpServletResponse response) throws IOException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment