@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(); }
private LineOutput processLine(LineInfo info, HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) { if (!info.isLink()) { return new LineOutput(info.getLine(), null); } Resource appCacheResource = transformerChain.getResolverChain() .resolveResource(null, info.getLine(), Collections.singletonList(resource)); String path = info.getLine(); String absolutePath = toAbsolutePath(path, request); String newPath = resolveUrlPath(absolutePath, request, resource, transformerChain); return new LineOutput((newPath != null ? newPath : path), appCacheResource); }
@Before public void setup() { VersionResourceResolver versionResolver = new VersionResourceResolver(); versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy())); PathResourceResolver pathResolver = new PathResourceResolver(); pathResolver.setAllowedLocations(new ClassPathResource("test/", getClass())); List<ResourceResolver> resolvers = new ArrayList<>(); resolvers.add(versionResolver); resolvers.add(pathResolver); ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers); this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList()); this.transformer = new AppCacheManifestTransformer(); this.transformer.setResourceUrlProvider(createUrlProvider(resolvers)); }
@Test public void transformManifest() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/test.appcache"); Resource resource = getResource("test.appcache"); Resource actual = this.transformer.transform(this.request, resource, this.chain); byte[] bytes = FileCopyUtils.copyToByteArray(actual.getInputStream()); String content = new String(bytes, "UTF-8"); assertThat("should rewrite resource links", content, containsString("/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css")); assertThat("should rewrite resource links", content, containsString("/static/bar-11e16cf79faee7ac698c805cf28248d2.css")); assertThat("should rewrite resource links", content, containsString("/static/js/bar-bd508c62235b832d960298ca6c0b7645.js")); assertThat("should not rewrite external resources", content, containsString("//example.org/style.css")); assertThat("should not rewrite external resources", content, containsString("http://example.org/image.png")); assertThat("should generate fingerprint", content, containsString("# Hash: 4bf0338bcbeb0a5b3a4ec9ed8864107d")); }
@Test public void resourceChainWithVersionResolver() throws Exception { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); this.registration.resourceChain(true).addResolver(versionResolver) .addTransformer(new AppCacheManifestTransformer()); ResourceHttpRequestHandler handler = getHandler("/resources/**"); List<ResourceResolver> resolvers = handler.getResourceResolvers(); assertThat(resolvers.toString(), resolvers, Matchers.hasSize(4)); assertThat(resolvers.get(0), Matchers.instanceOf(CachingResourceResolver.class)); assertThat(resolvers.get(1), Matchers.sameInstance(versionResolver)); assertThat(resolvers.get(2), Matchers.instanceOf(WebJarsResourceResolver.class)); assertThat(resolvers.get(3), Matchers.instanceOf(PathResourceResolver.class)); List<ResourceTransformer> transformers = handler.getResourceTransformers(); assertThat(transformers, Matchers.hasSize(3)); assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class)); assertThat(transformers.get(1), Matchers.instanceOf(CssLinkResourceTransformer.class)); assertThat(transformers.get(2), Matchers.instanceOf(AppCacheManifestTransformer.class)); }
@Test public void syntaxErrorInManifest() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/error.appcache"); Resource resource = getResource("error.appcache"); Resource result = this.transformer.transform(this.request, resource, this.chain); assertEquals(resource, result); }
private LineOutput processLine(LineInfo info, HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) { if (!info.isLink()) { return new LineOutput(info.getLine(), null); } Resource appCacheResource = transformerChain.getResolverChain() .resolveResource(null, info.getLine(), Collections.singletonList(resource)); String path = info.getLine(); String absolutePath = toAbsolutePath(path, request); String newPath = resolveUrlPath(absolutePath, request, resource, transformerChain); return new LineOutput((newPath != null ? newPath : path), appCacheResource); }
@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(); }
@Test public void noTransformIfExtensionDoesNotMatch() throws Exception { this.request = new MockHttpServletRequest("GET", "/static/foo.css"); Resource resource = getResource("foo.css"); Resource result = this.transformer.transform(this.request, resource, this.chain); assertEquals(resource, result); }