Author: sebb Date: Fri Apr 3 11:33:57 2009 New Revision: 761626 URL: http://svn.apache.org/viewvc?rev=761626&view=rev Log: Bug 46690 - handling of 302 redirects with invalid relative paths. JMeter now removes extraneous leading "../" segments (as do many browsers)
Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/modifier/AnchorModifier.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParserHTMLParser.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParsingUtils.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/JTidyHTMLParser.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/RegexpHTMLParser.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/URLCollection.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/ConversionUtils.java jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/util/TestHTTPUtils.java jakarta/jmeter/trunk/xdocs/changes.xml Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/modifier/AnchorModifier.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/modifier/AnchorModifier.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/modifier/AnchorModifier.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/modifier/AnchorModifier.java Fri Apr 3 11:33:57 2009 @@ -34,6 +34,7 @@ import org.apache.jmeter.protocol.http.parser.HtmlParsingUtils; import org.apache.jmeter.protocol.http.sampler.HTTPSampleResult; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jmeter.protocol.http.util.HTTPConstants; import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.samplers.Sampler; @@ -184,7 +185,7 @@ continue; // No point trying these } try { - HTTPSamplerBase newUrl = HtmlParsingUtils.createUrlFromAnchor(hrefStr, new URL(result.getURL(), base)); + HTTPSamplerBase newUrl = HtmlParsingUtils.createUrlFromAnchor(hrefStr, ConversionUtils.makeRelativeURL(result.getURL(), base)); newUrl.setMethod(HTTPConstants.GET); if (log.isDebugEnabled()) { log.debug("Potential <a href> match: " + newUrl); @@ -217,7 +218,7 @@ String hrefStr = namedItem.getNodeValue(); try { HTTPSamplerBase newUrl = HtmlParsingUtils.createUrlFromAnchor( - hrefStr, new URL(result.getURL(), base)); + hrefStr, ConversionUtils.makeRelativeURL(result.getURL(), base)); newUrl.setMethod(HTTPConstants.GET); if (log.isDebugEnabled()) { log.debug("Potential <frame src> match: " + newUrl); Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParserHTMLParser.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParserHTMLParser.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParserHTMLParser.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParserHTMLParser.java Fri Apr 3 11:33:57 2009 @@ -22,6 +22,7 @@ import java.net.URL; import java.util.Iterator; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; import org.htmlparser.Node; @@ -131,7 +132,7 @@ try { if (!baseref.equals(""))// Bugzilla 30713 { - baseUrl.url = new URL(baseUrl.url, baseHref.getBaseUrl()); + baseUrl.url = ConversionUtils.makeRelativeURL(baseUrl.url, baseHref.getBaseUrl()); } } catch (MalformedURLException e1) { throw new HTMLParseException(e1); Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParsingUtils.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParsingUtils.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParsingUtils.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/HtmlParsingUtils.java Fri Apr 3 11:33:57 2009 @@ -30,6 +30,7 @@ import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jmeter.testelement.property.PropertyIterator; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.logging.LoggingManager; @@ -260,7 +261,7 @@ if (log.isDebugEnabled()) { log.debug("Creating URL from Anchor: " + parsedUrlString + ", base: " + context); } - URL url = new URL(context, parsedUrlString); + URL url = ConversionUtils.makeRelativeURL(context, parsedUrlString); HTTPSamplerBase sampler =HTTPSamplerFactory.newInstance(); sampler.setDomain(url.getHost()); sampler.setProtocol(url.getProtocol()); Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/JTidyHTMLParser.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/JTidyHTMLParser.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/JTidyHTMLParser.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/JTidyHTMLParser.java Fri Apr 3 11:33:57 2009 @@ -23,6 +23,7 @@ import java.net.URL; import java.util.Iterator; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; import org.w3c.dom.Document; @@ -102,7 +103,7 @@ String tmp = getValue(attrs, ATT_HREF); if (tmp != null) { try { - baseUrl = new URL(baseUrl, tmp); + baseUrl = ConversionUtils.makeRelativeURL(baseUrl, tmp); } catch (MalformedURLException e) { throw new HTMLParseException(e); } Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/RegexpHTMLParser.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/RegexpHTMLParser.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/RegexpHTMLParser.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/RegexpHTMLParser.java Fri Apr 3 11:33:57 2009 @@ -22,6 +22,7 @@ import java.net.URL; import java.util.Iterator; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; @@ -165,7 +166,7 @@ log.debug("new baseUrl: " + s + " - " + baseUrl.toString()); } try { - baseUrl = new URL(baseUrl, s); + baseUrl = ConversionUtils.makeRelativeURL(baseUrl, s); } catch (MalformedURLException e) { // Doesn't even look like a URL? // Maybe it isn't: Ignore the exception. Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/URLCollection.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/URLCollection.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/URLCollection.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/parser/URLCollection.java Fri Apr 3 11:33:57 2009 @@ -24,6 +24,7 @@ import java.util.Iterator; import org.apache.commons.lang.StringEscapeUtils; +import org.apache.jmeter.protocol.http.util.ConversionUtils; /** * Collection class designed for handling URLs @@ -91,7 +92,7 @@ url=StringEscapeUtils.unescapeXml(url); boolean b = false; try { - b = this.add(new URL(baseUrl, url)); + b = this.add(ConversionUtils.makeRelativeURL(baseUrl, url)); } catch (MalformedURLException mfue) { // TODO log a warning message? b = this.add(url);// Add the string if cannot create the URL Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java Fri Apr 3 11:33:57 2009 @@ -45,6 +45,7 @@ import org.apache.jmeter.protocol.http.control.HeaderManager; import org.apache.jmeter.protocol.http.parser.HTMLParseException; import org.apache.jmeter.protocol.http.parser.HTMLParser; +import org.apache.jmeter.protocol.http.util.ConversionUtils; import org.apache.jmeter.protocol.http.util.EncoderCache; import org.apache.jmeter.protocol.http.util.HTTPArgument; import org.apache.jmeter.protocol.http.util.HTTPFileArg; @@ -1292,7 +1293,7 @@ // this behaviour. String location = encodeSpaces(lastRes.getRedirectLocation()); try { - lastRes = sample(new URL(lastRes.getURL(), location), GET, true, frameDepth); + lastRes = sample(ConversionUtils.makeRelativeURL(lastRes.getURL(), location), GET, true, frameDepth); } catch (MalformedURLException e) { lastRes = errorResult(e, lastRes); // The redirect URL we got was not a valid URL Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/ConversionUtils.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/ConversionUtils.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/ConversionUtils.java (original) +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/util/ConversionUtils.java Fri Apr 3 11:33:57 2009 @@ -18,7 +18,11 @@ package org.apache.jmeter.protocol.http.util; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.Charset; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.jorphan.util.JOrphanUtils; @@ -69,4 +73,32 @@ } return charSet; } + + /** + * Generate a relative URL, allowing for extraneous leading "../" segments. + * The Java {...@link URL#URL(URL, String)} constructor does not remove these. + * + * @param baseURL + * @param location relative location, possibly with extraneous leading "../" + * @return URL with extraneous ../ removed + * @throws MalformedURLException + */ + public static URL makeRelativeURL(URL baseURL, String location) throws MalformedURLException{ + URL initial = new URL(baseURL,location); + // skip expensive processing if it cannot apply + if (!location.startsWith("../")){// $NON-NLS-1$ + return initial; + } + String path = initial.getPath(); + // Match /../[../] etc. + Pattern p = Pattern.compile("^/((?:\\.\\./)+)"); // $NON-NLS-1$ + Matcher m = p.matcher(path); + if (m.lookingAt()){ + String prefix = m.group(1); // get ../ or ../../ etc. + if (location.startsWith(prefix)){ + return new URL(baseURL, location.substring(prefix.length())); + } + } + return initial; + } } Modified: jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/util/TestHTTPUtils.java URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/util/TestHTTPUtils.java?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/util/TestHTTPUtils.java (original) +++ jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/http/util/TestHTTPUtils.java Fri Apr 3 11:33:57 2009 @@ -18,6 +18,8 @@ package org.apache.jmeter.protocol.http.util; +import java.net.URL; + import junit.framework.TestCase; public class TestHTTPUtils extends TestCase { @@ -35,4 +37,14 @@ assertNull(ConversionUtils.getEncodingFromContentType(";charset=;")); assertNull(ConversionUtils.getEncodingFromContentType(";charset=no-such-charset;")); } + + public void testMakeRelativeURL() throws Exception { + URL base = new URL("http://host/a/b/c"); + assertEquals(new URL("http://host/a/b/d"),ConversionUtils.makeRelativeURL(base,"d")); + assertEquals(new URL("http://host/a/d"),ConversionUtils.makeRelativeURL(base,"../d")); + assertEquals(new URL("http://host/d"),ConversionUtils.makeRelativeURL(base,"../../d")); + assertEquals(new URL("http://host/d"),ConversionUtils.makeRelativeURL(base,"../../../d")); + assertEquals(new URL("http://host/d"),ConversionUtils.makeRelativeURL(base,"../../../../d")); + assertEquals(new URL("http://host/../d"),ConversionUtils.makeRelativeURL(base,"/../d")); + } } Modified: jakarta/jmeter/trunk/xdocs/changes.xml URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=761626&r1=761625&r2=761626&view=diff ============================================================================== --- jakarta/jmeter/trunk/xdocs/changes.xml (original) +++ jakarta/jmeter/trunk/xdocs/changes.xml Fri Apr 3 11:33:57 2009 @@ -193,6 +193,10 @@ <li>Check validity of cookies before storing them.</li> <li>FTP Sampler now logs out before disconnecting.</li> <li>Bug 46838 - if there was no data, still need to set latency in HTTPSampler</li> +<li> +Bug 46690 - handling of 302 redirects with invalid relative paths. +JMeter now removes extraneous leading "../" segments (as do many browsers) +</li> </ul> <h3>Improvements</h3> --------------------------------------------------------------------- To unsubscribe, e-mail: jmeter-dev-unsubscr...@jakarta.apache.org For additional commands, e-mail: jmeter-dev-h...@jakarta.apache.org