List of usage examples for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED
int SC_NOT_MODIFIED
To view the source code for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.
Click Source Link
From source file:org.gss_project.gss.server.rest.Webdav.java
/** * Check if the if-modified-since condition is satisfied. * * @param request The servlet request we are processing * @param response The servlet response we are creating * @param file the file object/* w w w . j a v a 2 s. c o m*/ * @param oldBody the old version of the file, if requested * @return boolean true if the resource meets the specified condition, and * false if the condition is not satisfied, in which case request * processing is stopped */ private boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response, FileHeader file, FileBody oldBody) { try { long headerValue = request.getDateHeader("If-Modified-Since"); long lastModified = oldBody == null ? file.getAuditInfo().getModificationDate().getTime() : oldBody.getAuditInfo().getModificationDate().getTime(); if (headerValue != -1) // If an If-None-Match header has been specified, if modified // since is ignored. if (request.getHeader("If-None-Match") == null && lastModified < headerValue + 1000) { // The entity has not been modified since the date // specified by the client. This is not an error case. response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", getETag(file, oldBody)); return false; } } catch (IllegalArgumentException illegalArgument) { return true; } return true; }
From source file:org.gss_project.gss.server.rest.Webdav.java
/** * Check if the if-none-match condition is satisfied. * * @param request The servlet request we are processing * @param response The servlet response we are creating * @param file the file object/*from w w w .j a va2s. c o m*/ * @param oldBody the old version of the file, if requested * @return boolean true if the resource meets the specified condition, and * false if the condition is not satisfied, in which case request * processing is stopped * @throws IOException */ private boolean checkIfNoneMatch(HttpServletRequest request, HttpServletResponse response, FileHeader file, FileBody oldBody) throws IOException { String eTag = getETag(file, oldBody); String headerValue = request.getHeader("If-None-Match"); if (headerValue != null) { boolean conditionSatisfied = false; if (!headerValue.equals("*")) { StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ","); while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { String currentToken = commaTokenizer.nextToken(); if (currentToken.trim().equals(eTag)) conditionSatisfied = true; } } else conditionSatisfied = true; if (conditionSatisfied) { // For GET and HEAD, we should respond with 304 Not Modified. // For every other method, 412 Precondition Failed is sent // back. if ("GET".equals(request.getMethod()) || "HEAD".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", getETag(file, oldBody)); return false; } response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return false; } } return true; }
From source file:de.innovationgate.wgpublisher.WGPDispatcher.java
private void dispatchPublishingFile(PublishingFile publishingFile, HttpServletRequest request, HttpServletResponse response, String textOutputEncoding, FileCache fileCache, WGPRequestPath path) throws WGException, HttpErrorException, IOException { // Collect HTTP client hints (if enabled) ClientHints clientHints = new ClientHints(); boolean useHttpClientHints = false; if (publishingFile.getDatabase() != null) { Database database = WGA.get(request, response, getCore()).database(publishingFile.getDatabase()); if (database instanceof App && ((Boolean) database.getPublisherOption(WGACore.DBATTRIB_USE_NONFINAL_HT_FEATURES)) == true) { useHttpClientHints = true;//from www .j a v a 2s . co m } } if (useHttpClientHints) { String dprStr = request.getHeader("CH-DPR"); if (dprStr != null) { try { clientHints.setDevicePixelRatio(Float.valueOf(dprStr)); } catch (NumberFormatException e) { getCore().getLog().warn("Client uses unparseable device pixel ratio: " + dprStr); } } } // Optionally select derivate Float usedDevicePixelRatio = null; try { String derivate = request.getParameter(URLPARAM_DERIVATE); if (derivate != null) { DerivateQuery derivateQuery = getCore().getFileDerivateManager().parseDerivateQuery(derivate); if (publishingFile instanceof DocumentPublishingFile) { DocumentPublishingFile docPublishingFile = (DocumentPublishingFile) publishingFile; WGFileDerivateMetaData derivateMd = docPublishingFile.queryDerivate(derivateQuery, clientHints); if (derivateMd != null) { usedDevicePixelRatio = docPublishingFile.getUsedDevicePixelRatio(); publishingFile = new DerivatePublishingFile(this, docPublishingFile.getContainer(), derivateMd); } } else if (!isFallbackToOriginalOnDerivateQuery(derivateQuery, publishingFile)) { throw new WGNotSupportedException("Derivate queries are not supported on this file type"); } } } catch (WGNotSupportedException e) { throw new HttpErrorException(412, e.getMessage(), path.getDatabaseKey()); } catch (WGInvalidDerivateQueryException e) { throw new HttpErrorException(400, "Invalid derivate query: " + e.getMessage(), path.getDatabaseKey()); } catch (WGFailedDerivateQueryException e) { throw new HttpErrorException(412, "No derivate of file '" + publishingFile.getFileName() + "' matches the derivate query", path.getDatabaseKey()); } // Put out the used device pixel ratio, if any if (usedDevicePixelRatio != null) { response.setHeader("Vary", "CH-DPR"); response.setHeader("DPR", usedDevicePixelRatio.toString()); } // Handle browser cache long lastModified = determinePublishingFileLastModified(publishingFile, request, response); if (browserCacheIsValid(request, lastModified, publishingFile.getETag())) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } else { response.setDateHeader("Last-Modified", lastModified); response.setHeader("ETag", '"' + publishingFile.getETag() + '"'); } // Optionally inject online scaling information to file object String maxHeightStr = request.getParameter(URLPARAM_MAXHEIGHT); String maxWidthStr = request.getParameter(URLPARAM_MAXWIDTH); if (maxHeightStr != null || maxWidthStr != null) { try { int maxHeight = -1; if (maxHeightStr != null) { maxHeight = Integer.parseInt(maxHeightStr); } int maxWidth = -1; if (maxWidthStr != null) { maxWidth = Integer.parseInt(maxWidthStr); } publishingFile.setOnlineScaling(maxWidth, maxHeight, clientHints); } catch (NumberFormatException e) { getCore().getLog().error("Unparseable online scaling metrics", e); } catch (Exception e) { getCore().getLog().error("Exception setting online scaling information", e); } } // Put out content type String contentType = publishingFile.getContentType(); if (contentType == null) { contentType = "application/octet-stream"; } response.setContentType(contentType); // Content Disposition Header - Either if download forced or a disposition filename has been specified Boolean forceDownload = Boolean.parseBoolean(request.getParameter("forcedownload")); if (forceDownload) { response.setHeader("Content-disposition", "attachment" + (publishingFile.getDispositionFileName() != null ? ";filename=" + publishingFile.getDispositionFileName() : "")); } else if (publishingFile.getDispositionFileName() != null) { response.setHeader("Content-disposition", "inline;filename=" + publishingFile.getDispositionFileName()); } // Allow accept ranges on all CS with optimized file handling and binary responses if (publishingFile.isAllowAcceptRanges() && isBinary(request, response)) { response.setHeader("Accept-Ranges", "bytes"); } try { // Look if file is cached - If so, send it and exit if (fileCache != null) { boolean outputHandled = dispatchFileWithCache(publishingFile, request, response, fileCache, lastModified, textOutputEncoding, contentType, path); if (outputHandled) { return; } } // We serve from cache so must retrieve the file. Test for availability now which may load the document. if (!publishingFile.isAvailable()) { throw new HttpErrorException(404, "File not found: " + publishingFile.getName(), path.getDatabaseKey()); } // File is above threshold and not in cache - serve from database writeData(publishingFile, request, response, publishingFile.getTextEncoding(), publishingFile.getFileSize(), publishingFile.getSourceHint(), publishingFile.isAllowAcceptRanges() && isBinary(request, response)); } catch (java.net.SocketException exc) { _log.warn("Dispatch of file request failed bc. of socket error: " + exc.getMessage()); } catch (java.io.IOException exc) { if (!exc.getClass().getName().equals("org.apache.catalina.connector.ClientAbortException")) { _log.warn("Dispatch of file request failed bc. of IO error: " + exc.getMessage()); } } catch (HttpErrorException exc) { throw exc; } catch (Exception exc) { _log.error("Exception dispatching file " + publishingFile.getName(), exc); } }
From source file:de.innovationgate.wgpublisher.WGPDispatcher.java
private void dispatchResourceRequest(WGPRequestPath path, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws Exception { WGARequestInformation info = (WGARequestInformation) request .getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME); if (info != null) { info.setType(WGARequestInformation.TYPE_RESOURCE); }//from w w w . jav a 2s .c o m // determine mimeType String resourcePath = path.getResourcePath(); String mimeType = this.getServletContext().getMimeType(resourcePath); if (mimeType == null) { mimeType = "application/octet-stream"; } response.setContentType(mimeType); File file = null; boolean isTemporaryDownload = false; if (path.getPathCommand().equals(WGPRequestPath.PATHCMD_TEMP_DOWNLOAD)) { String tempFileName = path.getResourcePath().substring(path.getResourcePath().lastIndexOf("/") + 1); TemporaryDownloadsMap temporaryDownloads = (TemporaryDownloadsMap) request.getSession() .getAttribute(SESSION_TEMPORARYDOWNLOADS); if (temporaryDownloads != null) { TemporaryDownload tempDownload = (TemporaryDownload) temporaryDownloads.get(tempFileName); if (tempDownload != null) { file = tempDownload.getTempFile().getFile(); isTemporaryDownload = true; } } } else { file = new File(this.getServletContext().getRealPath("/"), path.getResourcePath()); } if (file == null || !file.exists() || !file.isFile()) { throw new HttpErrorException(404, "File not found: " + path.getResourcePath(), null); } // / Set expiration time int fileExpirationMinutes = getCore().getWgaConfiguration().getCacheExpirationForStaticResources(); if (fileExpirationMinutes > 0) { int fileExpirationSeconds = fileExpirationMinutes * 60; response.setHeader("Cache-Control", "max-age=" + fileExpirationSeconds + ", must-revalidate"); } // determine lastModified // - last modified of binary response depends only on resource change // date // - last change date of textual response additionally depends on // character encoding change date long lastModified; if (isBinary(request, response)) { lastModified = file.lastModified(); } else { lastModified = Math.max(file.lastModified(), _core.getCharacterEncodingLastModified()); } if (browserCacheIsValid(request, lastModified, String.valueOf(lastModified))) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } else { response.setDateHeader("Last-Modified", lastModified); response.setHeader("ETag", '"' + String.valueOf(lastModified) + '"'); } if (mimeType.startsWith("application/")) { response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); } // Dispatch to file resource try { if (!"HEAD".equalsIgnoreCase(request.getMethod())) { DataSource in = null; int fileSize = 0; // We allow direct file dispatching only for temporary files. In // all other cases we use the servlet // context which will take care of file system security. if (isTemporaryDownload) { response.setHeader("Content-Disposition", "attachment;filename=" + file.getName()); in = new URLDataSource(file.toURI().toURL()); fileSize = (int) file.length(); } else { in = new URLDataSource(this.getServletContext().getResource(resourcePath)); } // B000041DA // write data to response - use UTF-8 when reading characters - // WGA resources are UTF-8 encoded writeData(in, request, response, "UTF-8", fileSize, null, true); } } catch (java.net.SocketException exc) { _log.warn("Dispatch of resource request failed bc. of socket error: " + exc.getMessage()); } catch (java.io.IOException exc) { _log.warn("Dispatch of resource request failed bc. of IO error: " + exc.getMessage()); } }
From source file:org.wyona.yanel.servlet.YanelServlet.java
/** * Get global data located below reserved prefix *//*from w w w . ja v a2 s .c om*/ private void getGlobalData(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Resource resource = getResource(request, response); String path = resource.getPath(); java.util.Map<String, String> properties = new HashMap<String, String>(); final String pathPrefix = "/" + reservedPrefix + "/"; final String ABOUT_PAGE_PATH = pathPrefix + "about.html"; // About Yanel final String ABOUT_REALM_PAGE_PATH = pathPrefix + "about-realm.html"; // About realm final String RESOURCE_TYPES_PATH_PREFIX = pathPrefix + "resource-types/"; //XXX REFACTORME: in the cases where we simply use a resource-type's view // we should implement org.wyona.yanel.core.api.ResourceTypeMatcherV1 ( cf. http://lists.wyona.org/pipermail/yanel-development/2009-June/003749.html ) Realm realm; Environment environment = getEnvironment(request, response); ResourceConfiguration rc; YanelGlobalResourceTypeMatcher RTmatcher = new YanelGlobalResourceTypeMatcher(pathPrefix, servletContextRealPath); try { realm = getRealm(request); rc = RTmatcher.getResourceConfiguration(environment, realm, path); } catch (Exception e) { throw new ServletException(e.getMessage(), e); } if (rc != null) { if (generateResponseFromRTview(request, response, -1, rc, path)) { return; } response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND); return; } else if (path.equals(ABOUT_PAGE_PATH)) { //XXX REFACTORME: we should define an "about" resource-type instead! response.setStatus(javax.servlet.http.HttpServletResponse.SC_OK); response.setHeader("Content-Type", "text/html"); PrintWriter w = response.getWriter(); w.print(About.toHTML(yanelInstance.getVersion(), yanelInstance.getRevision(), yanelInstance.getTargetEnvironment())); return; } else if (path.equals(ABOUT_REALM_PAGE_PATH)) { //XXX REFACTORME: we should define an "about-realm" resource-type instead! response.setStatus(javax.servlet.http.HttpServletResponse.SC_OK); response.setHeader("Content-Type", "text/html"); PrintWriter w = response.getWriter(); w.print(AboutRealm.toHTML(realm)); return; } else if (path.startsWith(RESOURCE_TYPES_PATH_PREFIX)) { final String[] namespaceURI_and_rest = path.substring(RESOURCE_TYPES_PATH_PREFIX.length()).split("::", 2); final String namespaceURI = namespaceURI_and_rest[0]; final String[] name_and_rest = namespaceURI_and_rest[1].split("/", 2); final String name = name_and_rest[0]; // INFO: Decode URL, e.g. /yanel/resource-types/^http:^2f^2fwww.wyona.org^2fyanel^2fresource^2f1.0::user-admin/dummy.css final String decoded_namespaceURI = HttpServletRequestHelper.decodeURIinURLpath('^', namespaceURI); log.debug("decoded_namespaceURI: " + decoded_namespaceURI); if (log.isDebugEnabled()) log.debug("decoded_namespaceURI: " + decoded_namespaceURI); // The request (see resource.getPath()) seems to replace 'http://' or 'http%3a%2f%2f' by 'http:/', so let's change this back final String namespace = !decoded_namespaceURI.equals(namespaceURI) ? decoded_namespaceURI : namespaceURI.replaceAll("http:/", "http://"); rc = new ResourceConfiguration(name, namespace, properties); try { Resource resourceOfPrefix = yanelInstance.getResourceManager().getResource(environment, realm, path, rc); String htdocsPath; if (name_and_rest[1].startsWith(reservedPrefix + "/")) { htdocsPath = "rtyanelhtdocs:" + name_and_rest[1].substring(reservedPrefix.length()).replace('/', File.separatorChar); } else { htdocsPath = "rthtdocs:" + File.separatorChar + name_and_rest[1].replace('/', File.separatorChar); } SourceResolver resolver = new SourceResolver(resourceOfPrefix); Source source = resolver.resolve(htdocsPath, null); long sourceLastModified = -1; // INFO: Compare If-Modified-Since with lastModified and return 304 without content resp. check on ETag if (source instanceof YanelStreamSource) { sourceLastModified = ((YanelStreamSource) source).getLastModified(); long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (log.isDebugEnabled()) log.debug("sourceLastModified <= ifModifiedSince: " + sourceLastModified + " <= " + ifModifiedSince); if (ifModifiedSince != -1) { if (sourceLastModified <= ifModifiedSince) { response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED); return; } } } InputStream htdocIn = ((StreamSource) source).getInputStream(); if (htdocIn != null) { log.debug("Resource-Type specific data: " + htdocsPath); // TODO: Set more HTTP headers (size, etc.) String mimeType = guessMimeType(FilenameUtils.getExtension(FilenameUtils.getName(htdocsPath))); if (sourceLastModified >= 0) response.setDateHeader("Last-Modified", sourceLastModified); response.setHeader("Content-Type", mimeType); // INFO: Tell the client for how long it should cache the data which will be sent by the response if (cacheExpires != 0) { setExpiresHeader(response, cacheExpires); } byte buffer[] = new byte[8192]; int bytesRead; OutputStream out = response.getOutputStream(); while ((bytesRead = htdocIn.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } htdocIn.close(); return; } else { log.error("No such file or directory: " + htdocsPath); response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND); return; } } catch (Exception e) { throw new ServletException(e.getMessage(), e); } } else { File globalFile = org.wyona.commons.io.FileUtil.file(servletContextRealPath, "htdocs" + File.separator + path.substring(pathPrefix.length())); if (globalFile.exists()) { //log.debug("Get global file: " + globalFile); // INFO: Compare If-Modified-Since with lastModified and return 304 without content resp. check on ETag long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifModifiedSince != -1) { //log.debug("Last modified '" + globalFile.lastModified() + "' versus If-Modified-Since '" + ifModifiedSince + "'."); if (globalFile.lastModified() <= ifModifiedSince) { response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED); return; } } // TODO: Set more HTTP headers (size, etc.) String mimeType = guessMimeType(FilenameUtils.getExtension(globalFile.getName())); response.setHeader("Content-Type", mimeType); response.setDateHeader("Last-Modified", globalFile.lastModified()); // INFO: Tell the client for how long it should cache the data which will be sent by the response if (cacheExpires != 0) { //log.debug("Client should consider the content of '" + globalFile + "' as stale in '" + cacheExpires + "' hours from now on ..."); setExpiresHeader(response, cacheExpires); } else { //log.debug("No cache expires set."); } byte buffer[] = new byte[8192]; int bytesRead; InputStream in = new java.io.FileInputStream(globalFile); OutputStream out = response.getOutputStream(); while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } in.close(); return; } else { log.error("No such file or directory: " + globalFile); response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND); return; } } }
From source file:de.innovationgate.wgpublisher.WGPDispatcher.java
private void dispatchCssjsRequest(WGPRequestPath path, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception { WGARequestInformation info = (WGARequestInformation) request .getAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME); if (info != null) { info.setType(WGARequestInformation.TYPE_SCRIPT); }/*from w w w .j a va 2 s .c o m*/ // Fetch the database WGDatabase database = path.getDatabase(); // Fetch the library String codeType; switch (path.getPathType()) { case WGPRequestPath.TYPE_CSS: codeType = WGScriptModule.CODETYPE_CSS; break; case WGPRequestPath.TYPE_JS: codeType = WGScriptModule.CODETYPE_JS; break; default: throw new HttpErrorException(500, "Invalid path type to dispatch a css/js request: " + path.getPathType(), path.getDatabaseKey()); } WGCSSJSModule lib = database.getScriptModule(path.getCssjsKey(), codeType); if (lib == null) { if (codeType.equals(WGScriptModule.CODETYPE_CSS) && path.getCssjsKey().endsWith(".css")) { lib = database.getScriptModule(path.getCssjsKey().substring(0, path.getCssjsKey().length() - 4), codeType); } else if (codeType.equals(WGScriptModule.CODETYPE_JS) && path.getCssjsKey().endsWith(".js")) { lib = database.getScriptModule(path.getCssjsKey().substring(0, path.getCssjsKey().length() - 3), codeType); } } if (lib == null) { throw new HttpErrorException(404, "No css/js resource of name " + path.getCssjsKey(), path.getDatabaseKey()); } // determine mime type and encoding String mimeType; String libType = lib.getCodeType(); if (libType.equals(WGCSSJSModule.CODETYPE_CSS)) { mimeType = "text/css"; } else if (libType.equals(WGCSSJSModule.CODETYPE_JS)) { mimeType = "text/javascript"; } else { mimeType = "text/" + libType; } // Reading and post processing of code PostProcessResult result = postProcessDesignResource(lib, request, response); String code; if (result != null) { code = result.getCode(); if (result.getMimeType() != null) { mimeType = result.getMimeType(); } } else { code = lib.getCode(); } response.setContentType(mimeType); // Set expiration time int fileExpirationMinutes = ((Integer) _core.readPublisherOptionOrDefault(database, WGACore.DBATTRIB_FILEEXPIRATION_MINUTES)).intValue(); if (fileExpirationMinutes > 0) { int fileExpirationSeconds = fileExpirationMinutes * 60; boolean isAnonymousAccessible = database.isAnonymousAccessible(); if (isAnonymousAccessible) response.setHeader("Cache-Control", "public, max-age=" + fileExpirationSeconds); else response.setHeader("Cache-Control", "private, max-age=" + fileExpirationSeconds); } // determine lastModified // - last modified of binary response depends only on resource change // date // - last change date of textual response additionally depends on // character encoding change date long lastModified; if (isBinary(request, response)) { lastModified = lib.getLastModified().getTime(); } else { lastModified = Math.max(lib.getLastModified().getTime(), _core.getCharacterEncodingLastModified()); lastModified = Math.max(lastModified, _core.getDesignEncodingLastModified(database.getDbReference())); } String eTag = String.valueOf(code.hashCode()) + "-" + String.valueOf(_core.getDesignEncodingLastModified(database.getDbReference())); if (browserCacheIsValid(request, null, eTag)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", '"' + eTag + '"'); return; } else { response.setHeader("ETag", '"' + eTag + '"'); } // If this is a head request we are finished now if ("HEAD".equalsIgnoreCase(request.getMethod())) { return; } try { java.io.Writer out = response.getWriter(); out.write(code); } catch (java.net.SocketException exc) { _log.warn("Dispatch of css/js request failed bc. of socket error: " + exc.getMessage()); } catch (java.io.IOException exc) { _log.warn("Dispatch of css/js request failed bc. of IO error: " + exc.getMessage()); } }
From source file:org.wyona.yanel.servlet.YanelServlet.java
/** * Generate response from a resource view, whereas it will be checked first if the resource already wrote the response (if so, then just return) * * @param view View of resource/*from w w w.java 2 s. c o m*/ * @param res Resource which handles the request in order to generate a response * @param request TODO * @param response TODO * @param statusCode HTTP response status code (because one is not able to get status code from response) * @param doc TODO * @param size TODO * @param lastModified TODO * @param trackInfo Tracking information bean which might be updated by resource if resource is implementing trackable * * @return response to the client / browser */ private HttpServletResponse generateResponse(View view, Resource res, HttpServletRequest request, HttpServletResponse response, int statusCode, Document doc, long size, long lastModified, TrackingInformationV1 trackInfo) throws ServletException, IOException { //log.debug("Generate response: " + res.getPath()); // TODO: It seems like no header fields are being set (e.g. Content-Length, ...). Please see below ... // INFO: Check if viewable resource has already created a response if (!view.isResponse()) { if (logAccessIsApplicable(view.getMimeType(), res)) { //log.debug("Mime type '" + view.getMimeType() + "' of request: " + request.getServletPath() + "?" + request.getQueryString()); doLogAccess(request, response, statusCode, res, trackInfo); } log.debug("It seems that resource '" + res.getPath() + "' has directly created the response."); try { if ("true".equals(res.getResourceConfigProperty("yanel:no-cache"))) { log.debug("Set no-cache headers..."); response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. response.setHeader("Pragma", "no-cache"); // HTTP 1.0. response.setDateHeader("Expires", 0); // Proxies. } } catch (Exception e) { log.error(e, e); } return response; } // INFO: Set mime type and encoding String mimeType = view.getMimeType(); if (view.getEncoding() != null) { mimeType = patchMimeType(mimeType, request); response.setContentType(mimeType + "; charset=" + view.getEncoding()); } else if (res.getConfiguration() != null && res.getConfiguration().getEncoding() != null) { mimeType = patchMimeType(mimeType, request); response.setContentType(mimeType + "; charset=" + res.getConfiguration().getEncoding()); } else { // try to guess if we have to set the default encoding if (mimeType != null && mimeType.startsWith("text") || mimeType.equals("application/xml") || mimeType.equals("application/xhtml+xml") || mimeType.equals("application/atom+xml") || mimeType.equals("application/x-javascript")) { mimeType = patchMimeType(mimeType, request); response.setContentType(mimeType + "; charset=" + DEFAULT_ENCODING); } else { // probably binary mime-type, don't set encoding mimeType = patchMimeType(mimeType, request); response.setContentType(mimeType); } } if (logAccessIsApplicable(mimeType, res)) { //log.debug("Mime type '" + mimeType + "' of request: " + request.getServletPath() + "?" + request.getQueryString()); doLogAccess(request, response, statusCode, res, trackInfo); } // INFO: Set HTTP headers HashMap<?, ?> headers = view.getHttpHeaders(); Iterator<?> iter = headers.keySet().iterator(); while (iter.hasNext()) { String name = (String) iter.next(); String value = (String) headers.get(name); if (log.isDebugEnabled()) { log.debug("set http header: " + name + ": " + value); } response.setHeader(name, value); } try { if ("true".equals(res.getResourceConfigProperty("yanel:no-cache"))) { log.debug("Set no-cache headers..."); response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. response.setHeader("Pragma", "no-cache"); // HTTP 1.0. response.setDateHeader("Expires", 0); // Proxies. } } catch (Exception e) { log.error(e, e); } // INFO: Confirm DNT (do not track) String dntValue = request.getHeader("DNT"); if (dntValue != null) { response.setHeader("DNT", dntValue); // INFO: See spec about response header at http://tools.ietf.org/html/draft-mayer-do-not-track-00 } else { //log.debug("No DNT (do not track) header set, hence do not echo."); } // Possibly embed toolbar: // TODO: Check if user is authorized to actually see toolbar (Current flaw: Enabled Toolbar, Login, Toolbar is enabled, Logout, Toolbar is still visible!) if (yanelUI.isToolbarEnabled(request)) { // TODO: Check whether resource configuration has toolbar configured as suppressed: if ("suppress".equals(res.getResConfiguration("yanel.toolbar"))) { if (mimeType != null && mimeType.indexOf("html") > 0) { // TODO: What about other query strings or frames or TinyMCE (e.g. link.htm)? if (request.getParameter(YANEL_RESOURCE_USECASE) == null) { // INFO: In the case of a yanel resource usecase do NOT add the toolbar if (toolbarMasterSwitch.equals("on")) { OutputStream os = response.getOutputStream(); try { Usecase usecase = new Usecase(TOOLBAR_USECASE); Realm realm = map.getRealm(request.getServletPath()); Identity identity = getIdentityFromRequest(request, realm); String path = map.getPath(realm, request.getServletPath()); // NOTE: This extra authorization check is necessary within a multi-realm environment, because after activating the toolbar with a query string, the toolbar flag attached to the session will be ignored by doAccessControl(). One could possibly do this check within doAccessControl(), but could be a peformance issue! Or as an alternative one could refactor the code, such that the toolbar session flag is realm aware. if (realm.getPolicyManager().authorize(path, identity, usecase)) { yanelUI.mergeToolbarWithContent(request, response, res, view); return response; } else { log.warn("Toolbar authorization denied (Realm: '" + realm.getName() + "', User: '" + identity.getUsername() + "', Path: '" + path + "')!"); } } catch (Exception e) { String message = "Error merging toolbar into content: " + e.getMessage(); //log.error(message, e); log.error(e, e); Element exceptionElement = (Element) doc.getDocumentElement() .appendChild(doc.createElementNS(NAMESPACE, EXCEPTION_TAG_NAME)); exceptionElement.appendChild(doc.createTextNode(message)); response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR); setYanelOutput(request, response, doc); return response; } } else { log.info("Toolbar has been disabled. Please check web.xml!"); } } else { log.warn("Yanel resource usecase is not null, but set to '" + request.getParameter(YANEL_RESOURCE_USECASE) + "' and hence Yanel toolbar is suppressed/omitted in order to avoid that users are leaving the usecase because they might click on some toolbar menu item."); } } else { log.info("No HTML related mime type: " + mimeType); } } else { log.debug("Toolbar is turned off."); } InputStream is = view.getInputStream(); if (is != null) { try { // Compare If-Modified-Since with lastModified and return 304 without content resp. check on ETag long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifModifiedSince != -1) { //log.debug("Client set 'If-Modified-Since' ..."); if (res instanceof ModifiableV2) { long resourceLastMod = ((ModifiableV2) res).getLastModified(); //log.debug(resourceLastMod + " " + ifModifiedSince); if (resourceLastMod <= ifModifiedSince) { response.setStatus(javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED); return response; } } else { // TODO: Many resources do not implement ModifiableV2 and hence never return a lastModified and hence the browser will never ask for ifModifiedSince! //log.warn("Resource of path '" + res.getPath() + "' is not ModifiableV2 and hence cannot be cached!"); if (log.isDebugEnabled()) log.debug("Resource of path '" + res.getPath() + "' is not ModifiableV2 and hence cannot be cached!"); } } } catch (Exception e) { log.error(e.getMessage(), e); } if (lastModified >= 0) response.setDateHeader("Last-Modified", lastModified); if (size > 0) { if (log.isDebugEnabled()) log.debug("Size of " + request.getRequestURI() + ": " + size); response.setContentLength((int) size); } else { if (log.isDebugEnabled()) log.debug("No size for " + request.getRequestURI() + ": " + size); } try { // INFO: Check whether InputStream is empty and try to Write content into response byte buffer[] = new byte[8192]; int bytesRead; bytesRead = is.read(buffer); if (bytesRead != -1) { java.io.OutputStream os = response.getOutputStream(); os.write(buffer, 0, bytesRead); while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); } else { log.warn("Returned content size of request '" + request.getRequestURI() + "' is 0"); } } catch (Exception e) { log.error("Writing into response failed for request '" + request.getRequestURL() + "' (Client: " + getClientAddressOfUser(request) + ")"); // INFO: For example in the case of ClientAbortException log.error(e, e); throw new ServletException(e); } finally { //log.debug("Close InputStream in any case!"); is.close(); // INFO: Make sure to close InputStream, because otherwise we get bugged with open files } return response; } else { String message = "Returned InputStream of request '" + request.getRequestURI() + "' is null!"; Element exceptionElement = (Element) doc.getDocumentElement() .appendChild(doc.createElementNS(NAMESPACE, EXCEPTION_TAG_NAME)); exceptionElement.appendChild(doc.createTextNode(message)); response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR); setYanelOutput(request, response, doc); is.close(); return response; } }
From source file:org.gss_project.gss.server.rest.Webdav.java
/** * Check if the if-modified-since condition is satisfied. * * @param request The servlet request we are processing * @param response The servlet response we are creating * @param folder the folder object/* ww w .j av a 2 s .c o m*/ * @return boolean true if the resource meets the specified condition, and * false if the condition is not satisfied, in which case request * processing is stopped */ public boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response, Folder folder) { try { long headerValue = request.getDateHeader("If-Modified-Since"); long lastModified = folder.getAuditInfo().getModificationDate().getTime(); if (headerValue != -1) // If an If-None-Match header has been specified, if modified // since is ignored. if (request.getHeader("If-None-Match") == null && lastModified < headerValue + 1000) { // The entity has not been modified since the date // specified by the client. This is not an error case. response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return false; } } catch (IllegalArgumentException illegalArgument) { return true; } return true; }
From source file:org.sakaiproject.content.impl.BaseContentService.java
/** * Process the access request for a resource. * /*from w w w .j ava2s.c o m*/ * @param req * @param req * @param res * @param ref * @param copyrightAcceptedRefs * @throws PermissionException * @throws IdUnusedException * @throws ServerOverloadException * @throws CopyrightException */ protected void handleAccessResource(HttpServletRequest req, HttpServletResponse res, Reference ref, Collection<String> copyrightAcceptedRefs) throws EntityPermissionException, EntityNotDefinedException, EntityAccessOverloadException, EntityCopyrightException { // we only access resources, not collections if (ref.getId().endsWith(Entity.SEPARATOR)) throw new EntityNotDefinedException(ref.getReference()); // need read permission if (!allowGetResource(ref.getId())) throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), AUTH_RESOURCE_READ, ref.getReference()); ContentResource resource = null; try { resource = getResource(ref.getId()); } 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(ref.getReference()); } // if this entity requires a copyright agreement, and has not yet been set, get one if (((BaseResourceEdit) resource).requiresCopyrightAgreement() && !copyrightAcceptedRefs.contains(resource.getReference())) { throw new EntityCopyrightException(ref.getReference()); } // Wrap up the resource if we need to. resource = m_contentFilterService.wrap(resource); // Set some headers to tell browsers to revalidate and check for updated files res.addHeader("Cache-Control", "must-revalidate, private"); res.addHeader("Expires", "-1"); try { long len = resource.getContentLength(); String contentType = resource.getContentType(); 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)); } // for url content type, encode a redirect to the body URL if (contentType.equalsIgnoreCase(ResourceProperties.TYPE_URL)) { 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(EVENT_RESOURCE_READ, resource.getReference(null), false)); //SAK-23587 process any macros present in this URL String decodedUrl = URLDecoder.decode(uri.toString(), "UTF-8"); decodedUrl = expandMacros(decodedUrl); res.sendRedirect(decodedUrl); } 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 = Validator.getFileName(ref.getId()); String disposition = null; if (Validator.letBrowserInline(contentType)) { // if this is an html file we have more checks String lcct = contentType.toLowerCase(); if ((lcct.startsWith("text/") || lcct.startsWith("image/") || lcct.contains("html") || lcct.contains("script")) && m_serverConfigurationService.getBoolean(SECURE_INLINE_HTML, true)) { // increased checks to handle more mime-types - https://jira.sakaiproject.org/browse/KNL-749 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) { disposition = Web.buildContentDisposition(fileName, false); } } else { disposition = Web.buildContentDisposition(fileName, false); } } // drop through to attachment if (disposition == null) { disposition = Web.buildContentDisposition(fileName, true); } // 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; } // 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); res.addHeader("Accept-Ranges", "bytes"); 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); // 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(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 if (content != null) { content.close(); } if (out != null) { try { out.close(); } catch (IOException ignore) { // ignore } } } } 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 if (out != null) { try { out.close(); } catch (IOException ignore) { // ignore } } } } // output multiple ranges } // output partial content } // output resource } catch (Exception t) { throw new EntityNotDefinedException(ref.getReference(), t); } }