protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { ExternalIdentifierDAO identifierDAO = ExternalIdentifierDAOFactory.getInstance(context); Item item = null; Bitstream bitstream = null; String idString = request.getPathInfo(); String filenameNoPath = null; String fullpath = null; String uri = null; // Parse URL if (idString != null) { // Remove leading slash if (idString.startsWith("/")) { idString = idString.substring(1); } // Get uri and full file path int slashIndex = idString.indexOf('/'); if (slashIndex != -1) { slashIndex = idString.indexOf('/', slashIndex + 1); if (slashIndex != -1) { uri = idString.substring(0, slashIndex); fullpath = URLDecoder.decode(idString.substring(slashIndex + 1), Constants.DEFAULT_ENCODING); // Get filename with no path slashIndex = fullpath.indexOf('/'); if (slashIndex != -1) { String[] pathComponents = fullpath.split("/"); if (pathComponents.length <= maxDepthGuess + 1) { filenameNoPath = pathComponents[pathComponents.length - 1]; } } } } } if (uri != null && fullpath != null) { // Find the item try { /* * If the original item doesn't have a persistent identifier * yet (because it's in the workflow) what we actually have is * a URL of the form: db-id/1234 where 1234 is the database ID * of the item. * * FIXME: This first part could be totally omitted now that we * have the dsi:x/y format of identification. */ if (uri.startsWith("db-id")) { String dbIDString = uri.substring(uri.indexOf('/') + 1); int dbID = Integer.parseInt(dbIDString); item = ItemDAOFactory.getInstance(context).retrieve(dbID); } else { ExternalIdentifier identifier = identifierDAO.retrieve(uri); ObjectIdentifier oi = identifier.getObjectIdentifier(); item = (Item) oi.getObject(context); } } catch (NumberFormatException nfe) { // Invalid ID - this will be dealt with below } } if (item != null) { // Try to find bitstream with exactly matching name + path bitstream = getItemBitstreamByName(item, fullpath); if (bitstream == null && filenameNoPath != null) { // No match with the full path, but we can try again with // only the filename bitstream = getItemBitstreamByName(item, filenameNoPath); } } // Did we get a bitstream? if (bitstream != null) { log.info( LogManager.getHeader( context, "view_html", "uri=" + uri + ",bitstream_id=" + bitstream.getID())); // Set the response MIME type response.setContentType(bitstream.getFormat().getMIMEType()); // Response length response.setHeader("Content-Length", String.valueOf(bitstream.getSize())); // Pipe the bits InputStream is = bitstream.retrieve(); Utils.bufferedCopy(is, response.getOutputStream()); is.close(); response.getOutputStream().flush(); } else { // No bitstream - we got an invalid ID log.info(LogManager.getHeader(context, "view_html", "invalid_bitstream_id=" + idString)); JSPManager.showInvalidIDError(request, response, idString, Constants.BITSTREAM); } }
public void processDSpaceObject( Context context, HttpServletRequest request, HttpServletResponse response, DSpaceObject dso, String extraPathInfo) throws ServletException, IOException, SQLException, AuthorizeException { // OK, we have a valid URI. What is it? if (dso.getType() == Constants.BITSTREAM) { // FIXME: Check for if-modified-since header Bitstream bitstream = (Bitstream) dso; log.info( LogManager.getHeader(context, "view_bitstream", "bitstream_id=" + bitstream.getID())); // Pipe the bits // InputStream is = bitstream.retrieve(); InputStream is = BitstreamStorageManager.retrieve(context, bitstream); // Set the response MIME type response.setContentType(bitstream.getFormat().getMIMEType()); response.setHeader("Content-Length", String.valueOf(bitstream.getSize())); response.setHeader("Content-disposition", "attachment; filename=" + bitstream.getName()); Utils.bufferedCopy(is, response.getOutputStream()); is.close(); response.getOutputStream().flush(); } else if (dso.getType() == Constants.ITEM) { Item item = (Item) dso; response.setDateHeader("Last-Modified", item.getLastModified().getTime()); // Check for if-modified-since header long modSince = request.getDateHeader("If-Modified-Since"); if (modSince != -1 && item.getLastModified().getTime() < modSince) { // Item has not been modified since requested date, // hence bitstream has not; return 304 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } else { // Display the item page displayItem(context, request, response, item); } } else if (dso.getType() == Constants.COLLECTION) { Collection c = (Collection) dso; // Store collection location in request request.setAttribute("dspace.collection", c); /* * Find the "parent" community the collection, mainly for * "breadcrumbs" FIXME: At the moment, just grab the first community * the collection is in. This should probably be more context * sensitive when we have multiple inclusion. */ Community[] parents = (Community[]) c.getCommunities().toArray(); request.setAttribute("dspace.community", parents[0]); /* * Find all the "parent" communities for the collection for * "breadcrumbs" */ request.setAttribute("dspace.communities", getParents(parents[0], true)); // home page, or forward to another page? if ((extraPathInfo == null) || (extraPathInfo.equals("/"))) { collectionHome(context, request, response, parents[0], c); } else { // Forward to another servlet request.getRequestDispatcher(extraPathInfo).forward(request, response); } } else if (dso.getType() == Constants.COMMUNITY) { Community c = (Community) dso; // Store collection location in request request.setAttribute("dspace.community", c); /* * Find all the "parent" communities for the community */ request.setAttribute("dspace.communities", getParents(c, false)); // home page, or forward to another page? if ((extraPathInfo == null) || (extraPathInfo.equals("/"))) { communityHome(context, request, response, c); } else { // Forward to another servlet request.getRequestDispatcher(extraPathInfo).forward(request, response); } } else { // Shouldn't happen. Log and treat as invalid ID log.info( LogManager.getHeader( context, "URI not an item, collection or community", "identifier=" + dso.getIdentifier().toString())); JSPManager.showInvalidIDError(request, response, request.getPathInfo(), -1); return; } }
@Override protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { Item item = null; Bitstream bitstream = null; // Get the ID from the URL String idString = request.getPathInfo(); String handle = ""; String sequenceText = ""; String filename = null; int sequenceID; // Parse 'handle' and 'sequence' (bitstream seq. number) out // of remaining URL path, which is typically of the format: // {handle}/{sequence}/{bitstream-name} // But since the bitstream name MAY have any number of "/"s in // it, and the handle is guaranteed to have one slash, we // scan from the start to pick out handle and sequence: // Remove leading slash if any: if (idString.startsWith("/")) { idString = idString.substring(1); } // skip first slash within handle int slashIndex = idString.indexOf('/'); if (slashIndex != -1) { slashIndex = idString.indexOf('/', slashIndex + 1); if (slashIndex != -1) { handle = idString.substring(0, slashIndex); int slash2 = idString.indexOf('/', slashIndex + 1); if (slash2 != -1) { sequenceText = idString.substring(slashIndex + 1, slash2); filename = idString.substring(slash2 + 1); } } } try { sequenceID = Integer.parseInt(sequenceText); } catch (NumberFormatException nfe) { sequenceID = -1; } // Now try and retrieve the item DSpaceObject dso = HandleManager.resolveToObject(context, handle); // Make sure we have valid item and sequence number if (dso != null && dso.getType() == Constants.ITEM && sequenceID >= 0) { item = (Item) dso; if (item.isWithdrawn()) { log.info( LogManager.getHeader( context, "view_bitstream", "handle=" + handle + ",withdrawn=true")); JSPManager.showJSP(request, response, "/tombstone.jsp"); return; } boolean found = false; Bundle[] bundles = item.getBundles(); for (int i = 0; (i < bundles.length) && !found; i++) { Bitstream[] bitstreams = bundles[i].getBitstreams(); for (int k = 0; (k < bitstreams.length) && !found; k++) { if (sequenceID == bitstreams[k].getSequenceID()) { bitstream = bitstreams[k]; found = true; } } } } if (bitstream == null || filename == null || !filename.equals(bitstream.getName())) { // No bitstream found or filename was wrong -- ID invalid log.info(LogManager.getHeader(context, "invalid_id", "path=" + idString)); JSPManager.showInvalidIDError(request, response, idString, Constants.BITSTREAM); return; } log.info(LogManager.getHeader(context, "view_bitstream", "bitstream_id=" + bitstream.getID())); // Modification date // Only use last-modified if this is an anonymous access // - caching content that may be generated under authorisation // is a security problem if (context.getCurrentUser() == null) { // TODO: Currently the date of the item, since we don't have dates // for files response.setDateHeader("Last-Modified", item.getLastModified().getTime()); // Check for if-modified-since header long modSince = request.getDateHeader("If-Modified-Since"); if (modSince != -1 && item.getLastModified().getTime() < modSince) { // Item has not been modified since requested date, // hence bitstream has not; return 304 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } } // Pipe the bits InputStream is = bitstream.retrieve(); // Set the response MIME type response.setContentType(bitstream.getFormat().getMIMEType()); // Response length response.setHeader("Content-Length", String.valueOf(bitstream.getSize())); if (threshold != -1 && bitstream.getSize() >= threshold) { setBitstreamDisposition(bitstream.getName(), request, response); } Utils.bufferedCopy(is, response.getOutputStream()); is.close(); response.getOutputStream().flush(); }