From a157c54b6efb216b8c7aff2cc4cdd962d1dcd0a6 Mon Sep 17 00:00:00 2001 From: Kenji Nagahashi Date: Wed, 16 Mar 2016 11:39:35 -0700 Subject: [PATCH] Use CompositeResource everywhere for handling revisit records - added getContentEncoding() method to Resource for reading Content-Encoding header from the original - made one-resource version of ReplayRenderer.renderResource() method the primary, rewrite all invocations, and deprecate all two-resource version. --- .../org/archive/wayback/ReplayRenderer.java | 1 + .../ArchivalUrlSAXRewriteReplayRenderer.java | 30 ++++---- .../org/archive/wayback/core/Resource.java | 20 +++++ .../wayback/replay/CompositeResource.java | 8 ++ .../wayback/replay/TextReplayRenderer.java | 75 +++++++++++++++---- .../replay/TransparentReplayRenderer.java | 24 +++--- .../wayback/replay/swf/SWFReplayRenderer.java | 26 ++++--- .../archive/wayback/webapp/AccessPoint.java | 35 +++++---- ...JSStringTransformerReplayRendererTest.java | 2 +- .../ArchivalUrlCSSReplayRendererTest.java | 2 +- ...chivalUrlSAXRewriteReplayRendererTest.java | 10 ++- .../replay/TransparentReplayRendererTest.java | 13 ++-- .../wayback/webapp/AccessPointTest.java | 32 +++++--- 13 files changed, 184 insertions(+), 94 deletions(-) diff --git a/wayback-core/src/main/java/org/archive/wayback/ReplayRenderer.java b/wayback-core/src/main/java/org/archive/wayback/ReplayRenderer.java index 3e3607aa7b..ead9906fcf 100644 --- a/wayback-core/src/main/java/org/archive/wayback/ReplayRenderer.java +++ b/wayback-core/src/main/java/org/archive/wayback/ReplayRenderer.java @@ -90,6 +90,7 @@ public void renderResource(HttpServletRequest httpRequest, * @throws IOException per usual * @throws WaybackException if Wayback data specific, anticipated exceptions * occur + * @deprecated 2016-03-08 Use one-Resource version above with CompositeResource. */ public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, diff --git a/wayback-core/src/main/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRenderer.java b/wayback-core/src/main/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRenderer.java index 8e1b679595..e3fe3be61a 100644 --- a/wayback-core/src/main/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRenderer.java +++ b/wayback-core/src/main/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRenderer.java @@ -36,6 +36,7 @@ import org.archive.wayback.core.WaybackRequest; import org.archive.wayback.exception.WaybackException; import org.archive.wayback.proxy.ProxyHttpsResultURIConverter; +import org.archive.wayback.replay.CompositeResource; import org.archive.wayback.replay.HttpHeaderOperation; import org.archive.wayback.replay.HttpHeaderProcessor; import org.archive.wayback.replay.JSPExecutor; @@ -89,16 +90,6 @@ public ArchivalUrlSAXRewriteReplayRenderer(HttpHeaderProcessor httpHeaderProcess this.httpHeaderProcessor = httpHeaderProcessor; } - // assume this is only called for appropriate doc types: html - public void renderResource(HttpServletRequest httpRequest, - HttpServletResponse httpResponse, WaybackRequest wbRequest, - CaptureSearchResult result, Resource resource, - ResultURIConverter uriConverter, CaptureSearchResults results) - throws ServletException, IOException, WaybackException { - renderResource(httpRequest, httpResponse, wbRequest, result, resource, - resource, uriConverter, results); - } - @Override public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, @@ -106,8 +97,19 @@ public void renderResource(HttpServletRequest httpRequest, Resource payloadResource, ResultURIConverter uriConverter, CaptureSearchResults results) throws ServletException, IOException, WaybackException { + final Resource resource = httpHeadersResource == payloadResource ? payloadResource + : new CompositeResource(httpHeadersResource, payloadResource); + renderResource(httpRequest, httpResponse, wbRequest, result, resource, + uriConverter, results); + } - Resource decodedResource = TextReplayRenderer.decodeResource(httpHeadersResource, payloadResource); + public void renderResource(HttpServletRequest httpRequest, + HttpServletResponse httpResponse, WaybackRequest wbRequest, + CaptureSearchResult result, Resource resource, + ResultURIConverter uriConverter, CaptureSearchResults results) + throws ServletException, IOException, WaybackException { + // TODO: wrong + Resource decodedResource = TextReplayRenderer.decodeResource(resource); // The URL of the page, for resolving in-page relative URLs: // URL url = null; @@ -119,7 +121,7 @@ public void renderResource(HttpServletRequest httpRequest, // throw new IOException(e1.getMessage()); // } // determine the character set used to encode the document bytes: - String charSet = charsetDetector.getCharset(httpHeadersResource, decodedResource, wbRequest); + String charSet = charsetDetector.getCharset(resource, decodedResource, wbRequest); // set up the context: final ReplayParseContext context = ReplayParseContext.create( @@ -165,11 +167,11 @@ public void renderResource(HttpServletRequest httpRequest, // copy the HTTP response code: - HttpHeaderOperation.copyHTTPMessageHeader(httpHeadersResource, httpResponse); + HttpHeaderOperation.copyHTTPMessageHeader(resource, httpResponse); // transform the original headers according to our headerProcessor: Map headers = HttpHeaderOperation.processHeaders( - httpHeadersResource, context, httpHeaderProcessor); + resource, context, httpHeaderProcessor); // prepare several objects for the parse: diff --git a/wayback-core/src/main/java/org/archive/wayback/core/Resource.java b/wayback-core/src/main/java/org/archive/wayback/core/Resource.java index 2f4749861e..c3302e2cf7 100644 --- a/wayback-core/src/main/java/org/archive/wayback/core/Resource.java +++ b/wayback-core/src/main/java/org/archive/wayback/core/Resource.java @@ -47,6 +47,12 @@ * @author Brad Tofel */ public abstract class Resource extends InputStream { + + /** + * Upper-case header field name for {@code Content-Encoding}. + * For use with {@link #getHeader(String)} + */ + public static final String HTTP_CONTENT_ENCODING = "CONTENT-ENCODING"; private InputStream is; @@ -115,6 +121,20 @@ public String getHeader(String headerName) { return null; } + /** + * Return content-encoding of the payload. + *

+ * Currently meaningful for HTTP response resource only, + * and returns the value of HTTP {@code Content-Encoding}. + * Composite resource would override this method to return + * a value from appropriate member Resource. + *

+ * @return content-encoding header field value + */ + public String getContentEncoding() { + return getHeader(HTTP_CONTENT_ENCODING); + } + private void validate() throws IOException { if(is == null) { throw new IOException("No InputStream"); diff --git a/wayback-core/src/main/java/org/archive/wayback/replay/CompositeResource.java b/wayback-core/src/main/java/org/archive/wayback/replay/CompositeResource.java index 16d8681ae2..cf2418a8b5 100644 --- a/wayback-core/src/main/java/org/archive/wayback/replay/CompositeResource.java +++ b/wayback-core/src/main/java/org/archive/wayback/replay/CompositeResource.java @@ -83,6 +83,14 @@ public String getHeader(String headerName) { else return headersResource.getHeader(headerName); } + /** + * Returns {@code Content-Encoding} header field value + * from the original record. + */ + @Override + public String getContentEncoding() { + return payloadResource.getHeader(HTTP_CONTENT_ENCODING); + } @Override public void setChunkedEncoding() throws IOException { payloadResource.setChunkedEncoding(); diff --git a/wayback-core/src/main/java/org/archive/wayback/replay/TextReplayRenderer.java b/wayback-core/src/main/java/org/archive/wayback/replay/TextReplayRenderer.java index ebedb2468c..32dd46d2d3 100644 --- a/wayback-core/src/main/java/org/archive/wayback/replay/TextReplayRenderer.java +++ b/wayback-core/src/main/java/org/archive/wayback/replay/TextReplayRenderer.java @@ -95,15 +95,6 @@ protected abstract void updatePage(TextDocument page, ResultURIConverter uriConverter, CaptureSearchResults results) throws ServletException, IOException; - @Override - public void renderResource(HttpServletRequest httpRequest, - HttpServletResponse httpResponse, WaybackRequest wbRequest, - CaptureSearchResult result, Resource resource, - ResultURIConverter uriConverter, CaptureSearchResults results) - throws ServletException, IOException, BadContentException { - renderResource(httpRequest, httpResponse, wbRequest, result, resource, resource, uriConverter, results); - } - @Override public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, @@ -111,19 +102,30 @@ public void renderResource(HttpServletRequest httpRequest, Resource payloadResource, ResultURIConverter uriConverter, CaptureSearchResults results) throws ServletException, IOException, BadContentException { + final Resource resource = httpHeadersResource == payloadResource ? payloadResource + : new CompositeResource(httpHeadersResource, payloadResource); + renderResource(httpRequest, httpResponse, wbRequest, result, resource, + uriConverter, results); + } + @Override + public void renderResource(HttpServletRequest httpRequest, + HttpServletResponse httpResponse, WaybackRequest wbRequest, + CaptureSearchResult result, Resource resource, + ResultURIConverter uriConverter, CaptureSearchResults results) + throws ServletException, IOException, BadContentException { // Decode resource (such as if gzip encoded) - Resource decodedResource = decodeResource(httpHeadersResource, payloadResource); + Resource decodedResource = decodeResource(resource); ReplayParseContext context = ReplayParseContext.create(uriConverter, wbRequest, null, result, false); - HttpHeaderOperation.copyHTTPMessageHeader(httpHeadersResource, httpResponse); + HttpHeaderOperation.copyHTTPMessageHeader(resource, httpResponse); Map headers = HttpHeaderOperation.processHeaders( - httpHeadersResource, context, httpHeaderProcessor); + resource, context, httpHeaderProcessor); - String charSet = charsetDetector.getCharset(httpHeadersResource, - decodedResource, wbRequest); + String charSet = charsetDetector.getCharset(resource, decodedResource, + wbRequest); ResultURIConverter pageConverter = uriConverter; // this feature was meant for using special ResultURIConverter for rewriting XML, but @@ -213,8 +215,48 @@ public void setGuessedCharsetHeader(String guessedCharsetHeader) { this.guessedCharsetHeader = guessedCharsetHeader; } + /** + * return gzip-decoding wrapper Resource if Resource has {@code Content-Encoding: gzip}. + * return {@code resource} as-is otherwise. + *

if resource's content is gzip-compressed (i.e. {@code Content-Encoding} is "{@code gzip}"), + * return a wrapping Resource that returns decoded content.

+ *

As a side-effect, {@code Content-Encoding} and + * {@code Transfer-Encoding} headers are removed from {@code resource} (this happens only when + * {@code resource} is gzip-compressed.).

+ *

TODO: XArchiveHttpHeaderProcessor also does HTTP header removal. Check for refactoring case.

+ * @param resource Resource to read HTTP headers from. + * @return either wrapping decoder Resource or {@code resource} + * @throws IOException + */ public static Resource decodeResource(Resource resource) throws IOException { - return decodeResource(resource, resource); + // Content-Encoding may differ between headersResource and + // payloadResource. We use Content-Encoding of payloadResource, + // as we're reading content from it. Then update headersResource, + // as we're rendering headers from headersResource. + String encoding = resource.getContentEncoding(); + if (encoding != null) { + if (encoding.toLowerCase().equals(GzipDecodingResource.GZIP)) { + // if headersResource (revisit) has Content-Encoding, set it aside. + Map revHeaders = resource.getHttpHeaders(); + String revEncoding = HttpHeaderOperation.getHeaderValue( + revHeaders, HttpHeaderOperation.HTTP_CONTENT_ENCODING); + if (revEncoding != null) { + revHeaders.put(ORIG_ENCODING, encoding); + HttpHeaderOperation.removeHeader(revHeaders, + HttpHeaderOperation.HTTP_CONTENT_ENCODING); + } + + if (HttpHeaderOperation.isChunkEncoded(revHeaders)) { + HttpHeaderOperation.removeHeader(revHeaders, + HttpHeaderOperation.HTTP_TRANSFER_ENC_HEADER); + } + + return new GzipDecodingResource(resource); + } + + // TODO: check for other encodings? + } + return resource; } /** @@ -242,12 +284,15 @@ public void setOverrideContentMimeType(String overrideContentMimeType) { * {@code Transfer-Encoding} headers are removed from {@code headersResource} (this happens only when * {@code headerResoruce} is gzip-compressed.). It is assumed that {@code headerResource} and * {@code payloadResource} are captures of identical response content.

+ *

WARNING: this method does not work as intended with CompositeResource, whose + * {@code getHttpHeaders()} method returns HTTP headers from revisit record.

*

TODO: XArchiveHttpHeaderProcessor also does HTTP header removal. Check for refactoring case.

* @param headersResource Resource to read HTTP headers from. * @param payloadResource Resource to read content from (same as {@code headerResource} for regular captures, * different Resource if headersResource is a revisit record.) * @return * @throws IOException + * @deprecated 2016-03-08 use single-Resource version with CompositeResource */ public static Resource decodeResource(Resource headersResource, Resource payloadResource) throws IOException { diff --git a/wayback-core/src/main/java/org/archive/wayback/replay/TransparentReplayRenderer.java b/wayback-core/src/main/java/org/archive/wayback/replay/TransparentReplayRenderer.java index 4e114c609f..a5b851ac33 100644 --- a/wayback-core/src/main/java/org/archive/wayback/replay/TransparentReplayRenderer.java +++ b/wayback-core/src/main/java/org/archive/wayback/replay/TransparentReplayRenderer.java @@ -62,27 +62,29 @@ public TransparentReplayRenderer(HttpHeaderProcessor httpHeaderProcessor) { @Override public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, - CaptureSearchResult result, Resource resource, - ResultURIConverter uriConverter, CaptureSearchResults results) - throws ServletException, IOException, BadContentException { + CaptureSearchResult result, Resource httpHeadersResource, + Resource payloadResource, ResultURIConverter uriConverter, + CaptureSearchResults results) throws ServletException, IOException, + BadContentException { + final Resource resource = httpHeadersResource == payloadResource ? payloadResource + : new CompositeResource(httpHeadersResource, payloadResource); renderResource(httpRequest, httpResponse, wbRequest, result, resource, - resource, uriConverter, results); + uriConverter, results); } @Override public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, - CaptureSearchResult result, Resource httpHeadersResource, - Resource payloadResource, ResultURIConverter uriConverter, - CaptureSearchResults results) throws ServletException, IOException, - BadContentException { + CaptureSearchResult result, Resource resource, + ResultURIConverter uriConverter, CaptureSearchResults results) + throws ServletException, IOException, BadContentException { - HttpHeaderOperation.copyHTTPMessageHeader(httpHeadersResource, httpResponse); + HttpHeaderOperation.copyHTTPMessageHeader(resource, httpResponse); ReplayParseContext context = ReplayParseContext.create(uriConverter, wbRequest, null, result, false); Map headers = HttpHeaderOperation.processHeaders( - httpHeadersResource, context, httpHeaderProcessor); + resource, context, httpHeaderProcessor); // HACKHACK: getContentLength() may not find the original content length // if a HttpHeaderProcessor has mangled it too badly. Should this @@ -111,7 +113,7 @@ public void renderResource(HttpServletRequest httpRequest, OutputStream os = httpResponse.getOutputStream(); byte[] buffer = new byte[BUFFER_SIZE]; long total = 0; - for (int r = -1; (r = payloadResource.read(buffer, 0, BUFFER_SIZE)) != -1;) { + for (int r = -1; (r = resource.read(buffer, 0, BUFFER_SIZE)) != -1;) { os.write(buffer, 0, r); total += r; } diff --git a/wayback-core/src/main/java/org/archive/wayback/replay/swf/SWFReplayRenderer.java b/wayback-core/src/main/java/org/archive/wayback/replay/swf/SWFReplayRenderer.java index 5d0b35b47a..9f8f5118c4 100644 --- a/wayback-core/src/main/java/org/archive/wayback/replay/swf/SWFReplayRenderer.java +++ b/wayback-core/src/main/java/org/archive/wayback/replay/swf/SWFReplayRenderer.java @@ -44,6 +44,7 @@ import org.archive.wayback.exception.BadContentException; import org.archive.wayback.exception.BetterRequestException; import org.archive.wayback.exception.WaybackException; +import org.archive.wayback.replay.CompositeResource; import org.archive.wayback.replay.HttpHeaderOperation; import org.archive.wayback.replay.HttpHeaderProcessor; import org.archive.wayback.replay.html.ReplayParseContext; @@ -78,15 +79,6 @@ public SWFReplayRenderer(HttpHeaderProcessor httpHeaderProcessor) { this.httpHeaderProcessor = httpHeaderProcessor; } - public void renderResource(HttpServletRequest httpRequest, - HttpServletResponse httpResponse, WaybackRequest wbRequest, - CaptureSearchResult result, Resource resource, - ResultURIConverter uriConverter, CaptureSearchResults results) - throws ServletException, IOException, WaybackException { - renderResource(httpRequest, httpResponse, wbRequest, result, resource, - resource, uriConverter, results); - } - @Override public void renderResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, WaybackRequest wbRequest, @@ -94,17 +86,27 @@ public void renderResource(HttpServletRequest httpRequest, Resource payloadResource, ResultURIConverter uriConverter, CaptureSearchResults results) throws ServletException, IOException, WaybackException { + final Resource resource = httpHeadersResource == payloadResource ? payloadResource + : new CompositeResource(httpHeadersResource, payloadResource); + renderResource(httpRequest, httpResponse, wbRequest, result, resource, + uriConverter, results); + } + public void renderResource(HttpServletRequest httpRequest, + HttpServletResponse httpResponse, WaybackRequest wbRequest, + CaptureSearchResult result, Resource resource, + ResultURIConverter uriConverter, CaptureSearchResults results) + throws ServletException, IOException, WaybackException { try { // copy HTTP response code: - HttpHeaderOperation.copyHTTPMessageHeader(httpHeadersResource, httpResponse); + HttpHeaderOperation.copyHTTPMessageHeader(resource, httpResponse); ReplayParseContext context = ReplayParseContext.create(uriConverter, wbRequest, null, result, false); // load and process original headers: Map headers = HttpHeaderOperation.processHeaders( - httpHeadersResource, context, httpHeaderProcessor); + resource, context, httpHeaderProcessor); // The URL of the resource, for resolving embedded relative URLs: URL url = null; @@ -122,7 +124,7 @@ public void renderResource(HttpServletRequest httpRequest, Movie movie = getRobustMovie(RobustMovieDecoder.DECODE_RULE_NULLS); try { - movie.decodeFromStream(payloadResource); + movie.decodeFromStream(resource); } catch (DataFormatException e1) { throw new BadContentException(e1.getLocalizedMessage()); } diff --git a/wayback-core/src/main/java/org/archive/wayback/webapp/AccessPoint.java b/wayback-core/src/main/java/org/archive/wayback/webapp/AccessPoint.java index 9e8d6e6d23..d385675844 100644 --- a/wayback-core/src/main/java/org/archive/wayback/webapp/AccessPoint.java +++ b/wayback-core/src/main/java/org/archive/wayback/webapp/AccessPoint.java @@ -76,6 +76,7 @@ import org.archive.wayback.memento.DefaultMementoHandler; import org.archive.wayback.memento.MementoHandler; import org.archive.wayback.memento.MementoUtils; +import org.archive.wayback.replay.CompositeResource; import org.archive.wayback.replay.DefaultReplayCaptureSelector; import org.archive.wayback.replay.ReplayCaptureSelector; import org.archive.wayback.replay.html.RewriteDirector; @@ -815,8 +816,7 @@ protected void handleReplay(WaybackRequest wbRequest, // throw new BetterRequestException(fullRedirect, Integer.valueOf(closest.getHttpCode())); //} - Resource httpHeadersResource = null; - Resource payloadResource = null; + Resource resource = null; boolean isRevisit = false; try { @@ -872,17 +872,15 @@ protected void handleReplay(WaybackRequest wbRequest, closest.setOffset(closest.getDuplicatePayloadOffset()); // See that this is successful - httpHeadersResource = resourceStore.retrieveResource(closest); + resource = resourceStore.retrieveResource(closest); // Hmm, since this is a revisit it should not redirect -- was: if both headers and payload are from a different timestamp, redirect to that timestamp // if (!closest.getCaptureTimestamp().equals(closest.getDuplicateDigestStoredTimestamp())) { // throwRedirect(wbRequest, httpResponse, captureResults, closest.getDuplicateDigestStoredTimestamp(), closest.getOriginalUrl(), closest.getHttpCode()); // } - payloadResource = httpHeadersResource; - } else { - httpHeadersResource = resourceStore.retrieveResource(closest); + Resource httpHeadersResource = resourceStore.retrieveResource(closest); CaptureSearchResult payloadLocation = retrievePayloadForIdenticalContentRevisit(wbRequest, httpHeadersResource, closest); @@ -890,24 +888,19 @@ protected void handleReplay(WaybackRequest wbRequest, throw new ResourceNotAvailableException("Revisit: Missing original for revisit record " + closest.toString(), 404); } - payloadResource = resourceStore.retrieveResource(payloadLocation); + Resource payloadResource = resourceStore.retrieveResource(payloadLocation); - // If zero length old-style revisit with no headers, then must use payloadResource as headersResource - if (httpHeadersResource.getRecordLength() <= 0) { - httpHeadersResource.close(); - httpHeadersResource = payloadResource; - } + resource = new CompositeResource(httpHeadersResource, payloadResource); } } else { - httpHeadersResource = resourceStore.retrieveResource(closest); - payloadResource = httpHeadersResource; + resource = resourceStore.retrieveResource(closest); } // Ensure that we are not self-redirecting! // If the status is a redirect, check that the location or url date's are different from the current request // Otherwise, replay the previous matched capture. // This chain is unlikely to go past one previous capture, but is possible - if (isSelfRedirect(httpHeadersResource, closest, wbRequest, requestURL)) { + if (isSelfRedirect(resource, closest, wbRequest, requestURL)) { LOGGER.info("Self-Redirect: Skipping " + closest.getCaptureTimestamp() + "/" + closest.getOriginalUrl()); //closest = findNextClosest(closest, captureResults, requestMS); closest = captureSelector.next(); @@ -921,7 +914,7 @@ protected void handleReplay(WaybackRequest wbRequest, p.retrieved(); ReplayRenderer renderer = - getReplay().getRenderer(wbRequest, closest, httpHeadersResource, payloadResource); + getReplay().getRenderer(wbRequest, closest, resource); if (this.isEnableWarcFileHeader() && (warcFileHeader != null)) { if (isRevisit && (closest.getDuplicatePayloadFile() != null)) { @@ -959,7 +952,7 @@ protected void handleReplay(WaybackRequest wbRequest, } renderer.renderResource(httpRequest, httpResponse, wbRequest, - closest, httpHeadersResource, payloadResource, uriConverter, captureResults); + closest, resource, uriConverter, captureResults); p.rendered(); p.write(wbRequest.getReplayTimestamp() + " " + @@ -1027,7 +1020,13 @@ protected void handleReplay(WaybackRequest wbRequest, throw scre; } } finally { - closeResources(payloadResource, httpHeadersResource); + if (resource != null) { + try { + resource.close(); + } catch (IOException e) { + LOGGER.warning(e.toString()); + } + } } } } diff --git a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalURLJSStringTransformerReplayRendererTest.java b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalURLJSStringTransformerReplayRendererTest.java index 8200f996e0..80722f3d25 100644 --- a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalURLJSStringTransformerReplayRendererTest.java +++ b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalURLJSStringTransformerReplayRendererTest.java @@ -157,7 +157,7 @@ public void testProxyHttpsTranslation() throws Exception { EasyMock.replay(response); - renderer.renderResource(request, response, wbRequest, result, payloadResource, payloadResource, proxyURIConverter, null); + renderer.renderResource(request, response, wbRequest, result, payloadResource, proxyURIConverter, null); String out = servletOutput.getString(); assertEquals("servlet output", expected, out); diff --git a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlCSSReplayRendererTest.java b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlCSSReplayRendererTest.java index de3cbcefe0..7114828ddd 100644 --- a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlCSSReplayRendererTest.java +++ b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlCSSReplayRendererTest.java @@ -125,7 +125,7 @@ public void testBasicBehavior() throws Exception { EasyMock.replay(response, uriConverter); - cut.renderResource(null, response, wbRequest, result, payloadResource, payloadResource, uriConverter, null); + cut.renderResource(null, response, wbRequest, result, payloadResource, uriConverter, null); EasyMock.verify(response, uriConverter); diff --git a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRendererTest.java b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRendererTest.java index 36aae18263..f7719b1c19 100644 --- a/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRendererTest.java +++ b/wayback-core/src/test/java/org/archive/wayback/archivalurl/ArchivalUrlSAXRewriteReplayRendererTest.java @@ -17,6 +17,7 @@ import org.archive.wayback.core.CaptureSearchResult; import org.archive.wayback.core.Resource; import org.archive.wayback.core.WaybackRequest; +import org.archive.wayback.replay.CompositeResource; import org.archive.wayback.replay.RedirectRewritingHttpHeaderProcessor; import org.archive.wayback.replay.TextReplayRenderer; import org.archive.wayback.replay.TransparentReplayRendererTest.TestServletOutputStream; @@ -155,7 +156,7 @@ public void testBasicBehavior() throws Exception { EasyMock.replay(nodeHandler, response, uriConverter); - cut.renderResource(null, response, wbRequest, result, payloadResource, payloadResource, uriConverter, null); + cut.renderResource(null, response, wbRequest, result, payloadResource, uriConverter, null); EasyMock.verify(nodeHandler, response, uriConverter); @@ -198,7 +199,8 @@ public void testRevisit() throws Exception { EasyMock.replay(nodeHandler, response, uriConverter); - cut.renderResource(null, response, wbRequest, result, headerResource, payloadResource, uriConverter, null); + Resource compResource = new CompositeResource(headerResource, payloadResource); + cut.renderResource(null, response, wbRequest, result, compResource, uriConverter, null); EasyMock.verify(nodeHandler, response, uriConverter); @@ -280,7 +282,7 @@ public void testDoneFlagSetForFrameset() throws Exception { EasyMock.replay(nodeHandler, response, uriConverter); - cut.renderResource(null, response, wbRequest, result, payloadResource, payloadResource, uriConverter, null); + cut.renderResource(null, response, wbRequest, result, payloadResource, uriConverter, null); EasyMock.verify(nodeHandler, response, uriConverter); @@ -319,7 +321,7 @@ public void testDoneFlagNotSetForFrameWrapperContext() throws Exception { // !!! KEY SETTING OF THIS TEST !!! wbRequest.setFrameWrapperContext(true); - cut.renderResource(null, response, wbRequest, result, payloadResource, payloadResource, uriConverter, null); + cut.renderResource(null, response, wbRequest, result, payloadResource, uriConverter, null); EasyMock.verify(nodeHandler, response, uriConverter); diff --git a/wayback-core/src/test/java/org/archive/wayback/replay/TransparentReplayRendererTest.java b/wayback-core/src/test/java/org/archive/wayback/replay/TransparentReplayRendererTest.java index 8bec350d1c..65b0b0cbb4 100644 --- a/wayback-core/src/test/java/org/archive/wayback/replay/TransparentReplayRendererTest.java +++ b/wayback-core/src/test/java/org/archive/wayback/replay/TransparentReplayRendererTest.java @@ -96,7 +96,6 @@ public void testRenderResource_BasicCapture() throws Exception { WARCRecord rec = ar.get(0); Resource payloadResource = new WarcResource(rec, ar); payloadResource.parseHeaders(); - Resource headersResource = payloadResource; TestServletOutputStream servletOutput = new TestServletOutputStream(); response.setStatus(200); @@ -110,7 +109,7 @@ public void testRenderResource_BasicCapture() throws Exception { EasyMock.replay(response); cut.renderResource(request, response, wbRequest, result, - headersResource, payloadResource, uriConverter, results); + payloadResource, uriConverter, results); EasyMock.verify(response); byte[] content = servletOutput.getBytes(); @@ -135,7 +134,6 @@ public void testRenderResource_CompressedCapture() throws Exception { WARCRecord rec = ar.get(0); Resource payloadResource = new WarcResource(rec, ar); payloadResource.parseHeaders(); - Resource headersResource = payloadResource; TestServletOutputStream servletOutput = new TestServletOutputStream(); response.setStatus(200); @@ -150,7 +148,7 @@ public void testRenderResource_CompressedCapture() throws Exception { EasyMock.replay(response); cut.renderResource(request, response, wbRequest, result, - headersResource, payloadResource, uriConverter, results); + payloadResource, uriConverter, results); EasyMock.verify(response); @@ -193,7 +191,7 @@ public void testRenderResource_Redirect() throws Exception { EasyMock.replay(response, uriConverter); cut.renderResource(request, response, wbRequest, result, - payloadResource, payloadResource, uriConverter, results); + payloadResource, uriConverter, results); EasyMock.verify(response, uriConverter); @@ -229,7 +227,6 @@ public void testRenderResource_Chunked() throws Exception { WARCRecord rec = ar.get(0); Resource payloadResource = new WarcResource(rec, ar); payloadResource.parseHeaders(); - Resource headersResource = payloadResource; TestServletOutputStream servletOutput = new TestServletOutputStream(); // expectations @@ -246,8 +243,8 @@ public void testRenderResource_Chunked() throws Exception { // creating separate test object to use IdentityHttpHeaderProcessor TransparentReplayRenderer cut2 = new TransparentReplayRenderer(new IdentityHttpHeaderProcessor()); - cut2.renderResource(request, response, wbRequest, result, - headersResource, payloadResource, uriConverter, results); + cut2.renderResource(request, response, wbRequest, result, + payloadResource, uriConverter, results); EasyMock.verify(response); diff --git a/wayback-core/src/test/java/org/archive/wayback/webapp/AccessPointTest.java b/wayback-core/src/test/java/org/archive/wayback/webapp/AccessPointTest.java index 91b61b4961..226ef60671 100644 --- a/wayback-core/src/test/java/org/archive/wayback/webapp/AccessPointTest.java +++ b/wayback-core/src/test/java/org/archive/wayback/webapp/AccessPointTest.java @@ -43,6 +43,7 @@ import org.archive.wayback.exception.WaybackException; import org.archive.wayback.memento.MementoHandler; import org.archive.wayback.memento.MementoUtils; +import org.archive.wayback.replay.CompositeResource; import org.archive.wayback.resourcestore.resourcefile.ArcResource; import org.archive.wayback.resourcestore.resourcefile.WarcResource; import org.archive.wayback.util.url.KeyMakerUrlCanonicalizer; @@ -521,11 +522,23 @@ protected void expectRendering(CaptureSearchResult capture, Resource headersResource, Resource payloadResource, CaptureSearchResults results) throws ServletException, IOException, WaybackException { - EasyMock.expect( - replay.getRenderer(wbRequest, capture, headersResource, - payloadResource)).andReturn(replayRenderer); - replayRenderer.renderResource(httpRequest, httpResponse, wbRequest, - capture, headersResource, cut.getUriConverter(), results); + if (headersResource == payloadResource) { + EasyMock.expect( + replay.getRenderer(wbRequest, capture, headersResource)) + .andReturn(replayRenderer); + replayRenderer.renderResource(httpRequest, httpResponse, wbRequest, + capture, headersResource, cut.getUriConverter(), results); + } else { + EasyMock.expect( + replay.getRenderer(EasyMock.same(wbRequest), + EasyMock.same(capture), + EasyMock.isA(CompositeResource.class))).andReturn( + replayRenderer); + replayRenderer.renderResource(EasyMock.same(httpRequest), + EasyMock.same(httpResponse), EasyMock.same(wbRequest), + EasyMock.same(capture), EasyMock.isA(CompositeResource.class), + EasyMock.same(cut.getUriConverter()), EasyMock.same(results)); + } } /** @@ -1392,12 +1405,11 @@ public ReplayURIConverter decorateURIConverter( CaptureSearchResults results = setupCaptures(0, payloadResource); CaptureSearchResult closest = results.getClosest(); - //expectRendering(closest, payloadResource, payloadResource, results); - EasyMock.expect( - replay.getRenderer(wbRequest, closest, payloadResource, - payloadResource)).andReturn(replayRenderer); + EasyMock + .expect(replay.getRenderer(wbRequest, closest, payloadResource)) + .andReturn(replayRenderer); replayRenderer.renderResource(httpRequest, httpResponse, wbRequest, - closest, payloadResource, payloadResource, decorated, results); + closest, payloadResource, decorated, results); EasyMock.replay(httpRequest, httpResponse, resourceIndex, resourceStore, replay, replayRenderer, decorated);