You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ol...@apache.org on 2005/05/26 20:21:15 UTC
svn commit: r178662 - in /jakarta/commons/proper/httpclient/trunk/src:
java/org/apache/commons/httpclient/auth/
java/org/apache/commons/httpclient/cookie/
java/org/apache/commons/httpclient/util/ test/org/apache/commons/httpclient/
Author: olegk
Date: Thu May 26 11:21:14 2005
New Revision: 178662
URL: http://svn.apache.org/viewcvs?rev=178662&view=rev
Log:
PR #34961 (HttpClient does not correctly handle escaped characters in HTTP header elements)
Contributed by Oleg Kalnichevski
Reviewed by Ortwin Glück
Added:
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java (with props)
jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java (with props)
Modified:
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/auth/DigestScheme.java
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterParser.java
jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestNoHost.java
jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterParser.java
Modified: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/auth/DigestScheme.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/auth/DigestScheme.java?rev=178662&r1=178661&r2=178662&view=diff
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/auth/DigestScheme.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/auth/DigestScheme.java Thu May 26 11:21:14 2005
@@ -31,13 +31,17 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.util.EncodingUtil;
+import org.apache.commons.httpclient.util.ParameterFormatter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -97,6 +101,7 @@
private int qopVariant = QOP_MISSING;
private String cnonce;
+ private final ParameterFormatter formatter;
/**
* Default constructor for the digest authetication scheme.
*
@@ -105,6 +110,8 @@
public DigestScheme() {
super();
this.complete = false;
+ this.formatter = new ParameterFormatter();
+ this.formatter.setAlwaysUseQuotes(true);
}
/**
@@ -138,8 +145,8 @@
*/
public DigestScheme(final String challenge)
throws MalformedChallengeException {
- super(challenge);
- this.complete = true;
+ this();
+ processChallenge(challenge);
}
/**
@@ -431,7 +438,7 @@
return serverDigest;
}
-
+
/**
* Creates digest-response header as defined in RFC2617.
*
@@ -440,12 +447,12 @@
*
* @return The digest-response as String.
*/
- private String createDigestHeader(String uname, String digest) throws AuthenticationException {
+ private String createDigestHeader(final String uname, final String digest)
+ throws AuthenticationException {
LOG.trace("enter DigestScheme.createDigestHeader(String, Map, "
+ "String)");
- StringBuffer sb = new StringBuffer();
String uri = getParameter("uri");
String realm = getParameter("realm");
String nonce = getParameter("nonce");
@@ -455,22 +462,34 @@
String qop = getParameter("qop");
String algorithm = getParameter("algorithm");
- sb.append("username=\"" + uname + "\"")
- .append(", realm=\"" + realm + "\"")
- .append(", nonce=\"" + nonce + "\"").append(", uri=\"" + uri + "\"")
- .append(", response=\"" + response + "\"");
+ List params = new ArrayList(20);
+ params.add(new NameValuePair("username", uname));
+ params.add(new NameValuePair("realm", realm));
+ params.add(new NameValuePair("nonce", nonce));
+ params.add(new NameValuePair("uri", uri));
+ params.add(new NameValuePair("response", response));
+
if (qopVariant != QOP_MISSING) {
- sb.append(", qop=\"" + getQopVariantString() + "\"")
- .append(", nc="+ NC)
- .append(", cnonce=\"" + cnonce + "\"");
+ params.add(new NameValuePair("qop", getQopVariantString()));
+ params.add(new NameValuePair("nc", NC));
+ params.add(new NameValuePair("cnonce", this.cnonce));
}
if (algorithm != null) {
- sb.append(", algorithm=\"" + algorithm + "\"");
+ params.add(new NameValuePair("algorithm", algorithm));
}
if (opaque != null) {
- sb.append(", opaque=\"" + opaque + "\"");
+ params.add(new NameValuePair("opaque", opaque));
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < params.size(); i++) {
+ NameValuePair param = (NameValuePair) params.get(i);
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ this.formatter.format(buffer, param);
}
- return sb.toString();
+ return buffer.toString();
}
private String getQopVariantString() {
Modified: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java?rev=178662&r1=178661&r2=178662&view=diff
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java Thu May 26 11:21:14 2005
@@ -31,6 +31,7 @@
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.util.ParameterFormatter;
/**
* <p>RFC 2109 specific cookie management functions
@@ -51,12 +52,15 @@
public class RFC2109Spec extends CookieSpecBase {
+ private final ParameterFormatter formatter;
+
/** Default constructor */
public RFC2109Spec() {
super();
+ this.formatter = new ParameterFormatter();
+ this.formatter.setAlwaysUseQuotes(true);
}
-
/**
* Parse RFC 2109 specific cookie attribute and update the corresponsing
* {@link Cookie} properties.
@@ -189,60 +193,46 @@
* Return a name/value string suitable for sending in a <tt>"Cookie"</tt>
* header as defined in RFC 2109 for backward compatibility with cookie
* version 0
- * @param name The name.
- * @param value The value
+ * @param buffer The string buffer to use for output
+ * @param param The parameter.
* @param version The cookie version
- * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
*/
-
- private String formatNameValuePair(
- final String name, final String value, int version) {
-
- final StringBuffer buffer = new StringBuffer();
+ private void formatParam(final StringBuffer buffer, final NameValuePair param, int version) {
if (version < 1) {
- buffer.append(name);
+ buffer.append(param.getName());
buffer.append("=");
- if (value != null) {
- buffer.append(value);
+ if (param.getValue() != null) {
+ buffer.append(param.getValue());
}
} else {
- buffer.append(name);
- buffer.append("=\"");
- if (value != null) {
- buffer.append(value);
- }
- buffer.append("\"");
+ this.formatter.format(buffer, param);
}
- return buffer.toString();
}
/**
* Return a string suitable for sending in a <tt>"Cookie"</tt> header
* as defined in RFC 2109 for backward compatibility with cookie version 0
- * @param cookie a {@link Cookie} to be formatted as string
+ * @param buffer The string buffer to use for output
+ * @param cookie The {@link Cookie} to be formatted as string
* @param version The version to use.
- * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
*/
- private String formatCookieAsVer(Cookie cookie, int version) {
- LOG.trace("enter RFC2109Spec.formatCookieAsVer(Cookie)");
- StringBuffer buf = new StringBuffer();
- buf.append(formatNameValuePair(cookie.getName(),
- cookie.getValue(), version));
+ private void formatCookieAsVer(final StringBuffer buffer, final Cookie cookie, int version) {
+ String value = cookie.getValue();
+ if (value == null) {
+ value = "";
+ }
+ formatParam(buffer, new NameValuePair(cookie.getName(), value), version);
if (cookie.getDomain() != null
&& cookie.isDomainAttributeSpecified()) {
-
- buf.append("; ");
- buf.append(formatNameValuePair("$Domain",
- cookie.getDomain(), version));
+ buffer.append("; ");
+ formatParam(buffer, new NameValuePair("$Domain", cookie.getDomain()), version);
}
if (cookie.getPath() != null && cookie.isPathAttributeSpecified()) {
- buf.append("; ");
- buf.append(formatNameValuePair("$Path", cookie.getPath(), version));
+ buffer.append("; ");
+ formatParam(buffer, new NameValuePair("$Path", cookie.getPath()), version);
}
- return buf.toString();
}
-
/**
* Return a string suitable for sending in a <tt>"Cookie"</tt> header as
* defined in RFC 2109
@@ -254,12 +244,13 @@
if (cookie == null) {
throw new IllegalArgumentException("Cookie may not be null");
}
- int ver = cookie.getVersion();
+ int version = cookie.getVersion();
StringBuffer buffer = new StringBuffer();
- buffer.append(formatNameValuePair("$Version",
- Integer.toString(ver), ver));
+ formatParam(buffer,
+ new NameValuePair("$Version", Integer.toString(version)),
+ version);
buffer.append("; ");
- buffer.append(formatCookieAsVer(cookie, ver));
+ formatCookieAsVer(buffer, cookie, version);
return buffer.toString();
}
@@ -281,11 +272,12 @@
}
}
final StringBuffer buffer = new StringBuffer();
- buffer.append(formatNameValuePair("$Version",
- Integer.toString(version), version));
+ formatParam(buffer,
+ new NameValuePair("$Version", Integer.toString(version)),
+ version);
for (int i = 0; i < cookies.length; i++) {
buffer.append("; ");
- buffer.append(formatCookieAsVer(cookies[i], version));
+ formatCookieAsVer(buffer, cookies[i], version);
}
return buffer.toString();
}
Added: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java?rev=178662&view=auto
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java (added)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java Thu May 26 11:21:14 2005
@@ -0,0 +1,241 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+import org.apache.commons.httpclient.NameValuePair;
+
+/**
+ * <p>
+ * This formatter produces a textual representation of attribute/value pairs. It
+ * comforms to the generic grammar and formatting rules outlined in the
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.1">Section 2.1</a>
+ * and
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section 3.6</a>
+ * of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC 2616</a>
+ * </p>
+ * <h>2.1 Augmented BNF</h>
+ * <p>
+ * Many HTTP/1.1 header field values consist of words separated by LWS or special
+ * characters. These special characters MUST be in a quoted string to be used within
+ * a parameter value (as defined in section 3.6).
+ * <p>
+ * <pre>
+ * token = 1*<any CHAR except CTLs or separators>
+ * separators = "(" | ")" | "<" | ">" | "@"
+ * | "," | ";" | ":" | "\" | <">
+ * | "/" | "[" | "]" | "?" | "="
+ * | "{" | "}" | SP | HT
+ * </pre>
+ * <p>
+ * A string of text is parsed as a single word if it is quoted using double-quote marks.
+ * </p>
+ * <pre>
+ * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
+ * qdtext = <any TEXT except <">>
+ * </pre>
+ * <p>
+ * The backslash character ("\") MAY be used as a single-character quoting mechanism only
+ * within quoted-string and comment constructs.
+ * </p>
+ * <pre>
+ * quoted-pair = "\" CHAR
+ * </pre>
+ * <h>3.6 Transfer Codings</h>
+ * <p>
+ * Parameters are in the form of attribute/value pairs.
+ * </p>
+ * <pre>
+ * parameter = attribute "=" value
+ * attribute = token
+ * value = token | quoted-string
+ * </pre>
+ *
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @since 3.0
+ */
+public class ParameterFormatter {
+
+ /**
+ * Special characters that can be used as separators in HTTP parameters.
+ * These special characters MUST be in a quoted string to be used within
+ * a parameter value
+ */
+ private static final char[] SEPARATORS = {
+ '(', ')', '<', '>', '@',
+ ',', ';', ':', '\\', '"',
+ '/', '[', ']', '?', '=',
+ '{', '}', ' ', '\t'
+ };
+
+ /**
+ * Unsafe special characters that must be escaped using the backslash
+ * character
+ */
+ private static final char[] UNSAFE_CHARS = {
+ '"', '\\'
+ };
+
+ /**
+ * This flag determines whether all parameter values must be enclosed in
+ * quotation marks, even if they do not contain any special characters
+ */
+ private boolean alwaysUseQuotes = true;
+
+ /** Default ParameterFormatter constructor */
+ public ParameterFormatter() {
+ super();
+ }
+
+ private static boolean isOneOf(char[] chars, char ch) {
+ for (int i = 0; i < chars.length; i++) {
+ if (ch == chars[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean isUnsafeChar(char ch) {
+ return isOneOf(UNSAFE_CHARS, ch);
+ }
+
+ private static boolean isSeparator(char ch) {
+ return isOneOf(SEPARATORS, ch);
+ }
+
+ /**
+ * Determines whether all parameter values must be enclosed in quotation
+ * marks, even if they do not contain any special characters
+ *
+ * @return <tt>true</tt> if all parameter values must be enclosed in
+ * quotation marks, <tt>false</tt> otherwise
+ */
+ public boolean isAlwaysUseQuotes() {
+ return alwaysUseQuotes;
+ }
+
+ /**
+ * Defines whether all parameter values must be enclosed in quotation
+ * marks, even if they do not contain any special characters
+ *
+ * @param alwaysUseQuotes
+ */
+ public void setAlwaysUseQuotes(boolean alwaysUseQuotes) {
+ this.alwaysUseQuotes = alwaysUseQuotes;
+ }
+
+ /**
+ * Formats the given parameter value using formatting rules defined
+ * in RFC 2616
+ *
+ * @param buffer output buffer
+ * @param value the parameter value to be formatted
+ * @param alwaysUseQuotes <tt>true</tt> if the parameter value must
+ * be enclosed in quotation marks, even if it does not contain any special
+ * characters<tt>, false</tt> only if the parameter value contains
+ * potentially unsafe special characters
+ */
+ public static void formatValue(
+ final StringBuffer buffer, final String value, boolean alwaysUseQuotes) {
+ if (buffer == null) {
+ throw new IllegalArgumentException("String buffer may not be null");
+ }
+ if (value == null) {
+ throw new IllegalArgumentException("Value buffer may not be null");
+ }
+ if (alwaysUseQuotes) {
+ buffer.append('"');
+ for (int i = 0; i < value.length(); i++) {
+ char ch = value.charAt(i);
+ if (isUnsafeChar(ch)) {
+ buffer.append('\\');
+ }
+ buffer.append(ch);
+ }
+ buffer.append('"');
+ } else {
+ int offset = buffer.length();
+ boolean unsafe = false;
+ for (int i = 0; i < value.length(); i++) {
+ char ch = value.charAt(i);
+ if (isSeparator(ch)) {
+ unsafe = true;
+ }
+ if (isUnsafeChar(ch)) {
+ buffer.append('\\');
+ }
+ buffer.append(ch);
+ }
+ if (unsafe) {
+ buffer.insert(offset, '"');
+ buffer.append('"');
+ }
+ }
+ }
+
+ /**
+ * Produces textual representaion of the attribute/value pair using
+ * formatting rules defined in RFC 2616
+ *
+ * @param buffer output buffer
+ * @param param the parameter to be formatted
+ */
+ public void format(final StringBuffer buffer, final NameValuePair param) {
+ if (buffer == null) {
+ throw new IllegalArgumentException("String buffer may not be null");
+ }
+ if (param == null) {
+ throw new IllegalArgumentException("Parameter may not be null");
+ }
+ buffer.append(param.getName());
+ String value = param.getValue();
+ if (value != null) {
+ buffer.append("=");
+ formatValue(buffer, value, this.alwaysUseQuotes);
+ }
+ }
+
+ /**
+ * Produces textual representaion of the attribute/value pair using
+ * formatting rules defined in RFC 2616
+ *
+ * @param param the parameter to be formatted
+ *
+ * @return RFC 2616 conformant textual representaion of the
+ * attribute/value pair
+ */
+ public String format(final NameValuePair param) {
+ StringBuffer buffer = new StringBuffer();
+ format(buffer, param);
+ return buffer.toString();
+ }
+
+}
Propchange: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterParser.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterParser.java?rev=178662&r1=178661&r2=178662&view=diff
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterParser.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterParser.java Thu May 26 11:21:14 2005
@@ -142,16 +142,19 @@
i1 = pos;
i2 = pos;
boolean quoted = false;
+ boolean charEscaped = false;
while (hasChar()) {
ch = chars[pos];
if (!quoted && isOneOf(ch, terminators)) {
break;
}
- if (ch == '"') {
+ if (!charEscaped && ch == '"') {
quoted = !quoted;
}
+ charEscaped = (!charEscaped && ch == '\\');
i2++;
pos++;
+
}
return getToken(true);
}
Modified: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestNoHost.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestNoHost.java?rev=178662&r1=178661&r2=178662&view=diff
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestNoHost.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestNoHost.java Thu May 26 11:21:14 2005
@@ -64,6 +64,7 @@
suite.addTest(TestRequestHeaders.suite());
suite.addTest(TestStreams.suite());
suite.addTest(TestParameterParser.suite());
+ suite.addTest(TestParameterFormatter.suite());
suite.addTest(TestNVP.suite());
suite.addTest(TestMethodCharEncoding.suite());
suite.addTest(TestHttpVersion.suite());
Added: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java?rev=178662&view=auto
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java (added)
+++ jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java Thu May 26 11:21:14 2005
@@ -0,0 +1,88 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.httpclient;
+
+import org.apache.commons.httpclient.util.ParameterFormatter;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit tests for {@link ParameterFormatter}.
+ *
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ */
+public class TestParameterFormatter extends TestCase {
+
+ // ------------------------------------------------------------ Constructor
+ public TestParameterFormatter(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestParameterFormatter.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestParameterFormatter.class);
+ }
+
+ public void testBasicValueFormatting() throws Exception {
+ ParameterFormatter formatter = new ParameterFormatter();
+
+ NameValuePair param1 = new NameValuePair("param", "regular_stuff");
+ NameValuePair param2 = new NameValuePair("param", "this\\that");
+ NameValuePair param3 = new NameValuePair("param", "this,that");
+ NameValuePair param4 = new NameValuePair("param", "quote marks (\") must be escaped");
+ NameValuePair param5 = new NameValuePair("param", "back slash (\\) must be escaped too");
+ NameValuePair param6 = new NameValuePair("param", "values with\tblanks must always be quoted");
+
+ formatter.setAlwaysUseQuotes(false);
+ assertEquals("param=regular_stuff", formatter.format(param1));
+ assertEquals("param=\"this\\\\that\"", formatter.format(param2));
+ assertEquals("param=\"this,that\"", formatter.format(param3));
+ assertEquals("param=\"quote marks (\\\") must be escaped\"", formatter.format(param4));
+ assertEquals("param=\"back slash (\\\\) must be escaped too\"", formatter.format(param5));
+ assertEquals("param=\"values with\tblanks must always be quoted\"", formatter.format(param6));
+
+ formatter.setAlwaysUseQuotes(true);
+ assertEquals("param=\"regular_stuff\"", formatter.format(param1));
+ assertEquals("param=\"this\\\\that\"", formatter.format(param2));
+ assertEquals("param=\"this,that\"", formatter.format(param3));
+ assertEquals("param=\"quote marks (\\\") must be escaped\"", formatter.format(param4));
+ assertEquals("param=\"back slash (\\\\) must be escaped too\"", formatter.format(param5));
+ assertEquals("param=\"values with\tblanks must always be quoted\"", formatter.format(param6));
+ }
+
+}
Propchange: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterFormatter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterParser.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterParser.java?rev=178662&r1=178661&r2=178662&view=diff
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterParser.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestParameterParser.java Thu May 26 11:21:14 2005
@@ -1,4 +1,7 @@
/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
* ====================================================================
*
* Copyright 1999-2004 The Apache Software Foundation
@@ -21,8 +24,6 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
- * [Additional notices, if required by prior licensing conditions]
- *
*/
package org.apache.commons.httpclient;
@@ -38,7 +39,7 @@
/**
* Unit tests for {@link ParameterParser}.
*
- * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*/
public class TestParameterParser extends TestCase {
@@ -98,4 +99,27 @@
params = parser.parse(s, ';');
assertEquals(0, params.size());
}
+
+ public void testParsingEscapedChars() {
+ String s = "param = \"stuff\\\"; more stuff\"";
+ ParameterParser parser = new ParameterParser();
+ List params = parser.parse(s, ';');
+ assertEquals(1, params.size());
+ assertEquals("param",
+ ((NameValuePair)params.get(0)).getName());
+ assertEquals("stuff\\\"; more stuff",
+ ((NameValuePair)params.get(0)).getValue());
+
+ s = "param = \"stuff\\\\\"; anotherparam";
+ params = parser.parse(s, ';');
+ assertEquals(2, params.size());
+ assertEquals("param",
+ ((NameValuePair)params.get(0)).getName());
+ assertEquals("stuff\\\\",
+ ((NameValuePair)params.get(0)).getValue());
+ assertEquals("anotherparam",
+ ((NameValuePair)params.get(1)).getName());
+ assertNull(
+ ((NameValuePair)params.get(1)).getValue());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org