List of usage examples for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT
int SC_PARTIAL_CONTENT
To view the source code for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT.
Click Source Link
From source file:org.openhab.ui.cometvisu.servlet.CometVisuServlet.java
/** * Process the actual request./*from w w w. ja v a 2 s.c om*/ * * @param request * The request to be processed. * @param response * The response to be created. * @param content * Whether the request body should be written (GET) or not * (HEAD). * @throws IOException * If something fails at I/O level. * * @author BalusC * @link * http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and * .html */ private void processStaticRequest(File file, HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException { // Validate the requested file // ------------------------------------------------------------ if (file == null) { // Get requested file by path info. String requestedFile = request.getPathInfo(); // Check if file is actually supplied to the request URL. if (requestedFile == null) { // Do your thing if the file is not supplied to the request URL. // Throw an exception, or send 404, or show default/warning // page, or // just ignore it. response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // URL-decode the file name (might contain spaces and on) and // prepare // file object. file = new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8")); } // Check if file actually exists in filesystem. if (!file.exists()) { // Do your thing if the file appears to be non-existing. // Throw an exception, or send 404, or show default/warning page, or // just ignore it. response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // Prepare some variables. The ETag is an unique identifier of the file. String fileName = file.getName(); long length = file.length(); long lastModified = file.lastModified(); String eTag = fileName + "_" + length + "_" + lastModified; long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME; // Validate request headers for caching // --------------------------------------------------- // If-None-Match header should contain "*" or ETag. If so, then return // 304. String ifNoneMatch = request.getHeader("If-None-Match"); if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", eTag); // Required in 304. response.setDateHeader("Expires", expires); // Postpone cache with 1 // week. return; } // If-Modified-Since header should be greater than LastModified. If so, // then return 304. // This header is ignored if any If-None-Match header is specified. long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", eTag); // Required in 304. response.setDateHeader("Expires", expires); // Postpone cache with 1 // week. return; } // Validate request headers for resume // ---------------------------------------------------- // If-Match header should contain "*" or ETag. If not, then return 412. String ifMatch = request.getHeader("If-Match"); if (ifMatch != null && !matches(ifMatch, eTag)) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // If-Unmodified-Since header should be greater than LastModified. If // not, then return 412. long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since"); if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // Validate and process range // ------------------------------------------------------------- // Prepare some variables. The full Range represents the complete file. Range full = new Range(0, length - 1, length); List<Range> ranges = new ArrayList<Range>(); // Validate and process Range and If-Range headers. String range = request.getHeader("Range"); if (range != null) { // Range header should match format "bytes=n-n,n-n,n-n...". If not, // then return 416. if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { response.setHeader("Content-Range", "bytes */" + length); // Required // in // 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // If-Range header should either match ETag or be greater then // LastModified. If not, // then return full file. String ifRange = request.getHeader("If-Range"); if (ifRange != null && !ifRange.equals(eTag)) { try { long ifRangeTime = request.getDateHeader("If-Range"); // Throws // IAE // if // invalid. if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) { ranges.add(full); } } catch (IllegalArgumentException ignore) { ranges.add(full); } } // If any valid If-Range header, then process each part of byte // range. if (ranges.isEmpty()) { for (String part : range.substring(6).split(",")) { // Assuming a file with length of 100, the following // examples returns bytes at: // 50-80 (50 to 80), 40- (40 to length=100), -20 // (length-20=80 to length=100). long start = sublong(part, 0, part.indexOf("-")); long end = sublong(part, part.indexOf("-") + 1, part.length()); if (start == -1) { start = length - end; end = length - 1; } else if (end == -1 || end > length - 1) { end = length - 1; } // Check if Range is syntactically valid. If not, then // return 416. if (start > end) { response.setHeader("Content-Range", "bytes */" + length); // Required // in // 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // Add range. ranges.add(new Range(start, end, length)); } } } // Prepare and initialize response // -------------------------------------------------------- // Get content type by file name and set default GZIP support and // content disposition. String contentType = getServletContext().getMimeType(fileName); boolean acceptsGzip = false; String disposition = "inline"; // If content type is unknown, then set the default value. // For all content types, see: // http://www.w3schools.com/media/media_mimeref.asp // To add new content types, add new mime-mapping entry in web.xml. if (contentType == null) { contentType = "application/octet-stream"; } // If content type is text, then determine whether GZIP content encoding // is supported by // the browser and expand content type with the one and right character // encoding. if (contentType.startsWith("text")) { String acceptEncoding = request.getHeader("Accept-Encoding"); acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip"); contentType += ";charset=UTF-8"; } // Else, expect for images, determine content disposition. If content // type is supported by // the browser, then set to inline, else attachment which will pop a // 'save as' dialogue. else if (!contentType.startsWith("image")) { String accept = request.getHeader("Accept"); disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment"; } // Initialize response. response.reset(); response.setBufferSize(DEFAULT_BUFFER_SIZE); response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\""); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("ETag", eTag); response.setDateHeader("Last-Modified", lastModified); response.setDateHeader("Expires", expires); // Send requested file (part(s)) to client // ------------------------------------------------ // Prepare streams. RandomAccessFile input = null; OutputStream output = null; try { // Open streams. input = new RandomAccessFile(file, "r"); output = response.getOutputStream(); if (ranges.isEmpty() || ranges.get(0) == full) { // Return full file. Range r = full; response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); if (content) { if (acceptsGzip) { // The browser accepts GZIP, so GZIP the content. response.setHeader("Content-Encoding", "gzip"); output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE); } else { // Content length is not directly predictable in case of // GZIP. // So only add it if there is no means of GZIP, else // browser will hang. response.setHeader("Content-Length", String.valueOf(r.length)); } // Copy full range. copy(input, output, r.start, r.length); } } else if (ranges.size() == 1) { // Return single part of file. Range r = ranges.get(0); response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); response.setHeader("Content-Length", String.valueOf(r.length)); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Copy single part range. copy(input, output, r.start, r.length); } } else { // Return multiple parts of file. response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Cast back to ServletOutputStream to get the easy println // methods. ServletOutputStream sos = (ServletOutputStream) output; // Copy multi part range. for (Range r : ranges) { // Add multipart boundary and header fields for every // range. sos.println(); sos.println("--" + MULTIPART_BOUNDARY); sos.println("Content-Type: " + contentType); sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total); // Copy single part range of multi part range. copy(input, output, r.start, r.length); } // End with multipart boundary. sos.println(); sos.println("--" + MULTIPART_BOUNDARY + "--"); } } } finally { // Gently close streams. close(output); close(input); } }
From source file:org.openhab.ui.cometvisu.internal.servlet.CometVisuServlet.java
/** * Process the actual request./*from ww w .j a v a 2 s . c o m*/ * * @param request * The request to be processed. * @param response * The response to be created. * @param content * Whether the request body should be written (GET) or not * (HEAD). * @throws IOException * If something fails at I/O level. * * @author BalusC * @link * http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and * .html */ private void processStaticRequest(File file, HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException { // Validate the requested file // ------------------------------------------------------------ if (file == null) { // Get requested file by path info. String requestedFile = request.getPathInfo(); // Check if file is actually supplied to the request URL. if (requestedFile == null) { // Do your thing if the file is not supplied to the request URL. // Throw an exception, or send 404, or show default/warning // page, or // just ignore it. response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // URL-decode the file name (might contain spaces and on) and // prepare // file object. file = new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8")); } if (file.equals(rootFolder) || (file.exists() && file.isDirectory())) { file = new File(file, "index.html"); } // Check if file actually exists in filesystem. if (!file.exists()) { // show installation hints if the CometVisu-Clients main index.html is requested but cannot be found if (file.getParentFile().equals(rootFolder) && (file.getName().equalsIgnoreCase("index.html") || file.getName().length() == 0)) { // looking for CometVisu clients index.html file String path = null; File folder = file.isDirectory() ? file : file.getParentFile(); if (folder.exists()) { File index = ClientInstaller.findClientRoot(folder, "index.html"); path = index.exists() ? index.getPath().replaceFirst(rootFolder.getPath() + "/", "") : null; } if (path != null) { // forward to position response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.setHeader("Location", path + "?" + request.getQueryString()); } else { showInstallationHint(request, response); } } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } return; } // Prepare some variables. The ETag is an unique identifier of the file. String fileName = file.getName(); long length = file.length(); long lastModified = file.lastModified(); String eTag = fileName + "_" + length + "_" + lastModified; long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME; // Validate request headers for caching // --------------------------------------------------- // If-None-Match header should contain "*" or ETag. If so, then return // 304. String ifNoneMatch = request.getHeader("If-None-Match"); if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", eTag); // Required in 304. response.setDateHeader("Expires", expires); // Postpone cache with 1 // week. return; } // If-Modified-Since header should be greater than LastModified. If so, // then return 304. // This header is ignored if any If-None-Match header is specified. long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", eTag); // Required in 304. response.setDateHeader("Expires", expires); // Postpone cache with 1 // week. return; } // Validate request headers for resume // ---------------------------------------------------- // If-Match header should contain "*" or ETag. If not, then return 412. String ifMatch = request.getHeader("If-Match"); if (ifMatch != null && !matches(ifMatch, eTag)) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // If-Unmodified-Since header should be greater than LastModified. If // not, then return 412. long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since"); if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // Validate and process range // ------------------------------------------------------------- // Prepare some variables. The full Range represents the complete file. Range full = new Range(0, length - 1, length); List<Range> ranges = new ArrayList<Range>(); // Validate and process Range and If-Range headers. String range = request.getHeader("Range"); if (range != null) { // Range header should match format "bytes=n-n,n-n,n-n...". If not, // then return 416. if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { response.setHeader("Content-Range", "bytes */" + length); // Required // in // 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // If-Range header should either match ETag or be greater then // LastModified. If not, // then return full file. String ifRange = request.getHeader("If-Range"); if (ifRange != null && !ifRange.equals(eTag)) { try { long ifRangeTime = request.getDateHeader("If-Range"); // Throws // IAE // if // invalid. if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) { ranges.add(full); } } catch (IllegalArgumentException ignore) { ranges.add(full); } } // If any valid If-Range header, then process each part of byte // range. if (ranges.isEmpty()) { for (String part : range.substring(6).split(",")) { // Assuming a file with length of 100, the following // examples returns bytes at: // 50-80 (50 to 80), 40- (40 to length=100), -20 // (length-20=80 to length=100). long start = sublong(part, 0, part.indexOf("-")); long end = sublong(part, part.indexOf("-") + 1, part.length()); if (start == -1) { start = length - end; end = length - 1; } else if (end == -1 || end > length - 1) { end = length - 1; } // Check if Range is syntactically valid. If not, then // return 416. if (start > end) { response.setHeader("Content-Range", "bytes */" + length); // Required // in // 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // Add range. ranges.add(new Range(start, end, length)); } } } // Prepare and initialize response // -------------------------------------------------------- // Get content type by file name and set default GZIP support and // content disposition. String contentType = getServletContext().getMimeType(fileName); boolean acceptsGzip = false; String disposition = "inline"; // If content type is unknown, then set the default value. // For all content types, see: // http://www.w3schools.com/media/media_mimeref.asp // To add new content types, add new mime-mapping entry in web.xml. if (contentType == null) { contentType = "application/octet-stream"; } // If content type is text, then determine whether GZIP content encoding // is supported by // the browser and expand content type with the one and right character // encoding. if (contentType.startsWith("text")) { String acceptEncoding = request.getHeader("Accept-Encoding"); acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip"); contentType += ";charset=UTF-8"; } // Else, expect for images, determine content disposition. If content // type is supported by // the browser, then set to inline, else attachment which will pop a // 'save as' dialogue. else if (!contentType.startsWith("image")) { String accept = request.getHeader("Accept"); disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment"; } response.setBufferSize(DEFAULT_BUFFER_SIZE); response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\""); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("ETag", eTag); response.setDateHeader("Last-Modified", lastModified); response.setDateHeader("Expires", expires); // Send requested file (part(s)) to client // ------------------------------------------------ // Prepare streams. RandomAccessFile input = null; OutputStream output = null; try { // Open streams. input = new RandomAccessFile(file, "r"); output = response.getOutputStream(); if (ranges.isEmpty() || ranges.get(0) == full) { // Return full file. Range r = full; response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); if (content) { if (acceptsGzip) { // The browser accepts GZIP, so GZIP the content. response.setHeader("Content-Encoding", "gzip"); output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE); } else { // Content length is not directly predictable in case of // GZIP. // So only add it if there is no means of GZIP, else // browser will hang. response.setHeader("Content-Length", String.valueOf(r.length)); } // Copy full range. copy(input, output, r.start, r.length); } } else if (ranges.size() == 1) { // Return single part of file. Range r = ranges.get(0); response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); response.setHeader("Content-Length", String.valueOf(r.length)); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Copy single part range. copy(input, output, r.start, r.length); } } else { // Return multiple parts of file. response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Cast back to ServletOutputStream to get the easy println // methods. ServletOutputStream sos = (ServletOutputStream) output; // Copy multi part range. for (Range r : ranges) { // Add multipart boundary and header fields for every // range. sos.println(); sos.println("--" + MULTIPART_BOUNDARY); sos.println("Content-Type: " + contentType); sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total); // Copy single part range of multi part range. copy(input, output, r.start, r.length); } // End with multipart boundary. sos.println(); sos.println("--" + MULTIPART_BOUNDARY + "--"); } } } finally { // Gently close streams. close(output); close(input); } }
From source file:org.sakaiproject.lessonbuildertool.service.LessonBuilderAccessService.java
public HttpAccess getHttpAccess() { return new HttpAccess() { public void handleAccess(HttpServletRequest req, HttpServletResponse res, Reference ref, Collection copyrightAcceptedRefs) throws EntityPermissionException, EntityNotDefinedException, EntityAccessOverloadException, EntityCopyrightException { // preauthorized by encrypted key boolean isAuth = false; // if the id is null, the request was for just ".../content" String refId = ref.getId(); if (refId == null) { refId = ""; }//from w w w . j a v a 2 s.c o m if (!refId.startsWith("/item")) { throw new EntityNotDefinedException(ref.getReference()); } String itemString = refId.substring("/item/".length()); // string is of form /item/NNN/url. get the number int i = itemString.indexOf("/"); if (i < 0) { throw new EntityNotDefinedException(ref.getReference()); } // get session. The problem here is that some multimedia tools don't reliably // pass JSESSIONID String sessionParam = req.getParameter("lb.session"); if (sessionParam != null) { try { Cipher sessionCipher = Cipher.getInstance("Blowfish"); sessionCipher.init(Cipher.DECRYPT_MODE, sessionKey); byte[] sessionBytes = DatatypeConverter.parseHexBinary(sessionParam); sessionBytes = sessionCipher.doFinal(sessionBytes); String sessionString = new String(sessionBytes); int j = sessionString.indexOf(":"); String sessionId = sessionString.substring(0, j); String url = sessionString.substring(j + 1); UsageSession s = UsageSessionService.getSession(sessionId); if (s == null || s.isClosed() || url == null || !url.equals(refId)) { throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), ContentHostingService.AUTH_RESOURCE_READ, ref.getReference()); } else { isAuth = true; } } catch (Exception e) { System.out.println("unable to decode lb.session " + e); } } // basically there are two checks to be done: is the item accessible in Lessons, // and is the underlying resource accessible in Sakai. // This code really does check both. Sort of. // 1) it checks accessibility to the containing page by seeing if it has been visited. // This is stricter than necessary, but there's no obvious reason to let people use this // who aren't following an actual URL we gave them. // 2) it checks group access as part of the normal resource permission check. Sakai // should sync the two. We actually don't check it for items in student home directories, // as far as I can tell // 3) it checks availability (prerequisites) by calling the code from SimplePageBean // We could rewrite this with the new LessonsAccess methods, but since we have to do // resource permission checking also, and there's some duplication, it doesn't seem worth // rewriting this code. What I've done is review it to make sure it does the same thing. String id = itemString.substring(i); itemString = itemString.substring(0, i); boolean pushedAdvisor = false; try { securityService.pushAdvisor(allowReadAdvisor); pushedAdvisor = true; Long itemId = 0L; try { itemId = (Long) Long.parseLong(itemString); } catch (Exception e) { throw new EntityNotDefinedException(ref.getReference()); } // say we've read this if (itemId != 0L) track(itemId.longValue(), sessionManager.getCurrentSessionUserId()); // code here is also in simplePageBean.isItemVisible. change it there // too if you change this logic SimplePageItem item = simplePageToolDao.findItem(itemId.longValue()); SimplePage currentPage = simplePageToolDao.getPage(item.getPageId()); String owner = currentPage.getOwner(); // if student content String group = currentPage.getGroup(); // if student content if (group != null) group = "/site/" + currentPage.getSiteId() + "/group/" + group; String currentSiteId = currentPage.getSiteId(); // first let's make sure the user is allowed to access // the containing page if (!isAuth && !canReadPage(currentSiteId)) { throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), ContentHostingService.AUTH_RESOURCE_READ, ref.getReference()); } // If the resource is the actual one in the item, or // it is in the containing folder, then do lesson builder checking. // otherwise do normal resource checking if (!isAuth) { boolean useLb = false; // I've seen sakai id's with //, not sure why. they work but will mess up the comparison String itemResource = item.getSakaiId().replace("//", "/"); // only use lb security if the user has visited the page // this handles the various page release issues, although // it's not quite as flexible as the real code. But I don't // see any reason to help the user follow URLs that they can't // legitimately have seen. if (simplePageToolDao.isPageVisited(item.getPageId(), sessionManager.getCurrentSessionUserId(), owner)) { if (id.equals(itemResource)) useLb = true; else { // not exact, but see if it's in the containing folder int endFolder = itemResource.lastIndexOf("/"); if (endFolder > 0) { String folder = itemResource.substring(0, endFolder + 1); if (id.startsWith(folder)) useLb = true; } } } if (useLb) { // key into access cache String accessKey = itemString + ":" + sessionManager.getCurrentSessionUserId(); // special access if we have a student site and item is in worksite of one of the students // Normally we require that the person doing the access be able to see the file, but in // that specific case we allow the access. Note that in order to get a sakaiid pointing // into the user's space, the person editing the page must have been able to read the file. // this allows a user in your group to share any of your resources that he can see. String usersite = null; if (owner != null && group != null && id.startsWith("/user/")) { String username = id.substring(6); int slash = username.indexOf("/"); if (slash > 0) usersite = username.substring(0, slash); // normally it is /user/EID, so convert to userid try { usersite = UserDirectoryService.getUserId(usersite); } catch (Exception e) { } ; String itemcreator = item.getAttribute("addedby"); // suppose a member of the group adds a resource from another member of // the group. (This will only work if they have read access to it.) // We don't want to gimick access in that case. I think if you // add your own item, you've given consent. But not if someone else does. // itemcreator == null is for items added before this patch. I'm going to // continue to allow access for them, to avoid breaking existing content. if (usersite != null && itemcreator != null && !usersite.equals(itemcreator)) usersite = null; } // code here is also in simplePageBean.isItemVisible. change it there // too if you change this logic // for a student page, if it's in one of the groups' worksites, allow it // The assumption is that only one of those people can put content in the // page, and then only if the can see it. if (owner != null && usersite != null && authzGroupService.getUserRole(usersite, group) != null) { // OK } else if (owner != null && group == null && id.startsWith("/user/" + owner)) { // OK } else { // do normal checking for other content if (pushedAdvisor) { securityService.popAdvisor(); pushedAdvisor = false; } // our version of allowget does not check hidden but does everything else // if it's a student page, however use the normal check so students can't // use this to bypass release control if (owner == null && !allowGetResource(id, currentSiteId) || owner != null && !contentHostingService.allowGetResource(id)) { throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), ContentHostingService.AUTH_RESOURCE_READ, ref.getReference()); } securityService.pushAdvisor(allowReadAdvisor); pushedAdvisor = true; } // now enforce LB access restrictions if any if (item != null && item.isPrerequisite() && !"true".equals((String) accessCache.get(accessKey))) { // computing requirements is so messy that it's worth // instantiating // a SimplePageBean to do it. Otherwise we have to duplicate // lots of // code that changes. And we want it to be a transient bean // because there are // caches that we aren't trying to manage in the long term // but don't do this unless the item needs checking if (!canSeeAll(currentPage.getSiteId())) { SimplePageBean simplePageBean = new SimplePageBean(); simplePageBean.setMessageLocator(messageLocator); simplePageBean.setToolManager(toolManager); simplePageBean.setSecurityService(securityService); simplePageBean.setSessionManager(sessionManager); simplePageBean.setSiteService(siteService); simplePageBean.setContentHostingService(contentHostingService); simplePageBean.setSimplePageToolDao(simplePageToolDao); simplePageBean.setForumEntity(forumEntity); simplePageBean.setQuizEntity(quizEntity); simplePageBean.setAssignmentEntity(assignmentEntity); simplePageBean.setBltiEntity(bltiEntity); simplePageBean.setGradebookIfc(gradebookIfc); simplePageBean.setMemoryService(memoryService); simplePageBean.setCurrentSiteId(currentPage.getSiteId()); simplePageBean.setCurrentPage(currentPage); simplePageBean.setCurrentPageId(currentPage.getPageId()); simplePageBean.init(); if (!simplePageBean.isItemAvailable(item, item.getPageId())) { throw new EntityPermissionException(null, null, null); } } accessCache.put(accessKey, "true"); } } else { // normal security. no reason to use advisor if (pushedAdvisor) securityService.popAdvisor(); pushedAdvisor = false; // not uselb -- their allowget, not ours. theirs checks hidden if (!contentHostingService.allowGetResource(id)) { throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), ContentHostingService.AUTH_RESOURCE_READ, ref.getReference()); } } } // access checks are OK, get the thing // first see if it's not in resources, i.e. // if it doesn't start with /access/content it's something odd. redirect to it. // probably resources access control won't apply to it String url = contentHostingService.getUrl(id); // https://heidelberg.rutgers.edu/access/citation/content/group/24da8519-08c2-4c8c-baeb-8abdfd6c69d7/New%20Citation%20List int n = url.indexOf("//"); if (n > 0) { n = url.indexOf("/", n + 2); if (n > 0) { String path = url.substring(n); if (!path.startsWith("/access/content")) { res.sendRedirect(url); return; } } } ContentResource resource = null; try { resource = contentHostingService.getResource(id); } catch (IdUnusedException e) { throw new EntityNotDefinedException(e.getId()); } catch (PermissionException e) { throw new EntityPermissionException(e.getUser(), e.getLock(), e.getResource()); } catch (TypeException e) { throw new EntityNotDefinedException(id); } // we only do copyright on resources. I.e. not on inline things,which are MULTIMEDIA if (item.getType() == SimplePageItem.RESOURCE && needsCopyright(resource)) { throw new EntityCopyrightException(resource.getReference()); } try { // Wrap it in any filtering needed. resource = contentFilterService.wrap(resource); // following cast is redundant is current kernels, but is needed for Sakai 2.6.1 long len = (long) resource.getContentLength(); String contentType = resource.getContentType(); // for url resource type, encode a redirect to the body URL // in 2.10 have to check resourcetype, but in previous releasese // it doesn't get copied in site copy, so check content type. 10 doesn't set the contenttype to url // so we have to check both to work in all versions if (contentType.equalsIgnoreCase(ResourceProperties.TYPE_URL) || "org.sakaiproject.content.types.urlResource" .equalsIgnoreCase(resource.getResourceType())) { if (len < MAX_URL_LENGTH) { byte[] content = resource.getContent(); if ((content == null) || (content.length == 0)) { throw new IdUnusedException(ref.getReference()); } // An invalid URI format will get caught by the // outermost catch block URI uri = new URI(new String(content, "UTF-8")); eventTrackingService.post( eventTrackingService.newEvent(ContentHostingService.EVENT_RESOURCE_READ, resource.getReference(null), false)); res.sendRedirect(uri.toASCIIString()); } else { // we have a text/url mime type, but the body is too // long to issue as a redirect throw new EntityNotDefinedException(ref.getReference()); } } else { // use the last part, the file name part of the id, for // the download file name String fileName = Web.encodeFileName(req, Validator.getFileName(ref.getId())); String disposition = null; boolean inline = false; if (Validator.letBrowserInline(contentType)) { // type can be inline, but if HTML we have more checks to do if (inlineHtml || (!"text/html".equalsIgnoreCase(contentType) && !"application/xhtml+xml".equals(contentType))) // easy cases: not HTML or HTML always OK inline = true; else { // HTML and html is not allowed globally. code copied from BaseContentServices ResourceProperties rp = resource.getProperties(); boolean fileInline = false; boolean folderInline = false; try { fileInline = rp.getBooleanProperty(ResourceProperties.PROP_ALLOW_INLINE); } catch (EntityPropertyNotDefinedException e) { // we expect this so nothing to do! } if (!fileInline) try { folderInline = resource.getContainingCollection().getProperties() .getBooleanProperty(ResourceProperties.PROP_ALLOW_INLINE); } catch (EntityPropertyNotDefinedException e) { // we expect this so nothing to do! } if (fileInline || folderInline) { inline = true; } } } if (inline) { disposition = "inline; filename=\"" + fileName + "\""; } else { disposition = "attachment; filename=\"" + fileName + "\""; } // NOTE: Only set the encoding on the content we have // to. // Files uploaded by the user may have been created with // different encodings, such as ISO-8859-1; // rather than (sometimes wrongly) saying its UTF-8, let // the browser auto-detect the encoding. // If the content was created through the WYSIWYG // editor, the encoding does need to be set (UTF-8). String encoding = resource.getProperties() .getProperty(ResourceProperties.PROP_CONTENT_ENCODING); if (encoding != null && encoding.length() > 0) { contentType = contentType + "; charset=" + encoding; } // from contenthosting res.addHeader("Cache-Control", "must-revalidate, private"); res.addHeader("Expires", "-1"); ResourceProperties rp = resource.getProperties(); long lastModTime = 0; try { Time modTime = rp.getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE); lastModTime = modTime.getTime(); } catch (Exception e1) { M_log.info("Could not retrieve modified time for: " + resource.getId()); } // KNL-1316 tell the browser when our file was last modified for caching reasons if (lastModTime > 0) { SimpleDateFormat rfc1123Date = new SimpleDateFormat(RFC1123_DATE, LOCALE_US); rfc1123Date.setTimeZone(TimeZone.getTimeZone("GMT")); res.addHeader("Last-Modified", rfc1123Date.format(lastModTime)); } // KNL-1316 let's see if the user already has a cached copy. Code copied and modified from Tomcat DefaultServlet.java long headerValue = req.getDateHeader("If-Modified-Since"); if (headerValue != -1 && (lastModTime < headerValue + 1000)) { // The entity has not been modified since the date specified by the client. This is not an error case. res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } ArrayList<Range> ranges = parseRange(req, res, len); if (req.getHeader("Range") == null || (ranges == null) || (ranges.isEmpty())) { // stream the content using a small buffer to keep memory managed InputStream content = null; OutputStream out = null; try { content = resource.streamContent(); if (content == null) { throw new IdUnusedException(ref.getReference()); } res.setContentType(contentType); res.addHeader("Content-Disposition", disposition); res.addHeader("Accept-Ranges", "bytes"); // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4187336 if (len <= Integer.MAX_VALUE) { res.setContentLength((int) len); } else { res.addHeader("Content-Length", Long.toString(len)); } // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRange(content, out, 0, len - 1); } catch (ServerOverloadException e) { throw e; } catch (Exception ignore) { } finally { // be a good little program and close the stream - freeing up valuable system resources if (content != null) { content.close(); } if (out != null) { try { out.close(); } catch (Exception ignore) { } } } // Track event - only for full reads eventTrackingService.post( eventTrackingService.newEvent(ContentHostingService.EVENT_RESOURCE_READ, resource.getReference(null), false)); } else { // Output partial content. Adapted from Apache Tomcat 5.5.27 DefaultServlet.java res.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { // Single response Range range = (Range) ranges.get(0); res.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length); long length = range.end - range.start + 1; if (length < Integer.MAX_VALUE) { res.setContentLength((int) length); } else { // Set the content-length as String to be able to use a long res.setHeader("content-length", "" + length); } res.addHeader("Content-Disposition", disposition); if (contentType != null) { res.setContentType(contentType); } // stream the content using a small buffer to keep memory managed InputStream content = null; OutputStream out = null; try { content = resource.streamContent(); if (content == null) { throw new IdUnusedException(ref.getReference()); } // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRange(content, out, range.start, range.end); } catch (ServerOverloadException e) { throw e; } catch (SocketException e) { //a socket exception usualy means the client aborted the connection or similar if (M_log.isDebugEnabled()) { M_log.debug("SocketExcetion", e); } } catch (Exception ignore) { } finally { // be a good little program and close the stream - freeing up valuable system resources IOUtils.closeQuietly(content); IOUtils.closeQuietly(out); } } else { // Multipart response res.setContentType("multipart/byteranges; boundary=" + MIME_SEPARATOR); // stream the content using a small buffer to keep memory managed OutputStream out = null; try { // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRanges(resource, out, ranges.iterator(), contentType); } catch (SocketException e) { //a socket exception usualy means the client aborted the connection or similar if (M_log.isDebugEnabled()) { M_log.debug("SocketExcetion", e); } } catch (Exception ignore) { M_log.error("Swallowing exception", ignore); } finally { // be a good little program and close the stream - freeing up valuable system resources IOUtils.closeQuietly(out); } } // output multiple ranges } // output partial content } } catch (Exception t) { throw new EntityNotDefinedException(ref.getReference()); // following won't work in 2.7.1 // throw new EntityNotDefinedException(ref.getReference(), t); } // not sure why we're trapping exceptions and calling them not defined, but // a few types are needed by the caller } catch (EntityCopyrightException ce) { // copyright exception needs to go as is, to give copyright alert throw ce; } catch (EntityPermissionException pe) { // also want permission exceptions; it will generate a login page throw pe; } catch (Exception ex) { throw new EntityNotDefinedException(ref.getReference()); } finally { if (pushedAdvisor) securityService.popAdvisor(); } } }; }
From source file:org.apache.catalina.servlets.DefaultServlet.java
/** * Serve the specified resource, optionally including the data content. * * @param context The servlet request we are processing * @param content Should the content be included? * @param method Description of the Parameter * @throws IOException if an input/output error occurs * @throws ServletException if a servlet-specified error occurs *//*ww w .ja v a 2 s . c o m*/ protected void serveResource(ActionContext context, boolean content, String method) throws IOException, ServletException { //TODO: remove this hardcoding debug = 2; // Identify the requested resource path String path = getRelativePath(context.getRequest()); if (path.indexOf("/.") > -1) { //MAC OSX Fix return; } if (debug > 0) { if (content) { log("DefaultServlet.serveResource: Serving resource '" + path + "' headers and data"); } else { log("DefaultServlet.serveResource: Serving resource '" + path + "' headers only"); } } // Retrieve the Catalina context and Resources implementation Connection db = null; ModuleContext resources = null; ResourceInfo resourceInfo = null; SystemStatus thisSystem = null; boolean status = true; try { //System.out.println("DefaultServlet-> Serving Resource " + (content ? "WITH CONTENT" : "WITHOUT CONTENT")); db = this.getConnection(context); resources = getCFSResources(db, context); if (resources == null) { context.getResponse().sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } thisSystem = this.getSystemStatus(context); if (method.equals(METHOD_GET)) { Object current = resources.lookup(thisSystem, db, path); } resourceInfo = new ResourceInfo(thisSystem, path, resources); } catch (SQLException e) { e.printStackTrace(System.out); context.getResponse().sendError(CFS_SQLERROR, e.getMessage()); status = false; } catch (Exception e) { } finally { this.freeConnection(db, context); } if (!status) { return; } if (!resourceInfo.exists) { context.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND, context.getRequest().getRequestURI()); return; } // If the resource is not a collection, and the resource path // ends with "/" or "\", return NOT FOUND if (!resourceInfo.collection) { if (path.endsWith("/") || (path.endsWith("\\"))) { context.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND, context.getRequest().getRequestURI()); return; } } // Check if the conditions specified in the optional If headers are // satisfied. if (!resourceInfo.collection) { // Checking If headers boolean included = (context.getRequest().getAttribute(Globals.INCLUDE_CONTEXT_PATH_ATTR) != null); if (!included && !checkIfHeaders(context.getRequest(), context.getResponse(), resourceInfo)) { return; } } // Find content type String contentType = getServletContext().getMimeType(resourceInfo.clientFilename); Vector ranges = null; if (resourceInfo.collection) { // Skip directory listings if we have been configured to // suppress them if (!listings) { context.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND, context.getRequest().getRequestURI()); return; } contentType = "text/html;charset=UTF-8"; } else { // Parse range specifier ranges = parseRange(context.getRequest(), context.getResponse(), resourceInfo); // ETag header context.getResponse().setHeader("ETag", getETag(resourceInfo)); // Last-Modified header if (debug > 0) { log("DefaultServlet.serveFile: lastModified='" + (new Timestamp(resourceInfo.date)).toString() + "'"); } context.getResponse().setHeader("Last-Modified", resourceInfo.httpDate); } ServletOutputStream ostream = null; PrintWriter writer = null; if (content) { // Trying to retrieve the servlet output stream try { ostream = context.getResponse().getOutputStream(); } catch (IllegalStateException e) { // If it fails, we try to get a Writer instead if we're // trying to serve a text file if ((contentType == null) || (contentType.startsWith("text"))) { writer = context.getResponse().getWriter(); } else { throw e; } } } if ((resourceInfo.collection) || (((ranges == null) || (ranges.isEmpty())) && (context.getRequest().getHeader("Range") == null))) { // Set the appropriate output headers if (contentType != null) { if (debug > 0) { log("DefaultServlet.serveFile: contentType='" + contentType + "'"); } context.getResponse().setContentType(contentType); } long contentLength = resourceInfo.length; if ((!resourceInfo.collection) && (contentLength >= 0)) { if (debug > 0) { log("DefaultServlet.serveFile: contentLength=" + contentLength); } context.getResponse().setContentLength((int) contentLength); } if (resourceInfo.collection) { if (content) { // Serve the directory browser resourceInfo.setStream(render(context.getRequest().getContextPath(), resourceInfo)); } } // Copy the input stream to our output stream (if requested) if (content) { try { context.getResponse().setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(resourceInfo, ostream); } else { copy(resourceInfo, writer); } } } else { if ((ranges == null) || (ranges.isEmpty())) { return; } // Partial content response. context.getResponse().setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { Range range = (Range) ranges.elementAt(0); context.getResponse().addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length); context.getResponse().setContentLength((int) (range.end - range.start + 1)); if (contentType != null) { if (debug > 0) { log("DefaultServlet.serveFile: contentType='" + contentType + "'"); } context.getResponse().setContentType(contentType); } if (content) { try { context.getResponse().setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(resourceInfo, ostream, range); } else { copy(resourceInfo, writer, range); } } } else { context.getResponse().setContentType("multipart/byteranges; boundary=" + mimeSeparation); if (content) { try { context.getResponse().setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(resourceInfo, ostream, ranges.elements(), contentType); } else { copy(resourceInfo, writer, ranges.elements(), contentType); } } } } }
From source file:org.structr.web.servlet.HtmlServlet.java
private void streamFile(SecurityContext securityContext, final File file, HttpServletRequest request, HttpServletResponse response, final EditMode edit) throws IOException { if (!securityContext.isVisible(file)) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return;//from w w w. j a v a 2s . co m } final ServletOutputStream out = response.getOutputStream(); final String downloadAsFilename = request.getParameter(DOWNLOAD_AS_FILENAME_KEY); final Map<String, Object> callbackMap = new LinkedHashMap<>(); // make edit mode available in callback method callbackMap.put("editMode", edit); if (downloadAsFilename != null) { // Set Content-Disposition header to suggest a default filename and force a "save-as" dialog // See: // http://en.wikipedia.org/wiki/MIME#Content-Disposition, // http://tools.ietf.org/html/rfc2183 // http://tools.ietf.org/html/rfc1806 // http://tools.ietf.org/html/rfc2616#section-15.5 and http://tools.ietf.org/html/rfc2616#section-19.5.1 response.addHeader("Content-Disposition", "attachment; filename=\"" + downloadAsFilename + "\""); callbackMap.put("requestedFileName", downloadAsFilename); } if (!EditMode.WIDGET.equals(edit) && notModifiedSince(request, response, file, false)) { out.flush(); out.close(); callbackMap.put("statusCode", HttpServletResponse.SC_NOT_MODIFIED); } else { final String downloadAsDataUrl = request.getParameter(DOWNLOAD_AS_DATA_URL_KEY); if (downloadAsDataUrl != null) { IOUtils.write(FileHelper.getBase64String(file), out); response.setContentType("text/plain"); response.setStatus(HttpServletResponse.SC_OK); out.flush(); out.close(); callbackMap.put("statusCode", HttpServletResponse.SC_OK); } else { // 2b: stream file to response final InputStream in = file.getInputStream(); final String contentType = file.getContentType(); if (contentType != null) { response.setContentType(contentType); } else { // Default response.setContentType("application/octet-stream"); } final String range = request.getHeader("Range"); try { if (StringUtils.isNotEmpty(range)) { final long len = file.getSize(); long start = 0; long end = len - 1; final Matcher matcher = Pattern.compile("bytes=(?<start>\\d*)-(?<end>\\d*)").matcher(range); if (matcher.matches()) { String startGroup = matcher.group("start"); start = startGroup.isEmpty() ? start : Long.valueOf(startGroup); start = Math.max(0, start); String endGroup = matcher.group("end"); end = endGroup.isEmpty() ? end : Long.valueOf(endGroup); end = end > len - 1 ? len - 1 : end; } long contentLength = end - start + 1; // Tell the client that we support byte ranges response.setHeader("Accept-Ranges", "bytes"); response.setHeader("Content-Range", String.format("bytes %s-%s/%s", start, end, len)); response.setHeader("Content-Length", String.format("%s", contentLength)); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); callbackMap.put("statusCode", HttpServletResponse.SC_PARTIAL_CONTENT); IOUtils.copyLarge(in, out, start, contentLength); } else { response.setStatus(HttpServletResponse.SC_OK); callbackMap.put("statusCode", HttpServletResponse.SC_OK); IOUtils.copyLarge(in, out); } } catch (Throwable t) { } finally { if (out != null) { try { // 3: output content out.flush(); out.close(); } catch (Throwable t) { } } if (in != null) { in.close(); } response.setStatus(HttpServletResponse.SC_OK); } } } // WIDGET mode means "opened in frontend", which we don't want to count as an external download if (!EditMode.WIDGET.equals(edit)) { // call onDownload callback try { file.invokeMethod("onDownload", Collections.EMPTY_MAP, false); } catch (FrameworkException fex) { fex.printStackTrace(); } } }
From source file:org.gaul.s3proxy.S3ProxyHandler.java
private void handleGetBlob(HttpServletRequest request, HttpServletResponse response, BlobStore blobStore, String containerName, String blobName) throws IOException, S3Exception { int status = HttpServletResponse.SC_OK; GetOptions options = new GetOptions(); String ifMatch = request.getHeader(HttpHeaders.IF_MATCH); if (ifMatch != null) { options.ifETagMatches(ifMatch);//from w w w . j a v a2 s. c o m } String ifNoneMatch = request.getHeader(HttpHeaders.IF_NONE_MATCH); if (ifNoneMatch != null) { options.ifETagDoesntMatch(ifNoneMatch); } long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); if (ifModifiedSince != -1) { options.ifModifiedSince(new Date(ifModifiedSince)); } long ifUnmodifiedSince = request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE); if (ifUnmodifiedSince != -1) { options.ifUnmodifiedSince(new Date(ifUnmodifiedSince)); } String range = request.getHeader(HttpHeaders.RANGE); if (range != null && range.startsWith("bytes=") && // ignore multiple ranges range.indexOf(',') == -1) { range = range.substring("bytes=".length()); String[] ranges = range.split("-", 2); if (ranges[0].isEmpty()) { options.tail(Long.parseLong(ranges[1])); } else if (ranges[1].isEmpty()) { options.startAt(Long.parseLong(ranges[0])); } else { options.range(Long.parseLong(ranges[0]), Long.parseLong(ranges[1])); } status = HttpServletResponse.SC_PARTIAL_CONTENT; } Blob blob; try { blob = blobStore.getBlob(containerName, blobName, options); } catch (IllegalArgumentException iae) { // TODO: correct mapping? throw new S3Exception(S3ErrorCode.INVALID_RANGE, iae); } if (blob == null) { throw new S3Exception(S3ErrorCode.NO_SUCH_KEY); } response.setStatus(status); if (corsAllowAll) { response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); } addMetadataToResponse(request, response, blob.getMetadata()); // TODO: handles only a single range due to jclouds limitations Collection<String> contentRanges = blob.getAllHeaders().get(HttpHeaders.CONTENT_RANGE); if (!contentRanges.isEmpty()) { response.addHeader(HttpHeaders.CONTENT_RANGE, contentRanges.iterator().next()); response.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes"); } try (InputStream is = blob.getPayload().openStream(); OutputStream os = response.getOutputStream()) { ByteStreams.copy(is, os); os.flush(); } }
From source file:org.gss_project.gss.server.rest.Webdav.java
/** * Serve the specified resource, optionally including the data content. * * @param req The servlet request we are processing * @param resp The servlet response we are creating * @param content Should the content be included? * @exception IOException if an input/output error occurs * @exception ServletException if a servlet-specified error occurs * @throws RpcException//from w w w . j av a2s . c o m * @throws InsufficientPermissionsException * @throws ObjectNotFoundException */ protected void serveResource(HttpServletRequest req, HttpServletResponse resp, boolean content) throws IOException, ServletException, ObjectNotFoundException, InsufficientPermissionsException, RpcException { // Identify the requested resource path String path = getRelativePath(req); if (logger.isDebugEnabled()) if (content) logger.debug("Serving resource '" + path + "' headers and data"); else logger.debug("Serving resource '" + path + "' headers only"); User user = getUser(req); boolean exists = true; Object resource = null; FileHeader file = null; Folder folder = null; try { resource = getService().getResourceAtPath(user.getId(), path, true); } catch (ObjectNotFoundException e) { exists = false; } catch (RpcException e) { resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path); return; } if (!exists) { resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI()); return; } if (resource instanceof Folder) folder = (Folder) resource; else file = (FileHeader) resource; // If the resource is not a collection, and the resource path // ends with "/" or "\", return NOT FOUND if (folder == null) if (path.endsWith("/") || path.endsWith("\\")) { resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI()); return; } // Check if the conditions specified in the optional If headers are // satisfied. if (folder == null) // Checking If headers if (!checkIfHeaders(req, resp, file, null)) return; // Find content type. String contentType = null; if (file != null) { contentType = file.getCurrentBody().getMimeType(); if (contentType == null) { contentType = getServletContext().getMimeType(file.getName()); file.getCurrentBody().setMimeType(contentType); } } else contentType = "text/html;charset=UTF-8"; ArrayList ranges = null; long contentLength = -1L; if (file != null) { // Accept ranges header resp.setHeader("Accept-Ranges", "bytes"); // Parse range specifier ranges = parseRange(req, resp, file, null); // ETag header resp.setHeader("ETag", getETag(file, null)); // Last-Modified header resp.setHeader("Last-Modified", getLastModifiedHttp(file.getAuditInfo())); // Get content length contentLength = file.getCurrentBody().getFileSize(); // Special case for zero length files, which would cause a // (silent) ISE when setting the output buffer size if (contentLength == 0L) content = false; } ServletOutputStream ostream = null; PrintWriter writer = null; if (content) try { ostream = resp.getOutputStream(); } catch (IllegalStateException e) { // If it fails, we try to get a Writer instead if we're // trying to serve a text file if (contentType == null || contentType.startsWith("text") || contentType.endsWith("xml")) writer = resp.getWriter(); else throw e; } if (folder != null || (ranges == null || ranges.isEmpty()) && req.getHeader("Range") == null || ranges == FULL) { // Set the appropriate output headers if (contentType != null) { if (logger.isDebugEnabled()) logger.debug("DefaultServlet.serveFile: contentType='" + contentType + "'"); resp.setContentType(contentType); } if (file != null && contentLength >= 0) { if (logger.isDebugEnabled()) logger.debug("DefaultServlet.serveFile: contentLength=" + contentLength); if (contentLength < Integer.MAX_VALUE) resp.setContentLength((int) contentLength); else // Set the content-length as String to be able to use a long resp.setHeader("content-length", "" + contentLength); } InputStream renderResult = null; if (folder != null) if (content) // Serve the directory browser renderResult = renderHtml(req.getContextPath(), path, folder, req); // Copy the input stream to our output stream (if requested) if (content) { try { resp.setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) copy(file, renderResult, ostream, req, null); else copy(file, renderResult, writer, req, null); updateAccounting(user, new Date(), contentLength); } } else { if (ranges == null || ranges.isEmpty()) return; // Partial content response. resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { Range range = (Range) ranges.get(0); resp.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length); long length = range.end - range.start + 1; if (length < Integer.MAX_VALUE) resp.setContentLength((int) length); else // Set the content-length as String to be able to use a long resp.setHeader("content-length", "" + length); if (contentType != null) { if (logger.isDebugEnabled()) logger.debug("DefaultServlet.serveFile: contentType='" + contentType + "'"); resp.setContentType(contentType); } if (content) { try { resp.setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) copy(file, ostream, range, req, null); else copy(file, writer, range, req, null); updateAccounting(user, new Date(), contentLength); } } else { resp.setContentType("multipart/byteranges; boundary=" + mimeSeparation); if (content) { try { resp.setBufferSize(output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) copy(file, ostream, ranges.iterator(), contentType, req, null); else copy(file, writer, ranges.iterator(), contentType, req, null); } } } }
From source file:org.opencms.webdav.CmsWebdavServlet.java
/** * Serve the specified resource, optionally including the data content.<p> * * @param request the servlet request we are processing * @param response the servlet response we are creating * @param content should the content be included? * * @throws IOException if an input/output error occurs */// w w w . jav a 2 s .com protected void serveResource(HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException { // Identify the requested resource path String path = getRelativePath(request); if (LOG.isDebugEnabled()) { if (content) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_SERVE_ITEM_1, path)); } else { LOG.debug(Messages.get().getBundle().key(Messages.LOG_SERVE_ITEM_HEADER_1, path)); } } I_CmsRepositoryItem item = null; try { item = m_session.getItem(path); } catch (CmsException ex) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_ITEM_NOT_FOUND_1, path)); } return; } // If the resource is not a collection, and the resource path // ends with "/" or "\", return NOT FOUND if (!item.isCollection()) { if (path.endsWith("/") || (path.endsWith("\\"))) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_ITEM_NOT_FOUND_1, path)); } return; } } // Find content type. String contentType = item.getMimeType(); if (contentType == null) { contentType = getServletContext().getMimeType(item.getName()); } ArrayList<CmsWebdavRange> ranges = null; long contentLength = -1L; if (item.isCollection()) { // Skip directory listings if we have been configured to suppress them if (!m_listings) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } contentType = "text/html;charset=UTF-8"; } else { // Parse range specifier ranges = parseRange(request, response, item); // ETag header response.setHeader(HEADER_ETAG, getETag(item)); // Last-Modified header response.setHeader(HEADER_LASTMODIFIED, HTTP_DATE_FORMAT.format(new Date(item.getLastModifiedDate()))); // Get content length contentLength = item.getContentLength(); // Special case for zero length files, which would cause a // (silent) ISE when setting the output buffer size if (contentLength == 0L) { content = false; } } ServletOutputStream ostream = null; PrintWriter writer = null; if (content) { // Trying to retrieve the servlet output stream try { ostream = response.getOutputStream(); } catch (IllegalStateException e) { // If it fails, we try to get a Writer instead if we're // trying to serve a text file if ((contentType == null) || (contentType.startsWith("text")) || (contentType.endsWith("xml"))) { writer = response.getWriter(); } else { throw e; } } } if ((item.isCollection()) || (((ranges == null) || (ranges.isEmpty())) && (request.getHeader(HEADER_RANGE) == null)) || (ranges == FULL_RANGE)) { // Set the appropriate output headers if (contentType != null) { if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_SERVE_ITEM_CONTENT_TYPE_1, contentType)); } response.setContentType(contentType); } if ((!item.isCollection()) && (contentLength >= 0)) { if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_SERVE_ITEM_CONTENT_LENGTH_1, new Long(contentLength))); } if (contentLength < Integer.MAX_VALUE) { response.setContentLength((int) contentLength); } else { // Set the content-length as String to be able to use a long response.setHeader(HEADER_CONTENTLENGTH, "" + contentLength); } } InputStream renderResult = null; if (item.isCollection()) { if (content) { // Serve the directory browser renderResult = renderHtml(request.getContextPath() + request.getServletPath(), item.getName()); } } // Copy the input stream to our output stream (if requested) if (content) { try { response.setBufferSize(m_output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(item, renderResult, ostream); } else { copy(item, renderResult, writer); } } } else { if ((ranges == null) || (ranges.isEmpty())) { return; } // Partial content response. response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { CmsWebdavRange range = ranges.get(0); response.addHeader(HEADER_CONTENTRANGE, "bytes " + range.getStart() + "-" + range.getEnd() + "/" + range.getLength()); long length = (range.getEnd() - range.getStart()) + 1; if (length < Integer.MAX_VALUE) { response.setContentLength((int) length); } else { // Set the content-length as String to be able to use a long response.setHeader(HEADER_CONTENTLENGTH, "" + length); } if (contentType != null) { if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_SERVE_ITEM_CONTENT_TYPE_1, contentType)); } response.setContentType(contentType); } if (content) { try { response.setBufferSize(m_output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(item, ostream, range); } else { copy(item, writer, range); } } } else { response.setContentType("multipart/byteranges; boundary=" + MIME_SEPARATION); if (content) { try { response.setBufferSize(m_output); } catch (IllegalStateException e) { // Silent catch } if (ostream != null) { copy(item, ostream, ranges.iterator(), contentType); } else { copy(item, writer, ranges.iterator(), contentType); } } } } }
From source file:de.innovationgate.wgpublisher.WGPDispatcher.java
/** * writes the given data to the response based on response.getContentType() * either reader/writer (for textual content) or binary streams are used * //from w w w .ja v a 2 s.c om * @param data * - the data as inputstream to write - implicit closed after * method call * @param request * @param response * @param characterEncoding * - encoding to use when reading character based from given * data, if null platform encoding is used * @throws IOException * @throws HttpErrorException */ private void writeData(DataSource data, HttpServletRequest request, HttpServletResponse response, String characterEncoding, long size, String sourceHint, boolean allowRequestRanges) throws IOException, HttpErrorException { // Parse accept ranges if requested List<AcceptRange> ranges = new ArrayList<AcceptRange>(); String rangeHeader = request.getHeader("Range"); if (rangeHeader != null && allowRequestRanges && size > 0) { if (rangeHeader.startsWith("bytes=")) { rangeHeader = rangeHeader.substring("bytes=".length()); String[] subranges = rangeHeader.split("\\s*,\\s*"); for (String r : subranges) { Matcher matcher = ACCEPT_RANGE_PATTERN.matcher(r); if (matcher.matches()) { String from = matcher.group(1); String to = matcher.group(2); AcceptRange newRange; try { newRange = new AcceptRange(from != null ? Integer.parseInt(from) : -1, to != null ? Integer.parseInt(to) : -1); if (newRange.from == -1) { newRange.from = size - newRange.to; newRange.to = size - 1; } else if (newRange.to == -1) { newRange.to = size - 1; } } catch (NumberFormatException e) { response.addHeader("Content-Range", "bytes */" + size); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } if ((newRange.from == -1 && newRange.to == -1) || newRange.to > size) { response.addHeader("Content-Range", "bytes */" + size); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } ranges.add(newRange); } else { response.addHeader("Content-Range", "bytes */" + size); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } } } else { response.addHeader("Content-Range", "bytes */" + size); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } } if (ranges.isEmpty()) { // We can only set the raw length on binary resources bc. // transcoding textual response can change the size if (isBinary(request, response) && size > 0) { response.setContentLength((new Long(size)).intValue()); } if (!"HEAD".equalsIgnoreCase(request.getMethod())) { writeWholeData(data, request, response, characterEncoding, sourceHint); } } else { response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { AcceptRange r = ranges.get(0); response.addHeader("Content-Range", "bytes " + r.from + "-" + r.to + "/" + size); response.setContentLength((new Long(r.to - r.from + 1)).intValue()); } else { response.setContentType("multipart/byteranges; boundary=" + BYTERANGE_BOUNDARY); } if (!"HEAD".equalsIgnoreCase(request.getMethod())) { writeRangesData(data, ranges, response, sourceHint, size); } } }