Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/protocol/http/sampler/TestHTTPSamplersAgainstHttpMirrorServer.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/protocol/http/sampler/TestHTTPSamplersAgainstHttpMirrorServer.java (revision 527881) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/protocol/http/sampler/TestHTTPSamplersAgainstHttpMirrorServer.java (working copy) @@ -25,11 +25,13 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.net.URL; import java.util.Locale; import org.apache.jmeter.config.Arguments; import org.apache.jmeter.engine.util.ValueReplacer; import org.apache.jmeter.protocol.http.control.HttpMirrorControl; +import org.apache.jmeter.protocol.http.util.EncoderCache; import org.apache.jmeter.protocol.http.util.HTTPArgument; import org.apache.jmeter.testelement.TestPlan; import org.apache.jmeter.threads.JMeterContextService; @@ -88,7 +90,7 @@ // delete temporay file temporaryFile.delete(); } - + public void testPostRequest_UrlEncoded() throws Exception { // Test HTTPSampler String samplerDefaultEncoding = "ISO-8859-1"; @@ -98,7 +100,7 @@ samplerDefaultEncoding = "US-ASCII"; testPostRequest_UrlEncoded(HTTP_SAMPLER2, samplerDefaultEncoding); } - + public void testPostRequest_FormMultipart() throws Exception { // Test HTTPSampler String samplerDefaultEncoding = "ISO-8859-1"; @@ -117,6 +119,22 @@ // Test HTTPSampler2 samplerDefaultEncoding = "US-ASCII"; testPostRequest_FileUpload(HTTP_SAMPLER2, samplerDefaultEncoding); + } + + public void testGetRequest() throws Exception { + // Test HTTPSampler + testGetRequest(HTTP_SAMPLER); + + // Test HTTPSampler2 + testGetRequest(HTTP_SAMPLER2); + } + + public void testGetRequest_Parameters() throws Exception { + // Test HTTPSampler + testGetRequest_Parameters(HTTP_SAMPLER); + + // Test HTTPSampler2 + testGetRequest_Parameters(HTTP_SAMPLER2); } private void testPostRequest_UrlEncoded(int samplerType, String samplerDefaultEncoding) throws Exception { @@ -286,6 +304,124 @@ checkPostRequestFileUpload(sampler, res, samplerDefaultEncoding, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, fileField, temporaryFile, fileMimeType, TEST_FILE_CONTENT); } + private void testGetRequest(int samplerType) throws Exception { + // Test sending simple HTTP get + // Test sending data with default encoding + HTTPSamplerBase sampler = createHttpSampler(samplerType); + String contentEncoding = ""; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + HTTPSampleResult res = executeSampler(sampler); + checkGetRequest(sampler, res); + + // Test sending data with ISO-8859-1 encoding + sampler = createHttpSampler(samplerType); + contentEncoding = "ISO-8859-1"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + res = executeSampler(sampler); + checkGetRequest(sampler, res); + + // Test sending data with UTF-8 encoding + sampler = createHttpSampler(samplerType); + contentEncoding = "UTF-8"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + res = executeSampler(sampler); + checkGetRequest(sampler, res); + } + + private void testGetRequest_Parameters(int samplerType) throws Exception { + String titleField = "title"; + String titleValue = "mytitle"; + String descriptionField = "description"; + String descriptionValue = "mydescription"; + + // Test sending simple HTTP get + // Test sending data with default encoding + HTTPSamplerBase sampler = createHttpSampler(samplerType); + String contentEncoding = ""; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + setupFormData(sampler, false, titleField, titleValue, descriptionField, descriptionValue); + HTTPSampleResult res = executeSampler(sampler); + sampler.setRunningVersion(true); + URL executedUrl = sampler.getUrl(); + sampler.setRunningVersion(false); + checkGetRequest_Parameters(sampler, res, contentEncoding, executedUrl, titleField, titleValue, descriptionField, descriptionValue); + + // Test sending data with ISO-8859-1 encoding + sampler = createHttpSampler(samplerType); + contentEncoding = "ISO-8859-1"; + titleValue = "mytitle\uc385"; + descriptionValue = "mydescription\uc385"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + setupFormData(sampler, false, titleField, titleValue, descriptionField, descriptionValue); + res = executeSampler(sampler); + sampler.setRunningVersion(true); + executedUrl = sampler.getUrl(); + sampler.setRunningVersion(false); + checkGetRequest_Parameters(sampler, res, contentEncoding, executedUrl, titleField, titleValue, descriptionField, descriptionValue); + + // Test sending data with UTF-8 encoding + sampler = createHttpSampler(samplerType); + contentEncoding = "UTF-8"; + titleValue = "mytitle\u0153\u20a1\u0115\u00c5"; + descriptionValue = "mydescription\u0153\u20a1\u0115\u00c5"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + setupFormData(sampler, false, titleField, titleValue, descriptionField, descriptionValue); + res = executeSampler(sampler); + sampler.setRunningVersion(true); + executedUrl = sampler.getUrl(); + sampler.setRunningVersion(false); + checkGetRequest_Parameters(sampler, res, contentEncoding, executedUrl, titleField, titleValue, descriptionField, descriptionValue); + + // Test sending data as UTF-8, with values that changes when urlencoded + sampler = createHttpSampler(samplerType); + contentEncoding = "UTF-8"; + titleValue = "mytitle\u0153+\u20a1 \u0115&yes\u00c5"; + descriptionValue = "mydescription \u0153 \u20a1 \u0115 \u00c5"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + setupFormData(sampler, false, titleField, titleValue, descriptionField, descriptionValue); + res = executeSampler(sampler); + sampler.setRunningVersion(true); + executedUrl = sampler.getUrl(); + sampler.setRunningVersion(false); + checkGetRequest_Parameters(sampler, res, contentEncoding, executedUrl, titleField, titleValue, descriptionField, descriptionValue); + + // Test sending data as UTF-8, where user defined variables are used + // to set the value for form data + JMeterUtils.setLocale(Locale.ENGLISH); + TestPlan testPlan = new TestPlan(); + JMeterVariables vars = new JMeterVariables(); + vars.put("title_prefix", "a test\u00c5"); + vars.put("description_suffix", "the_end"); + JMeterContextService.getContext().setVariables(vars); + JMeterContextService.getContext().setSamplingStarted(true); + ValueReplacer replacer = new ValueReplacer(); + replacer.setUserDefinedVariables(testPlan.getUserDefinedVariables()); + + sampler = createHttpSampler(samplerType); + contentEncoding = "UTF-8"; + titleValue = "${title_prefix}mytitle\u0153\u20a1\u0115\u00c5"; + descriptionValue = "mydescription\u0153\u20a1\u0115\u00c5${description_suffix}"; + setupUrl(sampler, contentEncoding); + sampler.setMethod(HTTPSamplerBase.GET); + setupFormData(sampler, false, titleField, titleValue, descriptionField, descriptionValue); + // Replace the variables in the sampler + replacer.replaceValues(sampler); + res = executeSampler(sampler); + String expectedTitleValue = "a test\u00c5mytitle\u0153\u20a1\u0115\u00c5"; + String expectedDescriptionValue = "mydescription\u0153\u20a1\u0115\u00c5the_end"; + sampler.setRunningVersion(true); + executedUrl = sampler.getUrl(); + sampler.setRunningVersion(false); + checkGetRequest_Parameters(sampler, res, contentEncoding, executedUrl, titleField, expectedTitleValue, descriptionField, expectedDescriptionValue); + } + private HTTPSampleResult executeSampler(HTTPSamplerBase sampler) { sampler.setRunningVersion(true); sampler.threadStarted(); @@ -332,6 +468,9 @@ // Skip the blank line with crlf dividing headers and body bodySent = dataSentToMirrorServer.substring(posDividerHeadersAndBody+2); } + else { + fail("No header and body section found"); + } // Check response headers assertTrue(isInRequestHeaders(headersSent, HTTPSamplerBase.HEADER_CONTENT_TYPE, HTTPSamplerBase.APPLICATION_X_WWW_FORM_URLENCODED)); assertTrue( @@ -344,6 +483,8 @@ // Check post body which was sent to the mirror server, and // sent back by the mirror server checkArraysHaveSameContent(expectedPostBody.getBytes(contentEncoding), bodySent.getBytes(contentEncoding)); + // Check method, path and query sent + checkMethodPathQuery(headersSent, sampler.getMethod(), sampler.getPath(), null); } private void checkPostRequestFormMultipart( @@ -385,6 +526,9 @@ // Skip the blank line with crlf dividing headers and body bodySent = dataSentToMirrorServer.substring(posDividerHeadersAndBody+2); } + else { + fail("No header and body section found"); + } // Check response headers assertTrue(isInRequestHeaders(headersSent, HTTPSamplerBase.HEADER_CONTENT_TYPE, "multipart/form-data" + "; boundary=" + boundaryString)); assertTrue( @@ -397,6 +541,8 @@ // Check post body which was sent to the mirror server, and // sent back by the mirror server checkArraysHaveSameContent(expectedPostBody, bodySent.getBytes(contentEncoding)); + // Check method, path and query sent + checkMethodPathQuery(headersSent, sampler.getMethod(), sampler.getPath(), null); } private void checkPostRequestFileUpload( @@ -443,6 +589,9 @@ // Skip the blank line with crlf dividing headers and body bodySent = dataSentToMirrorServer.substring(posDividerHeadersAndBody+2); } + else { + fail("No header and body section found"); + } // Check response headers assertTrue(isInRequestHeaders(headersSent, HTTPSamplerBase.HEADER_CONTENT_TYPE, "multipart/form-data" + "; boundary=" + boundaryString)); assertTrue( @@ -457,8 +606,124 @@ // We cannot check this merely by getting the body in the contentEncoding, // since the actual file content is sent binary, without being encoded //checkArraysHaveSameContent(expectedPostBody, bodySent.getBytes(contentEncoding)); - } + // Check method, path and query sent + checkMethodPathQuery(headersSent, sampler.getMethod(), sampler.getPath(), null); + } + private void checkGetRequest( + HTTPSamplerBase sampler, + HTTPSampleResult res + ) throws IOException { + // Check URL + assertEquals(sampler.getUrl(), res.getURL()); + // Check method + assertEquals(sampler.getMethod(), res.getHTTPMethod()); + // Check that the query string is empty + assertEquals(0, res.getQueryString().length()); + + // Find the data sent to the mirror server, which the mirror server is sending back to us + String dataSentToMirrorServer = new String(res.getResponseData(), EncoderCache.URL_ARGUMENT_ENCODING); + int posDividerHeadersAndBody = getPositionOfBody(dataSentToMirrorServer); + String headersSent = null; + String bodySent = null; + if(posDividerHeadersAndBody >= 0) { + headersSent = dataSentToMirrorServer.substring(0, posDividerHeadersAndBody); + // Skip the blank line with crlf dividing headers and body + bodySent = dataSentToMirrorServer.substring(posDividerHeadersAndBody+2); + } + else { + fail("No header and body section found"); + } + // No body should have been sent + assertEquals(bodySent.length(), 0); + // Check method, path and query sent + checkMethodPathQuery(headersSent, sampler.getMethod(), sampler.getPath(), null); + } + + private void checkGetRequest_Parameters( + HTTPSamplerBase sampler, + HTTPSampleResult res, + String contentEncoding, + URL executedUrl, + String titleField, + String titleValue, + String descriptionField, + String descriptionValue) throws IOException { + if(contentEncoding == null || contentEncoding.length() == 0) { + contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING; + } + // Check URL + assertEquals(executedUrl, res.getURL()); + // Check method + assertEquals(sampler.getMethod(), res.getHTTPMethod()); + // Cannot check the query string of the result, because the mirror server + // replies without including query string in URL + String expectedQueryString = titleField + "=" + URLEncoder.encode(titleValue, contentEncoding) + "&" + descriptionField + "=" + URLEncoder.encode(descriptionValue, contentEncoding); + + // Find the data sent to the mirror server, which the mirror server is sending back to us + String dataSentToMirrorServer = new String(res.getResponseData(), EncoderCache.URL_ARGUMENT_ENCODING); + int posDividerHeadersAndBody = getPositionOfBody(dataSentToMirrorServer); + String headersSent = null; + String bodySent = null; + if(posDividerHeadersAndBody >= 0) { + headersSent = dataSentToMirrorServer.substring(0, posDividerHeadersAndBody); + // Skip the blank line with crlf dividing headers and body + bodySent = dataSentToMirrorServer.substring(posDividerHeadersAndBody+2); + } + else { + fail("No header and body section found"); + } + // No body should have been sent + assertEquals(bodySent.length(), 0); + // Check method, path and query sent + checkMethodPathQuery(headersSent, sampler.getMethod(), sampler.getPath(), expectedQueryString); + } + + private void checkMethodPathQuery( + String headersSent, + String expectedMethod, + String expectedPath, + String expectedQueryString) + throws IOException { + // Check the Request URI sent to the mirror server, and + // sent back by the mirror server + int indexFirstSpace = headersSent.indexOf(" "); + int indexSecondSpace = headersSent.indexOf(" ", headersSent.length() > indexFirstSpace ? indexFirstSpace + 1 : indexFirstSpace); + if(indexFirstSpace <= 0 && indexSecondSpace <= 0 || indexFirstSpace == indexSecondSpace) { + fail("Could not find method and URI sent"); + } + String methodSent = headersSent.substring(0, indexFirstSpace); + assertEquals(expectedMethod, methodSent); + String uriSent = headersSent.substring(indexFirstSpace + 1, indexSecondSpace); + int indexQueryStart = uriSent.indexOf("?"); + if(expectedQueryString != null && expectedQueryString.length() > 0) { + // We should have a query string part + if(indexQueryStart <= 0 || (indexQueryStart == uriSent.length() - 1)) { + fail("Could not find query string in URI"); + } + } + else { + if(indexQueryStart > 0) { + // We should not have a query string part + fail("Query string present in URI"); + } + else { + indexQueryStart = uriSent.length(); + } + } + // Check path + String pathSent = uriSent.substring(0, indexQueryStart); + assertEquals(expectedPath, pathSent); + // Check query + if(expectedQueryString != null && expectedQueryString.length() > 0) { + String queryStringSent = uriSent.substring(indexQueryStart + 1); + // Is it only the parameter values which are encoded in the specified + // content encoding, the rest of the query is encoded in UTF-8 + // Therefore we compare the whole query using UTF-8 + checkArraysHaveSameContent(expectedQueryString.getBytes(EncoderCache.URL_ARGUMENT_ENCODING), queryStringSent.getBytes(EncoderCache.URL_ARGUMENT_ENCODING)); + } + } + private boolean isInRequestHeaders(String requestHeaders, String headerName, String headerValue) { return checkRegularExpression(requestHeaders, headerName + ": " + headerValue); } Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java (revision 527881) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java (working copy) @@ -233,7 +233,7 @@ // We create the post body content now, so we know the size ByteArrayOutputStream bos = new ByteArrayOutputStream(); - String postBody = getQueryStringForPostBody(sampler, contentEncoding); + String postBody = sampler.getQueryString(contentEncoding); // Query string should be encoded in UTF-8 bos.write(postBody.getBytes("UTF-8")); // $NON-NLS-1$ bos.flush(); @@ -252,37 +252,6 @@ } } - /** - * Gets the query string for the sampler encoded for http post body. - * This method works differently from the getQueryString in HttpSamplerBase, - * becuase this method does not force the parameter value to be url encoded - * in utf8. Rather, it uses the specified encoding for the parameter value - * - * @return the querystring encoded as usable for a http post body request - */ - private String getQueryStringForPostBody(HTTPSampler sampler, String contentEncoding) throws IOException { - StringBuffer buf = new StringBuffer(); - PropertyIterator iter = sampler.getArguments().iterator(); - boolean first = true; - while (iter.hasNext()) { - HTTPArgument arg = (HTTPArgument) iter.next().getObjectValue(); - - if (!first) { - buf.append("&"); - } else { - first = false; - } - buf.append(arg.getEncodedName()); - if (arg.getMetaData() == null) { - buf.append("="); - } else { - buf.append(arg.getMetaData()); - } - buf.append(URLEncoder.encode(arg.getValue(), contentEncoding)); - } - return buf.toString(); - } - /** * Get the boundary string, used to separate multiparts * Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (revision 527881) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (working copy) @@ -19,6 +19,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; @@ -36,6 +37,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.EncoderCache; import org.apache.jmeter.protocol.http.util.HTTPArgument; import org.apache.jmeter.samplers.AbstractSampler; import org.apache.jmeter.samplers.Entry; @@ -486,6 +488,22 @@ } return port; } + + /** + * Tell wether the default port for the specified protocol is used + * + * @return true if the default port number for the protocol is used, false otherwise + */ + public boolean isProtocolDefaultPort() { + if (getPort() == UNSPECIFIED_PORT || + (PROTOCOL_HTTP.equals(getProtocol()) && getPort() == DEFAULT_HTTP_PORT) || + (PROTOCOL_HTTPS.equals(getProtocol()) && getPort() == DEFAULT_HTTPS_PORT)) { + return true; + } + else { + return false; + } + } public int getPort() { int port = getPropertyAsInt(PORT); @@ -620,26 +638,55 @@ pathAndQuery.append("/"); // $NON-NLS-1$ } pathAndQuery.append(path); - if (this.getMethod().equals(GET) && getQueryString().length() > 0) { - if (path.indexOf(QRY_PFX) > -1) { - pathAndQuery.append(QRY_SEP); - } else { - pathAndQuery.append(QRY_PFX); - } - pathAndQuery.append(getQueryString()); + + // Add the query string if it is a HTTP GET request + if(GET.equals(getMethod())) { + // Get the query string encoded in specified encoding + // If no encoding is specified by user, we will get it + // encoded in UTF-8, which is what the HTTP spec says + String queryString = getQueryString(getContentEncoding()); + if(queryString.length() > 0) { + if (path.indexOf(QRY_PFX) > -1) { + pathAndQuery.append(QRY_SEP); + } else { + pathAndQuery.append(QRY_PFX); + } + pathAndQuery.append(queryString); + } } - if (getPort() == UNSPECIFIED_PORT || getPort() == DEFAULT_HTTP_PORT) { + // If default port for protocol is used, we do not include port in URL + if(isProtocolDefaultPort()) { return new URL(getProtocol(), getDomain(), pathAndQuery.toString()); } - return new URL(getProtocol(), getPropertyAsString(DOMAIN), getPort(), pathAndQuery.toString()); + else { + return new URL(getProtocol(), getDomain(), getPort(), pathAndQuery.toString()); + } } + /** + * Gets the QueryString attribute of the UrlConfig object, using + * UTF-8 to encode the URL + * + * @return the QueryString value + */ + public String getQueryString() { + // We use the encoding which should be used according to the HTTP spec, which is UTF-8 + return getQueryString(EncoderCache.URL_ARGUMENT_ENCODING); + } + /** - * Gets the QueryString attribute of the UrlConfig object. + * Gets the QueryString attribute of the UrlConfig object, using the + * specified encoding to encode the parameter values put into the URL * + * @param contentEncoding the encoding to use for encoding parameter values * @return the QueryString value */ - public String getQueryString() { + public String getQueryString(String contentEncoding) { + // Check if the sampler has a specified content encoding + if(contentEncoding == null || contentEncoding.trim().length() == 0) { + // We use the encoding which should be used according to the HTTP spec, which is UTF-8 + contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING; + } StringBuffer buf = new StringBuffer(); PropertyIterator iter = getArguments().iterator(); boolean first = true; @@ -669,7 +716,14 @@ } else { buf.append(item.getMetaData()); } - buf.append(item.getEncodedValue()); + + // Encode the parameter value in the specified content encoding + try { + buf.append(item.getEncodedValue(contentEncoding)); + } + catch(UnsupportedEncodingException e) { + log.warn("Unable to encode parameter in encoding " + contentEncoding + ", parameter value not included in query string"); + } } return buf.toString(); } Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPArgument.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPArgument.java (revision 527881) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPArgument.java (working copy) @@ -92,8 +92,8 @@ setAlwaysEncoded(true); if (alreadyEncoded) { try { - name = URLDecoder.decode(name, "UTF-8"); // $NON-NLS-1$ - value = URLDecoder.decode(value, "UTF-8"); // $NON-NLS-1$ + name = URLDecoder.decode(name, EncoderCache.URL_ARGUMENT_ENCODING); + value = URLDecoder.decode(value, EncoderCache.URL_ARGUMENT_ENCODING); } catch (UnsupportedEncodingException e) { // UTF-8 unsupported? You must be joking! log.error("UTF-8 encoding not supported!"); @@ -132,14 +132,37 @@ } } - public String getEncodedValue() { - if (isAlwaysEncoded()) { - return cache.getEncoded(getValue()); - } else { - return getValue(); - } - } + /** + * Get the argument value encoded using UTF-8 + * + * @return the argument value encoded in UTF-8 + */ + public String getEncodedValue() { + // Encode according to the HTTP spec, i.e. UTF-8 + try { + return getEncodedValue(EncoderCache.URL_ARGUMENT_ENCODING); + } catch (UnsupportedEncodingException e) { + // This can't happen (how should utf8 not be supported!?!), + // so just throw an Error: + throw new Error("Should not happen: " + e.toString()); + } + } + /** + * Get the argument value encoded in the specified encoding + * + * @param contentEncoding the encoding to use when encoding the argument value + * @return the argument value encoded in the specified encoding + * @throws UnsupportedEncodingException + */ + public String getEncodedValue(String contentEncoding) throws UnsupportedEncodingException { + if (isAlwaysEncoded()) { + return cache.getEncoded(getValue(), contentEncoding); + } else { + return getValue(); + } + } + public String getEncodedName() { if (isAlwaysEncoded()) { return cache.getEncoded(getName()); Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/EncoderCache.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/EncoderCache.java (revision 527881) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/util/EncoderCache.java (working copy) @@ -30,25 +30,50 @@ * @version $Revision$ last updated $Date$ */ public class EncoderCache { - Cache cache; + /** The encoding which should be usd for URLs, according to HTTP specification */ + public static final String URL_ARGUMENT_ENCODING = "UTF-8"; - public EncoderCache(int cacheSize) { - cache = new CacheLRU(cacheSize); - } + Cache cache; - public String getEncoded(String k) { - Object encodedValue = cache.getElement(k); - if (encodedValue != null) { - return (String) encodedValue; - } - try { - encodedValue = URLEncoder.encode(k, "utf8"); - } catch (UnsupportedEncodingException e) { - // This can't happen (how should utf8 not be supported!?!), - // so just throw an Error: - throw new Error("Should not happen: " + e.toString()); - } - cache.addElement(k, encodedValue); - return (String) encodedValue; - } + public EncoderCache(int cacheSize) { + cache = new CacheLRU(cacheSize); + } + + /** + * Get the specified value URL encoded using UTF-8 encoding + * + * @param k the value to encode + * @return the value URL encoded used UTF-8 + */ + public String getEncoded(String k) { + try { + return getEncoded(k, URL_ARGUMENT_ENCODING); + } catch (UnsupportedEncodingException e) { + // This can't happen (how should utf8 not be supported!?!), + // so just throw an Error: + throw new Error("Should not happen: " + e.toString()); + } + } + + /** + * Get the specified value URL encoded using the specified encoding + * + * @param k the value to encode + * @param contentEncoding the encoding to use when URL encoding + * @return the value URL encoded using the specified encoding + * @throws UnsupportedEncodingException if the specified encoding is not supported + */ + public String getEncoded(String k, String contentEncoding) throws UnsupportedEncodingException { + String cacheKey = k + contentEncoding; + // Check if we have it in the cache + Object encodedValue = cache.getElement(cacheKey); + if (encodedValue != null) { + return (String) encodedValue; + } + // Perform the encoding + encodedValue = URLEncoder.encode(k, contentEncoding); + // Add to cache + cache.addElement(cacheKey, encodedValue); + return (String) encodedValue; + } }