Index: java/org/apache/commons/httpclient/ChunkedInputStream.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ChunkedInputStream.java,v
retrieving revision 1.16
diff -u -r1.16 ChunkedInputStream.java
--- java/org/apache/commons/httpclient/ChunkedInputStream.java 8 May 2003 17:33:51 -0000 1.16
+++ java/org/apache/commons/httpclient/ChunkedInputStream.java 12 Jul 2003 19:37:06 -0000
@@ -78,8 +78,6 @@
* not requiring the client to remember to read the entire contents of the
* response.
*
- * @see ResponseInputStream
- *
* @author Ortwin Glück
* @author Sean C. Sullivan
* @author Martin Elwin
Index: java/org/apache/commons/httpclient/Header.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Header.java,v
retrieving revision 1.10
diff -u -r1.10 Header.java
--- java/org/apache/commons/httpclient/Header.java 28 Jan 2003 04:40:20 -0000 1.10
+++ java/org/apache/commons/httpclient/Header.java 12 Jul 2003 19:37:07 -0000
@@ -123,9 +123,23 @@
* @see HeaderElement#parse
* @throws HttpException When ? occurs
* @return an array of header elements
+ *
+ * @deprecated Use #getElements
*/
public HeaderElement[] getValues() throws HttpException {
return HeaderElement.parse(getValue());
+ }
+
+ /**
+ * Returns an array of {@link HeaderElement}s
+ * constructed from my value.
+ *
+ * @see HeaderElement#parseElements(String)
+ *
+ * @return an array of header elements
+ */
+ public HeaderElement[] getElements() {
+ return HeaderElement.parseElements(getValue());
}
}
Index: java/org/apache/commons/httpclient/HeaderElement.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HeaderElement.java,v
retrieving revision 1.18
diff -u -r1.18 HeaderElement.java
--- java/org/apache/commons/httpclient/HeaderElement.java 14 Apr 2003 04:06:55 -0000 1.18
+++ java/org/apache/commons/httpclient/HeaderElement.java 12 Jul 2003 19:37:09 -0000
@@ -63,15 +63,13 @@
package org.apache.commons.httpclient;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.util.ParameterParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import java.util.BitSet;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-
/**
* One element of an HTTP header's value.
*
@@ -114,6 +112,7 @@
* @author B.C. Holmes
* @author Park, Sung-Gu
* @author Mike Bowler
+ * @author Oleg Kalnichevski
*
* @since 1.0
* @version $Revision: 1.18 $ $Date: 2003/04/14 04:06:55 $
@@ -148,87 +147,47 @@
public HeaderElement(String name, String value,
NameValuePair[] parameters) {
super(name, value);
- setParameters(parameters);
+ this.parameters = parameters;
}
- // -------------------------------------------------------- Constants
-
- /** Log object for this class. */
- private static final Log LOG = LogFactory.getLog(HeaderElement.class);
-
/**
- * Map of numeric values to whether or not the
- * corresponding character is a "separator
- * character" (tspecial).
- */
- private static final BitSet SEPARATORS = new BitSet(128);
-
- /**
- * Map of numeric values to whether or not the
- * corresponding character is a "token
- * character".
- */
- private static final BitSet TOKEN_CHAR = new BitSet(128);
+ * Constructor with array of characters.
+ *
+ * @param chars the array of characters
+ * @param offset - the initial offset.
+ * @param length - the length.
+ */
+ public HeaderElement(char[] chars, int offset, int length) {
+ this();
+ if (chars == null) {
+ return;
+ }
+ ParameterParser parser = new ParameterParser();
+ List params = parser.parse(chars, offset, length, ';');
+ if (params.size() > 0) {
+ NameValuePair element = (NameValuePair)params.remove(0);
+ setName(element.getName());
+ setValue(element.getValue());
+ if (params.size() > 0) {
+ this.parameters = (NameValuePair[])
+ params.toArray(new NameValuePair[params.size()]);
+ }
+ }
+ }
/**
- * Map of numeric values to whether or not the
- * corresponding character is an "unsafe
- * character".
+ * Constructor with array of characters.
+ *
+ * @param chars the array of characters
*/
- private static final BitSet UNSAFE_CHAR = new BitSet(128);
+ public HeaderElement(char[] chars) {
+ this(chars, 0, chars.length);
+ }
- /**
- * Static initializer for {@link #SEPARATORS},
- * {@link #TOKEN_CHAR}, and {@link #UNSAFE_CHAR}.
- */
- static {
- // rfc-2068 tspecial
- SEPARATORS.set('(');
- SEPARATORS.set(')');
- SEPARATORS.set('<');
- SEPARATORS.set('>');
- SEPARATORS.set('@');
- SEPARATORS.set(',');
- SEPARATORS.set(';');
- SEPARATORS.set(':');
- SEPARATORS.set('\\');
- SEPARATORS.set('"');
- SEPARATORS.set('/');
- SEPARATORS.set('[');
- SEPARATORS.set(']');
- SEPARATORS.set('?');
- SEPARATORS.set('=');
- SEPARATORS.set('{');
- SEPARATORS.set('}');
- SEPARATORS.set(' ');
- SEPARATORS.set('\t');
-
- // rfc-2068 token
- for (int ch = 32; ch < 127; ch++) {
- TOKEN_CHAR.set(ch);
- }
- TOKEN_CHAR.xor(SEPARATORS);
+ // -------------------------------------------------------- Constants
- // rfc-1738 unsafe characters, including CTL and SP, and excluding
- // "#" and "%"
- for (int ch = 0; ch < 32; ch++) {
- UNSAFE_CHAR.set(ch);
- }
- UNSAFE_CHAR.set(' ');
- UNSAFE_CHAR.set('<');
- UNSAFE_CHAR.set('>');
- UNSAFE_CHAR.set('"');
- UNSAFE_CHAR.set('{');
- UNSAFE_CHAR.set('}');
- UNSAFE_CHAR.set('|');
- UNSAFE_CHAR.set('\\');
- UNSAFE_CHAR.set('^');
- UNSAFE_CHAR.set('~');
- UNSAFE_CHAR.set('[');
- UNSAFE_CHAR.set(']');
- UNSAFE_CHAR.set('`');
- UNSAFE_CHAR.set(127);
- }
+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(HeaderElement.class);
// ----------------------------------------------------- Instance Variables
@@ -247,187 +206,91 @@
return this.parameters;
}
- /**
- *
- * @param pairs The new parameters. May be null.
- */
- protected void setParameters(final NameValuePair[] pairs) {
- parameters = pairs;
- }
// --------------------------------------------------------- Public Methods
/**
* This parses the value part of a header. The result is an array of
* HeaderElement objects.
*
- * @param headerValue the string representation of the header value
+ * @param headerValue the array of char representation of the header value
* (as received from the web server).
- * @return the header elements containing Header elements.
- * @throws HttpException if the above syntax rules are violated.
+ * @return array of {@link HeaderElement}s.
*/
- public static final HeaderElement[] parse(String headerValue)
- throws HttpException {
+ public static final HeaderElement[] parseElements(char[] headerValue) {
- LOG.trace("enter HeaderElement.parse(String)");
+ LOG.trace("enter HeaderElement.parseElements(char[])");
if (headerValue == null) {
return null;
}
+ List elements = new ArrayList();
- Vector elements = new Vector();
- StringTokenizer tokenizer =
- new StringTokenizer(headerValue.trim(), ",");
-
- while (tokenizer.countTokens() > 0) {
- String nextToken = tokenizer.nextToken();
-
- // FIXME: refactor into private method named ?
- // careful... there may have been a comma in a quoted string
- try {
- while (HeaderElement.hasOddNumberOfQuotationMarks(nextToken)) {
- nextToken += "," + tokenizer.nextToken();
- }
- } catch (NoSuchElementException exception) {
- throw new HttpException(
- "Bad header format: wrong number of quotation marks");
- }
-
- // FIXME: Refactor out into a private method named ?
- try {
- /*
- * Following to RFC 2109 and 2965, in order not to conflict
- * with the next header element, make it sure to parse tokens.
- * the expires date format is "Wdy, DD-Mon-YY HH:MM:SS GMT".
- * Notice that there is always comma(',') sign.
- * For the general cases, rfc1123-date, rfc850-date.
- */
- if (tokenizer.hasMoreTokens()) {
- String s = nextToken.toLowerCase();
- if (s.endsWith("mon")
- || s.endsWith("tue")
- || s.endsWith("wed")
- || s.endsWith("thu")
- || s.endsWith("fri")
- || s.endsWith("sat")
- || s.endsWith("sun")
- || s.endsWith("monday")
- || s.endsWith("tuesday")
- || s.endsWith("wednesday")
- || s.endsWith("thursday")
- || s.endsWith("friday")
- || s.endsWith("saturday")
- || s.endsWith("sunday")) {
-
- nextToken += "," + tokenizer.nextToken();
- }
- }
- } catch (NoSuchElementException exception) {
- throw new HttpException
- ("Bad header format: parsing with wrong header elements");
- }
-
- String tmp = nextToken.trim();
- if (!tmp.endsWith(";")) {
- tmp += ";";
+ int i = 0;
+ int from = 0;
+ int len = headerValue.length;
+ boolean qouted = false;
+ while(i < len) {
+ char ch = headerValue[i];
+ if (ch == '"') {
+ qouted = !qouted;
}
- char[] header = tmp.toCharArray();
-
- // FIXME: refactor into a private method named? parseElement?
- boolean inAString = false;
- int startPos = 0;
- HeaderElement element = new HeaderElement();
- Vector paramlist = new Vector();
- for (int i = 0 ; i < header.length ; i++) {
- if (header[i] == ';' && !inAString) {
- NameValuePair pair = parsePair(header, startPos, i);
- if (pair == null) {
- throw new HttpException(
- "Bad header format: empty name/value pair in"
- + nextToken);
-
- // the first name/value pair are handled differently
- } else if (startPos == 0) {
- element.setName(pair.getName());
- element.setValue(pair.getValue());
- } else {
- paramlist.addElement(pair);
- }
- startPos = i + 1;
- } else if (header[i] == '"'
- && !(inAString && i > 0 && header[i - 1] == '\\')) {
- inAString = !inAString;
- }
+ HeaderElement element = null;
+ if ((!qouted) && (ch == ',')) {
+ element = new HeaderElement(headerValue, from, i);
+ from = i + 1;
+ } else if (i == len - 1) {
+ element = new HeaderElement(headerValue, from, len);
}
-
- // now let's add all the parameters into the header element
- if (paramlist.size() > 0) {
- NameValuePair[] tmp2 = new NameValuePair[paramlist.size()];
- paramlist.copyInto((NameValuePair[]) tmp2);
- element.setParameters (tmp2);
- paramlist.removeAllElements();
+ if ((element != null) && (element.getName() != null)) {
+ elements.add(element);
}
-
- // and save the header element into the list of header elements
- elements.addElement(element);
+ i++;
}
-
- HeaderElement[] headerElements = new HeaderElement[elements.size()];
- elements.copyInto((HeaderElement[]) headerElements);
- return headerElements;
+ return (HeaderElement[])
+ elements.toArray(new HeaderElement[elements.size()]);
}
/**
- * Return true if string has
- * an odd number of " characters.
+ * This parses the value part of a header. The result is an array of
+ * HeaderElement objects.
*
- * @param string the string to test
- * @return true if there are an odd number of quotation marks, false
- * otherwise
+ * @param headerValue the string representation of the header value
+ * (as received from the web server).
+ * @return array of {@link HeaderElement}s.
+ * @throws HttpException if the above syntax rules are violated.
*/
- private static final boolean hasOddNumberOfQuotationMarks(String string) {
- boolean odd = false;
- int start = -1;
- while ((start = string.indexOf('"', start + 1)) != -1) {
- odd = !odd;
+ public static final HeaderElement[] parseElements(String headerValue) {
+
+ LOG.trace("enter HeaderElement.parseElements(String)");
+
+ if (headerValue == null) {
+ return null;
}
- return odd;
+ return parseElements(headerValue.toCharArray());
}
/**
- * Parse a header character array into a {@link NameValuePair}
+ * This parses the value part of a header. The result is an array of
+ * HeaderElement objects.
*
- * @param header the character array to parse
- * @param start the starting position of the text within the array
- * @param end the end position of the text within the array
- * @return a {@link NameValuePair} representing the header
+ * @param headerValue the string representation of the header value
+ * (as received from the web server).
+ * @return array of {@link HeaderElement}s.
+ * @throws HttpException if the above syntax rules are violated.
+ *
+ * @deprecated Use #parseElements(String).
*/
- private static final NameValuePair parsePair(char[] header,
- int start, int end) {
+ public static final HeaderElement[] parse(String headerValue)
+ throws HttpException {
- LOG.trace("enter HeaderElement.parsePair(char[], int, int)");
+ LOG.trace("enter HeaderElement.parse(String)");
- NameValuePair pair = null;
- String name = new String(header, start, end - start).trim();
- String value = null;
-
- //TODO: This would certainly benefit from a StringBuffer
- int index = name.indexOf("=");
- if (index >= 0) {
- if ((index + 1) < name.length()) {
- value = name.substring(index + 1).trim();
- // strip quotation marks
- if (value.startsWith("\"") && value.endsWith("\"")) {
- value = value.substring(1, value.length() - 1);
- }
- }
- name = name.substring(0, index).trim();
+ if (headerValue == null) {
+ return null;
}
-
- pair = new NameValuePair(name, value);
-
- return pair;
+ return parseElements(headerValue.toCharArray());
}
-
+
/**
* Returns parameter with the given name, if found. Otherwise null
@@ -438,8 +301,11 @@
*/
public NameValuePair getParameterByName(String name) {
+
+ LOG.trace("enter HeaderElement.getParameterByName(String)");
+
if (name == null) {
- throw new NullPointerException("Name is null");
+ throw new IllegalArgumentException("Name may not be null");
}
NameValuePair found = null;
NameValuePair parameters[] = getParameters();
@@ -454,7 +320,6 @@
}
return found;
}
-
}
Index: java/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.164
diff -u -r1.164 HttpMethodBase.java
--- java/org/apache/commons/httpclient/HttpMethodBase.java 11 Jul 2003 01:07:29 -0000 1.164
+++ java/org/apache/commons/httpclient/HttpMethodBase.java 12 Jul 2003 19:37:24 -0000
@@ -2054,7 +2054,7 @@
LOG.warn("Unsupported transfer encoding: " + transferEncoding);
}
}
- HeaderElement[] encodings = transferEncodingHeader.getValues();
+ HeaderElement[] encodings = transferEncodingHeader.getElements();
// The chunked encoding must be the last one applied
// RFC2616, 14.41
int len = encodings.length;
@@ -2655,20 +2655,16 @@
LOG.trace("enter getContentCharSet( Header contentheader )");
String charset = null;
if (contentheader != null) {
- try {
- HeaderElement values[] = contentheader.getValues();
- // I expect only one header element to be there
- // No more. no less
- if (values.length == 1) {
- NameValuePair param = values[0].getParameterByName("charset");
- if (param != null) {
- // If I get anything "funny"
- // UnsupportedEncondingException will result
- charset = param.getValue();
- }
+ HeaderElement values[] = contentheader.getElements();
+ // I expect only one header element to be there
+ // No more. no less
+ if (values.length == 1) {
+ NameValuePair param = values[0].getParameterByName("charset");
+ if (param != null) {
+ // If I get anything "funny"
+ // UnsupportedEncondingException will result
+ charset = param.getValue();
}
- } catch (HttpException e) {
- LOG.error(e);
}
}
if (charset == null) {
Index: java/org/apache/commons/httpclient/HttpState.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpState.java,v
retrieving revision 1.24
diff -u -r1.24 HttpState.java
--- java/org/apache/commons/httpclient/HttpState.java 5 Jul 2003 22:31:20 -0000 1.24
+++ java/org/apache/commons/httpclient/HttpState.java 12 Jul 2003 19:37:27 -0000
@@ -1,5 +1,5 @@
/*
- * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpState.java,v 1.24 2003/07/05 22:31:20 olegk Exp $
+ * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpState.java,v 1.24 2003/07/05 22:31:20 olegk Exp $
* $Revision: 1.24 $
* $Date: 2003/07/05 22:31:20 $
*
@@ -233,7 +233,7 @@
*
* @return an array of my {@link Cookie}s.
*
- * @see #getCookies(String, int, String, boolean, java.util.Date)
+ * @see #getCookies(String, int, String, boolean)
*
*/
public synchronized Cookie[] getCookies() {
@@ -251,9 +251,10 @@
* @param secure true when using HTTPS
* @return an array of my {@link Cookie}s.
*
- * @see Cookie#matches
* @see #getCookies()
*
+ * @deprecated Use {@link CookieSpec#match(String,int,String,boolean,Cookie)}
+ *
*/
public synchronized Cookie[] getCookies(
String domain,
@@ -455,8 +456,8 @@
* @param proxyHost the proxy host
* @param credentials the authentication credentials for the given realm
*
- * @see #getProxyCredentials(String)
- * @see #setCredentials(String, Credentials)
+ * @see #getProxyCredentials(String,String)
+ * @see #setCredentials(String, String, Credentials)
*
*/
public synchronized void setProxyCredentials(
Index: java/org/apache/commons/httpclient/package.html
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/package.html,v
retrieving revision 1.9
diff -u -r1.9 package.html
--- java/org/apache/commons/httpclient/package.html 17 Dec 2002 02:41:38 -0000 1.9
+++ java/org/apache/commons/httpclient/package.html 12 Jul 2003 19:37:28 -0000
@@ -82,12 +82,12 @@
an enumeration of HttpStatus codes.
- {@link org.apache.commons.httpclient.RequestOutputStream}
+ {@link org.apache.commons.httpclient.ChunkedOutputStream}
an {@link java.io.OutputStream} wrapper supporting the "chunked"
transfer encoding.
- {@link org.apache.commons.httpclient.ResponseInputStream}
+ {@link org.apache.commons.httpclient.ChunkedInputStream}
an {@link java.io.InputStream} wrapper supporting the "chunked"
transfer encoding.
Index: java/org/apache/commons/httpclient/auth/AuthChallengeParser.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeParser.java,v
retrieving revision 1.4
diff -u -r1.4 AuthChallengeParser.java
--- java/org/apache/commons/httpclient/auth/AuthChallengeParser.java 6 Apr 2003 22:31:53 -0000 1.4
+++ java/org/apache/commons/httpclient/auth/AuthChallengeParser.java 12 Jul 2003 19:37:29 -0000
@@ -63,8 +63,12 @@
package org.apache.commons.httpclient.auth;
-import java.util.Map;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.util.ParameterParser;
/**
* This class provides utility methods for parsing HTTP www and proxy authentication
@@ -92,12 +96,12 @@
if (challengeStr == null) {
throw new IllegalArgumentException("Challenge may not be null");
}
- int i = challengeStr.indexOf(' ');
+ int idx = challengeStr.indexOf(' ');
String s = null;
- if (i == -1) {
+ if (idx == -1) {
s = challengeStr;
} else {
- s = challengeStr.substring(0, i);
+ s = challengeStr.substring(0, idx);
}
if (s.equals("")) {
throw new MalformedChallengeException("Invalid challenge: " + challengeStr);
@@ -121,114 +125,18 @@
if (challengeStr == null) {
throw new IllegalArgumentException("Challenge may not be null");
}
- int i = challengeStr.indexOf(' ');
- if (i == -1) {
+ int idx = challengeStr.indexOf(' ');
+ if (idx == -1) {
throw new MalformedChallengeException("Invalid challenge: " + challengeStr);
}
-
- Map elements = new HashMap();
-
- i++;
- int len = challengeStr.length();
-
- String name = null;
- String value = null;
-
- StringBuffer buffer = new StringBuffer();
-
- boolean parsingName = true;
- boolean inQuote = false;
- boolean gotIt = false;
-
- while (i < len) {
- // Parse one char at a time
- char ch = challengeStr.charAt(i);
- i++;
- // Process the char
- if (parsingName) {
- // parsing name
- if (ch == '=') {
- name = buffer.toString().trim();
- parsingName = false;
- buffer.setLength(0);
- } else if (ch == ',') {
- name = buffer.toString().trim();
- value = null;
- gotIt = true;
- buffer.setLength(0);
- } else {
- buffer.append(ch);
- }
- // Have I reached the end of the challenge string?
- if (i == len) {
- name = buffer.toString().trim();
- value = null;
- gotIt = true;
- }
- } else {
- //parsing value
- if (!inQuote) {
- // Value is not quoted or not found yet
- if (ch == ',') {
- value = buffer.toString().trim();
- gotIt = true;
- buffer.setLength(0);
- } else {
- // no value yet
- if (buffer.length() == 0) {
- if (ch == ' ') {
- //discard
- } else if (ch == '\t') {
- //discard
- } else if (ch == '\n') {
- //discard
- } else if (ch == '\r') {
- //discard
- } else {
- // otherwise add to the buffer
- buffer.append(ch);
- if (ch == '"') {
- inQuote = true;
- }
- }
- } else {
- // already got something
- // just keep on adding to the buffer
- buffer.append(ch);
- }
- }
- } else {
- // Value is quoted
- // Keep on adding until closing quote is encountered
- buffer.append(ch);
- if (ch == '"') {
- inQuote = false;
- }
- }
- // Have I reached the end of the challenge string?
- if (i == len) {
- value = buffer.toString().trim();
- gotIt = true;
- }
- }
- if (gotIt) {
- // Got something
- if ((name == null) || (name.equals(""))) {
- throw new MalformedChallengeException("Invalid challenge: " + challengeStr);
- }
- // Strip quotes when present
- if ((value != null) && (value.length() > 1)) {
- if ((value.charAt(0) == '"')
- && (value.charAt(value.length() - 1) == '"')) {
- value = value.substring(1, value.length() - 1);
- }
- }
-
- elements.put(name, value);
- parsingName = true;
- gotIt = false;
- }
+ Map map = new HashMap();
+ ParameterParser parser = new ParameterParser();
+ List params = parser.parse(
+ challengeStr.substring(idx + 1, challengeStr.length()), ',');
+ for (int i = 0; i < params.size(); i++) {
+ NameValuePair param = (NameValuePair)params.get(i);
+ map.put(param.getName().toLowerCase(), param.getValue());
}
- return elements;
+ return map;
}
}
Index: java/org/apache/commons/httpclient/auth/HttpAuthenticator.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthenticator.java,v
retrieving revision 1.7
diff -u -r1.7 HttpAuthenticator.java
--- java/org/apache/commons/httpclient/auth/HttpAuthenticator.java 26 May 2003 22:07:22 -0000 1.7
+++ java/org/apache/commons/httpclient/auth/HttpAuthenticator.java 12 Jul 2003 19:37:31 -0000
@@ -261,7 +261,7 @@
*
* @throws AuthenticationException when a parsing or other error occurs
- * @see HttpState#setCredentials(String,Credentials)
+ * @see HttpState#setCredentials(String,String,Credentials)
*/
public static boolean authenticateProxyDefault(
HttpMethod method,
@@ -342,7 +342,7 @@
*
* @throws AuthenticationException when a parsing or other error occurs
- * @see HttpState#setCredentials(String,Credentials)
+ * @see HttpState#setCredentials(String,String,Credentials)
*/
public static boolean authenticate(
AuthScheme authscheme,
@@ -374,7 +374,7 @@
*
* @throws AuthenticationException when a parsing or other error occurs
- * @see HttpState#setCredentials(String,Credentials)
+ * @see HttpState#setCredentials(String,String,Credentials)
*/
public static boolean authenticateProxy(
AuthScheme authscheme,
Index: java/org/apache/commons/httpclient/cookie/CookieSpecBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v
retrieving revision 1.16
diff -u -r1.16 CookieSpecBase.java
--- java/org/apache/commons/httpclient/cookie/CookieSpecBase.java 12 Jun 2003 19:12:16 -0000 1.16
+++ java/org/apache/commons/httpclient/cookie/CookieSpecBase.java 12 Jul 2003 19:37:35 -0000
@@ -1,5 +1,5 @@
/*
- * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v 1.16 2003/06/12 19:12:16 olegk Exp $
+ * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v 1.16 2003/06/12 19:12:16 olegk Exp $
* $Revision: 1.16 $
* $Date: 2003/06/12 19:12:16 $
*
@@ -70,7 +70,6 @@
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HeaderElement;
-import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.util.DateParseException;
import org.apache.commons.httpclient.util.DateParser;
@@ -166,14 +165,7 @@
path = PATH_DELIM;
}
host = host.toLowerCase();
-
- HeaderElement[] headerElements = null;
- try {
- headerElements = HeaderElement.parse(header);
- } catch (HttpException e) {
- throw new MalformedCookieException(e.getMessage());
- }
-
+
String defaultPath = path;
int lastSlashIndex = defaultPath.lastIndexOf(PATH_DELIM);
if (lastSlashIndex >= 0) {
@@ -183,6 +175,31 @@
}
defaultPath = defaultPath.substring(0, lastSlashIndex);
}
+
+ HeaderElement[] headerElements = null;
+
+ boolean isNetscapeCookie = false;
+ int i1 = header.toLowerCase().indexOf("expires=");
+ if (i1 != -1) {
+ i1 += "expires=".length();
+ int i2 = header.indexOf(";", i1);
+ if (i2 == -1) {
+ i2 = header.length();
+ }
+ try {
+ DateParser.parseDate(header.substring(i1, i2));
+ isNetscapeCookie = true;
+ } catch(DateParseException e) {
+ // Does not look like a valid expiry date
+ }
+ }
+ if (isNetscapeCookie) {
+ headerElements = new HeaderElement[] {
+ new HeaderElement(header.toCharArray())
+ };
+ } else {
+ headerElements = HeaderElement.parseElements(header.toCharArray());
+ }
Cookie[] cookies = new Cookie[headerElements.length];
@@ -330,14 +347,6 @@
if (paramValue == null) {
throw new MalformedCookieException(
"Missing value for expires attribute");
- }
- // trim single quotes around expiry if present
- // see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5279
- if (paramValue.length() > 1
- && paramValue.startsWith("'")
- && paramValue.endsWith("'")) {
- paramValue
- = paramValue.substring (1, paramValue.length() - 1);
}
try {
Index: java/org/apache/commons/httpclient/util/DateParser.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/DateParser.java,v
retrieving revision 1.3
diff -u -r1.3 DateParser.java
--- java/org/apache/commons/httpclient/util/DateParser.java 26 May 2003 21:51:37 -0000 1.3
+++ java/org/apache/commons/httpclient/util/DateParser.java 12 Jul 2003 19:37:37 -0000
@@ -144,6 +144,15 @@
if (dateValue == null) {
throw new IllegalArgumentException("dateValue is null");
}
+
+ // trim single quotes around date if present
+ // see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5279
+ if (dateValue.length() > 1
+ && dateValue.startsWith("'")
+ && dateValue.endsWith("'"))
+ {
+ dateValue = dateValue.substring (1, dateValue.length() - 1);
+ }
SimpleDateFormat dateParser = null;
Index: java/org/apache/commons/httpclient/util/ParameterParser.java
===================================================================
RCS file: java/org/apache/commons/httpclient/util/ParameterParser.java
diff -N java/org/apache/commons/httpclient/util/ParameterParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/util/ParameterParser.java 12 Jul 2003 19:37:38 -0000
@@ -0,0 +1,261 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.NameValuePair;
+
+/**
+ * A simple parser intended to parse sequences of name/value pairs.
+ * Parameter values are exptected to be enclosed in quotes if they
+ * contain unsafe characters, such as '=' characters or separators.
+ * Parameter values are optional and can be omitted.
+ *
+ *
+ * param1 = value; param2 = "anything goes; really"; param3
+ *
+ *
+ * @author Oleg Kalnichevski
+ */
+
+public class ParameterParser {
+
+ /** String to be parsed */
+ private char[] chars = null;
+
+ /** Current position in the string */
+ private int pos = 0;
+
+ /** Maximum position in the string */
+ private int len = 0;
+
+ /** Start of a token */
+ private int i1 = 0;
+
+ /** End of a token */
+ private int i2 = 0;
+
+ /** Default ParameterParser constructor */
+ public ParameterParser() {
+ super();
+ }
+
+
+ /** Are there any characters left to parse? */
+ private boolean hasChar() {
+ return this.pos < this.len;
+ }
+
+
+ /** A helper method to process the parsed token. */
+ private String getToken(boolean quoted) {
+ // Trim leading white spaces
+ while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) {
+ i1++;
+ }
+ // Trim trailing white spaces
+ while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) {
+ i2--;
+ }
+ // Strip away quotes if necessary
+ if (quoted) {
+ if (((i2 - i1) >= 2) &&
+ (chars[i1] == '"') &&
+ (chars[i2 - 1] == '"') ) {
+ i1++;
+ i2--;
+ }
+ }
+ String result = null;
+ if (i2 > i1) {
+ result = new String(chars, i1, i2 - i1);
+ }
+ return result;
+ }
+
+
+ /** Is given character present in the array of characters? */
+ private boolean isOneOf(char ch, char[] charray) {
+ boolean result = false;
+ for (int i = 0; i < charray.length; i ++) {
+ if (ch == charray[i]) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+
+ /** Parse out a token until any of the given terminators
+ * is encountered. */
+ private String parseToken(final char[] terminators) {
+ char ch;
+ i1 = pos;
+ i2 = pos;
+ while (hasChar()) {
+ ch = chars[pos];
+ if (isOneOf(ch, terminators)) {
+ break;
+ }
+ i2++;
+ pos++;
+ }
+ return getToken(false);
+ }
+
+
+ /** Parse out a token until any of the given terminators
+ * is encountered. Special characters in quoted tokens
+ * are escaped. */
+ private String parseQuotedToken(final char[] terminators) {
+ char ch;
+ i1 = pos;
+ i2 = pos;
+ boolean quoted = false;
+ while (hasChar()) {
+ ch = chars[pos];
+ if (!quoted && isOneOf(ch, terminators)) {
+ break;
+ }
+ if (ch == '"') {
+ quoted = !quoted;
+ }
+ i2++;
+ pos++;
+ }
+ return getToken(true);
+ }
+
+ /**
+ * Extracts a list of {@link NameValuePair}s from the given string.
+ *
+ * @param str the string that contains a sequence of name/value pairs
+ * @return a list of {@link NameValuePair}s
+ *
+ */
+ public List parse(final String str, char separator) {
+
+ if (str == null) {
+ return null;
+ }
+ return parse(str.toCharArray(), separator);
+ }
+
+ /**
+ * Extracts a list of {@link NameValuePair}s from the given array of
+ * characters.
+ *
+ * @param chars the array of characters that contains a sequence of
+ * name/value pairs
+ *
+ * @return a list of {@link NameValuePair}s
+ */
+ public List parse(final char[] chars, char separator) {
+
+ if (chars == null) {
+ return null;
+ }
+ return parse(chars, 0, chars.length, separator);
+ }
+
+
+ /**
+ * Extracts a list of {@link NameValuePair}s from the given array of
+ * characters.
+ *
+ * @param chars the array of characters that contains a sequence of
+ * name/value pairs
+ * @param offset - the initial offset.
+ * @param length - the length.
+ *
+ * @return a list of {@link NameValuePair}s
+ */
+ public List parse(final char[] chars, int offset, int length, char separator) {
+
+ if (chars == null) {
+ return null;
+ }
+ List params = new ArrayList();
+ this.chars = chars;
+ this.pos = offset;
+ this.len = length;
+
+ String paramName = null;
+ String paramValue = null;
+ boolean done = false;
+ while (hasChar()) {
+ paramName = parseToken(new char[] {'=', separator});
+ paramValue = null;
+ if (hasChar() && (chars[pos] == '=')) {
+ pos++; // skip '='
+ paramValue = parseQuotedToken(new char[] {separator});
+ }
+ if (hasChar() && (chars[pos] == separator)) {
+ pos++; // skip separator
+ }
+ if ((paramName != null) && (paramName.length() > 0)) {
+ params.add(new NameValuePair(paramName, paramValue));
+ }
+ }
+ return params;
+ }
+}
Index: test/org/apache/commons/httpclient/TestHeaderElement.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHeaderElement.java,v
retrieving revision 1.5
diff -u -r1.5 TestHeaderElement.java
--- test/org/apache/commons/httpclient/TestHeaderElement.java 28 Jan 2003 04:40:23 -0000 1.5
+++ test/org/apache/commons/httpclient/TestHeaderElement.java 12 Jul 2003 19:37:39 -0000
@@ -70,6 +70,7 @@
* @author Rodney Waldhoff
* @author B.C. Holmes
* @author Park, Sung-Gu
+ * @author oleg Kalnichevski
* @version $Id: TestHeaderElement.java,v 1.5 2003/01/28 04:40:23 jsdever Exp $
*/
public class TestHeaderElement extends TestNVP {
@@ -108,7 +109,7 @@
// this is derived from the old main method in HeaderElement
String headerValue = "name1 = value1; name2; name3=\"value3\" , name4=value4; " +
"name5=value5, name6= ; name7 = value7; name8 = \" value8\"";
- HeaderElement[] elements = HeaderElement.parse(headerValue);
+ HeaderElement[] elements = HeaderElement.parseElements(headerValue);
// there are 3 elements
assertEquals(3,elements.length);
// 1st element
@@ -129,12 +130,32 @@
assertEquals("value5",elements[1].getParameters()[0].getValue());
// 3rd element
assertEquals("name6",elements[2].getName());
- assertTrue(null == elements[2].getValue());
+ assertEquals(null,elements[2].getValue());
// 3rd element has 2 getParameters()
assertEquals(2,elements[2].getParameters().length);
assertEquals("name7",elements[2].getParameters()[0].getName());
assertEquals("value7",elements[2].getParameters()[0].getValue());
assertEquals("name8",elements[2].getParameters()[1].getName());
assertEquals(" value8",elements[2].getParameters()[1].getValue());
+ }
+
+ public void testFringeCase1() throws Exception {
+ String headerValue = "name1 = value1,";
+ HeaderElement[] elements = HeaderElement.parseElements(headerValue);
+ assertEquals("Number of elements", 1, elements.length);
+ }
+
+
+ public void testFringeCase2() throws Exception {
+ String headerValue = "name1 = value1, ";
+ HeaderElement[] elements = HeaderElement.parseElements(headerValue);
+ assertEquals("Number of elements", 1, elements.length);
+ }
+
+
+ public void testFringeCase3() throws Exception {
+ String headerValue = ",, ,, ,";
+ HeaderElement[] elements = HeaderElement.parseElements(headerValue);
+ assertEquals("Number of elements", 0, elements.length);
}
}
Index: test/org/apache/commons/httpclient/TestNoHost.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v
retrieving revision 1.22
diff -u -r1.22 TestNoHost.java
--- test/org/apache/commons/httpclient/TestNoHost.java 17 Apr 2003 11:34:19 -0000 1.22
+++ test/org/apache/commons/httpclient/TestNoHost.java 12 Jul 2003 19:37:40 -0000
@@ -87,6 +87,7 @@
suite.addTest(TestCookie.suite());
suite.addTest(TestNVP.suite());
suite.addTest(TestHeader.suite());
+ suite.addTest(TestParameterParser.suite());
suite.addTest(TestHeaderElement.suite());
suite.addTest(TestChallengeParser.suite());
suite.addTest(TestAuthenticator.suite());
Index: test/org/apache/commons/httpclient/TestParameterParser.java
===================================================================
RCS file: test/org/apache/commons/httpclient/TestParameterParser.java
diff -N test/org/apache/commons/httpclient/TestParameterParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/org/apache/commons/httpclient/TestParameterParser.java 12 Jul 2003 19:37:41 -0000
@@ -0,0 +1,133 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.List;
+
+import org.apache.commons.httpclient.util.ParameterParser;
+
+/**
+ * Unit tests for {@link ParameterParser}.
+ *
+ * @author Oleg Kalnichevski
+ */
+public class TestParameterParser extends TestCase {
+
+ // ------------------------------------------------------------ Constructor
+ public TestParameterParser(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestParameterParser.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestParameterParser.class);
+ }
+
+
+ public void testParsing() {
+ String s =
+ "test; test1 = stuff ; test2 = \"stuff; stuff\"; test3=\"stuff";
+ ParameterParser parser = new ParameterParser();
+ List params = parser.parse(s, ';');
+ assertEquals("test", ((NameValuePair)params.get(0)).getName());
+ assertEquals(null, ((NameValuePair)params.get(0)).getValue());
+ assertEquals("test1", ((NameValuePair)params.get(1)).getName());
+ assertEquals("stuff", ((NameValuePair)params.get(1)).getValue());
+ assertEquals("test2", ((NameValuePair)params.get(2)).getName());
+ assertEquals("stuff; stuff", ((NameValuePair)params.get(2)).getValue());
+ assertEquals("test3", ((NameValuePair)params.get(3)).getName());
+ assertEquals("\"stuff", ((NameValuePair)params.get(3)).getValue());
+
+ s = " test , test1=stuff , , test2=, test3, ";
+ params = parser.parse(s, ',');
+ assertEquals("test", ((NameValuePair)params.get(0)).getName());
+ assertEquals(null, ((NameValuePair)params.get(0)).getValue());
+ assertEquals("test1", ((NameValuePair)params.get(1)).getName());
+ assertEquals("stuff", ((NameValuePair)params.get(1)).getValue());
+ assertEquals("test2", ((NameValuePair)params.get(2)).getName());
+ assertEquals(null, ((NameValuePair)params.get(2)).getValue());
+ assertEquals("test3", ((NameValuePair)params.get(3)).getName());
+ assertEquals(null, ((NameValuePair)params.get(3)).getValue());
+
+ s = " test";
+ params = parser.parse(s, ';');
+ assertEquals("test", ((NameValuePair)params.get(0)).getName());
+ assertEquals(null, ((NameValuePair)params.get(0)).getValue());
+
+ s = " ";
+ params = parser.parse(s, ';');
+ assertEquals(0, params.size());
+
+ s = " = stuff ";
+ params = parser.parse(s, ';');
+ assertEquals(0, params.size());
+ }
+}