AbstractAggregatorImpl extends HttpServlet implements IAggregator { protected void processResourceRequest(HttpServletRequest req, HttpServletResponse resp, URI uri, String path) { final String sourceMethod = "processRequest"; boolean isTraceLogging = log.isLoggable(Level.FINER); if (isTraceLogging) { log.entering(AbstractAggregatorImpl.class.getName(), sourceMethod, new Object[]{req, resp, uri, path}); } try { if (path != null && path.length() > 0) { if (!uri.getPath().endsWith("/")) { uri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath() + "/", uri.getQuery(), uri.getFragment()); } uri = uri.resolve("."); URI resolvedUri = uri.resolve(path); String resolvedPath = resolvedUri.getPath(); if (!resolvedPath.startsWith(uri.getPath()) || resolvedPath.startsWith("/../")) { throw new BadRequestException(path); } uri = resolvedUri; } IResource resolved = newResource(uri); if (!resolved.exists()) { throw new NotFoundException(resolved.getURI().toString()); } getTransport().decorateRequest(req); boolean isNoCache = RequestUtil.isIgnoreCached(req); long modifiedSince = req.getDateHeader("If-Modified-Since"); if (modifiedSince >= resolved.lastModified() && !isNoCache) { if (log.isLoggable(Level.FINER)) { log.finer("Returning Not Modified response for resource in servlet" + getName() + ":" + resolved.getURI()); } resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } else { setResourceResponseCacheHeaders(req, resp, resolved, isNoCache); String contentType = getContentType(resolved.getPath()); resp.setHeader("Content-Type", contentType); InputStream is = null; if (RequestUtil.isGzipEncoding(req) && !contentType.startsWith("image/")) { MutableInt contentLength = new MutableInt(); is = getCacheManager().getCache().getGzipCache().getInputStream(path, resolved.getURI(), contentLength); resp.setContentLength(contentLength.getValue()); resp.addHeader("Content-Encoding", "gzip"); } else { is = resolved.getInputStream(); resp.setContentLength(resolved.getURI().toURL().openConnection().getContentLength()); } writeResponse(is, req, resp); } } catch (BadRequestException e) { logException(req, Level.INFO, sourceMethod, e); resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (NotFoundException e) { logException(req, Level.INFO, sourceMethod, e); resp.setStatus(HttpServletResponse.SC_NOT_FOUND); } catch (Throwable t) { logException(req, Level.WARNING, sourceMethod, t); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } if (isTraceLogging) { log.exiting(AbstractAggregatorImpl.class.getName(), sourceMethod); } }  @Override void init(ServletConfig servletConfig); @Override void destroy(); @Override boolean reloadConfig(); @Override IDependencies getDependencies(); @Override String getName(); @Override IConfig getConfig(); @Override ICacheManager getCacheManager(); @Override InitParams getInitParams(); @Override HttpServlet asServlet(); @Override IHttpTransport getTransport(); @Override IResourceFactory getResourceFactory(Mutable<URI> uriRef); @Override IResource newResource(URI uri); @Override IResource runConverters(IResource resource); @Override IModuleBuilder getModuleBuilder(String mid, IResource res); @Override Iterable<IAggregatorExtension> getExtensions(String extensionPointId); @Override IModule newModule(String mid, URI uri); @Override ILayerCache newLayerCache(); @Override IModuleCache newModuleCache(); @Override IGzipCache newGzipCache(); @Override String substituteProps(String str); @Override String substituteProps(String str, SubstitutionTransformer transformer); String getPropValue(String propName); @Override abstract IOptions getOptions(); @Override abstract IExecutors getExecutors(); @Override IPlatformServices getPlatformServices(); void initialize(IConfig config); @Override String setForceError(String forceError); @Override Future<?> buildAsync(final Callable<?> builder, final HttpServletRequest req); @Override HttpServletRequest getCurrentRequest();  }
@Test public void testProcessResourceRequest_invalidAccess() throws Exception { final MutableObject<URI> newResource = new MutableObject<URI>(); @SuppressWarnings("serial") AbstractAggregatorImpl testAggregator = new TestAggregatorImpl() { @Override public IResource newResource(URI uri) { newResource.setValue(uri); return new NotFoundResource(uri); } }; Map<String, String> responseParams = new HashMap<String, String>(); HttpServletRequest req = TestUtils.createMockRequest(testAggregator); HttpServletResponse resp = TestUtils.createMockResponse(responseParams); EasyMock.replay(req, resp); URI uri = new URI("/folder/"); testAggregator.processResourceRequest(req, resp, uri, "sub/../../file.res"); Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, resp.getStatus()); testAggregator.processResourceRequest(req, resp, uri, "/file.res"); Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, resp.getStatus()); uri = new URI("/folder"); testAggregator.processResourceRequest(req, resp, uri, "/folder.js"); Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, resp.getStatus()); newResource.setValue(null); testAggregator.processResourceRequest(req, resp, uri, "./file.js"); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, resp.getStatus()); Assert.assertEquals(new URI("/folder/file.js"), newResource.getValue()); newResource.setValue(null); testAggregator.processResourceRequest(req, resp, uri, "file.js"); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, resp.getStatus()); Assert.assertEquals(new URI("/folder/file.js"), newResource.getValue()); uri = new URI("/"); newResource.setValue(null); testAggregator.processResourceRequest(req, resp, uri, "/file.js"); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, resp.getStatus()); Assert.assertEquals(new URI("/file.js"), newResource.getValue()); newResource.setValue(null); testAggregator.processResourceRequest(req, resp, uri, "./file.js"); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, resp.getStatus()); Assert.assertEquals(new URI("/file.js"), newResource.getValue()); testAggregator.processResourceRequest(req, resp, uri, "../file.js"); Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, resp.getStatus()); }