From: <rb...@us...> - 2013-09-28 10:51:57
|
Revision: 8523 http://sourceforge.net/p/htmlunit/code/8523 Author: rbri Date: 2013-09-28 10:51:52 +0000 (Sat, 28 Sep 2013) Log Message: ----------- caching now works for encoded URLs also. Issue 1352 Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/Cache.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/CacheTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/changes/changes.xml 2013-09-28 10:51:52 UTC (rev 8523) @@ -8,6 +8,9 @@ <body> <release version="2.13" date="???" description="Bugfixes"> + <action type="fix" dev="rbri" issue="1352"> + Caching now works for encoded URLs also. + </action> <action type="update" dev="asashour"> Deprecate KeyDataPair. </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/Cache.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/Cache.java 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/Cache.java 2013-09-28 10:51:52 UTC (rev 8523) @@ -15,6 +15,7 @@ package com.gargoylesoftware.htmlunit; import java.io.Serializable; +import java.net.URL; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -89,15 +90,14 @@ * Caches the specified object, if the corresponding request and response objects indicate * that it is cacheable. * - * @param request the request corresponding to the specified compiled script + * @param url the cache key * @param response the response corresponding to the specified compiled script * @param toCache the object that is to be cached, if possible (may be for instance a compiled script or * simply a WebResponse) */ - public void cacheIfPossible(final WebRequest request, final WebResponse response, final Object toCache) { - if (isCacheable(request, response)) { - final String url = response.getWebRequest().getUrl().toString(); - final Entry entry = new Entry(url, toCache); + public void cacheIfPossible(final URL url, final WebResponse response, final Object toCache) { + if (isCacheable(response)) { + final Entry entry = new Entry(url.toString(), toCache); entries_.put(entry.key_, entry); deleteOverflow(); } @@ -135,11 +135,10 @@ /** * Determines if the specified response can be cached. * - * @param request the performed request * @param response the received response * @return <code>true</code> if the response can be cached */ - protected boolean isCacheable(final WebRequest request, final WebResponse response) { + protected boolean isCacheable(final WebResponse response) { return HttpMethod.GET == response.getWebRequest().getHttpMethod() && !isDynamicContent(response); } @@ -205,14 +204,11 @@ * Returns the cached object corresponding to the specified request. If there is * no corresponding cached object, this method returns <tt>null</tt>. * - * @param request the request whose corresponding cached compiled script is sought + * @param url the cache key * @return the cached object corresponding to the specified request if any */ - public Object getCachedObject(final WebRequest request) { - if (HttpMethod.GET != request.getHttpMethod()) { - return null; - } - final Entry cachedEntry = entries_.get(request.getUrl().toString()); + public Object getCachedObject(final URL url) { + final Entry cachedEntry = entries_.get(url.toString()); if (cachedEntry == null) { return null; } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java 2013-09-28 10:51:52 UTC (rev 8523) @@ -1275,8 +1275,11 @@ addDefaultHeaders(webRequest); // Retrieve the response, either from the cache or from the server. - final Object fromCache = getCache().getCachedObject(webRequest); final WebResponse webResponse; + Object fromCache = null; + if (HttpMethod.GET == webRequest.getHttpMethod()) { + fromCache = getCache().getCachedObject(url); + } if (fromCache != null && fromCache instanceof WebResponse) { webResponse = new WebResponseFromCache((WebResponse) fromCache, webRequest); } @@ -1287,7 +1290,7 @@ catch (final NoHttpResponseException e) { return new WebResponse(responseDataNoHttpResponse_, webRequest, 0); } - getCache().cacheIfPossible(webRequest, webResponse, webResponse); + getCache().cacheIfPossible(url, webResponse, webResponse); } // Continue according to the HTTP status code. Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2013-09-28 10:51:52 UTC (rev 8523) @@ -1089,7 +1089,7 @@ request.setAdditionalHeaders(new HashMap<String, String>(referringRequest.getAdditionalHeaders())); request.setAdditionalHeader("Referer", referringRequest.getUrl().toString()); - final Object cachedScript = cache.getCachedObject(request); + final Object cachedScript = cache.getCachedObject(url); if (cachedScript instanceof Script) { return (Script) cachedScript; } @@ -1142,7 +1142,7 @@ final JavaScriptEngine javaScriptEngine = client.getJavaScriptEngine(); final Script script = javaScriptEngine.compile(this, scriptCode, url.toExternalForm(), 1); if (script != null) { - cache.cacheIfPossible(request, response, script); + cache.cacheIfPossible(url, response, script); } return script; Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java 2013-09-28 10:51:52 UTC (rev 8523) @@ -72,6 +72,7 @@ import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.Cache; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; @@ -301,11 +302,14 @@ request.setAdditionalHeader("Referer", referer); } - uri = request.getUrl().toExternalForm(); + final URL reqUrl = request.getUrl(); + Object fromCache = null; final Cache cache = client.getCache(); - final Object fromCache = cache.getCachedObject(request); + if (HttpMethod.GET == request.getHttpMethod()) { + fromCache = cache.getCachedObject(reqUrl); + } if (fromCache != null && fromCache instanceof org.w3c.dom.css.CSSStyleSheet) { - sheet = new CSSStyleSheet(element, (org.w3c.dom.css.CSSStyleSheet) fromCache, uri); + sheet = new CSSStyleSheet(element, (org.w3c.dom.css.CSSStyleSheet) fromCache, reqUrl.toExternalForm()); } else { final WebResponse response = client.loadWebResponse(request); @@ -317,7 +321,7 @@ source.setByteStream(response.getContentAsStream()); source.setEncoding(response.getContentCharset()); sheet = new CSSStyleSheet(element, source, uri); - cache.cacheIfPossible(request, response, sheet.getWrappedSheet()); + cache.cacheIfPossible(reqUrl, response, sheet.getWrappedSheet()); } } catch (final FailingHttpStatusCodeException e) { Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/CacheTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/CacheTest.java 2013-09-27 21:15:35 UTC (rev 8522) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/CacheTest.java 2013-09-28 10:51:52 UTC (rev 8523) @@ -138,6 +138,63 @@ *@throws Exception if the test fails */ @Test + public void usageUrlEncoded() throws Exception { + final String content = "<html>\n" + + "<head>\n" + + " <title>page 1</title>\n" + + " <script src='foo1.js'></script>\n" + + " <script src='foo2.js?foo[1]=bar/baz'></script>\n" + + "</head>\n" + + "<body>\n" + + " <a href='page2.html'>to page 2</a>\n" + + "</body>\n" + + "</html>"; + + final String content2 = "<html>\n2" + + "<head>\n" + + " <title>page 2</title>\n" + + " <script src='foo2.js?foo[1]=bar/baz'></script>\n" + + "</head>\n" + + "<body>\n" + + " <a href='page1.html'>to page 1</a>\n" + + "</body>\n" + + "</html>"; + + final String script1 = "alert('in foo1');"; + final String script2 = "alert('in foo2');"; + + final URL urlPage1 = new URL(URL_FIRST, "page1.html"); + getMockWebConnection().setResponse(urlPage1, content); + final URL urlPage2 = new URL(URL_FIRST, "page2.html"); + getMockWebConnection().setResponse(urlPage2, content2); + + final List<NameValuePair> headers = new ArrayList<NameValuePair>(); + headers.add(new NameValuePair("Last-Modified", "Sun, 15 Jul 2007 20:46:27 GMT")); + getMockWebConnection().setResponse(new URL(URL_FIRST, "foo1.js"), script1, + 200, "ok", JAVASCRIPT_MIME_TYPE, headers); + getMockWebConnection().setDefaultResponse(script2, 200, "ok", JAVASCRIPT_MIME_TYPE, headers); + + final WebClient webClient = getWebClientWithMockWebConnection(); + + final List<String> collectedAlerts = new ArrayList<String>(); + webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); + + final HtmlPage page1 = webClient.getPage(urlPage1); + final String[] expectedAlerts = {"in foo1", "in foo2"}; + assertEquals(expectedAlerts, collectedAlerts); + + collectedAlerts.clear(); + page1.getAnchors().get(0).click(); + + assertEquals(new String[] {"in foo2"}, collectedAlerts); + assertEquals("no request for scripts should have been performed", + urlPage2, getMockWebConnection().getLastWebRequest().getUrl()); + } + + /** + *@throws Exception if the test fails + */ + @Test public void maxSizeMaintained() throws Exception { final String html = "<html><head><title>page 1</title>\n" + "<script src='foo1.js' type='text/javascript'/>\n" |