public void init() throws ServletException { super.init(); // allow = ThreddsConfig.getBoolean("NetcdfSubsetService.allow", true); // String radarLevel2Dir = ThreddsConfig.get("NetcdfSubsetService.radarLevel2DataDir", // "/data/ldm/pub/native/radar/level2/"); // if (!allow) return; contentPath = ServletUtil.getContentPath(); rm = new RadarMethods(contentPath, logServerStartup); // read in radarCollections.xml catalog InvCatalogFactory factory = InvCatalogFactory.getDefaultFactory(false); // no validation cat = readCatalog(factory, getPath() + catName, contentPath + getPath() + catName); if (cat == null) { logServerStartup.info("cat initialization failed"); return; } // URI tmpURI = cat.getBaseURI(); cat.setBaseURI(catURI); // get path and location from cat List parents = cat.getDatasets(); for (int i = 0; i < parents.size(); i++) { InvDataset top = (InvDataset) parents.get(i); datasets = top.getDatasets(); // dataset scans for (int j = 0; j < datasets.size(); j++) { InvDatasetScan ds = (InvDatasetScan) datasets.get(j); if (ds.getPath() != null) { dataLocation.put(ds.getPath(), ds.getScanLocation()); logServerStartup.info("path =" + ds.getPath() + " location =" + ds.getScanLocation()); } ds.setXlinkHref(ds.getPath() + "/dataset.xml"); } } logServerStartup.info(getClass().getName() + " initialization complete "); } // end init
public void doGetDIR(ReqState rs) throws Exception { // rather dangerous here, since you can go into an infinite loop // so we're going to insist that there's no suffix HttpServletResponse response = rs.getResponse(); HttpServletRequest request = rs.getRequest(); if ((rs.getRequestSuffix() == null) || (rs.getRequestSuffix().length() == 0)) { ServletUtil.forwardToCatalogServices(request, response); return; } sendErrorResponse(response, 0, "Unrecognized request"); }
@Override public String getViewerLinkHtml(InvDatasetImpl ds, HttpServletRequest req) { InvAccess access = ds.getAccess(ServiceType.WMS); URI dataURI = access.getStandardUri(); try { URI base = new URI(req.getRequestURL().toString()); dataURI = base.resolve(dataURI); } catch (URISyntaxException e) { return "Error generating viewer link"; } // ToDo Switch to use TdsContext.getContextPath() return "<a href='" + ServletUtil.getContextPath() + "/godiva2/godiva2.html?server=" + dataURI.toString() + "'>Godiva2 (browser-based)</a>"; }
/** * Write a file to the response stream. * * @param servlet called from here * @param contentPath file root path * @param path file path reletive to the root * @param req the request * @param res the response * @param contentType content type, or null * @throws IOException on write error */ public static void returnFile( HttpServlet servlet, String contentPath, String path, HttpServletRequest req, HttpServletResponse res, String contentType) throws IOException { String filename = ServletUtil.formFilename(contentPath, path); log.debug("returnFile(): returning file <" + filename + ">."); // No file, nothing to view if (filename == null) { log.info( "returnFile(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, 0)); res.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // dontallow .. if (filename.indexOf("..") != -1) { log.info( "returnFile(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_FORBIDDEN, 0)); res.sendError(HttpServletResponse.SC_FORBIDDEN); return; } // dont allow access to WEB-INF or META-INF String upper = filename.toUpperCase(); if (upper.indexOf("WEB-INF") != -1 || upper.indexOf("META-INF") != -1) { log.info( "returnFile(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_FORBIDDEN, 0)); res.sendError(HttpServletResponse.SC_FORBIDDEN); return; } returnFile(servlet, req, res, new File(filename), contentType); }
public void afterPropertiesSet() { // ToDo Instead of stdout, use servletContext.log( "...") [NOTE: it writes to localhost.*.log // rather than catalina.out]. if (servletContext == null) throw new IllegalArgumentException("ServletContext must not be null."); // ToDo LOOK - Are we still using this. ServletUtil.initDebugging(servletContext); // Set the webapp name. this.webappName = servletContext.getServletContextName(); // Set the context path. // Servlet 2.5 allows the following. // contextPath = servletContext.getContextPath(); String tmpContextPath = servletContext.getInitParameter( "ContextPath"); // cannot be overridden in the ThreddsConfig file if (tmpContextPath == null) tmpContextPath = "thredds"; contextPath = "/" + tmpContextPath; // ToDo LOOK - Get rid of need for setting contextPath in ServletUtil. ServletUtil.setContextPath(contextPath); // Set the root directory and source. String rootPath = servletContext.getRealPath("/"); if (rootPath == null) { String msg = "Webapp [" + this.webappName + "] must run with exploded deployment directory (not from .war)."; System.out.println("ERROR - TdsContext.init(): " + msg); // logServerStartup.error( "TdsContext.init(): " + msg ); throw new IllegalStateException(msg); } this.rootDirectory = new File(rootPath); this.rootDirSource = new BasicDescendantFileSource(this.rootDirectory); this.rootDirectory = this.rootDirSource.getRootDirectory(); // ToDo LOOK - Get rid of need for setting rootPath in ServletUtil. ServletUtil.setRootPath(this.rootDirSource.getRootDirectoryPath()); // Set the startup (initial install) content directory and source. this.startupContentDirectory = new File(this.rootDirectory, this.startupContentPath); this.startupContentDirSource = new BasicDescendantFileSource(this.startupContentDirectory); this.startupContentDirectory = this.startupContentDirSource.getRootDirectory(); this.webinfPath = this.rootDirectory + "/WEB-INF"; // set the tomcat logging directory try { String base = System.getProperty("catalina.base"); if (base != null) { this.tomcatLogDir = new File(base, "logs").getCanonicalFile(); if (!this.tomcatLogDir.exists()) { String msg = "'catalina.base' directory not found"; System.out.println("WARN - TdsContext.init(): " + msg); // logServerStartup.error( "TdsContext.init(): " + msg ); } } else { String msg = "'catalina.base' property not found - probably not a tomcat server"; System.out.println("WARN - TdsContext.init(): " + msg); // logServerStartup.warn( "TdsContext.init(): " + msg ); } } catch (IOException e) { String msg = "tomcatLogDir could not be created"; System.out.println("WARN - TdsContext.init(): " + msg); // logServerStartup.error( "TdsContext.init(): " + msg ); } // Set the content directory and source. File contentRootDir = new File(this.contentRootPath); if (!contentRootDir.isAbsolute()) this.contentDirectory = new File(new File(this.rootDirectory, this.contentRootPath), this.contentPath); else { if (contentRootDir.isDirectory()) this.contentDirectory = new File(contentRootDir, this.contentPath); else { String msg = "Content root directory [" + this.contentRootPath + "] not a directory."; System.out.println("ERROR - TdsContext.init(): " + msg); // logServerStartup.error( "TdsContext.init(): " + msg ); throw new IllegalStateException(msg); } } // If the content directory doesn't exist, try to copy startup content directory. if (!this.contentDirectory.exists()) { try { IO.copyDirTree(this.startupContentDirectory.getPath(), this.contentDirectory.getPath()); } catch (IOException e) { String tmpMsg = "Content directory does not exist and could not be created"; System.out.println( "ERROR - TdsContext.init(): " + tmpMsg + " [" + this.contentDirectory.getAbsolutePath() + "]."); // logServerStartup.error( "TdsContext.init(): " + tmpMsg + " [" + // this.contentDirectory.getAbsolutePath() + "]" ); throw new IllegalStateException(tmpMsg); } } // If content directory exists, make sure it is a directory. if (this.contentDirectory.isDirectory()) { this.contentDirSource = new BasicDescendantFileSource( StringUtils.cleanPath(this.contentDirectory.getAbsolutePath())); this.contentDirectory = this.contentDirSource.getRootDirectory(); } else { String tmpMsg = "Content directory not a directory"; System.out.println( "ERROR - TdsContext.init(): " + tmpMsg + " [" + this.contentDirectory.getAbsolutePath() + "]."); // logServerStartup.error( "TdsContext.init(): " + tmpMsg + " [" + // this.contentDirectory.getAbsolutePath() + "]" ); throw new IllegalStateException(tmpMsg); } ServletUtil.setContentPath(this.contentDirSource.getRootDirectoryPath()); File logDir = new File(this.contentDirectory, "logs"); if (!logDir.exists()) { if (!logDir.mkdirs()) { String msg = "Couldn't create TDS log directory [" + logDir.getPath() + "]."; // System.out.println( "ERROR - TdsContext.init(): " + msg); logServerStartup.error("TdsContext.init(): " + msg); throw new IllegalStateException(msg); } } String loggingDirectory = StringUtil2.substitute(logDir.getPath(), "\\", "/"); System.setProperty("tds.log.dir", loggingDirectory); // variable substitution // LOOK Remove log4j init JC 6/13/2012 // which is used in log4j.xml file loaded here. Log4jWebConfigurer.initLogging(servletContext); logServerStartup.info("TdsConfigContextListener.contextInitialized() start[2]: "); logServerStartup.info("TdsContext.init() intializating logging..."); // read in persistent user-defined params from threddsConfig.xml File tdsConfigFile = this.contentDirSource.getFile(this.getTdsConfigFileName()); String tdsConfigFilename = tdsConfigFile != null ? tdsConfigFile.getPath() : ""; ThreddsConfig.init(tdsConfigFilename); this.publicContentDirectory = new File(this.contentDirectory, "public"); if (!publicContentDirectory.exists()) { if (!publicContentDirectory.mkdirs()) { String msg = "Couldn't create TDS public directory [" + publicContentDirectory.getPath() + "]."; // System.out.println( "ERROR - TdsContext.init(): " + msg); logServerStartup.error("TdsContext.init(): " + msg); throw new IllegalStateException(msg); } } this.publicContentDirSource = new BasicDescendantFileSource(this.publicContentDirectory); this.iddContentDirectory = new File(this.rootDirectory, this.iddContentPath); this.iddContentPublicDirSource = new BasicDescendantFileSource(this.iddContentDirectory); this.motherlodeContentDirectory = new File(this.rootDirectory, this.motherlodeContentPath); this.motherlodeContentPublicDirSource = new BasicDescendantFileSource(this.motherlodeContentDirectory); List<DescendantFileSource> chain = new ArrayList<DescendantFileSource>(); DescendantFileSource contentMinusPublicSource = new BasicWithExclusionsDescendantFileSource( this.contentDirectory, Collections.singletonList("public")); chain.add(contentMinusPublicSource); for (String curContentRoot : ThreddsConfig.getContentRootList()) { if (curContentRoot.equalsIgnoreCase("idd")) chain.add(this.iddContentPublicDirSource); else if (curContentRoot.equalsIgnoreCase("motherlode")) chain.add(this.motherlodeContentPublicDirSource); else { try { chain.add(new BasicDescendantFileSource(StringUtils.cleanPath(curContentRoot))); } catch (IllegalArgumentException e) { String msg = "Couldn't add content root [" + curContentRoot + "]: " + e.getMessage(); // System.out.println( "WARN - TdsContext.init(): " + msg ); logServerStartup.warn("TdsContext.init(): " + msg, e); } } } this.configSource = new ChainedFileSource(chain); this.publicDocSource = this.publicContentDirSource; // ToDo LOOK Find a better way once thredds.catalog2 is used. InvDatasetScan.setContext(contextPath); InvDatasetScan.setCatalogServletName("/catalog"); InvDatasetFeatureCollection.setContext(contextPath); // GridServlet.setContextPath( contextPath ); // Won't need when switch GridServlet to use Swing // MVC and TdsContext jspRequestDispatcher = servletContext.getNamedDispatcher("jsp"); defaultRequestDispatcher = servletContext.getNamedDispatcher("default"); TdsConfigMapper tdsConfigMapper = new TdsConfigMapper(); tdsConfigMapper.setTdsServerInfo(this.serverInfo); tdsConfigMapper.setHtmlConfig(this.htmlConfig); tdsConfigMapper.setWmsConfig(this.wmsConfig); tdsConfigMapper.init(this); }
void init(TdsContext tdsContext) { // new for 4.2 - feature collection caching String fcCache = ThreddsConfig.get( "FeatureCollection.cacheDirectory", tdsContext.getContentDirectory().getPath() + "/collectionCache/"); try { thredds.inventory.bdb.MetadataManager.setCacheDirectory(fcCache); startupLog.info("CdmInit: FeatureCollection.cacheDirectory= " + fcCache); } catch (Exception e) { startupLog.error("CdmInit: Failed to open FeatureCollection.cacheDirectory= " + fcCache, e); } // new for 4.1 - ehcache object caching String ehConfig = ThreddsConfig.get("ehcache.configFile", tdsContext.getWebinfPath() + "/ehcache.xml"); String ehDirectory = ThreddsConfig.get( "ehcache.directory", tdsContext.getContentDirectory().getPath() + "/ehcache/"); try { cacheManager = thredds.filesystem.ControllerCaching.makeStandardController(ehConfig, ehDirectory); thredds.inventory.DatasetCollectionManager.setController(cacheManager); startupLog.info("CdmInit: ehcache.config= " + ehConfig + " directory= " + ehDirectory); } catch (IOException ioe) { startupLog.error("CdmInit: Cant read ehcache config file " + ehConfig, ioe); } boolean useBytesForDataSize = ThreddsConfig.getBoolean("catalogWriting.useBytesForDataSize", false); InvCatalogFactory10.useBytesForDataSize(useBytesForDataSize); //////////////////////////////////// // AggregationFmrc.setDefinitionDirectory(new File(tdsContext.getRootDirectory(), // fmrcDefinitionDirectory)); FmrcInventoryServlet.setDefinitionDirectory( new File(tdsContext.getRootDirectory(), fmrcDefinitionDirectory)); // NetcdfFileCache : default is allow 200 - 400 open files, cleanup every 10 minutes int min = ThreddsConfig.getInt("NetcdfFileCache.minFiles", 200); int max = ThreddsConfig.getInt("NetcdfFileCache.maxFiles", 400); int secs = ThreddsConfig.getSeconds("NetcdfFileCache.scour", 10 * 60); if (max > 0) { NetcdfDataset.initNetcdfFileCache(min, max, secs); } // HTTP file access : // allow 20 - 40 open datasets, cleanup every 10 minutes min = ThreddsConfig.getInt("HTTPFileCache.minFiles", 25); max = ThreddsConfig.getInt("HTTPFileCache.maxFiles", 40); secs = ThreddsConfig.getSeconds("HTTPFileCache.scour", 10 * 60); if (max > 0) { ServletUtil.setFileCache(new FileCacheRaf(min, max, secs)); } // for backwards compatibility - should be replaced by direct specifying of the IndexExtendMode // turn off Grib extend indexing; indexes are automatically done every 10 minutes externally boolean extendIndex = ThreddsConfig.getBoolean("GribIndexing.setExtendIndex", false); GridServiceProvider.IndexExtendMode mode = extendIndex ? GridServiceProvider.IndexExtendMode.extendwrite : GridServiceProvider.IndexExtendMode.readonly; ucar.nc2.iosp.grid.GridServiceProvider.setIndexFileModeOnOpen(mode); ucar.nc2.iosp.grid.GridServiceProvider.setIndexFileModeOnSync(mode); boolean alwaysUseCache = ThreddsConfig.getBoolean("GribIndexing.alwaysUseCache", false); ucar.nc2.iosp.grid.GridServiceProvider.setIndexAlwaysInCache(alwaysUseCache); // optimization: netcdf-3 files can only grow, not have metadata changes ucar.nc2.NetcdfFile.setProperty("syncExtendOnly", "true"); // persist joinNew aggregations. default every 24 hours, delete stuff older than 90 days String dir = ThreddsConfig.get( "AggregationCache.dir", new File(tdsContext.getContentDirectory().getPath(), "cacheAged").getPath()); int scourSecs = ThreddsConfig.getSeconds("AggregationCache.scour", 24 * 60 * 60); int maxAgeSecs = ThreddsConfig.getSeconds("AggregationCache.maxAge", 90 * 24 * 60 * 60); aggCache = new DiskCache2(dir, false, maxAgeSecs / 60, scourSecs / 60); Aggregation.setPersistenceCache(aggCache); // how to choose the typical dataset ? String typicalDataset = ThreddsConfig.get("Aggregation.typicalDataset", "penultimate"); Aggregation.setTypicalDatasetMode(typicalDataset); // Nj22 disk cache dir = ThreddsConfig.get( "DiskCache.dir", new File(tdsContext.getContentDirectory(), "cache").getPath()); boolean alwaysUse = ThreddsConfig.getBoolean("DiskCache.alwaysUse", false); scourSecs = ThreddsConfig.getSeconds("DiskCache.scour", 60 * 60); long maxSize = ThreddsConfig.getBytes("DiskCache.maxSize", (long) 1000 * 1000 * 1000); DiskCache.setRootDirectory(dir); DiskCache.setCachePolicy(alwaysUse); Calendar c = Calendar.getInstance(); // contains current startup time c.add(Calendar.SECOND, scourSecs / 2); // starting in half the scour time timer = new Timer(); timer.scheduleAtFixedRate(new CacheScourTask(maxSize), c.getTime(), (long) 1000 * scourSecs); startupLog.info("CdmInit complete"); }
public void doGet(HttpServletRequest request, HttpServletResponse response) { log.info("doGet(): " + UsageLog.setupRequestContext(request)); // System.out.printf("opendap doGet: req=%s%n%s%n", ServletUtil.getRequest(request), // ServletUtil.showRequestDetail(this, request)); String path = null; ReqState rs = getRequestState(request, response); try { path = request.getPathInfo(); log.debug("doGet path={}", path); if (thredds.servlet.Debug.isSet("showRequestDetail")) log.debug(ServletUtil.showRequestDetail(this, request)); if (path == null) { log.info( "doGet(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (baseURI == null) { // first time, set baseURI URI reqURI = ServletUtil.getRequestURI(request); // Build base URI from request (rather than hard-coding "/thredds/dodsC/"). String baseUriString = request.getContextPath() + request.getServletPath() + "/"; baseURI = reqURI.resolve(baseUriString); log.debug("doGet(): baseURI was set = {}", baseURI); } if (path.endsWith("latest.xml")) { DataRootHandler.getInstance().processReqForLatestDataset(this, request, response); return; } // Redirect all catalog requests at the root level. if (path.equals("/") || path.equals("/catalog.html") || path.equals("/catalog.xml")) { ServletUtil.sendPermanentRedirect(ServletUtil.getContextPath() + path, request, response); return; } // Make sure catalog requests match a dataRoot before trying to handle. if (path.endsWith("/") || path.endsWith("/catalog.html") || path.endsWith("/catalog.xml")) { if (!DataRootHandler.getInstance().hasDataRootMatch(path)) { log.info( "doGet(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (!DataRootHandler.getInstance().processReqForCatalog(request, response)) log.error( "doGet(): " + UsageLog.closingMessageForRequestContext( ServletUtil.STATUS_FORWARD_FAILURE, -1)); return; } if (rs != null) { String dataSet = rs.getDataSet(); String requestSuffix = rs.getRequestSuffix(); if ((dataSet == null) || dataSet.equals("/") || dataSet.equals("")) { doGetDIR(rs); } else if (requestSuffix.equalsIgnoreCase("blob")) { doGetBLOB(rs); } else if (requestSuffix.equalsIgnoreCase("close")) { doClose(rs); } else if (requestSuffix.equalsIgnoreCase("dds")) { doGetDDS(rs); } else if (requestSuffix.equalsIgnoreCase("das")) { doGetDAS(rs); } else if (requestSuffix.equalsIgnoreCase("ddx")) { doGetDDX(rs); } else if (requestSuffix.equalsIgnoreCase("dods")) { doGetDAP2Data(rs); } else if (requestSuffix.equalsIgnoreCase("asc") || requestSuffix.equalsIgnoreCase("ascii")) { doGetASC(rs); } else if (requestSuffix.equalsIgnoreCase("info")) { doGetINFO(rs); } else if (requestSuffix.equalsIgnoreCase("html") || requestSuffix.equalsIgnoreCase("htm")) { doGetHTML(rs); } else if (requestSuffix.equalsIgnoreCase("ver") || requestSuffix.equalsIgnoreCase("version") || dataSet.equalsIgnoreCase("/version") || dataSet.equalsIgnoreCase("/version/")) { doGetVER(rs); } else if (dataSet.equalsIgnoreCase("/help") || dataSet.equalsIgnoreCase("/help/") || dataSet.equalsIgnoreCase("/" + requestSuffix) || requestSuffix.equalsIgnoreCase("help")) { doGetHELP(rs); } else { sendErrorResponse(response, HttpServletResponse.SC_BAD_REQUEST, "Unrecognized request"); return; } } else { sendErrorResponse(response, HttpServletResponse.SC_BAD_REQUEST, "Unrecognized request"); return; } log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_OK, -1)); // plain ol' 404 } catch (FileNotFoundException e) { sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, e.getMessage()); // DAP2Exception bad url } catch (BadURLException e) { log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_BAD_REQUEST, -1)); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); dap2ExceptionHandler(e, rs); // all other DAP2Exception } catch (DAP2Exception de) { int status = (de.getErrorCode() == DAP2Exception.NO_SUCH_FILE) ? HttpServletResponse.SC_NOT_FOUND : HttpServletResponse.SC_BAD_REQUEST; if ((de.getErrorCode() != DAP2Exception.NO_SUCH_FILE) && (de.getErrorMessage() != null)) log.debug(de.getErrorMessage()); log.info(UsageLog.closingMessageForRequestContext(status, -1)); response.setStatus(status); dap2ExceptionHandler(de, rs); // parsing, usually the CE } catch (ParseException pe) { log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_BAD_REQUEST, -1)); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); parseExceptionHandler(pe, response); // 403 - request too big } catch (UnsupportedOperationException e) { sendErrorResponse(response, HttpServletResponse.SC_FORBIDDEN, e.getMessage()); } catch (java.net.SocketException e) { log.info("SocketException: " + e.getMessage(), e); log.info(UsageLog.closingMessageForRequestContext(ServletUtil.STATUS_CLIENT_ABORT, -1)); } catch (IOException e) { String eName = e.getClass().getName(); // dont want compile time dependency on ClientAbortException if (eName.equals("org.apache.catalina.connector.ClientAbortException")) { log.debug("ClientAbortException: " + e.getMessage()); log.info(UsageLog.closingMessageForRequestContext(ServletUtil.STATUS_CLIENT_ABORT, -1)); return; } log.error("path= " + path, e); sendErrorResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); // everything else } catch (Throwable t) { log.error("path= " + path, t); t.printStackTrace(); sendErrorResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage()); } }
/** * Convenience routine used by handleRequestForContentFile() and handleRequestForRootFile(). * * @param pathPrefix * @param path * @param servlet * @param req request * @param res response * @throws IOException on IO error */ private static void handleRequestForContentOrRootFile( String pathPrefix, String path, HttpServlet servlet, HttpServletRequest req, HttpServletResponse res) throws IOException { if (!pathPrefix.equals("/content/") && !pathPrefix.equals("/root/")) { log.error( "handleRequestForContentFile(): The path prefix <" + pathPrefix + "> must be \"/content/\" or \"/root/\"."); throw new IllegalArgumentException("Path prefix must be \"/content/\" or \"/root/\"."); } if (!path.startsWith(pathPrefix)) { log.error( "handleRequestForContentFile(): path <" + path + "> must start with \"" + pathPrefix + "\"."); throw new IllegalArgumentException("Path must start with \"" + pathPrefix + "\"."); } // Don't allow ".." directories in path. if (path.indexOf("/../") != -1 || path.equals("..") || path.startsWith("../") || path.endsWith("/..")) { res.sendError(HttpServletResponse.SC_FORBIDDEN, "Path cannot contain \"..\" directory."); log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_FORBIDDEN, -1)); return; } // Find the requested file. File file = new File( ServletUtil.formFilename(getContentPath(), path.substring(pathPrefix.length() - 1))); if (file.exists()) { // Do not allow request for a directory. if (file.isDirectory()) { if (!path.endsWith("/")) { String redirectPath = req.getRequestURL().append("/").toString(); ServletUtil.sendPermanentRedirect(redirectPath, req, res); return; } int i = HtmlWriter.getInstance().writeDirectory(res, file, path); int status = i == 0 ? HttpServletResponse.SC_NOT_FOUND : HttpServletResponse.SC_OK; log.info(UsageLog.closingMessageForRequestContext(status, i)); return; } // Return the requested file. ServletUtil.returnFile(servlet, req, res, file, null); } else { // Requested file not found. log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); res.sendError(HttpServletResponse.SC_NOT_FOUND); // 404 } }
/** * Handle a request for a raw/static file (i.e., not a catalog or dataset request). * * <p>Look in the content (user) directory then the root (distribution) directory for a file that * matches the given path and, if found, return it as the content of the HttpServletResponse. If * the file is forbidden (i.e., the path contains a "..", "WEB-INF", or "META-INF" directory), * send a HttpServletResponse.SC_FORBIDDEN response. If no file matches the request (including an * "index.html" file if the path ends in "/"), send an HttpServletResponse.SC_NOT_FOUND.. * * <p> * * <ol> * <li>Make sure the path does not contain ".." directories. * <li>Make sure the path does not contain "WEB-INF" or "META-INF". * <li>Check for requested file in the content directory (if the path is a directory, make sure * the path ends with "/" and check for an "index.html" file). * <li>Check for requested file in the root directory (if the path is a directory, make sure the * path ends with "/" and check for an "index.html" file). </ol * * @param path the requested path * @param servlet the servlet handling the request * @param req the HttpServletRequest * @param res the HttpServletResponse * @throws IOException if can't complete request due to IO problems. */ public static void handleRequestForRawFile( String path, HttpServlet servlet, HttpServletRequest req, HttpServletResponse res) throws IOException { // Don't allow ".." directories in path. if (path.indexOf("/../") != -1 || path.equals("..") || path.startsWith("../") || path.endsWith("/..")) { res.sendError(HttpServletResponse.SC_FORBIDDEN, "Path cannot contain \"..\" directory."); log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_FORBIDDEN, -1)); return; } // Don't allow access to WEB-INF or META-INF directories. String upper = path.toUpperCase(); if (upper.indexOf("WEB-INF") != -1 || upper.indexOf("META-INF") != -1) { res.sendError( HttpServletResponse.SC_FORBIDDEN, "Path cannot contain \"WEB-INF\" or \"META-INF\"."); log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_FORBIDDEN, -1)); return; } // Find a regular file File regFile = null; // Look in content directory for regular file. File cFile = new File(ServletUtil.formFilename(getContentPath(), path)); if (cFile.exists()) { if (cFile.isDirectory()) { if (!path.endsWith("/")) { String newPath = req.getRequestURL().append("/").toString(); ServletUtil.sendPermanentRedirect(newPath, req, res); } // If request path is a directory, check for index.html file. cFile = new File(cFile, "index.html"); if (cFile.exists() && !cFile.isDirectory()) regFile = cFile; } // If not a directory, use this file. else regFile = cFile; } if (regFile == null) { // Look in root directory. File rFile = new File(ServletUtil.formFilename(getRootPath(), path)); if (rFile.exists()) { if (rFile.isDirectory()) { if (!path.endsWith("/")) { String newPath = req.getRequestURL().append("/").toString(); ServletUtil.sendPermanentRedirect(newPath, req, res); } rFile = new File(rFile, "index.html"); if (rFile.exists() && !rFile.isDirectory()) regFile = rFile; } else regFile = rFile; } } if (regFile == null) { res.sendError(HttpServletResponse.SC_NOT_FOUND); // 404 log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); return; } ServletUtil.returnFile(servlet, req, res, regFile, null); }
protected long getLastModified(HttpServletRequest req) { contentPath = ServletUtil.getContentPath(); File file = new File(contentPath + getPath() + catName); return file.lastModified(); }