changeset 1617:07fa6a16073e iiif-presentation-2

Manifester with better URL handling, basic auth and error handling, and getLastModified().
author Robert Casties <casties@mpiwg-berlin.mpg.de>
date Fri, 26 May 2017 15:47:14 +0200
parents 4a54658a376c
children e198d165ce75
files iiif-presentation/src/main/java/digilib/servlet/Manifester.java
diffstat 1 files changed, 82 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/iiif-presentation/src/main/java/digilib/servlet/Manifester.java	Fri May 26 15:45:14 2017 +0200
+++ b/iiif-presentation/src/main/java/digilib/servlet/Manifester.java	Fri May 26 15:47:14 2017 +0200
@@ -28,6 +28,8 @@
  */
 
 import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
 
 import javax.json.Json;
 import javax.json.stream.JsonGenerator;
@@ -41,7 +43,9 @@
 
 import org.apache.log4j.Logger;
 
+import digilib.auth.AuthOpException;
 import digilib.auth.AuthzOps;
+import digilib.conf.DigilibRequest.ParsingOption;
 import digilib.conf.DigilibServletConfiguration;
 import digilib.conf.DigilibServletRequest;
 import digilib.conf.ManifestServletConfiguration;
@@ -123,6 +127,36 @@
 		iiifPathSep = dlConfig.getAsString("iiif-slash-replacement");
 	}
 
+    /**
+     * Returns modification time relevant to the request for caching.
+     * 
+     * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest)
+     */
+    public long getLastModified(HttpServletRequest request) {
+        accountlog.debug("GetLastModified from " + request.getRemoteAddr() + " for " + request.getQueryString());
+        long mtime = -1;
+        try {
+            // create new digilib request
+			DigilibServletRequest dlRequest = new DigilibServletRequest(request, dlConfig,
+					EnumSet.of(ParsingOption.omitIiifImageApi));
+			// get list of IIIF parameters
+			@SuppressWarnings("unchecked")
+			List<String> iiifParams = (List<String>) dlRequest.getValue("request.iiif.elements");
+			// get identifier (first parameter)
+			String identifier = iiifParams.get(0);
+			// decode identifier to file path
+			dlRequest.setValueFromString("fn", dlRequest.decodeIiifIdentifier(identifier));
+            DocuDirectory dd = dirCache.getDirectory(dlRequest.getFilePath());
+            if (dd != null) {
+                mtime = dd.getDirMTime() / 1000 * 1000;
+            }
+        } catch (Exception e) {
+            logger.error("error in getLastModified: " + e.getMessage());
+        }
+        logger.debug("  returns " + mtime);
+        return mtime;
+    }
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -150,13 +184,27 @@
 	}
 
 	protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
-
-		/*
-		 * request parameters
-		 */
-		// create new request with defaults
-		DigilibServletRequest dlRequest = new DigilibServletRequest(request, dlConfig);
 		try {
+			// create DigilibRequest from ServletRequest, omit IIIF Image API parsing
+			DigilibServletRequest dlRequest = new DigilibServletRequest(request, dlConfig,
+					EnumSet.of(ParsingOption.omitIiifImageApi));
+			// get list of IIIF parameters
+			@SuppressWarnings("unchecked")
+			List<String> iiifParams = (List<String>) dlRequest.getValue("request.iiif.elements");
+			if (iiifParams == null) {
+				logger.error("Invalid IIIF request.");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid IIIF request.");
+				return;
+			}
+			// get identifier (first parameter)
+			String identifier = iiifParams.get(0);
+			if (identifier == null) {
+				logger.error("IIIF identifier missing");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "IIIF identifier missing.");
+				return;
+			}
+			// decode identifier to file path
+			dlRequest.setValueFromString("fn", dlRequest.decodeIiifIdentifier(identifier));
 			// get directory path
 			String dlFn = dlRequest.getFilePath();
 			// get information about the directory
@@ -184,6 +232,18 @@
 				}
 			}
 
+            /*
+             * check permissions
+             */
+            if (useAuthorization) {
+                // is the current request/user authorized?
+                if (!authzOp.isAuthorized(dlRequest)) {
+                	// TODO: does this work for directories?
+                    // send deny answer and abort
+                    throw new AuthOpException("Access denied!");
+                }
+            }
+
 			// use JSON-LD content type only when asked
 			String accept = request.getHeader("Accept");
 			if (accept != null && accept.contains("application/ld+json")) {
@@ -195,23 +255,16 @@
 			/*
 			 * get manifest base URL
 			 */
-			String baseurl = request.getRequestURL().toString();
+			String url = request.getRequestURL().toString();
 			// get base URL for Servlets
 			int srvPathLen = request.getServletPath().length() + request.getPathInfo().length();
-			String servletBaseUrl = baseurl.substring(0, baseurl.length() - srvPathLen);
-			// clean manifest base URL
-			if (baseurl.endsWith("/")) {
-				baseurl = baseurl.substring(0, baseurl.length() - 1);
-			}
-			// pathInfo = IIIF id with prefix
-			String iiifPath = request.getPathInfo();
-            if (iiifPath.endsWith("/")) {
-                iiifPath = iiifPath.substring(0, iiifPath.length() - 1);
-            }
+			String servletBaseUrl = url.substring(0, url.length() - srvPathLen);
+			// manifest base URL
+			String baseurl = servletBaseUrl + request.getServletPath() + "/" + dlConfig.getAsString("iiif-prefix") + "/" + identifier;
 			
 			params.manifestUrl = baseurl;
-			params.imgApiUrl = servletBaseUrl +"/" + this.scalerServletPath;
-			params.iiifPath = iiifPath;
+			params.imgApiUrl = servletBaseUrl +"/" + this.scalerServletPath + "/" + dlConfig.getAsString("iiif-prefix");
+			params.identifier = identifier;
 			params.docuDir = dlDir;
 			
 			/*
@@ -234,6 +287,13 @@
 
 		} catch (IOException e) {
 			logger.error("ERROR sending manifest: ", e);
+		} catch (AuthOpException e) {
+			logger.debug("Permission denied.");
+			try {
+				response.sendError(HttpServletResponse.SC_FORBIDDEN);
+			} catch (IOException e1) {
+				logger.error("Error sending error: ", e);
+			}
 		}
 	}
 
@@ -325,7 +385,7 @@
         manifest.writeStartObject()
             .write("@type", "sc:Canvas")
             .write("@id", params.manifestUrl + "/canvas/p" + idx)
-            .write("label", "image " + imgFile.getName())
+            .write("label", "image " + FileOps.basename(imgFile.getName()))
             .write("height", imgSize.getHeight())
             .write("width", imgSize.getWidth());
         /*
@@ -390,7 +450,7 @@
     protected void writeResource(JsonGenerator manifest, DocuDirent imgFile, ImageSize imgSize,
             ManifestParams params) {
         // base URL for image using IIIF image API
-        String iiifImgBaseUrl = params.imgApiUrl + params.iiifPath + this.iiifPathSep + FileOps.basename(imgFile.getName());
+        String iiifImgBaseUrl = params.imgApiUrl + "/" + params.identifier + this.iiifPathSep + FileOps.basename(imgFile.getName());
         // IIIF image parameters
         String imgUrl = iiifImgBaseUrl + "/full/full/0/default.jpg";
 		manifest.writeStartObject("resource")
@@ -429,6 +489,6 @@
 	    public DocuDirectory docuDir;
         String manifestUrl;
 	    String imgApiUrl;
-	    String iiifPath;	    
+	    String identifier;	    
 	}
 }
\ No newline at end of file