@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException { Resource transformed = this.cache.get(resource, Resource.class); if (transformed != null) { if (logger.isTraceEnabled()) { logger.trace("Resource resolved from cache"); } return transformed; } transformed = transformerChain.transform(request, resource); this.cache.put(resource, transformed); return transformed; }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException { Resource transformed = transformerChain.transform(request, resource); return minifyService.minify(transformed); }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException { if (resourceTransformerCachingEnabled) { return super.transform(request, resource, transformerChain); } else { return transformerChain.transform(request, resource); } }
@Nullable protected Resource getResource(HttpServletRequest request) throws IOException { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); if (path == null) { throw new IllegalStateException("Required request attribute '" + HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set"); } path = processPath(path); if (!StringUtils.hasText(path) || isInvalidPath(path)) { return null; } if (isInvalidEncodedPath(path)) { return null; } Assert.notNull(this.resolverChain, "ResourceResolverChain not initialized."); Assert.notNull(this.transformerChain, "ResourceTransformerChain not initialized."); Resource resource = this.resolverChain.resolveResource(request, path, getLocations()); if (resource != null) { resource = this.transformerChain.transform(request, resource); } return resource; }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException { Resource transformed = this.cache.get(resource, Resource.class); if (transformed != null) { if (logger.isTraceEnabled()) { logger.trace("Resource resolved from cache"); } return transformed; } transformed = transformerChain.transform(request, resource); this.cache.put(resource, transformed); return transformed; }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain chain) throws IOException { resource = chain.transform(request, resource); if (!this.fileExtension.equals(StringUtils.getFilenameExtension(resource.getFilename()))) { return resource; } byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); String content = new String(bytes, DEFAULT_CHARSET); if (!content.startsWith(MANIFEST_HEADER)) { if (logger.isTraceEnabled()) { logger.trace("Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'"); } return resource; } @SuppressWarnings("resource") Scanner scanner = new Scanner(content); LineInfo previous = null; LineAggregator aggregator = new LineAggregator(resource, content); while (scanner.hasNext()) { String line = scanner.nextLine(); LineInfo current = new LineInfo(line, previous); LineOutput lineOutput = processLine(current, request, resource, chain); aggregator.add(lineOutput); previous = current; } return aggregator.createResource(); }
throws IOException { resource = transformerChain.transform(request, resource);
@Nullable protected Resource getResource(HttpServletRequest request) throws IOException { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); if (path == null) { throw new IllegalStateException("Required request attribute '" + HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set"); } path = processPath(path); if (!StringUtils.hasText(path) || isInvalidPath(path)) { return null; } if (isInvalidEncodedPath(path)) { return null; } Assert.notNull(this.resolverChain, "ResourceResolverChain not initialized."); Assert.notNull(this.transformerChain, "ResourceTransformerChain not initialized."); Resource resource = this.resolverChain.resolveResource(request, path, getLocations()); if (resource != null) { resource = this.transformerChain.transform(request, resource); } return resource; }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain chain) throws IOException { resource = chain.transform(request, resource); if (!this.fileExtension.equals(StringUtils.getFilenameExtension(resource.getFilename()))) { return resource; } byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); String content = new String(bytes, DEFAULT_CHARSET); if (!content.startsWith(MANIFEST_HEADER)) { if (logger.isTraceEnabled()) { logger.trace("Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'"); } return resource; } @SuppressWarnings("resource") Scanner scanner = new Scanner(content); LineInfo previous = null; LineAggregator aggregator = new LineAggregator(resource, content); while (scanner.hasNext()) { String line = scanner.nextLine(); LineInfo current = new LineInfo(line, previous); LineOutput lineOutput = processLine(current, request, resource, chain); aggregator.add(lineOutput); previous = current; } return aggregator.createResource(); }
throws IOException { resource = transformerChain.transform(request, resource);
@Test public void transformSkippedForGzippedResource() throws Exception { EncodedResourceResolverTests.createGzippedFile("main.css"); this.request = new MockHttpServletRequest("GET", "/static/main.css"); Resource original = new ClassPathResource("test/main.css", getClass()); EncodedResource gzipped = new EncodedResource(original, "gzip", ".gz"); Resource actual = this.transformerChain.transform(this.request, gzipped); assertSame(gzipped, actual); }
@Test public void transformExtLinksNotAllowed() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/external.css"); List<ResourceTransformer> transformers = Collections.singletonList(new CssLinkResourceTransformer()); ResourceResolverChain mockChain = Mockito.mock(DefaultResourceResolverChain.class); ResourceTransformerChain chain = new DefaultResourceTransformerChain(mockChain, transformers); Resource resource = getResource("external.css"); String expected = "@import url(\"http://example.org/fonts/css\");\n" + "body { background: url(\"file:///home/spring/image.png\") }\n" + "figure { background: url(\"//example.org/style.css\")}"; TransformedResource transformedResource = (TransformedResource) chain.transform(this.request, resource); String result = new String(transformedResource.getByteArray(), StandardCharsets.UTF_8); result = StringUtils.deleteAny(result, "\r"); assertEquals(expected, result); List<Resource> locations = Collections.singletonList(resource); Mockito.verify(mockChain, Mockito.never()).resolveUrlPath("http://example.org/fonts/css", locations); Mockito.verify(mockChain, Mockito.never()).resolveUrlPath("file:///home/spring/image.png", locations); Mockito.verify(mockChain, Mockito.never()).resolveUrlPath("//example.org/style.css", locations); }
@Test public void transformSkippedForNonCssResource() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/images/image.png"); Resource expected = getResource("images/image.png"); Resource actual = this.transformerChain.transform(this.request, expected); assertSame(expected, actual); }
@Test public void transformNoLinks() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/foo.css"); Resource expected = getResource("foo.css"); Resource actual = this.transformerChain.transform(this.request, expected); assertSame(expected, actual); }
@Test public void transform() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/main.css"); Resource css = getResource("main.css"); String expected = "\n" + "@import url(\"/static/bar-11e16cf79faee7ac698c805cf28248d2.css?#iefix\");\n" + "@import url('/static/bar-11e16cf79faee7ac698c805cf28248d2.css#bla-normal');\n" + "@import url(/static/bar-11e16cf79faee7ac698c805cf28248d2.css);\n\n" + "@import \"/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css\";\n" + "@import '/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css';\n\n" + "body { background: url(\"/static/images/image-f448cd1d5dba82b774f3202c878230b3.png?#iefix\") }\n"; TransformedResource actual = (TransformedResource) this.transformerChain.transform(this.request, css); String result = new String(actual.getByteArray(), StandardCharsets.UTF_8); result = StringUtils.deleteAny(result, "\r"); assertEquals(expected, result); }
@Override public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException { Resource transformed = this.cache.get(resource, Resource.class); if (transformed != null) { if (logger.isTraceEnabled()) { logger.trace("Found match: " + transformed); } return transformed; } transformed = transformerChain.transform(request, resource); if (logger.isTraceEnabled()) { logger.trace("Putting transformed resource in cache: " + transformed); } this.cache.put(resource, transformed); return transformed; }
protected Resource getResource(HttpServletRequest request) throws IOException { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); if (path == null) { throw new IllegalStateException("Required request attribute '" + HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set"); } path = processPath(path); if (!StringUtils.hasText(path) || isInvalidPath(path)) { if (logger.isTraceEnabled()) { logger.trace("Ignoring invalid resource path [" + path + "]"); } return null; } if (isInvalidEncodedPath(path)) { if (logger.isTraceEnabled()) { logger.trace("Ignoring invalid resource path with escape sequences [" + path + "]"); } return null; } ResourceResolverChain resolveChain = new DefaultResourceResolverChain(getResourceResolvers()); Resource resource = resolveChain.resolveResource(request, path, getLocations()); if (resource == null || getResourceTransformers().isEmpty()) { return resource; } ResourceTransformerChain transformChain = new DefaultResourceTransformerChain(resolveChain, getResourceTransformers()); resource = transformChain.transform(request, resource); return resource; }