Index: 3rdParty_sources/versions.txt
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v
diff -u -r1.1 -r1.2
--- 3rdParty_sources/versions.txt 17 Aug 2012 15:17:21 -0000 1.1
+++ 3rdParty_sources/versions.txt 22 Aug 2012 17:30:39 -0000 1.2
@@ -9,6 +9,8 @@
CKEditor 3.6.2
+Commons HttpClient 3.0
+
Hibernate Core 3.3.1 GA
jbosscache 3.1.0.CR1
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/AutoCloseInputStream.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/AutoCloseInputStream.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/AutoCloseInputStream.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,185 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/AutoCloseInputStream.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * len
bytes of data from the stream.
+ *
+ * @param b a byte
array to read data into
+ * @param off an offset within the array to store data
+ * @param len the maximum number of bytes to read
+ * @return the number of bytes read or -1 for EOF
+ * @throws IOException if there are errors reading
+ */
+ public int read(byte[] b, int off, int len) throws IOException {
+ int l = -1;
+
+ if (isReadAllowed()) {
+ l = super.read(b, off, len);
+ checkClose(l);
+ }
+
+ return l;
+ }
+
+ /**
+ * Reads some number of bytes from the input stream and stores them into the
+ * buffer array b.
+ *
+ * @param b a byte
array to read data into
+ * @return the number of bytes read or -1 for EOF
+ * @throws IOException if there are errors reading
+ */
+ public int read(byte[] b) throws IOException {
+ int l = -1;
+
+ if (isReadAllowed()) {
+ l = super.read(b);
+ checkClose(l);
+ }
+ return l;
+ }
+
+ /**
+ * Close the stream, and also close the underlying stream if it is not
+ * already closed.
+ * @throws IOException If an IO problem occurs.
+ */
+ public void close() throws IOException {
+ if (!selfClosed) {
+ selfClosed = true;
+ notifyWatcher();
+ }
+ }
+
+ /**
+ * Close the underlying stream should the end of the stream arrive.
+ *
+ * @param readResult The result of the read operation to check.
+ * @throws IOException If an IO problem occurs.
+ */
+ private void checkClose(int readResult) throws IOException {
+ if (readResult == -1) {
+ notifyWatcher();
+ }
+ }
+
+ /**
+ * See whether a read of the underlying stream should be allowed, and if
+ * not, check to see whether our stream has already been closed!
+ *
+ * @return true
if it is still OK to read from the stream.
+ * @throws IOException If an IO problem occurs.
+ */
+ private boolean isReadAllowed() throws IOException {
+ if (!streamOpen && selfClosed) {
+ throw new IOException("Attempted read on closed stream.");
+ }
+ return streamOpen;
+ }
+
+ /**
+ * Notify the watcher that the contents have been consumed.
+ * @throws IOException If an IO problem occurs.
+ */
+ private void notifyWatcher() throws IOException {
+ if (streamOpen) {
+ super.close();
+ streamOpen = false;
+
+ if (watcher != null) {
+ watcher.responseConsumed();
+ }
+ }
+ }
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedInputStream.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedInputStream.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedInputStream.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,372 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedInputStream.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ *
Transparently coalesces chunks of a HTTP stream that uses + * Transfer-Encoding chunked.
+ * + *Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, it will read until the "end" of its chunking on close, + * which allows for the seamless invocation of subsequent HTTP 1.1 calls, while + * not requiring the client to remember to read the entire contents of the + * response.
+ * + * @author Ortwin Glueck + * @author Sean C. Sullivan + * @author Martin Elwin + * @author Eric Johnson + * @author Mike Bowler + * @author Michael Becke + * @author Oleg Kalnichevski + * + * @since 2.0 + * + */ +public class ChunkedInputStream extends InputStream { + /** The inputstream that we're wrapping */ + private InputStream in; + + /** The chunk size */ + private int chunkSize; + + /** The current position within the current chunk */ + private int pos; + + /** True if we'are at the beginning of stream */ + private boolean bof = true; + + /** True if we've reached the end of stream */ + private boolean eof = false; + + /** True if this stream is closed */ + private boolean closed = false; + + /** The method that this stream came from */ + private HttpMethod method = null; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(ChunkedInputStream.class); + + /** + * ChunkedInputStream constructor that associates the chunked input stream with a + * {@link HttpMethod HTTP method}. Usually it should be the same {@link HttpMethod + * HTTP method} the chunked input stream originates from. If chunked input stream + * contains any footers (trailing headers), they will be added to the associated + * {@link HttpMethod HTTP method}. + * + * @param in the raw input stream + * @param method the HTTP method to associate this input stream with. Can be null. + * + * @throws IOException If an IO error occurs + */ + public ChunkedInputStream( + final InputStream in, final HttpMethod method) throws IOException { + + if (in == null) { + throw new IllegalArgumentException("InputStream parameter may not be null"); + } + this.in = in; + this.method = method; + this.pos = 0; + } + + /** + * ChunkedInputStream constructor + * + * @param in the raw input stream + * + * @throws IOException If an IO error occurs + */ + public ChunkedInputStream(final InputStream in) throws IOException { + this(in, null); + } + + /** + *Returns all the data in a chunked stream in coalesced form. A chunk + * is followed by a CRLF. The method returns -1 as soon as a chunksize of 0 + * is detected.
+ * + *Trailer headers are read automcatically at the end of the stream and + * can be obtained with the getResponseFooters() method.
+ * + * @return -1 of the end of the stream has been reached or the next data + * byte + * @throws IOException If an IO problem occurs + * + * @see HttpMethod#getResponseFooters() + */ + public int read() throws IOException { + + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + if (eof) { + return -1; + } + if (pos >= chunkSize) { + nextChunk(); + if (eof) { + return -1; + } + } + pos++; + return in.read(); + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @param off The offset into the byte array at which bytes will start to be + * placed. + * @param len the maximum number of bytes that can be returned. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @see java.io.InputStream#read(byte[], int, int) + * @throws IOException if an IO problem occurs. + */ + public int read (byte[] b, int off, int len) throws IOException { + + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (eof) { + return -1; + } + if (pos >= chunkSize) { + nextChunk(); + if (eof) { + return -1; + } + } + len = Math.min(len, chunkSize - pos); + int count = in.read(b, off, len); + pos += count; + return count; + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @see java.io.InputStream#read(byte[]) + * @throws IOException if an IO problem occurs. + */ + public int read (byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Read the CRLF terminator. + * @throws IOException If an IO error occurs. + */ + private void readCRLF() throws IOException { + int cr = in.read(); + int lf = in.read(); + if ((cr != '\r') || (lf != '\n')) { + throw new IOException( + "CRLF expected at end of chunk: " + cr + "/" + lf); + } + } + + + /** + * Read the next chunk. + * @throws IOException If an IO error occurs. + */ + private void nextChunk() throws IOException { + if (!bof) { + readCRLF(); + } + chunkSize = getChunkSizeFromInputStream(in); + bof = false; + pos = 0; + if (chunkSize == 0) { + eof = true; + parseTrailerHeaders(); + } + } + + /** + * Expects the stream to start with a chunksize in hex with optional + * comments after a semicolon. The line must end with a CRLF: "a3; some + * comment\r\n" Positions the stream at the start of the next line. + * + * @param in The new input stream. + * @param required true if a valid chunk must be present, + * false otherwise. + * + * @return the chunk size as integer + * + * @throws IOException when the chunk size could not be parsed + */ + private static int getChunkSizeFromInputStream(final InputStream in) + throws IOException { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // States: 0=normal, 1=\r was scanned, 2=inside quoted string, -1=end + int state = 0; + while (state != -1) { + int b = in.read(); + if (b == -1) { + throw new IOException("chunked stream ended unexpectedly"); + } + switch (state) { + case 0: + switch (b) { + case '\r': + state = 1; + break; + case '\"': + state = 2; + /* fall through */ + default: + baos.write(b); + } + break; + + case 1: + if (b == '\n') { + state = -1; + } else { + // this was not CRLF + throw new IOException("Protocol violation: Unexpected" + + " single newline character in chunk size"); + } + break; + + case 2: + switch (b) { + case '\\': + b = in.read(); + baos.write(b); + break; + case '\"': + state = 0; + /* fall through */ + default: + baos.write(b); + } + break; + default: throw new RuntimeException("assertion failed"); + } + } + + //parse data + String dataString = EncodingUtil.getAsciiString(baos.toByteArray()); + int separator = dataString.indexOf(';'); + dataString = (separator > 0) + ? dataString.substring(0, separator).trim() + : dataString.trim(); + + int result; + try { + result = Integer.parseInt(dataString.trim(), 16); + } catch (NumberFormatException e) { + throw new IOException ("Bad chunk size: " + dataString); + } + return result; + } + + /** + * Reads and stores the Trailer headers. + * @throws IOException If an IO problem occurs + */ + private void parseTrailerHeaders() throws IOException { + Header[] footers = null; + try { + String charset = "US-ASCII"; + if (this.method != null) { + charset = this.method.getParams().getHttpElementCharset(); + } + footers = HttpParser.parseHeaders(in, charset); + } catch(HttpException e) { + LOG.error("Error parsing trailer headers", e); + IOException ioe = new IOException(e.getMessage()); + ExceptionUtil.initCause(ioe, e); + throw ioe; + } + if (this.method != null) { + for (int i = 0; i < footers.length; i++) { + this.method.addResponseFooter(footers[i]); + } + } + } + + /** + * Upon close, this reads the remainder of the chunked message, + * leaving the underlying socket at a position to start reading the + * next response without scanning. + * @throws IOException If an IO problem occurs. + */ + public void close() throws IOException { + if (!closed) { + try { + if (!eof) { + exhaustInputStream(this); + } + } finally { + eof = true; + closed = true; + } + } + } + + /** + * Exhaust an input stream, reading until EOF has been encountered. + * + *Note that this function is intended as a non-public utility. + * This is a little weird, but it seemed silly to make a utility + * class for this one function, so instead it is just static and + * shared that way.
+ * + * @param inStream The {@link InputStream} to exhaust. + * @throws IOException If an IO problem occurs + */ + static void exhaustInputStream(InputStream inStream) throws IOException { + // read and discard the remainder of the message + byte buffer[] = new byte[1024]; + while (inStream.read(buffer) >= 0) { + ; + } + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedOutputStream.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,201 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedOutputStream.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *+ * This implementation adds User-Agent, Host, + * and Proxy-Authorization headers, when appropriate. + *
+ * + * @param state the client state + * @param conn the {@link HttpConnection} the headers will eventually be + * written to + * @throws IOException when an error occurs writing the request + * @throws HttpException when a HTTP protocol error occurs + * + * @see #writeRequestHeaders + */ + protected void addRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter ConnectMethod.addRequestHeaders(HttpState, " + + "HttpConnection)"); + addUserAgentRequestHeader(state, conn); + addHostRequestHeader(state, conn); + addProxyConnectionHeader(state, conn); + } + + /** + * Execute this method and create a tunneled HttpConnection. If the method + * is successful (i.e. the status is a 2xx) tunnelCreated() will be called + * on the connection. + * + * @param state the current http state + * @param conn the connection to write to + * @return the http status code from execution + * @throws HttpException when an error occurs writing the headers + * @throws IOException when an error occurs writing the headers + * + * @see HttpConnection#tunnelCreated() + */ + public int execute(HttpState state, HttpConnection conn) + throws IOException, HttpException { + + LOG.trace("enter ConnectMethod.execute(HttpState, HttpConnection)"); + int code = super.execute(state, conn); + if (LOG.isDebugEnabled()) { + LOG.debug("CONNECT status code " + code); + } + return code; + } + + /** + * Special Connect request. + * + * @param state the current http state + * @param conn the connection to write to + * @throws IOException when an error occurs writing the request + * @throws HttpException when an error occurs writing the request + */ + protected void writeRequestLine(HttpState state, HttpConnection conn) + throws IOException, HttpException { + int port = conn.getPort(); + if (port == -1) { + port = conn.getProtocol().getDefaultPort(); + } + StringBuffer buffer = new StringBuffer(); + buffer.append(getName()); + buffer.append(' '); + buffer.append(conn.getHost()); + if (port > -1) { + buffer.append(':'); + buffer.append(port); + } + buffer.append(" "); + buffer.append(getEffectiveVersion()); + String line = buffer.toString(); + conn.printLine(line, getParams().getHttpElementCharset()); + if (Wire.HEADER_WIRE.enabled()) { + Wire.HEADER_WIRE.output(line); + } + } + + /** + * Returnstrue
if the status code is anything other than
+ * SC_OK, false
otherwise.
+ *
+ * @see HttpMethodBase#shouldCloseConnection(HttpConnection)
+ * @see HttpStatus#SC_OK
+ *
+ * @return true
if the connection should be closed
+ */
+ protected boolean shouldCloseConnection(HttpConnection conn) {
+ if (getStatusCode() == HttpStatus.SC_OK) {
+ Header connectionHeader = null;
+ if (!conn.isTransparent()) {
+ connectionHeader = getResponseHeader("proxy-connection");
+ }
+ if (connectionHeader == null) {
+ connectionHeader = getResponseHeader("connection");
+ }
+ if (connectionHeader != null) {
+ if (connectionHeader.getValue().equalsIgnoreCase("close")) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Invalid header encountered '" + connectionHeader.toExternalForm()
+ + "' in response " + getStatusLine().toString());
+ }
+ }
+ }
+ return false;
+ } else {
+ return super.shouldCloseConnection(conn);
+ }
+ }
+
+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(ConnectMethod.class);
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectTimeoutException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectTimeoutException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectTimeoutException.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,75 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectTimeoutException.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * Implementation note: Choices abound. One approach would pass + * through the {@link InputStream#mark} and {@link InputStream#reset} calls to + * the underlying stream. That's tricky, though, because you then have to + * start duplicating the work of keeping track of how much a reset rewinds. + * Further, you have to watch out for the "readLimit", and since the semantics + * for the readLimit leave room for differing implementations, you might get + * into a lot of trouble.
+ * + *Alternatively, you could make this class extend {@link java.io.BufferedInputStream} + * and then use the protected members of that class to avoid duplicated effort. + * That solution has the side effect of adding yet another possible layer of + * buffering.
+ * + *Then, there is the simple choice, which this takes - simply don't + * support {@link InputStream#mark} and {@link InputStream#reset}. That choice + * has the added benefit of keeping this class very simple.
+ * + * @author Ortwin Glueck + * @author Eric Johnson + * @author Mike Bowler + * @since 2.0 + */ +public class ContentLengthInputStream extends InputStream { + + /** + * The maximum number of bytes that can be read from the stream. Subsequent + * read operations will return -1. + */ + private long contentLength; + + /** The current position */ + private long pos = 0; + + /** True if the stream is closed. */ + private boolean closed = false; + + /** + * Wrapped input stream that all calls are delegated to. + */ + private InputStream wrappedStream = null; + + /** + * @deprecated use {@link #ContentLengthInputStream(InputStream, long)} + * + * Creates a new length limited stream + * + * @param in The stream to wrap + * @param contentLength The maximum number of bytes that can be read from + * the stream. Subsequent read operations will return -1. + */ + public ContentLengthInputStream(InputStream in, int contentLength) { + this(in, (long)contentLength); + } + + /** + * Creates a new length limited stream + * + * @param in The stream to wrap + * @param contentLength The maximum number of bytes that can be read from + * the stream. Subsequent read operations will return -1. + * + * @since 3.0 + */ + public ContentLengthInputStream(InputStream in, long contentLength) { + super(); + this.wrappedStream = in; + this.contentLength = contentLength; + } + + /** + *Reads until the end of the known length of content.
+ * + *Does not close the underlying socket input, but instead leaves it + * primed to parse the next response.
+ * @throws IOException If an IO problem occurs. + */ + public void close() throws IOException { + if (!closed) { + try { + ChunkedInputStream.exhaustInputStream(this); + } finally { + // close after above so that we don't throw an exception trying + // to read after closed! + closed = true; + } + } + } + + + /** + * Read the next byte from the stream + * @return The next byte or -1 if the end of stream has been reached. + * @throws IOException If an IO problem occurs + * @see java.io.InputStream#read() + */ + public int read() throws IOException { + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (pos >= contentLength) { + return -1; + } + pos++; + return this.wrappedStream.read(); + } + + /** + * Does standard {@link InputStream#read(byte[], int, int)} behavior, but + * also notifies the watcher when the contents have been consumed. + * + * @param b The byte array to fill. + * @param off Start filling at this position. + * @param len The number of bytes to attempt to read. + * @return The number of bytes read, or -1 if the end of content has been + * reached. + * + * @throws java.io.IOException Should an error occur on the wrapped stream. + */ + public int read (byte[] b, int off, int len) throws java.io.IOException { + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (pos >= contentLength) { + return -1; + } + + if (pos + len > contentLength) { + len = (int) (contentLength - pos); + } + int count = this.wrappedStream.read(b, off, len); + pos += count; + return count; + } + + + /** + * Read more bytes from the stream. + * @param b The byte array to put the new data in. + * @return The number of bytes read into the buffer. + * @throws IOException If an IO problem occurs + * @see java.io.InputStream#read(byte[]) + */ + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Skips and discards a number of bytes from the input stream. + * @param n The number of bytes to skip. + * @return The actual number of bytes skipped. <= 0 if no bytes + * are skipped. + * @throws IOException If an error occurs while skipping bytes. + * @see InputStream#skip(long) + */ + public long skip(long n) throws IOException { + // make sure we don't skip more bytes than are + // still available + long length = Math.min(n, contentLength - pos); + // skip and keep track of the bytes actually skipped + length = this.wrappedStream.skip(length); + // only add the skipped bytes to the current position + // if bytes were actually skipped + if (length > 0) { + pos += length; + } + return length; + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Cookie.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Cookie.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Cookie.java 22 Aug 2012 17:30:33 -0000 1.1 @@ -0,0 +1,545 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Cookie.java,v 1.1 2012/08/22 17:30:33 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:33 $ + * + * ==================================================================== + * + * 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 "magic-cookie" represents a piece of state information + * that the HTTP agent and the target server can exchange to maintain + * a session. + *
+ * + * @author B.C. Holmes + * @author Park, Sung-Gu + * @author Doug Sale + * @author Rod Waldhoff + * @author dIon Gillard + * @author Sean C. Sullivan + * @author John Evans + * @author Marc A. Saegesser + * @author Oleg Kalnichevski + * @author Mike Bowler + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:33 $ + */ +public class Cookie extends NameValuePair implements Serializable, Comparator { + + // ----------------------------------------------------------- Constructors + + /** + * Default constructor. Creates a blank cookie + */ + + public Cookie() { + this(null, "noname", null, null, null, false); + } + + /** + * Creates a cookie with the given name, value and domain attribute. + * + * @param name the cookie name + * @param value the cookie value + * @param domain the domain this cookie can be sent to + */ + public Cookie(String domain, String name, String value) { + this(domain, name, value, null, null, false); + } + + /** + * Creates a cookie with the given name, value, domain attribute, + * path attribute, expiration attribute, and secure attribute + * + * @param name the cookie name + * @param value the cookie value + * @param domain the domain this cookie can be sent to + * @param path the path prefix for which this cookie can be sent + * @param expires the {@link Date} at which this cookie expires, + * or null if the cookie expires at the end + * of the session + * @param secure if true this cookie can only be sent over secure + * connections + * @throws IllegalArgumentException If cookie name is null or blank, + * cookie name contains a blank, or cookie name starts with character $ + * + */ + public Cookie(String domain, String name, String value, + String path, Date expires, boolean secure) { + + super(name, value); + LOG.trace("enter Cookie(String, String, String, String, Date, boolean)"); + if (name == null) { + throw new IllegalArgumentException("Cookie name may not be null"); + } + if (name.trim().equals("")) { + throw new IllegalArgumentException("Cookie name may not be blank"); + } + this.setPath(path); + this.setDomain(domain); + this.setExpiryDate(expires); + this.setSecure(secure); + } + + /** + * Creates a cookie with the given name, value, domain attribute, + * path attribute, maximum age attribute, and secure attribute + * + * @param name the cookie name + * @param value the cookie value + * @param domain the domain this cookie can be sent to + * @param path the path prefix for which this cookie can be sent + * @param maxAge the number of seconds for which this cookie is valid. + * maxAge is expected to be a non-negative number. + * -1 signifies that the cookie should never expire. + * @param secure if true this cookie can only be sent over secure + * connections + */ + public Cookie(String domain, String name, String value, String path, + int maxAge, boolean secure) { + + this(domain, name, value, path, null, secure); + if (maxAge < -1) { + throw new IllegalArgumentException("Invalid max age: " + Integer.toString(maxAge)); + } + if (maxAge >= 0) { + setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L)); + } + } + + /** + * Returns the comment describing the purpose of this cookie, or + * null if no such comment has been defined. + * + * @return comment + * + * @see #setComment(String) + */ + public String getComment() { + return cookieComment; + } + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described using this comment. + * + * @param comment + * + * @see #getComment() + */ + public void setComment(String comment) { + cookieComment = comment; + } + + /** + * Returns the expiration {@link Date} of the cookie, or null + * if none exists. + *Note: the object returned by this method is + * considered immutable. Changing it (e.g. using setTime()) could result + * in undefined behaviour. Do so at your peril.
+ * @return Expiration {@link Date}, or null. + * + * @see #setExpiryDate(java.util.Date) + * + */ + public Date getExpiryDate() { + return cookieExpiryDate; + } + + /** + * Sets expiration date. + *Note: the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined + * behaviour. Do so at your peril.
+ * + * @param expiryDate the {@link Date} after which this cookie is no longer valid. + * + * @see #getExpiryDate + * + */ + public void setExpiryDate (Date expiryDate) { + cookieExpiryDate = expiryDate; + } + + + /** + * Returns false if the cookie should be discarded at the end + * of the "session"; true otherwise. + * + * @return false if the cookie should be discarded at the end + * of the "session"; true otherwise + */ + public boolean isPersistent() { + return (null != cookieExpiryDate); + } + + + /** + * Returns domain attribute of the cookie. + * + * @return the value of the domain attribute + * + * @see #setDomain(java.lang.String) + */ + public String getDomain() { + return cookieDomain; + } + + /** + * Sets the domain attribute. + * + * @param domain The value of the domain attribute + * + * @see #getDomain + */ + public void setDomain(String domain) { + if (domain != null) { + int ndx = domain.indexOf(":"); + if (ndx != -1) { + domain = domain.substring(0, ndx); + } + cookieDomain = domain.toLowerCase(); + } + } + + + /** + * Returns the path attribute of the cookie + * + * @return The value of the path attribute. + * + * @see #setPath(java.lang.String) + */ + public String getPath() { + return cookiePath; + } + + /** + * Sets the path attribute. + * + * @param path The value of the path attribute + * + * @see #getPath + * + */ + public void setPath(String path) { + cookiePath = path; + } + + /** + * @returntrue
if this cookie should only be sent over secure connections.
+ * @see #setSecure(boolean)
+ */
+ public boolean getSecure() {
+ return isSecure;
+ }
+
+ /**
+ * Sets the secure attribute of the cookie.
+ * + * When true the cookie should only be sent + * using a secure protocol (https). This should only be set when + * the cookie's originating server used a secure protocol to set the + * cookie's value. + * + * @param secure The value of the secure attribute + * + * @see #getSecure() + */ + public void setSecure (boolean secure) { + isSecure = secure; + } + + /** + * Returns the version of the cookie specification to which this + * cookie conforms. + * + * @return the version of the cookie. + * + * @see #setVersion(int) + * + */ + public int getVersion() { + return cookieVersion; + } + + /** + * Sets the version of the cookie specification to which this + * cookie conforms. + * + * @param version the version of the cookie. + * + * @see #getVersion + */ + public void setVersion(int version) { + cookieVersion = version; + } + + /** + * Returns true if this cookie has expired. + * + * @return true if the cookie has expired. + */ + public boolean isExpired() { + return (cookieExpiryDate != null + && cookieExpiryDate.getTime() <= System.currentTimeMillis()); + } + + /** + * Returns true if this cookie has expired according to the time passed in. + * + * @param now The current time. + * + * @return true if the cookie expired. + */ + public boolean isExpired(Date now) { + return (cookieExpiryDate != null + && cookieExpiryDate.getTime() <= now.getTime()); + } + + + /** + * Indicates whether the cookie had a path specified in a + * path attribute of the Set-Cookie header. This value + * is important for generating the Cookie header because + * some cookie specifications require that the Cookie header + * should only include a path attribute if the cookie's path + * was specified in the Set-Cookie header. + * + * @param value true if the cookie's path was explicitly + * set, false otherwise. + * + * @see #isPathAttributeSpecified + */ + public void setPathAttributeSpecified(boolean value) { + hasPathAttribute = value; + } + + /** + * Returns true if cookie's path was set via a path attribute + * in the Set-Cookie header. + * + * @return value true if the cookie's path was explicitly + * set, false otherwise. + * + * @see #setPathAttributeSpecified + */ + public boolean isPathAttributeSpecified() { + return hasPathAttribute; + } + + /** + * Indicates whether the cookie had a domain specified in a + * domain attribute of the Set-Cookie header. This value + * is important for generating the Cookie header because + * some cookie specifications require that the Cookie header + * should only include a domain attribute if the cookie's domain + * was specified in the Set-Cookie header. + * + * @param value true if the cookie's domain was explicitly + * set, false otherwise. + * + * @see #isDomainAttributeSpecified + */ + public void setDomainAttributeSpecified(boolean value) { + hasDomainAttribute = value; + } + + /** + * Returns true if cookie's domain was set via a domain + * attribute in the Set-Cookie header. + * + * @return value true if the cookie's domain was explicitly + * set, false otherwise. + * + * @see #setDomainAttributeSpecified + */ + public boolean isDomainAttributeSpecified() { + return hasDomainAttribute; + } + + /** + * Returns a hash code in keeping with the + * {@link Object#hashCode} general hashCode contract. + * @return A hash code + */ + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.getName()); + hash = LangUtils.hashCode(hash, this.cookieDomain); + hash = LangUtils.hashCode(hash, this.cookiePath); + return hash; + } + + + /** + * Two cookies are equal if the name, path and domain match. + * @param obj The object to compare against. + * @return true if the two objects are equal. + */ + public boolean equals(Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (obj instanceof Cookie) { + Cookie that = (Cookie) obj; + return LangUtils.equals(this.getName(), that.getName()) + && LangUtils.equals(this.cookieDomain, that.cookieDomain) + && LangUtils.equals(this.cookiePath, that.cookiePath); + } else { + return false; + } + } + + + /** + * Return a textual representation of the cookie. + * + * @return string. + */ + public String toExternalForm() { + CookieSpec spec = null; + if (getVersion() > 0) { + spec = CookiePolicy.getDefaultSpec(); + } else { + spec = CookiePolicy.getCookieSpec(CookiePolicy.NETSCAPE); + } + return spec.formatCookie(this); + } + + /** + *
Compares two cookies to determine order for cookie header.
+ *Most specific should be first.
+ *This method is implemented so a cookie can be used as a comparator for + * a SortedSet of cookies. Specifically it's used above in the + * createCookieHeader method.
+ * @param o1 The first object to be compared + * @param o2 The second object to be compared + * @return See {@link java.util.Comparator#compare(Object,Object)} + */ + public int compare(Object o1, Object o2) { + LOG.trace("enter Cookie.compare(Object, Object)"); + + if (!(o1 instanceof Cookie)) { + throw new ClassCastException(o1.getClass().getName()); + } + if (!(o2 instanceof Cookie)) { + throw new ClassCastException(o2.getClass().getName()); + } + Cookie c1 = (Cookie) o1; + Cookie c2 = (Cookie) o2; + if (c1.getPath() == null && c2.getPath() == null) { + return 0; + } else if (c1.getPath() == null) { + // null is assumed to be "/" + if (c2.getPath().equals(CookieSpec.PATH_DELIM)) { + return 0; + } else { + return -1; + } + } else if (c2.getPath() == null) { + // null is assumed to be "/" + if (c1.getPath().equals(CookieSpec.PATH_DELIM)) { + return 0; + } else { + return 1; + } + } else { + return STRING_COLLATOR.compare(c1.getPath(), c2.getPath()); + } + } + + /** + * Return a textual representation of the cookie. + * + * @return string. + * + * @see #toExternalForm + */ + public String toString() { + return toExternalForm(); + } + + // ----------------------------------------------------- Instance Variables + + /** Comment attribute. */ + private String cookieComment; + + /** Domain attribute. */ + private String cookieDomain; + + /** Expiration {@link Date}. */ + private Date cookieExpiryDate; + + /** Path attribute. */ + private String cookiePath; + + /** My secure flag. */ + private boolean isSecure; + + /** + * Specifies if the set-cookie header included a Path attribute for this + * cookie + */ + private boolean hasPathAttribute = false; + + /** + * Specifies if the set-cookie header included a Domain attribute for this + * cookie + */ + private boolean hasDomainAttribute = false; + + /** The version of the cookie specification I was created from. */ + private int cookieVersion = 0; + + // -------------------------------------------------------------- Constants + + /** + * Collator for Cookie comparisons. Could be replaced with references to + * specific Locales. + */ + private static final RuleBasedCollator STRING_COLLATOR = + (RuleBasedCollator) RuleBasedCollator.getInstance( + new Locale("en", "US", "")); + + /** Log object for this class */ + private static final Log LOG = LogFactory.getLog(Cookie.class); + +} + Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Credentials.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Credentials.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Credentials.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,43 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Credentials.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * 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 + *Authentication credentials.
+ *+ * This is just a marker interface, the current implementation has no methods. + *
+ * @author Unascribed + * @author Mike Bowler + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:34 $ + */ +public interface Credentials { +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,147 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * 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 + *retryCount
and requestSentRetryEnabled
to determine
+ * if the given method should be retried.
+ *
+ * @see HttpMethodRetryHandler#retryMethod(HttpMethod, IOException, int)
+ */
+ public boolean retryMethod(
+ final HttpMethod method,
+ final IOException exception,
+ int executionCount) {
+ if (method == null) {
+ throw new IllegalArgumentException("HTTP method may not be null");
+ }
+ if (exception == null) {
+ throw new IllegalArgumentException("Exception parameter may not be null");
+ }
+ // HttpMethod interface is the WORST thing ever done to HttpClient
+ if (method instanceof HttpMethodBase) {
+ if (((HttpMethodBase)method).isAborted()) {
+ return false;
+ }
+ }
+ if (executionCount > this.retryCount) {
+ // Do not retry if over max retry count
+ return false;
+ }
+ if (exception instanceof NoHttpResponseException) {
+ // Retry if the server dropped connection on us
+ return true;
+ }
+ if (exception instanceof InterruptedIOException) {
+ // Timeout
+ return false;
+ }
+ if (exception instanceof UnknownHostException) {
+ // Unknown host
+ return false;
+ }
+ if (exception instanceof NoRouteToHostException) {
+ // Host unreachable
+ return false;
+ }
+ if (SSL_HANDSHAKE_EXCEPTION != null && SSL_HANDSHAKE_EXCEPTION.isInstance(exception)) {
+ // SSL handshake exception
+ return false;
+ }
+ if (!method.isRequestSent() || this.requestSentRetryEnabled) {
+ // Retry if the request has not been sent fully or
+ // if it's OK to retry methods that have been sent
+ return true;
+ }
+ // otherwise do not retry
+ return false;
+ }
+
+ /**
+ * @return true
if this handler will retry methods that have
+ * successfully sent their request, false
otherwise
+ */
+ public boolean isRequestSentRetryEnabled() {
+ return requestSentRetryEnabled;
+ }
+
+ /**
+ * @return the maximum number of times a method will be retried
+ */
+ public int getRetryCount() {
+ return retryCount;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultMethodRetryHandler.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultMethodRetryHandler.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultMethodRetryHandler.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,101 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultMethodRetryHandler.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * retryCount
and requestSentRetryEnabled
to determine
+ * if the given method should be retried.
+ *
+ * @see MethodRetryHandler#retryMethod(HttpMethod, HttpConnection, HttpRecoverableException, int, boolean)
+ */
+ public boolean retryMethod(
+ HttpMethod method,
+ HttpConnection connection,
+ HttpRecoverableException recoverableException,
+ int executionCount,
+ boolean requestSent
+ ) {
+ return ((!requestSent || requestSentRetryEnabled) && (executionCount <= retryCount));
+ }
+ /**
+ * @return true
if this handler will retry methods that have
+ * successfully sent their request, false
otherwise
+ */
+ public boolean isRequestSentRetryEnabled() {
+ return requestSentRetryEnabled;
+ }
+
+ /**
+ * @return the maximum number of times a method will be retried
+ */
+ public int getRetryCount() {
+ return retryCount;
+ }
+
+ /**
+ * @param requestSentRetryEnabled a flag indicating if methods that have
+ * successfully sent their request should be retried
+ */
+ public void setRequestSentRetryEnabled(boolean requestSentRetryEnabled) {
+ this.requestSentRetryEnabled = requestSentRetryEnabled;
+ }
+
+ /**
+ * @param retryCount the maximum number of times a method can be retried
+ */
+ public void setRetryCount(int retryCount) {
+ this.retryCount = retryCount;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Header.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Header.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Header.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,144 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Header.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * An HTTP header.
+ * + * @author Remy Maucherat + * @author Mike Bowler + * @author Oleg Kalnichevski + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:35 $ + */ +public class Header extends NameValuePair { + + // ----------------------------------------------------------- Constructors + + /** + * Autogenerated header flag. + */ + private boolean isAutogenerated = false; + + /** + * Default constructor. + */ + public Header() { + this(null, null); + } + + /** + * Constructor with name and value + * + * @param name the header name + * @param value the header value + */ + public Header(String name, String value) { + super(name, value); + } + + /** + * Constructor with name and value + * + * @param name the header name + * @param value the header value + * @param isAutogenerated true if the header is autogenerated, + * false otherwise. + * + * @since 3.0 + */ + public Header(String name, String value, boolean isAutogenerated) { + super(name, value); + this.isAutogenerated = isAutogenerated; + } + + // --------------------------------------------------------- Public Methods + + /** + * Returns a {@link String} representation of the header. + * + * @return stringHEAD + */ + public String toExternalForm() { + return ((null == getName() ? "" : getName()) + + ": " + + (null == getValue() ? "" : getValue()) + + "\r\n"); + } + + /** + * Returns a {@link String} representation of the header. + * + * @return stringHEAD + */ + public String toString() { + return toExternalForm(); + } + + /** + * Returns an array of {@link HeaderElement}s + * constructed from my value. + * + * @see HeaderElement#parse + * @throws HttpException if the header cannot be parsed + * @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 + * + * @since 3.0 + */ + public HeaderElement[] getElements() { + return HeaderElement.parseElements(getValue()); + } + + /** + * Returns the value of the auto-generated header flag. + * + * @return true if the header is autogenerated, + * false otherwise. + * + * @since 3.0 + */ + public boolean isAutogenerated() { + return isAutogenerated; + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderElement.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderElement.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderElement.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,298 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderElement.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * 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 + *One element of an HTTP header's value.
+ *+ * Some HTTP headers (such as the set-cookie header) have values that + * can be decomposed into multiple elements. Such headers must be in the + * following form: + *
+ *+ * header = [ element ] *( "," [ element ] ) + * element = name [ "=" [ value ] ] *( ";" [ param ] ) + * param = name [ "=" [ value ] ] + * + * name = token + * value = ( token | quoted-string ) + * + * token = 1*<any char except "=", ",", ";", <"> and + * white space> + * quoted-string = <"> *( text | quoted-char ) <"> + * text = any char except <"> + * quoted-char = "\" char + *+ *
+ * Any amount of white space is allowed between any part of the + * header, element or param and is ignored. A missing value in any + * element or param will be stored as the empty {@link String}; + * if the "=" is also missing null will be stored instead. + *
+ *+ * This class represents an individual header element, containing + * both a name/value pair (value may be null) and optionally + * a set of additional parameters. + *
+ *+ * This class also exposes a {@link #parse} method for parsing a + * {@link Header} value into an array of elements. + *
+ * + * @see Header + * + * @author B.C. Holmes + * @author Park, Sung-Gu + * @author Mike Bowler + * @author Oleg Kalnichevski + * + * @since 1.0 + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:34 $ + */ +public class HeaderElement extends NameValuePair { + + // ----------------------------------------------------------- Constructors + + /** + * Default constructor. + */ + public HeaderElement() { + this(null, null, null); + } + + /** + * Constructor. + * @param name my name + * @param value my (possibly null) value + */ + public HeaderElement(String name, String value) { + this(name, value, null); + } + + /** + * Constructor with name, value and parameters. + * + * @param name my name + * @param value my (possibly null) value + * @param parameters my (possibly null) parameters + */ + public HeaderElement(String name, String value, + NameValuePair[] parameters) { + super(name, value); + this.parameters = parameters; + } + + /** + * Constructor with array of characters. + * + * @param chars the array of characters + * @param offset - the initial offset. + * @param length - the length. + * + * @since 3.0 + */ + 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()]); + } + } + } + + /** + * Constructor with array of characters. + * + * @param chars the array of characters + * + * @since 3.0 + */ + public HeaderElement(char[] chars) { + this(chars, 0, chars.length); + } + + // -------------------------------------------------------- Constants + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(HeaderElement.class); + + // ----------------------------------------------------- Instance Variables + + /** My parameters, if any. */ + private NameValuePair[] parameters = null; + + // ------------------------------------------------------------- Properties + + /** + * Get parameters, if any. + * + * @since 2.0 + * @return parameters as an array of {@link NameValuePair}s + */ + public NameValuePair[] getParameters() { + return this.parameters; + } + + // --------------------------------------------------------- Public Methods + + /** + * This parses the value part of a header. The result is an array of + * HeaderElement objects. + * + * @param headerValue the array of char representation of the header value + * (as received from the web server). + * @return array of {@link HeaderElement}s. + * + * @since 3.0 + */ + public static final HeaderElement[] parseElements(char[] headerValue) { + + LOG.trace("enter HeaderElement.parseElements(char[])"); + + if (headerValue == null) { + return new HeaderElement[] {}; + } + List elements = new ArrayList(); + + int i = 0; + int from = 0; + int len = headerValue.length; + boolean qouted = false; + while (i < len) { + char ch = headerValue[i]; + if (ch == '"') { + qouted = !qouted; + } + 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); + } + if ((element != null) && (element.getName() != null)) { + elements.add(element); + } + i++; + } + return (HeaderElement[]) + elements.toArray(new HeaderElement[elements.size()]); + } + + /** + * 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 + * (as received from the web server). + * @return array of {@link HeaderElement}s. + * + * @since 3.0 + */ + public static final HeaderElement[] parseElements(String headerValue) { + + LOG.trace("enter HeaderElement.parseElements(String)"); + + if (headerValue == null) { + return new HeaderElement[] {}; + } + return parseElements(headerValue.toCharArray()); + } + + /** + * 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 + * (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). + */ + public static final HeaderElement[] parse(String headerValue) + throws HttpException { + + LOG.trace("enter HeaderElement.parse(String)"); + + if (headerValue == null) { + return new HeaderElement[] {}; + } + return parseElements(headerValue.toCharArray()); + } + + + /** + * Returns parameter with the given name, if found. Otherwise null + * is returned + * + * @param name The name to search by. + * @return NameValuePair parameter with the given name + */ + + public NameValuePair getParameterByName(String name) { + + LOG.trace("enter HeaderElement.getParameterByName(String)"); + + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + NameValuePair found = null; + NameValuePair parameters[] = getParameters(); + if (parameters != null) { + for (int i = 0; i < parameters.length; i++) { + NameValuePair current = parameters[ i ]; + if (current.getName().equalsIgnoreCase(name)) { + found = current; + break; + } + } + } + return found; + } + +} + Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderGroup.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderGroup.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderGroup.java 22 Aug 2012 17:30:33 -0000 1.1 @@ -0,0 +1,229 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderGroup.java,v 1.1 2012/08/22 17:30:33 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:33 $ + * + * ==================================================================== + * + * Copyright 2003-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 + *Header name comparison is case insensitive.
+ *
+ * @param name the name of the header(s) to get
+ * @return a header with a condensed value or null
if no
+ * headers by the given name are present
+ */
+ public Header getCondensedHeader(String name) {
+ Header[] headers = getHeaders(name);
+
+ if (headers.length == 0) {
+ return null;
+ } else if (headers.length == 1) {
+ return new Header(headers[0].getName(), headers[0].getValue());
+ } else {
+ StringBuffer valueBuffer = new StringBuffer(headers[0].getValue());
+
+ for (int i = 1; i < headers.length; i++) {
+ valueBuffer.append(", ");
+ valueBuffer.append(headers[i].getValue());
+ }
+
+ return new Header(name.toLowerCase(), valueBuffer.toString());
+ }
+ }
+
+ /**
+ * Gets all of the headers with the given name. The returned array
+ * maintains the relative order in which the headers were added.
+ *
+ *
Header name comparison is case insensitive. + * + * @param name the name of the header(s) to get + * + * @return an array of length >= 0 + */ + public Header[] getHeaders(String name) { + ArrayList headersFound = new ArrayList(); + + for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) { + Header header = (Header) headerIter.next(); + if (header.getName().equalsIgnoreCase(name)) { + headersFound.add(header); + } + } + + return (Header[]) headersFound.toArray(new Header[headersFound.size()]); + } + + /** + * Gets the first header with the given name. + * + *
Header name comparison is case insensitive.
+ *
+ * @param name the name of the header to get
+ * @return the first header or null
+ */
+ public Header getFirstHeader(String name) {
+ for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) {
+ Header header = (Header) headerIter.next();
+ if (header.getName().equalsIgnoreCase(name)) {
+ return header;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the last header with the given name.
+ *
+ *
Header name comparison is case insensitive.
+ *
+ * @param name the name of the header to get
+ * @return the last header or null
+ */
+ public Header getLastHeader(String name) {
+ // start at the end of the list and work backwards
+ for (int i = headers.size() - 1; i >= 0; i--) {
+ Header header = (Header) headers.get(i);
+ if (header.getName().equalsIgnoreCase(name)) {
+ return header;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets all of the headers contained within this group.
+ *
+ * @return an array of length >= 0
+ */
+ public Header[] getAllHeaders() {
+ return (Header[]) headers.toArray(new Header[headers.size()]);
+ }
+
+ /**
+ * Tests if headers with the given name are contained within this group.
+ *
+ *
Header name comparison is case insensitive.
+ *
+ * @param name the header name to test for
+ * @return true
if at least one header with the name is
+ * contained, false
otherwise
+ */
+ public boolean containsHeader(String name) {
+ for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) {
+ Header header = (Header) headerIter.next();
+ if (header.getName().equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns an iterator over this group of headers.
+ *
+ * @return iterator over this group of headers.
+ *
+ * @since 3.0
+ */
+ public Iterator getIterator() {
+ return this.headers.iterator();
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HostConfiguration.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HostConfiguration.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HostConfiguration.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,514 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HostConfiguration.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * null
. This value should be treated as immutable and only used in
+ * lookups and other such places to represent "any" host config.
+ */
+ public static final HostConfiguration ANY_HOST_CONFIGURATION = new HostConfiguration();
+
+ /** The host to use. */
+ private HttpHost host = null;
+
+ /** The host name of the proxy server */
+ private ProxyHost proxyHost = null;
+
+ /** The local address to use when creating the socket, or null to use the default */
+ private InetAddress localAddress = null;
+
+ /** Parameters specific to this host */
+ private HostParams params = new HostParams();
+
+ /**
+ * Constructor for HostConfiguration.
+ */
+ public HostConfiguration() {
+ super();
+ }
+
+ /**
+ * Copy constructor for HostConfiguration
+ *
+ * @param hostConfiguration the hostConfiguration to copy
+ */
+ public HostConfiguration (final HostConfiguration hostConfiguration) {
+ // wrap all of the assignments in a synchronized block to avoid
+ // having to negotiate the monitor for each method call
+ synchronized (hostConfiguration) {
+ try {
+ if (hostConfiguration.host != null) {
+ this.host = (HttpHost) hostConfiguration.host.clone();
+ } else {
+ this.host = null;
+ }
+ if (hostConfiguration.proxyHost != null) {
+ this.proxyHost = (ProxyHost) hostConfiguration.proxyHost.clone();
+ } else {
+ this.proxyHost = null;
+ }
+ this.localAddress = hostConfiguration.getLocalAddress();
+ this.params = (HostParams)hostConfiguration.getParams().clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalArgumentException("Host configuration could not be cloned");
+ }
+ }
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ public Object clone() {
+ return new HostConfiguration(this);
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public synchronized String toString() {
+
+ boolean appendComma = false;
+ StringBuffer b = new StringBuffer(50);
+ b.append("HostConfiguration[");
+
+ if (this.host != null) {
+ appendComma = true;
+ b.append("host=").append(this.host);
+ }
+ if (this.proxyHost != null) {
+ if (appendComma) {
+ b.append(", ");
+ } else {
+ appendComma = true;
+ }
+ b.append("proxyHost=").append(this.proxyHost);
+ }
+ if (this.localAddress != null) {
+ if (appendComma) {
+ b.append(", ");
+ } else {
+ appendComma = true;
+ }
+ b.append("localAddress=").append(this.localAddress);
+ if (appendComma) {
+ b.append(", ");
+ } else {
+ appendComma = true;
+ }
+ b.append("params=").append(this.params);
+ }
+ b.append("]");
+ return b.toString();
+ }
+
+ /**
+ * Tests if the host configuration equals the configuration set on the
+ * connection. True only if the host, port, protocol, local address and virtual address
+ * are equal. If no host configuration has been set false will be returned.
+ *
+ * @param connection the connection to test against
+ * @return true
if the connection's host information equals that of this
+ * configuration
+ *
+ * @see #proxyEquals(HttpConnection)
+ */
+ public synchronized boolean hostEquals(final HttpConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection may not be null");
+ }
+ if (this.host != null) {
+ if (!this.host.getHostName().equalsIgnoreCase(connection.getHost())) {
+ return false;
+ }
+ if (this.host.getPort() != connection.getPort()) {
+ return false;
+ }
+ if (!this.host.getProtocol().equals(connection.getProtocol())) {
+ return false;
+ }
+ if (this.localAddress != null) {
+ if (!this.localAddress.equals(connection.getLocalAddress())) {
+ return false;
+ }
+ } else {
+ if (connection.getLocalAddress() != null) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Tests if the proxy configuration equals the configuration set on the
+ * connection. True only if the proxyHost and proxyPort are equal.
+ *
+ * @param connection the connection to test against
+ * @return true
if the connection's proxy information equals that of this
+ * configuration
+ *
+ * @see #hostEquals(HttpConnection)
+ */
+ public synchronized boolean proxyEquals(final HttpConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection may not be null");
+ }
+ if (this.proxyHost != null) {
+ return
+ this.proxyHost.getHostName().equalsIgnoreCase(connection.getProxyHost())
+ && this.proxyHost.getPort() == connection.getProxyPort();
+ } else {
+ return connection.getProxyHost() == null;
+ }
+ }
+
+ /**
+ * Returns true if the host is set.
+ * @return true
if the host is set.
+ *
+ * @deprecated no longer used
+ */
+ public synchronized boolean isHostSet() {
+ return this.host != null;
+ }
+
+ /**
+ * Sets the given host
+ *
+ * @param host the host
+ */
+ public synchronized void setHost(final HttpHost host) {
+ this.host = host;
+ }
+
+ /**
+ * Sets the given host, port and protocol
+ *
+ * @param host the host(IP or DNS name)
+ * @param port The port
+ * @param protocol The protocol.
+ */
+ public synchronized void setHost(final String host, int port, final String protocol) {
+ this.host = new HttpHost(host, port, Protocol.getProtocol(protocol));
+ }
+
+ /**
+ * Sets the given host, virtual host, port and protocol.
+ *
+ * @param host the host(IP or DNS name)
+ * @param virtualHost the virtual host name or null
+ * @param port the host port or -1 to use protocol default
+ * @param protocol the protocol
+ *
+ * @deprecated #setHost(String, int, Protocol)
+ */
+ public synchronized void setHost(final String host, final String virtualHost, int port,
+ final Protocol protocol) {
+ setHost(host, port, protocol);
+ this.params.setVirtualHost(virtualHost);
+ }
+
+ /**
+ * Sets the given host, port and protocol.
+ *
+ * @param host the host(IP or DNS name)
+ * @param port The port
+ * @param protocol the protocol
+ */
+ public synchronized void setHost(final String host, int port, final Protocol protocol) {
+ if (host == null) {
+ throw new IllegalArgumentException("host must not be null");
+ }
+ if (protocol == null) {
+ throw new IllegalArgumentException("protocol must not be null");
+ }
+ this.host = new HttpHost(host, port, protocol);
+ }
+
+ /**
+ * Sets the given host and port. Uses the default protocol "http".
+ *
+ * @param host the host(IP or DNS name)
+ * @param port The port
+ */
+ public synchronized void setHost(final String host, int port) {
+ setHost(host, port, Protocol.getProtocol("http"));
+ }
+
+ /**
+ * Set the given host. Uses the default protocol("http") and its port.
+ *
+ * @param host The host(IP or DNS name).
+ */
+ public synchronized void setHost(final String host) {
+ Protocol defaultProtocol = Protocol.getProtocol("http");
+ setHost(host, defaultProtocol.getDefaultPort(), defaultProtocol);
+ }
+
+ /**
+ * Sets the protocol, host and port from the given URI.
+ * @param uri the URI.
+ */
+ public synchronized void setHost(final URI uri) {
+ try {
+ setHost(uri.getHost(), uri.getPort(), uri.getScheme());
+ } catch (URIException e) {
+ throw new IllegalArgumentException(e.toString());
+ }
+ }
+
+ /**
+ * Return the host url.
+ *
+ * @return The host url.
+ */
+ public synchronized String getHostURL() {
+ if (this.host == null) {
+ throw new IllegalStateException("Host must be set to create a host URL");
+ } else {
+ return this.host.toURI();
+ }
+ }
+
+ /**
+ * Returns the host.
+ *
+ * @return the host(IP or DNS name), or null
if not set
+ *
+ * @see #isHostSet()
+ */
+ public synchronized String getHost() {
+ if (this.host != null) {
+ return this.host.getHostName();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the virtual host.
+ *
+ * @return the virtual host name, or null
if not set
+ *
+ * @deprecated use HostParams
+ */
+ public synchronized String getVirtualHost() {
+ return this.params.getVirtualHost();
+ }
+
+ /**
+ * Returns the port.
+ *
+ * @return the host port, or -1
if not set
+ *
+ * @see #isHostSet()
+ */
+ public synchronized int getPort() {
+ if (this.host != null) {
+ return this.host.getPort();
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the protocol.
+ * @return The protocol.
+ */
+ public synchronized Protocol getProtocol() {
+ if (this.host != null) {
+ return this.host.getProtocol();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Tests if the proxy host/port have been set.
+ *
+ * @return true
if a proxy server has been set.
+ *
+ * @see #setProxy(String, int)
+ *
+ * @deprecated no longer used
+ */
+ public synchronized boolean isProxySet() {
+ return this.proxyHost != null;
+ }
+
+ /**
+ * Sets the given proxy host
+ *
+ * @param proxyHost the proxy host
+ */
+ public synchronized void setProxyHost(final ProxyHost proxyHost) {
+ this.proxyHost = proxyHost;
+ }
+
+ /**
+ * Set the proxy settings.
+ * @param proxyHost The proxy host
+ * @param proxyPort The proxy port
+ */
+ public synchronized void setProxy(final String proxyHost, int proxyPort) {
+ this.proxyHost = new ProxyHost(proxyHost, proxyPort);
+ }
+
+ /**
+ * Returns the proxyHost.
+ *
+ * @return the proxy host, or null
if not set
+ *
+ * @see #isProxySet()
+ */
+ public synchronized String getProxyHost() {
+ if (this.proxyHost != null) {
+ return this.proxyHost.getHostName();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the proxyPort.
+ *
+ * @return the proxy port, or -1
if not set
+ *
+ * @see #isProxySet()
+ */
+ public synchronized int getProxyPort() {
+ if (this.proxyHost != null) {
+ return this.proxyHost.getPort();
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Set the local address to be used when creating connections.
+ * If this is unset, the default address will be used.
+ * This is useful for specifying the interface to use on multi-homed or clustered systems.
+ *
+ * @param localAddress the local address to use
+ */
+
+ public synchronized void setLocalAddress(InetAddress localAddress) {
+ this.localAddress = localAddress;
+ }
+
+ /**
+ * Return the local address to be used when creating connections.
+ * If this is unset, the default address should be used.
+ *
+ * @return the local address to be used when creating Sockets, or null
+ */
+
+ public synchronized InetAddress getLocalAddress() {
+ return this.localAddress;
+ }
+
+ /**
+ * Returns {@link HostParams HTTP protocol parameters} associated with this host.
+ *
+ * @return HTTP parameters.
+ *
+ * @since 3.0
+ */
+ public HostParams getParams() {
+ return this.params;
+ }
+
+ /**
+ * Assigns {@link HostParams HTTP protocol parameters} specific to this host.
+ *
+ * @since 3.0
+ *
+ * @see HostParams
+ */
+ public void setParams(final HostParams params) {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ this.params = params;
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public synchronized boolean equals(final Object o) {
+ if (o instanceof HostConfiguration) {
+ // shortcut if we're comparing with ourselves
+ if (o == this) {
+ return true;
+ }
+ HostConfiguration that = (HostConfiguration) o;
+ return LangUtils.equals(this.host, that.host)
+ && LangUtils.equals(this.proxyHost, that.proxyHost)
+ && LangUtils.equals(this.localAddress, that.localAddress);
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public synchronized int hashCode() {
+ int hash = LangUtils.HASH_SEED;
+ hash = LangUtils.hashCode(hash, this.host);
+ hash = LangUtils.hashCode(hash, this.proxyHost);
+ hash = LangUtils.hashCode(hash, this.localAddress);
+ return hash;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClient.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClient.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClient.java 22 Aug 2012 17:30:33 -0000 1.1
@@ -0,0 +1,501 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClient.java,v 1.1 2012/08/22 17:30:33 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:33 $
+ *
+ * ====================================================================
+ *
+ * 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
+ *
+ * An HTTP "user-agent", containing an {@link HttpState HTTP state} and + * one or more {@link HttpConnection HTTP connections}, to which + * {@link HttpMethod HTTP methods} can be applied. + *
+ * @author Remy Maucherat + * @author Rodney Waldhoff + * @author Sean C. Sullivan + * @author dIon Gillard + * @author Ortwin Gl?ck + * @author Michael Becke + * @author Mike Bowler + * @author Sam Maloney + * @author Laura Werner + * @author Oleg Kalnichevski + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:33 $ + */ +public class HttpClient { + + + // -------------------------------------------------------------- Constants + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(HttpClient.class); + + static { + + if (LOG.isDebugEnabled()) { + try { + LOG.debug("Java version: " + System.getProperty("java.version")); + LOG.debug("Java vendor: " + System.getProperty("java.vendor")); + LOG.debug("Java class path: " + System.getProperty("java.class.path")); + LOG.debug("Operating system name: " + System.getProperty("os.name")); + LOG.debug("Operating system architecture: " + System.getProperty("os.arch")); + LOG.debug("Operating system version: " + System.getProperty("os.version")); + + Provider[] providers = Security.getProviders(); + for (int i = 0; i < providers.length; i++) { + Provider provider = providers[i]; + LOG.debug(provider.getName() + " " + provider.getVersion() + + ": " + provider.getInfo()); + } + } catch (SecurityException ignore) { + } + } + } + // ----------------------------------------------------------- Constructors + + /** + * Creates an instance of HttpClient using default {@link HttpClientParams parameter set}. + * + * @see HttpClientParams + */ + public HttpClient() { + this(new HttpClientParams()); + } + + /** + * Creates an instance of HttpClient using the given + * {@link HttpClientParams parameter set}. + * + * @param params The {@link HttpClientParams parameters} to use. + * + * @see HttpClientParams + * + * @since 3.0 + */ + public HttpClient(HttpClientParams params) { + super(); + if (params == null) { + throw new IllegalArgumentException("Params may not be null"); + } + this.params = params; + this.httpConnectionManager = null; + Class clazz = params.getConnectionManagerClass(); + if (clazz != null) { + try { + this.httpConnectionManager = (HttpConnectionManager) clazz.newInstance(); + } catch (Exception e) { + LOG.warn("Error instantiating connection manager class, defaulting to" + + " SimpleHttpConnectionManager", + e); + } + } + if (this.httpConnectionManager == null) { + this.httpConnectionManager = new SimpleHttpConnectionManager(); + } + if (this.httpConnectionManager != null) { + this.httpConnectionManager.getParams().setDefaults(this.params); + } + } + + /** + * Creates an instance of HttpClient with a user specified + * {@link HttpClientParams parameter set} and + * {@link HttpConnectionManager HTTP connection manager}. + * + * @param params The {@link HttpClientParams parameters} to use. + * @param httpConnectionManager The {@link HttpConnectionManager connection manager} + * to use. + * + * @since 3.0 + */ + public HttpClient(HttpClientParams params, HttpConnectionManager httpConnectionManager) { + super(); + if (httpConnectionManager == null) { + throw new IllegalArgumentException("httpConnectionManager cannot be null"); + } + if (params == null) { + throw new IllegalArgumentException("Params may not be null"); + } + this.params = params; + this.httpConnectionManager = httpConnectionManager; + if (this.httpConnectionManager != null) { + this.httpConnectionManager.getParams().setDefaults(this.params); + } + } + + /** + * Creates an instance of HttpClient with a user specified + * {@link HttpConnectionManager HTTP connection manager}. + * + * @param httpConnectionManager The {@link HttpConnectionManager connection manager} + * to use. + * + * @since 2.0 + */ + public HttpClient(HttpConnectionManager httpConnectionManager) { + this(new HttpClientParams(), httpConnectionManager); + } + + // ----------------------------------------------------- Instance Variables + + /** + * The {@link HttpConnectionManager connection manager} being used to manage + * connections for this HttpClient + */ + private HttpConnectionManager httpConnectionManager; + + /** + * The {@link HttpState HTTP state} associated with this HttpClient. + */ + private HttpState state = new HttpState(); + + /** + * The {@link HttpClientParams collection of parameters} associated with this HttpClient. + */ + private HttpClientParams params = null; + + /** + * The {@link HostConfiguration host configuration} associated with + * the HttpClient + */ + private HostConfiguration hostConfiguration = new HostConfiguration(); + + // ------------------------------------------------------------- Properties + + /** + * Returns {@link HttpState HTTP state} associated with the HttpClient. + * + * @see #setState(HttpState) + * @return the shared client state + */ + public synchronized HttpState getState() { + return state; + } + + /** + * Assigns {@link HttpState HTTP state} for the HttpClient. + * + * @see #getState() + * @param state the new {@link HttpState HTTP state} for the client + */ + public synchronized void setState(HttpState state) { + this.state = state; + } + + /** + * Defines how strictly the method follows the HTTP protocol specification + * (see RFC 2616 and other relevant RFCs). + * + * In the strict mode the method precisely + * implements the requirements of the specification, whereas in non-strict mode + * it attempts to mimic the exact behaviour of commonly used HTTP agents, + * which many HTTP servers expect. + * + * @param strictMode true for strict mode, false otherwise + * + * @see #isStrictMode() + * + * @deprecated Use {@link HttpClientParams#setParameter(String, Object)} + * to exercise a more granular control over HTTP protocol strictness. + */ + public synchronized void setStrictMode(boolean strictMode) { + if (strictMode) { + this.params.makeStrict(); + } else { + this.params.makeLenient(); + } + } + + /** + * Returns the value of the strict mode flag. + * + * @return true if strict mode is enabled, false otherwise + * + * @see #setStrictMode(boolean) + * + * @deprecated Use + * {@link org.apache.commons.httpclient.params.HttpClientParams#getParameter(String)} + * to exercise a more granular control over HTTP protocol strictness. + */ + public synchronized boolean isStrictMode() { + return false; + } + + /** + * Sets the socket timeout (SO_TIMEOUT) in milliseconds which is the + * timeout for waiting for data. A timeout value of zero is interpreted as an + * infinite timeout. + * + * @param newTimeoutInMilliseconds Timeout in milliseconds + * + * @deprecated Use + * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)}, + * {@link HttpConnectionManager#getParams()}. + * + */ + public synchronized void setTimeout(int newTimeoutInMilliseconds) { + this.params.setSoTimeout(newTimeoutInMilliseconds); + } + + /** + * Sets the timeout in milliseconds used when retrieving an + * {@link HttpConnection HTTP connection} from the + * {@link HttpConnectionManager HTTP connection manager}. + * + * @param timeout the timeout in milliseconds + * + * @see HttpConnectionManager#getConnection(HostConfiguration, long) + * + * @deprecated Use + * {@link org.apache.commons.httpclient.params.HttpClientParams#setConnectionManagerTimeout(long)}, + * {@link HttpClient#getParams()} + */ + public synchronized void setHttpConnectionFactoryTimeout(long timeout) { + this.params.setConnectionManagerTimeout(timeout); + } + + /** + * Sets the timeout until a connection is etablished. A value of zero + * means the timeout is not used. The default value is zero. + * + * @see HttpConnection#setConnectionTimeout(int) + * @param newTimeoutInMilliseconds Timeout in milliseconds. + * + * @deprecated Use + * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)}, + * {@link HttpConnectionManager#getParams()}. + */ + public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) { + this.httpConnectionManager.getParams().setConnectionTimeout(newTimeoutInMilliseconds); + } + + // --------------------------------------------------------- Public Methods + + /** + * Executes the given {@link HttpMethod HTTP method}. + * + * @param method the {@link HttpMethod HTTP method} to execute. + * @return the method's response code + * + * @throws IOException If an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException If a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + public int executeMethod(HttpMethod method) + throws IOException, HttpException { + + LOG.trace("enter HttpClient.executeMethod(HttpMethod)"); + // execute this method and use its host configuration, if it has one + return executeMethod(null, method, null); + } + + /** + * Executes the given {@link HttpMethod HTTP method} using custom + * {@link HostConfiguration host configuration}. + * + * @param hostConfiguration The {@link HostConfiguration host configuration} to use. + * @param method the {@link HttpMethod HTTP method} to execute. + * @return the method's response code + * + * @throws IOException If an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException If a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * @since 2.0 + */ + public int executeMethod(final HostConfiguration hostConfiguration, final HttpMethod method) + throws IOException, HttpException { + + LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod)"); + + return executeMethod(hostConfiguration, method, null); + } + + + + /** + * Executes the given {@link HttpMethod HTTP method} using the given custom + * {@link HostConfiguration host configuration} with the given custom + * {@link HttpState HTTP state}. + * + * @param hostconfig The {@link HostConfiguration host configuration} to use. + * @param method the {@link HttpMethod HTTP method} to execute. + * @param state the {@link HttpState HTTP state} to use when executing the method. + * Ifnull
, the state returned by {@link #getState} will be used instead.
+ *
+ * @return the method's response code
+ *
+ * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
+ * can be recovered from.
+ * @throws HttpException If a protocol exception occurs. Usually protocol exceptions
+ * cannot be recovered from.
+ * @since 2.0
+ */
+ public int executeMethod(HostConfiguration hostconfig,
+ final HttpMethod method, final HttpState state)
+ throws IOException, HttpException {
+
+ LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod,HttpState)");
+
+ if (method == null) {
+ throw new IllegalArgumentException("HttpMethod parameter may not be null");
+ }
+ HostConfiguration defaulthostconfig = getHostConfiguration();
+ if (hostconfig == null) {
+ hostconfig = defaulthostconfig;
+ }
+ URI uri = method.getURI();
+ if (hostconfig == defaulthostconfig || uri.isAbsoluteURI()) {
+ // make a deep copy of the host defaults
+ hostconfig = new HostConfiguration(hostconfig);
+ if (uri.isAbsoluteURI()) {
+ hostconfig.setHost(uri);
+ }
+ }
+
+ HttpMethodDirector methodDirector = new HttpMethodDirector(
+ getHttpConnectionManager(),
+ hostconfig,
+ this.params,
+ (state == null ? getState() : state));
+ methodDirector.executeMethod(method);
+ return method.getStatusCode();
+ }
+
+ /**
+ * Returns the default host.
+ *
+ * @return The default host.
+ *
+ * @deprecated use #getHostConfiguration()
+ */
+ public String getHost() {
+ return hostConfiguration.getHost();
+ }
+
+ /**
+ * Returns the default port.
+ *
+ * @return The default port.
+ *
+ * @deprecated use #getHostConfiguration()
+ */
+ public int getPort() {
+ return hostConfiguration.getPort();
+ }
+
+ /**
+ * Returns the {@link HostConfiguration host configuration} associated with the
+ * HttpClient.
+ *
+ * @return {@link HostConfiguration host configuration}
+ *
+ * @since 2.0
+ */
+ public synchronized HostConfiguration getHostConfiguration() {
+ return hostConfiguration;
+ }
+
+ /**
+ * Assigns the {@link HostConfiguration host configuration} to use with the
+ * HttpClient.
+ *
+ * @param hostConfiguration The {@link HostConfiguration host configuration} to set
+ *
+ * @since 2.0
+ */
+ public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) {
+ this.hostConfiguration = hostConfiguration;
+ }
+
+ /**
+ * Returns the {@link HttpConnectionManager HTTP connection manager} associated
+ * with the HttpClient.
+ *
+ * @return {@link HttpConnectionManager HTTP connection manager}
+ *
+ * @since 2.0
+ */
+ public synchronized HttpConnectionManager getHttpConnectionManager() {
+ return httpConnectionManager;
+ }
+
+ /**
+ * Assigns the {@link HttpConnectionManager HTTP connection manager} to use with
+ * the HttpClient.
+ *
+ * @param httpConnectionManager The {@link HttpConnectionManager HTTP connection manager}
+ * to set
+ *
+ * @since 2.0
+ */
+ public synchronized void setHttpConnectionManager(
+ HttpConnectionManager httpConnectionManager
+ ) {
+ this.httpConnectionManager = httpConnectionManager;
+ if (this.httpConnectionManager != null) {
+ this.httpConnectionManager.getParams().setDefaults(this.params);
+ }
+ }
+
+ /**
+ * Returns {@link HttpClientParams HTTP protocol parameters} associated with this HttpClient.
+ *
+ * @since 3.0
+ *
+ * @see HttpClientParams
+ */
+ public HttpClientParams getParams() {
+ return this.params;
+ }
+
+ /**
+ * Assigns {@link HttpClientParams HTTP protocol parameters} for this HttpClient.
+ *
+ * @since 3.0
+ *
+ * @see HttpClientParams
+ */
+ public void setParams(final HttpClientParams params) {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ this.params = params;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClientError.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClientError.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClientError.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,56 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClientError.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * + * The following options are set on the socket before getting the input/output + * streams in the {@link #open()} method: + *
Socket Method + * | Sockets Option + * | Configuration + * |
---|---|---|
{@link java.net.Socket#setTcpNoDelay(boolean)} + * | SO_NODELAY + * | {@link HttpConnectionParams#setTcpNoDelay(boolean)} + * |
{@link java.net.Socket#setSoTimeout(int)} + * | SO_TIMEOUT + * | {@link HttpConnectionParams#setSoTimeout(int)} + * |
{@link java.net.Socket#setSendBufferSize(int)} + * | SO_SNDBUF + * | {@link HttpConnectionParams#setSendBufferSize(int)} + * |
{@link java.net.Socket#setReceiveBufferSize(int)} + * | SO_RCVBUF + * | {@link HttpConnectionParams#setReceiveBufferSize(int)} + * |
true
if the connection is open
+ */
+ public boolean isOpen() {
+ return isOpen;
+ }
+
+ /**
+ * Closes the connection if stale.
+ *
+ * @return true
if the connection was stale and therefore closed,
+ * false
otherwise.
+ *
+ * @see #isStale()
+ *
+ * @since 3.0
+ */
+ public boolean closeIfStale() throws IOException {
+ if (isOpen && isStale()) {
+ LOG.debug("Connection is stale, closing...");
+ close();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Tests if stale checking is enabled.
+ *
+ * @return true
if enabled
+ *
+ * @see #isStale()
+ *
+ * @deprecated Use {@link HttpConnectionParams#isStaleCheckingEnabled()},
+ * {@link HttpConnection#getParams()}.
+ */
+ public boolean isStaleCheckingEnabled() {
+ return this.params.isStaleCheckingEnabled();
+ }
+
+ /**
+ * Sets whether or not isStale() will be called when testing if this connection is open.
+ *
+ * Setting this flag to false
will increase performance when reusing
+ * connections, but it will also make them less reliable. Stale checking ensures that
+ * connections are viable before they are used. When set to false
some
+ * method executions will result in IOExceptions and they will have to be retried.
true
to enable isStale()
+ *
+ * @see #isStale()
+ * @see #isOpen()
+ *
+ * @deprecated Use {@link HttpConnectionParams#setStaleCheckingEnabled(boolean)},
+ * {@link HttpConnection#getParams()}.
+ */
+ public void setStaleCheckingEnabled(boolean staleCheckEnabled) {
+ this.params.setStaleCheckingEnabled(staleCheckEnabled);
+ }
+
+ /**
+ * Determines whether this connection is "stale", which is to say that either
+ * it is no longer open, or an attempt to read the connection would fail.
+ *
+ * Unfortunately, due to the limitations of the JREs prior to 1.4, it is + * not possible to test a connection to see if both the read and write channels + * are open - except by reading and writing. This leads to a difficulty when + * some connections leave the "write" channel open, but close the read channel + * and ignore the request. This function attempts to ameliorate that + * problem by doing a test read, assuming that the caller will be doing a + * write followed by a read, rather than the other way around. + *
+ * + *To avoid side-effects, the underlying connection is wrapped by a + * {@link BufferedInputStream}, so although data might be read, what is visible + * to clients of the connection will not change with this call.true if the connection is already closed, or a read would + * fail. + */ + protected boolean isStale() throws IOException { + boolean isStale = true; + if (isOpen) { + // the connection is open, but now we have to see if we can read it + // assume the connection is not stale. + isStale = false; + try { + if (inputStream.available() <= 0) { + try { + socket.setSoTimeout(1); + inputStream.mark(1); + int byteRead = inputStream.read(); + if (byteRead == -1) { + // again - if the socket is reporting all data read, + // probably stale + isStale = true; + } else { + inputStream.reset(); + } + } finally { + socket.setSoTimeout(this.params.getSoTimeout()); + } + } + } catch (InterruptedIOException e) { + if (!ExceptionUtil.isSocketTimeoutException(e)) { + throw e; + } + // aha - the connection is NOT stale - continue on! + } catch (IOException e) { + // oops - the connection is stale, the read or soTimeout failed. + LOG.debug( + "An error occurred while reading from the socket, is appears to be stale", + e + ); + isStale = true; + } + } + + return isStale; + } + + /** + * Returns true if the connection is established via a proxy, + * false otherwise. + * + * @return true if a proxy is used to establish the connection, + * false otherwise. + */ + public boolean isProxied() { + return (!(null == proxyHostName || 0 >= proxyPortNumber)); + } + + /** + * Set the state to keep track of the last response for the last request. + * + *
The connection managers use this to ensure that previous requests are + * properly closed before a new request is attempted. That way, a GET + * request need not be read in its entirety before a new request is issued. + * Instead, this stream can be closed as appropriate.
+ * + * @param inStream The stream associated with an HttpMethod. + */ + public void setLastResponseInputStream(InputStream inStream) { + lastResponseInputStream = inStream; + } + + /** + * Returns the stream used to read the last response's body. + * + *Clients will generally not need to call this function unless + * using HttpConnection directly, instead of calling {@link HttpClient#executeMethod}. + * For those clients, call this function, and if it returns a non-null stream, + * close the stream before attempting to execute a method. Note that + * calling "close" on the stream returned by this function may close + * the connection if the previous response contained a "Connection: close" header.
+ * + * @return An {@link InputStream} corresponding to the body of the last + * response. + */ + public InputStream getLastResponseInputStream() { + return lastResponseInputStream; + } + + // --------------------------------------------------- Other Public Methods + + /** + * Returns {@link HttpConnectionParams HTTP protocol parameters} associated with this method. + * + * @return HTTP parameters. + * + * @since 3.0 + */ + public HttpConnectionParams getParams() { + return this.params; + } + + /** + * Assigns {@link HttpConnectionParams HTTP protocol parameters} for this method. + * + * @since 3.0 + * + * @see HttpConnectionParams + */ + public void setParams(final HttpConnectionParams params) { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + this.params = params; + } + + /** + * Set the {@link Socket}'s timeout, via {@link Socket#setSoTimeout}. If the + * connection is already open, the SO_TIMEOUT is changed. If no connection + * is open, then subsequent connections will use the timeout value. + *
+ * Note: This is not a connection timeout but a timeout on network traffic!
+ *
+ * @param timeout the timeout value
+ * @throws SocketException - if there is an error in the underlying
+ * protocol, such as a TCP error.
+ *
+ * @deprecated Use {@link HttpConnectionParams#setSoTimeout(int)},
+ * {@link HttpConnection#getParams()}.
+ */
+ public void setSoTimeout(int timeout)
+ throws SocketException, IllegalStateException {
+ this.params.setSoTimeout(timeout);
+ if (this.socket != null) {
+ this.socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Sets SO_TIMEOUT
value directly on the underlying {@link Socket socket}.
+ * This method does not change the default read timeout value set via
+ * {@link HttpConnectionParams}.
+ *
+ * @param timeout the timeout value
+ * @throws SocketException - if there is an error in the underlying
+ * protocol, such as a TCP error.
+ * @throws IllegalStateException if not connected
+ *
+ * @since 3.0
+ */
+ public void setSocketTimeout(int timeout)
+ throws SocketException, IllegalStateException {
+ assertOpen();
+ if (this.socket != null) {
+ this.socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Returns the {@link Socket}'s timeout, via {@link Socket#getSoTimeout}, if the
+ * connection is already open. If no connection is open, return the value subsequent
+ * connection will use.
+ *
+ * Note: This is not a connection timeout but a timeout on network traffic!
+ *
+ * @return the timeout value
+ *
+ * @deprecated Use {@link HttpConnectionParams#getSoTimeout()},
+ * {@link HttpConnection#getParams()}.
+ */
+ public int getSoTimeout() throws SocketException {
+ return this.params.getSoTimeout();
+ }
+
+ /**
+ * Sets the connection timeout. This is the maximum time that may be spent
+ * until a connection is established. The connection will fail after this
+ * amount of time.
+ * @param timeout The timeout in milliseconds. 0 means timeout is not used.
+ *
+ * @deprecated Use {@link HttpConnectionParams#setConnectionTimeout(int)},
+ * {@link HttpConnection#getParams()}.
+ */
+ public void setConnectionTimeout(int timeout) {
+ this.params.setConnectionTimeout(timeout);
+ }
+
+ /**
+ * Establishes a connection to the specified host and port
+ * (via a proxy if specified).
+ * The underlying socket is created from the {@link ProtocolSocketFactory}.
+ *
+ * @throws IOException if an attempt to establish the connection results in an
+ * I/O error.
+ */
+ public void open() throws IOException {
+ LOG.trace("enter HttpConnection.open()");
+
+ final String host = (proxyHostName == null) ? hostName : proxyHostName;
+ final int port = (proxyHostName == null) ? portNumber : proxyPortNumber;
+ assertNotOpen();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Open connection to " + host + ":" + port);
+ }
+
+ try {
+ if (this.socket == null) {
+ usingSecureSocket = isSecure() && !isProxied();
+ // use the protocol's socket factory unless this is a secure
+ // proxied connection
+ ProtocolSocketFactory socketFactory = null;
+ if (isSecure() && isProxied()) {
+ Protocol defaultprotocol = Protocol.getProtocol("http");
+ socketFactory = defaultprotocol.getSocketFactory();
+ } else {
+ socketFactory = this.protocolInUse.getSocketFactory();
+ }
+ this.socket = socketFactory.createSocket(
+ host, port,
+ localAddress, 0,
+ this.params);
+ }
+
+ /*
+ "Nagling has been broadly implemented across networks,
+ including the Internet, and is generally performed by default
+ - although it is sometimes considered to be undesirable in
+ highly interactive environments, such as some client/server
+ situations. In such cases, nagling may be turned off through
+ use of the TCP_NODELAY sockets option." */
+
+ socket.setTcpNoDelay(this.params.getTcpNoDelay());
+ socket.setSoTimeout(this.params.getSoTimeout());
+
+ int linger = this.params.getLinger();
+ if (linger >= 0) {
+ socket.setSoLinger(linger > 0, linger);
+ }
+
+ int sndBufSize = this.params.getSendBufferSize();
+ if (sndBufSize >= 0) {
+ socket.setSendBufferSize(sndBufSize);
+ }
+ int rcvBufSize = this.params.getReceiveBufferSize();
+ if (rcvBufSize >= 0) {
+ socket.setReceiveBufferSize(rcvBufSize);
+ }
+ int outbuffersize = socket.getSendBufferSize();
+ if ((outbuffersize > 2048) || (outbuffersize <= 0)) {
+ outbuffersize = 2048;
+ }
+ int inbuffersize = socket.getReceiveBufferSize();
+ if ((inbuffersize > 2048) || (inbuffersize <= 0)) {
+ inbuffersize = 2048;
+ }
+ inputStream = new BufferedInputStream(socket.getInputStream(), inbuffersize);
+ outputStream = new BufferedOutputStream(socket.getOutputStream(), outbuffersize);
+ isOpen = true;
+ } catch (IOException e) {
+ // Connection wasn't opened properly
+ // so close everything out
+ closeSocketAndStreams();
+ throw e;
+ }
+ }
+
+ /**
+ * Instructs the proxy to establish a secure tunnel to the host. The socket will
+ * be switched to the secure socket. Subsequent communication is done via the secure
+ * socket. The method can only be called once on a proxied secure connection.
+ *
+ * @throws IllegalStateException if connection is not secure and proxied or
+ * if the socket is already secure.
+ * @throws IOException if an attempt to establish the secure tunnel results in an
+ * I/O error.
+ */
+ public void tunnelCreated() throws IllegalStateException, IOException {
+ LOG.trace("enter HttpConnection.tunnelCreated()");
+
+ if (!isSecure() || !isProxied()) {
+ throw new IllegalStateException(
+ "Connection must be secure "
+ + "and proxied to use this feature");
+ }
+
+ if (usingSecureSocket) {
+ throw new IllegalStateException("Already using a secure socket");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Secure tunnel to " + this.hostName + ":" + this.portNumber);
+ }
+
+ SecureProtocolSocketFactory socketFactory =
+ (SecureProtocolSocketFactory) protocolInUse.getSocketFactory();
+
+ socket = socketFactory.createSocket(socket, hostName, portNumber, true);
+ int sndBufSize = this.params.getSendBufferSize();
+ if (sndBufSize >= 0) {
+ socket.setSendBufferSize(sndBufSize);
+ }
+ int rcvBufSize = this.params.getReceiveBufferSize();
+ if (rcvBufSize >= 0) {
+ socket.setReceiveBufferSize(rcvBufSize);
+ }
+ int outbuffersize = socket.getSendBufferSize();
+ if (outbuffersize > 2048) {
+ outbuffersize = 2048;
+ }
+ int inbuffersize = socket.getReceiveBufferSize();
+ if (inbuffersize > 2048) {
+ inbuffersize = 2048;
+ }
+ inputStream = new BufferedInputStream(socket.getInputStream(), inbuffersize);
+ outputStream = new BufferedOutputStream(socket.getOutputStream(), outbuffersize);
+ usingSecureSocket = true;
+ tunnelEstablished = true;
+ }
+
+ /**
+ * Indicates if the connection is completely transparent from end to end.
+ *
+ * @return true if conncetion is not proxied or tunneled through a transparent
+ * proxy; false otherwise.
+ */
+ public boolean isTransparent() {
+ return !isProxied() || tunnelEstablished;
+ }
+
+ /**
+ * Flushes the output request stream. This method should be called to
+ * ensure that data written to the request OutputStream is sent to the server.
+ *
+ * @throws IOException if an I/O problem occurs
+ */
+ public void flushRequestOutputStream() throws IOException {
+ LOG.trace("enter HttpConnection.flushRequestOutputStream()");
+ assertOpen();
+ outputStream.flush();
+ }
+
+ /**
+ * Returns an {@link OutputStream} suitable for writing the request.
+ *
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ * @return a stream to write the request to
+ */
+ public OutputStream getRequestOutputStream()
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.getRequestOutputStream()");
+ assertOpen();
+ OutputStream out = this.outputStream;
+ if (Wire.CONTENT_WIRE.enabled()) {
+ out = new WireLogOutputStream(out, Wire.CONTENT_WIRE);
+ }
+ return out;
+ }
+
+ /**
+ * Return a {@link InputStream} suitable for reading the response.
+ * @return InputStream The response input stream.
+ * @throws IOException If an IO problem occurs
+ * @throws IllegalStateException If the connection isn't open.
+ */
+ public InputStream getResponseInputStream()
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.getResponseInputStream()");
+ assertOpen();
+ return inputStream;
+ }
+
+ /**
+ * Tests if input data avaialble. This method returns immediately
+ * and does not perform any read operations on the input socket
+ *
+ * @return boolean true if input data is available,
+ * false otherwise.
+ *
+ * @throws IOException If an IO problem occurs
+ * @throws IllegalStateException If the connection isn't open.
+ */
+ public boolean isResponseAvailable()
+ throws IOException {
+ LOG.trace("enter HttpConnection.isResponseAvailable()");
+ if (this.isOpen) {
+ return this.inputStream.available() > 0;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Tests if input data becomes available within the given period time in milliseconds.
+ *
+ * @param timeout The number milliseconds to wait for input data to become available
+ * @return boolean true if input data is availble,
+ * false otherwise.
+ *
+ * @throws IOException If an IO problem occurs
+ * @throws IllegalStateException If the connection isn't open.
+ */
+ public boolean isResponseAvailable(int timeout)
+ throws IOException {
+ LOG.trace("enter HttpConnection.isResponseAvailable(int)");
+ assertOpen();
+ boolean result = false;
+ if (this.inputStream.available() > 0) {
+ result = true;
+ } else {
+ try {
+ this.socket.setSoTimeout(timeout);
+ inputStream.mark(1);
+ int byteRead = inputStream.read();
+ if (byteRead != -1) {
+ inputStream.reset();
+ LOG.debug("Input data available");
+ result = true;
+ } else {
+ LOG.debug("Input data not available");
+ }
+ } catch (InterruptedIOException e) {
+ if (!ExceptionUtil.isSocketTimeoutException(e)) {
+ throw e;
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Input data not available after " + timeout + " ms");
+ }
+ } finally {
+ try {
+ socket.setSoTimeout(this.params.getSoTimeout());
+ } catch (IOException ioe) {
+ LOG.debug("An error ocurred while resetting soTimeout, we will assume that"
+ + " no response is available.",
+ ioe);
+ result = false;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Writes the specified bytes to the output stream.
+ *
+ * @param data the data to be written
+ * @throws IllegalStateException if not connected
+ * @throws IOException if an I/O problem occurs
+ * @see #write(byte[],int,int)
+ */
+ public void write(byte[] data)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.write(byte[])");
+ this.write(data, 0, data.length);
+ }
+
+ /**
+ * Writes length bytes in data starting at
+ * offset to the output stream.
+ *
+ * The general contract for
+ * write(b, off, len) is that some of the bytes in the array b are written
+ * to the output stream in order; element b[off] is the first byte written
+ * and b[off+len-1] is the last byte written by this operation.
+ *
+ * @param data array containing the data to be written.
+ * @param offset the start offset in the data.
+ * @param length the number of bytes to write.
+ * @throws IllegalStateException if not connected
+ * @throws IOException if an I/O problem occurs
+ */
+ public void write(byte[] data, int offset, int length)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.write(byte[], int, int)");
+
+ if (offset < 0) {
+ throw new IllegalArgumentException("Array offset may not be negative");
+ }
+ if (length < 0) {
+ throw new IllegalArgumentException("Array length may not be negative");
+ }
+ if (offset + length > data.length) {
+ throw new IllegalArgumentException("Given offset and length exceed the array length");
+ }
+ assertOpen();
+ this.outputStream.write(data, offset, length);
+ }
+
+ /**
+ * Writes the specified bytes, followed by "\r\n".getBytes() to the
+ * output stream.
+ *
+ * @param data the bytes to be written
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ */
+ public void writeLine(byte[] data)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.writeLine(byte[])");
+ write(data);
+ writeLine();
+ }
+
+ /**
+ * Writes "\r\n".getBytes() to the output stream.
+ *
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ */
+ public void writeLine()
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.writeLine()");
+ write(CRLF);
+ }
+
+ /**
+ * @deprecated Use {@link #print(String, String)}
+ *
+ * Writes the specified String (as bytes) to the output stream.
+ *
+ * @param data the string to be written
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ */
+ public void print(String data)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.print(String)");
+ write(EncodingUtil.getBytes(data, "ISO-8859-1"));
+ }
+
+ /**
+ * Writes the specified String (as bytes) to the output stream.
+ *
+ * @param data the string to be written
+ * @param charset the charset to use for writing the data
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ *
+ * @since 3.0
+ */
+ public void print(String data, String charset)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.print(String)");
+ write(EncodingUtil.getBytes(data, charset));
+ }
+
+ /**
+ * @deprecated Use {@link #printLine(String, String)}
+ *
+ * Writes the specified String (as bytes), followed by
+ * "\r\n".getBytes() to the output stream.
+ *
+ * @param data the data to be written
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ */
+ public void printLine(String data)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.printLine(String)");
+ writeLine(EncodingUtil.getBytes(data, "ISO-8859-1"));
+ }
+
+ /**
+ * Writes the specified String (as bytes), followed by
+ * "\r\n".getBytes() to the output stream.
+ *
+ * @param data the data to be written
+ * @param charset the charset to use for writing the data
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ *
+ * @since 3.0
+ */
+ public void printLine(String data, String charset)
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.printLine(String)");
+ writeLine(EncodingUtil.getBytes(data, charset));
+ }
+
+ /**
+ * Writes "\r\n".getBytes() to the output stream.
+ *
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ */
+ public void printLine()
+ throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.printLine()");
+ writeLine();
+ }
+
+ /**
+ * Reads up to "\n" from the (unchunked) input stream.
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ *
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ * @return a line from the response
+ *
+ * @deprecated use #readLine(String)
+ */
+ public String readLine() throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.readLine()");
+
+ assertOpen();
+ return HttpParser.readLine(inputStream);
+ }
+
+ /**
+ * Reads up to "\n" from the (unchunked) input stream.
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ *
+ * @param charset the charset to use for reading the data
+ *
+ * @throws IllegalStateException if the connection is not open
+ * @throws IOException if an I/O problem occurs
+ * @return a line from the response
+ *
+ * @since 3.0
+ */
+ public String readLine(final String charset) throws IOException, IllegalStateException {
+ LOG.trace("enter HttpConnection.readLine()");
+
+ assertOpen();
+ return HttpParser.readLine(inputStream, charset);
+ }
+
+ /**
+ * Attempts to shutdown the {@link Socket}'s output, via Socket.shutdownOutput()
+ * when running on JVM 1.3 or higher.
+ *
+ * @deprecated unused
+ */
+ public void shutdownOutput() {
+ LOG.trace("enter HttpConnection.shutdownOutput()");
+
+ try {
+ // Socket.shutdownOutput is a JDK 1.3
+ // method. We'll use reflection in case
+ // we're running in an older VM
+ Class[] paramsClasses = new Class[0];
+ Method shutdownOutput =
+ socket.getClass().getMethod("shutdownOutput", paramsClasses);
+ Object[] params = new Object[0];
+ shutdownOutput.invoke(socket, params);
+ } catch (Exception ex) {
+ LOG.debug("Unexpected Exception caught", ex);
+ // Ignore, and hope everything goes right
+ }
+ // close output stream?
+ }
+
+ /**
+ * Closes the socket and streams.
+ */
+ public void close() {
+ LOG.trace("enter HttpConnection.close()");
+ closeSocketAndStreams();
+ }
+
+ /**
+ * Returns the httpConnectionManager.
+ * @return HttpConnectionManager
+ */
+ public HttpConnectionManager getHttpConnectionManager() {
+ return httpConnectionManager;
+ }
+
+ /**
+ * Sets the httpConnectionManager.
+ * @param httpConnectionManager The httpConnectionManager to set
+ */
+ public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
+ this.httpConnectionManager = httpConnectionManager;
+ }
+
+ /**
+ * Releases the connection. If the connection is locked or does not have a connection
+ * manager associated with it, this method has no effect. Note that it is completely safe
+ * to call this method multiple times.
+ */
+ public void releaseConnection() {
+ LOG.trace("enter HttpConnection.releaseConnection()");
+ if (locked) {
+ LOG.debug("Connection is locked. Call to releaseConnection() ignored.");
+ } else if (httpConnectionManager != null) {
+ LOG.debug("Releasing connection back to connection manager.");
+ httpConnectionManager.releaseConnection(this);
+ } else {
+ LOG.warn("HttpConnectionManager is null. Connection cannot be released.");
+ }
+ }
+
+ /**
+ * Tests if the connection is locked. Locked connections cannot be released.
+ * An attempt to release a locked connection will have no effect.
+ *
+ * @return true if the connection is locked, false otherwise.
+ *
+ * @since 3.0
+ */
+ protected boolean isLocked() {
+ return locked;
+ }
+
+ /**
+ * Locks or unlocks the connection. Locked connections cannot be released.
+ * An attempt to release a locked connection will have no effect.
+ *
+ * @param locked true to lock the connection, false to unlock
+ * the connection.
+ *
+ * @since 3.0
+ */
+ protected void setLocked(boolean locked) {
+ this.locked = locked;
+ }
+ // ------------------------------------------------------ Protected Methods
+
+ /**
+ * Closes everything out.
+ */
+ protected void closeSocketAndStreams() {
+ LOG.trace("enter HttpConnection.closeSockedAndStreams()");
+
+ isOpen = false;
+
+ // no longer care about previous responses...
+ lastResponseInputStream = null;
+
+ if (null != outputStream) {
+ OutputStream temp = outputStream;
+ outputStream = null;
+ try {
+ temp.close();
+ } catch (Exception ex) {
+ LOG.debug("Exception caught when closing output", ex);
+ // ignored
+ }
+ }
+
+ if (null != inputStream) {
+ InputStream temp = inputStream;
+ inputStream = null;
+ try {
+ temp.close();
+ } catch (Exception ex) {
+ LOG.debug("Exception caught when closing input", ex);
+ // ignored
+ }
+ }
+
+ if (null != socket) {
+ Socket temp = socket;
+ socket = null;
+ try {
+ temp.close();
+ } catch (Exception ex) {
+ LOG.debug("Exception caught when closing socket", ex);
+ // ignored
+ }
+ }
+
+ tunnelEstablished = false;
+ usingSecureSocket = false;
+ }
+
+ /**
+ * Throws an {@link IllegalStateException} if the connection is already open.
+ *
+ * @throws IllegalStateException if connected
+ */
+ protected void assertNotOpen() throws IllegalStateException {
+ if (isOpen) {
+ throw new IllegalStateException("Connection is open");
+ }
+ }
+
+ /**
+ * Throws an {@link IllegalStateException} if the connection is not open.
+ *
+ * @throws IllegalStateException if not connected
+ */
+ protected void assertOpen() throws IllegalStateException {
+ if (!isOpen) {
+ throw new IllegalStateException("Connection is not open");
+ }
+ }
+
+ /**
+ * Gets the socket's sendBufferSize.
+ *
+ * @return the size of the buffer for the socket OutputStream, -1 if the value
+ * has not been set and the socket has not been opened
+ *
+ * @throws SocketException if an error occurs while getting the socket value
+ *
+ * @see Socket#getSendBufferSize()
+ */
+ public int getSendBufferSize() throws SocketException {
+ if (socket == null) {
+ return -1;
+ } else {
+ return socket.getSendBufferSize();
+ }
+ }
+
+ /**
+ * Sets the socket's sendBufferSize.
+ *
+ * @param sendBufferSize the size to set for the socket OutputStream
+ *
+ * @throws SocketException if an error occurs while setting the socket value
+ *
+ * @see Socket#setSendBufferSize(int)
+ *
+ * @deprecated Use {@link HttpConnectionParams#setSendBufferSize(int)},
+ * {@link HttpConnection#getParams()}.
+ */
+ public void setSendBufferSize(int sendBufferSize) throws SocketException {
+ this.params.setSendBufferSize(sendBufferSize);
+ }
+
+ // ------------------------------------------------------- Static Variable
+
+ /** "\r\n", as bytes. */
+ private static final byte[] CRLF = new byte[] {(byte) 13, (byte) 10};
+
+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(HttpConnection.class);
+
+ // ----------------------------------------------------- Instance Variables
+
+ /** My host. */
+ private String hostName = null;
+
+ /** My port. */
+ private int portNumber = -1;
+
+ /** My proxy host. */
+ private String proxyHostName = null;
+
+ /** My proxy port. */
+ private int proxyPortNumber = -1;
+
+ /** My client Socket. */
+ private Socket socket = null;
+
+ /** My InputStream. */
+ private InputStream inputStream = null;
+
+ /** My OutputStream. */
+ private OutputStream outputStream = null;
+
+ /** An {@link InputStream} for the response to an individual request. */
+ private InputStream lastResponseInputStream = null;
+
+ /** Whether or not the connection is connected. */
+ protected boolean isOpen = false;
+
+ /** the protocol being used */
+ private Protocol protocolInUse;
+
+ /** Collection of HTTP parameters associated with this HTTP connection*/
+ private HttpConnectionParams params = new HttpConnectionParams();
+
+ /** flag to indicate if this connection can be released, if locked the connection cannot be
+ * released */
+ private boolean locked = false;
+
+ /** Whether or not the socket is a secure one. */
+ private boolean usingSecureSocket = false;
+
+ /** Whether the connection is open via a secure tunnel or not */
+ private boolean tunnelEstablished = false;
+
+ /** the connection manager that created this connection or null */
+ private HttpConnectionManager httpConnectionManager;
+
+ /** The local interface on which the connection is created, or null for the default */
+ private InetAddress localAddress;
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnectionManager.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnectionManager.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnectionManager.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,150 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnectionManager.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * null
.
+ * @param port the port. Value -1
can be used to set default protocol port
+ * @param protocol the protocol. Value null
can be used to set default protocol
+ */
+ public HttpHost(final String hostname, int port, final Protocol protocol) {
+ super();
+ if (hostname == null) {
+ throw new IllegalArgumentException("Host name may not be null");
+ }
+ if (protocol == null) {
+ throw new IllegalArgumentException("Protocol may not be null");
+ }
+ this.hostname = hostname;
+ this.protocol = protocol;
+ if (port >= 0) {
+ this.port = port;
+ } else {
+ this.port = this.protocol.getDefaultPort();
+ }
+ }
+
+ /**
+ * Constructor for HttpHost.
+ *
+ * @param hostname the hostname (IP or DNS name). Can be null
.
+ * @param port the port. Value -1
can be used to set default protocol port
+ */
+ public HttpHost(final String hostname, int port) {
+ this(hostname, port, Protocol.getProtocol("http"));
+ }
+
+ /**
+ * Constructor for HttpHost.
+ *
+ * @param hostname the hostname (IP or DNS name). Can be null
.
+ */
+ public HttpHost(final String hostname) {
+ this(hostname, -1, Protocol.getProtocol("http"));
+ }
+
+ /**
+ * URI constructor for HttpHost.
+ *
+ * @param uri the URI.
+ */
+ public HttpHost(final URI uri) throws URIException {
+ this(uri.getHost(), uri.getPort(), Protocol.getProtocol(uri.getScheme()));
+ }
+
+ /**
+ * Copy constructor for HttpHost
+ *
+ * @param httphost the HTTP host to copy details from
+ */
+ public HttpHost (final HttpHost httphost) {
+ super();
+ this.hostname = httphost.hostname;
+ this.port = httphost.port;
+ this.protocol = httphost.protocol;
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ public Object clone() {
+ return new HttpHost(this);
+ }
+
+ /**
+ * Returns the host name (IP or DNS name).
+ *
+ * @return the host name (IP or DNS name), or null
if not set
+ */
+ public String getHostName() {
+ return this.hostname;
+ }
+
+ /**
+ * Returns the port.
+ *
+ * @return the host port, or -1
if not set
+ */
+ public int getPort() {
+ return this.port;
+ }
+
+ /**
+ * Returns the protocol.
+ * @return The protocol.
+ */
+ public Protocol getProtocol() {
+ return this.protocol;
+ }
+
+ /**
+ * Return the host uri.
+ *
+ * @return The host uri.
+ */
+ public String toURI() {
+ StringBuffer buffer = new StringBuffer(50);
+ if (this.protocol != null) {
+ buffer.append(this.protocol.getScheme());
+ buffer.append("://");
+ }
+ buffer.append(this.hostname);
+ if (this.port != this.protocol.getDefaultPort()) {
+ buffer.append(':');
+ buffer.append(this.port);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(50);
+ buffer.append(toURI());
+ return buffer.toString();
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(final Object o) {
+
+ if (o instanceof HttpHost) {
+ // shortcut if we're comparing with ourselves
+ if (o == this) {
+ return true;
+ }
+ HttpHost that = (HttpHost) o;
+ if (!this.hostname.equalsIgnoreCase(that.hostname)) {
+ return false;
+ }
+ if (this.port != that.port) {
+ return false;
+ }
+ if (!this.protocol.equals(that.protocol)) {
+ return false;
+ }
+ // everything matches
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int hash = LangUtils.HASH_SEED;
+ hash = LangUtils.hashCode(hash, this.hostname);
+ hash = LangUtils.hashCode(hash, this.port);
+ hash = LangUtils.hashCode(hash, this.protocol);
+ return hash;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethod.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethod.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethod.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,576 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethod.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ *
+ * HttpMethod interface represents a request to be sent via a + * {@link HttpConnection HTTP connection} and a corresponding response. + *
+ * @author Remy Maucherat + * @author Rod Waldhoff + * @author Jeff Dever + * @author Mike Bowler + * @author Oleg Kalnichevski + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:35 $ + * + * @since 1.0 + */ +public interface HttpMethod { + + // ------------------------------------------- Property Setters and Getters + + /** + * Obtains the name of the HTTP method as used in the HTTP request line, + * for example "GET" or "POST". + * + * @return the name of this method + */ + String getName(); + + /** + * Gets the host configuration for this method. The configuration specifies + * the server, port, protocol, and proxy server via which this method will + * send its HTTP request. + * + * @deprecated no longer applicable + * + * @return the HostConfiguration ornull
if none is set
+ */
+ HostConfiguration getHostConfiguration();
+
+ /**
+ * Sets the path of the HTTP method.
+ * It is responsibility of the caller to ensure that the path is
+ * properly encoded (URL safe).
+ *
+ * @param path The path of the HTTP method. The path is expected
+ * to be URL encoded.
+ */
+ void setPath(String path);
+
+ /**
+ * Returns the path of the HTTP method.
+ *
+ * Calling this method after the request has been executed will
+ * return the actual path, following any redirects automatically
+ * handled by this HTTP method.
+ *
+ * @return the path of the HTTP method, in URL encoded form
+ */
+ String getPath();
+
+ /**
+ * Returns the URI for this method. The URI will be absolute if the host
+ * configuration has been set and relative otherwise.
+ *
+ * @return the URI for this method
+ *
+ * @throws URIException if a URI cannot be constructed
+ */
+ URI getURI() throws URIException;
+
+ /**
+ * Sets the URI for this method.
+ *
+ * @param uri URI to be set
+ *
+ * @throws URIException if a URI cannot be set
+ *
+ * @since 3.0
+ */
+ void setURI(URI uri) throws URIException;
+
+ /**
+ * Defines how strictly the method follows the HTTP protocol specification.
+ * (See RFC 2616 and other relevant RFCs.) In the strict mode the method precisely
+ * implements the requirements of the specification, whereas in non-strict mode
+ * it attempts to mimic the exact behaviour of commonly used HTTP agents,
+ * which many HTTP servers expect.
+ *
+ * @param strictMode true for strict mode, false otherwise
+ *
+ * @deprecated Use {@link org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)}
+ * to exercise a more granular control over HTTP protocol strictness.
+ *
+ * @see #isStrictMode()
+ */
+ void setStrictMode(boolean strictMode);
+
+ /**
+ * Returns the value of the strict mode flag.
+ *
+ * @return true if strict mode is enabled, false otherwise
+ *
+ * @deprecated Use {@link org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)}
+ * to exercise a more granular control over HTTP protocol strictness.
+ *
+ * @see #setStrictMode(boolean)
+ */
+ boolean isStrictMode();
+
+ /**
+ * Sets the specified request header, overwriting any
+ * previous value.
+ * Note that header-name matching is case insensitive.
+ * @param headerName the header's name
+ * @param headerValue the header's value
+ *
+ * @see #setRequestHeader(Header)
+ * @see #getRequestHeader(String)
+ * @see #removeRequestHeader(String)
+ */
+ void setRequestHeader(String headerName, String headerValue);
+
+ /**
+ * Sets the specified request header, overwriting any
+ * previous value.
+ * Note that header-name matching is case insensitive.
+ * @param header the header to be set
+ *
+ * @see #setRequestHeader(String,String)
+ * @see #getRequestHeader(String)
+ * @see #removeRequestHeader(String)
+ */
+ void setRequestHeader(Header header);
+
+ /**
+ * Adds the specified request header, not overwriting any previous value.
+ * If the same header is added multiple times, perhaps with different values,
+ * multiple instances of that header will be sent in the HTTP request.
+ * Note that header-name matching is case insensitive.
+ * @param headerName the header's name
+ * @param headerValue the header's value
+ *
+ * @see #addRequestHeader(Header)
+ * @see #getRequestHeader(String)
+ * @see #removeRequestHeader(String)
+ */
+ void addRequestHeader(String headerName, String headerValue);
+
+ /**
+ * Adds the specified request header, not overwriting any previous value.
+ * If the same header is added multiple times, perhaps with different values,
+ * multiple instances of that header will be sent in the HTTP request.
+ * Note that header-name matching is case insensitive.
+ * @param header the header
+ *
+ * @see #addRequestHeader(String,String)
+ * @see #getRequestHeader(String)
+ * @see #removeRequestHeader(String)
+ */
+ void addRequestHeader(Header header);
+
+ /**
+ * Gets the request header with the given name.
+ * If there are multiple headers with the same name,
+ * there values will be combined with the ',' separator as specified by RFC2616.
+ * Note that header-name matching is case insensitive.
+ * @param headerName the header name
+ * @return the header
+ */
+ Header getRequestHeader(String headerName);
+
+ /**
+ * Removes all request headers with the given name.
+ * Note that header-name matching is case insensitive.
+ * @param headerName the header name
+ */
+ void removeRequestHeader(String headerName);
+
+ /**
+ * Removes the given request header.
+ *
+ * @param header the header
+ *
+ * @since 3.0
+ */
+ void removeRequestHeader(Header header);
+
+ /**
+ * Returns true if the HTTP method should automatically follow HTTP redirects
+ * (status code 302, etc.), false otherwise.
+ *
+ * @return true if the method will automatically follow HTTP redirects,
+ * false otherwise
+ */
+ boolean getFollowRedirects();
+
+ /**
+ * Sets whether or not the HTTP method should automatically follow HTTP redirects
+ * (status code 302, etc.)
+ *
+ * @param followRedirects true if the method will automatically follow redirects,
+ * false otherwise.
+ */
+ void setFollowRedirects(boolean followRedirects);
+
+ /**
+ * Sets the query string of the HTTP method.
+ * It is responsibility of the caller to ensure that the path is
+ * properly encoded (URL safe). The string must not include an initial '?' character.
+ *
+ * @param queryString the query to be used in the request, with no leading '?' character
+ *
+ * @see #getQueryString()
+ * @see #setQueryString(NameValuePair[])
+ */
+ void setQueryString(String queryString);
+
+ /**
+ * Sets the query string of this HTTP method. The pairs are encoded as UTF-8 characters.
+ * To use a different charset the parameters can be encoded manually using EncodingUtil
+ * and set as a single String.
+ *
+ * @param params An array of NameValuePair
s to use as the query string.
+ * The name/value pairs will be automatically URL encoded and should not
+ * have been encoded previously.
+ *
+ * @see #getQueryString()
+ * @see #setQueryString(String)
+ * @see org.apache.commons.httpclient.util.EncodingUtil#formUrlEncode(NameValuePair[], String)
+ */
+ void setQueryString(NameValuePair[] params);
+
+ /**
+ * Returns the query string of this HTTP method.
+ *
+ * @return the query string in URL encoded form, without a leading '?'.
+ *
+ * @see #setQueryString(NameValuePair[])
+ * @see #setQueryString(String)
+ */
+ String getQueryString();
+
+ /**
+ * Returns the current request headers for this HTTP method. The returned headers
+ * will be in the same order that they were added with addRequestHeader
.
+ * If there are multiple request headers with the same name (e.g. Cookie
),
+ * they will be returned as multiple entries in the array.
+ *
+ * @return an array containing all of the request headers
+ *
+ * @see #addRequestHeader(Header)
+ * @see #addRequestHeader(String,String)
+ */
+ Header[] getRequestHeaders();
+
+ /**
+ * Returns the request headers with the given name. Note that header-name matching is
+ * case insensitive.
+ * @param headerName the name of the headers to be returned.
+ * @return an array of zero or more headers
+ *
+ * @since 3.0
+ */
+ Header[] getRequestHeaders(String headerName);
+
+ // ---------------------------------------------------------------- Queries
+
+ /**
+ * Returns true the method is ready to execute, false otherwise.
+ *
+ * @return true if the method is ready to execute, false otherwise.
+ */
+ boolean validate();
+
+ /**
+ * Returns the status code associated with the latest response.
+ *
+ * @return The status code from the most recent execution of this method.
+ * If the method has not yet been executed, the result is undefined.
+ */
+ int getStatusCode();
+
+ /**
+ * Returns the status text (or "reason phrase") associated with the latest
+ * response.
+ *
+ * @return The status text from the most recent execution of this method.
+ * If the method has not yet been executed, the result is undefined.
+ */
+ String getStatusText();
+
+ /**
+ * Returns the response headers from the most recent execution of this request.
+ *
+ * @return A newly-created array containing all of the response headers,
+ * in the order in which they appeared in the response.
+ */
+ Header[] getResponseHeaders();
+
+ /**
+ * Returns the specified response header. Note that header-name matching is
+ * case insensitive.
+ *
+ * @param headerName The name of the header to be returned.
+ *
+ * @return The specified response header. If the repsonse contained multiple
+ * instances of the header, its values will be combined using the ','
+ * separator as specified by RFC2616.
+ */
+ Header getResponseHeader(String headerName);
+
+ /**
+ * Returns the response headers with the given name. Note that header-name matching is
+ * case insensitive.
+ * @param headerName the name of the headers to be returned.
+ * @return an array of zero or more headers
+ *
+ * @since 3.0
+ */
+ Header[] getResponseHeaders(String headerName);
+
+ /**
+ * Returns the response footers from the most recent execution of this request.
+ *
+ * @return an array containing the response footers in the order that they
+ * appeared in the response. If the response had no footers,
+ * an empty array will be returned.
+ */
+ Header[] getResponseFooters();
+
+ /**
+ * Return the specified response footer. Note that footer-name matching is
+ * case insensitive.
+ *
+ * @param footerName The name of the footer.
+ * @return The response footer.
+ */
+ Header getResponseFooter(String footerName);
+
+ /**
+ * Returns the response body of the HTTP method, if any, as an array of bytes.
+ * If the method has not yet been executed or the response has no body, null
+ * is returned. Note that this method does not propagate I/O exceptions.
+ * If an error occurs while reading the body, null
will be returned.
+ *
+ * @return The response body, or null
if the
+ * body is not available.
+ *
+ * @throws IOException if an I/O (transport) problem occurs
+ */
+ byte[] getResponseBody() throws IOException;
+
+ /**
+ * Returns the response body of the HTTP method, if any, as a {@link String}.
+ * If response body is not available or cannot be read, null is returned.
+ * The raw bytes in the body are converted to a String
using the
+ * character encoding specified in the response's Content-Type header, or
+ * ISO-8859-1 if the response did not specify a character set.
+ *
+ * Note that this method does not propagate I/O exceptions.
+ * If an error occurs while reading the body, null
will be returned.
+ *
+ * @return The response body converted to a String
, or null
+ * if the body is not available.
+ *
+ * @throws IOException if an I/O (transport) problem occurs
+ */
+ String getResponseBodyAsString() throws IOException;
+
+ /**
+ * Returns the response body of the HTTP method, if any, as an InputStream.
+ * If the response had no body or the method has not yet been executed,
+ * null
is returned. Additionally, null
may be returned
+ * if {@link #releaseConnection} has been called or
+ * if this method was called previously and the resulting stream was closed.
+ *
+ * @return The response body, or null
if it is not available
+ *
+ * @throws IOException if an I/O (transport) problem occurs
+ */
+ InputStream getResponseBodyAsStream() throws IOException;
+
+ /**
+ * Returns true if the HTTP method has been already {@link #execute executed},
+ * but not {@link #recycle recycled}.
+ *
+ * @return true if the method has been executed, false otherwise
+ */
+ boolean hasBeenUsed();
+
+ // --------------------------------------------------------- Action Methods
+
+ /**
+ * Executes this method using the specified HttpConnection
and
+ * HttpState
.
+ *
+ * @param state the {@link HttpState state} information to associate with this method
+ * @param connection the {@link HttpConnection connection} used to execute
+ * this HTTP method
+ *
+ * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
+ * can be recovered from.
+ * @throws HttpException If a protocol exception occurs. Usually protocol exceptions
+ * cannot be recovered from.
+ *
+ * @return the integer status code if one was obtained, or -1
+ */
+ int execute(HttpState state, HttpConnection connection)
+ throws HttpException, IOException;
+
+ /**
+ * Aborts the execution of the HTTP method.
+ *
+ * @see #execute(HttpState, HttpConnection)
+ *
+ * @since 3.0
+ */
+ void abort();
+
+ /**
+ * Recycles the HTTP method so that it can be used again.
+ * Note that all of the instance variables will be reset
+ * once this method has been called. This method will also
+ * release the connection being used by this HTTP method.
+ *
+ * @see #releaseConnection()
+ *
+ * @deprecated no longer supported and will be removed in the future
+ * version of HttpClient
+ */
+ void recycle();
+
+ /**
+ * Releases the connection being used by this HTTP method. In particular the
+ * connection is used to read the response (if there is one) and will be held
+ * until the response has been read. If the connection can be reused by other
+ * HTTP methods it is NOT closed at this point.
+ *
+ * After this method is called, {@link #getResponseBodyAsStream} will return
+ * null
, and {@link #getResponseBody} and {@link #getResponseBodyAsString}
+ * may return null
.
+ */
+ void releaseConnection();
+
+ /**
+ * Add a footer to this method's response.
+ *
+ * Note: This method is for
+ * internal use only and should not be called by external clients.
+ *
+ * @param footer the footer to add
+ *
+ * @since 2.0
+ */
+ void addResponseFooter(Header footer);
+
+ /**
+ * Returns the Status-Line from the most recent response for this method,
+ * or null
if the method has not been executed.
+ *
+ * @return the status line, or null
if the method has not been executed
+ *
+ * @since 2.0
+ */
+ StatusLine getStatusLine();
+
+ /**
+ * Returns true if the HTTP method should automatically handle HTTP
+ * authentication challenges (status code 401, etc.), false otherwise
+ *
+ * @return true if authentication challenges will be processed
+ * automatically, false otherwise.
+ *
+ * @since 2.0
+ *
+ * @see #setDoAuthentication(boolean)
+ */
+ boolean getDoAuthentication();
+
+ /**
+ * Sets whether or not the HTTP method should automatically handle HTTP
+ * authentication challenges (status code 401, etc.)
+ *
+ * @param doAuthentication true to process authentication challenges
+ * automatically, false otherwise.
+ *
+ * @since 2.0
+ *
+ * @see #getDoAuthentication()
+ */
+ void setDoAuthentication(boolean doAuthentication);
+
+
+ /**
+ * Returns {@link HttpMethodParams HTTP protocol parameters} associated with this method.
+ *
+ * @since 3.0
+ *
+ * @see HttpMethodParams
+ */
+ public HttpMethodParams getParams();
+
+ /**
+ * Assigns {@link HttpMethodParams HTTP protocol parameters} for this method.
+ *
+ * @since 3.0
+ *
+ * @see HttpMethodParams
+ */
+ public void setParams(final HttpMethodParams params);
+
+ /**
+ * Returns the target host {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getHostAuthState();
+
+ /**
+ * Returns the proxy {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getProxyAuthState();
+
+ /**
+ * Returns true if the HTTP has been transmitted to the target
+ * server in its entirety, false otherwise. This flag can be useful
+ * for recovery logic. If the request has not been transmitted in its entirety,
+ * it is safe to retry the failed method.
+ *
+ * @return true if the request has been sent, false otherwise
+ */
+ boolean isRequestSent();
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodBase.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodBase.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,2413 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodBase.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ *
+ * At minimum, subclasses will need to override: + *
+ * When a method requires additional request headers, subclasses will typically + * want to override: + *
+ * When a method expects specific response headers, subclasses may want to + * override: + *
+ * Return -1 when the content-length is unknown. + *
+ * + * @return content length, if Content-Length header is available. + * 0 indicates that the request has no body. + * If Content-Length header is not present, the method + * returns -1. + */ + public long getResponseContentLength() { + Header[] headers = getResponseHeaderGroup().getHeaders("Content-Length"); + if (headers.length == 0) { + return -1; + } + if (headers.length > 1) { + LOG.warn("Multiple content-length headers detected"); + } + for (int i = headers.length - 1; i >= 0; i--) { + Header header = headers[i]; + try { + return Long.parseLong(header.getValue()); + } catch (NumberFormatException e) { + if (LOG.isWarnEnabled()) { + LOG.warn("Invalid content-length value: " + e.getMessage()); + } + } + // See if we can have better luck with another header, if present + } + return -1; + } + + + /** + * Returns the response body of the HTTP method, if any, as an array of bytes. + * If response body is not available or cannot be read, returns null + * + * Note: This will cause the entire response body to be buffered in memory. A + * malicious server may easily exhaust all the VM memory. It is strongly + * recommended, to use getResponseAsStream if the content length of the response + * is unknown or resonably large. + * + * @return The response body. + * + * @throws IOException If an I/O (transport) problem occurs while obtaining the + * response body. + */ + public byte[] getResponseBody() throws IOException { + if (this.responseBody == null) { + InputStream instream = getResponseBodyAsStream(); + if (instream != null) { + long contentLength = getResponseContentLength(); + if (contentLength > Integer.MAX_VALUE) { //guard below cast from overflow + throw new IOException("Content too large to be buffered: "+ contentLength +" bytes"); + } + int limit = getParams().getIntParameter(HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT, 1024*1024); + if ((contentLength == -1) || (contentLength > limit)) { + LOG.warn("Going to buffer response body of large or unknown size. " + +"Using getResponseBodyAsStream instead is recommended."); + } + LOG.debug("Buffering response body"); + ByteArrayOutputStream outstream = new ByteArrayOutputStream( + contentLength > 0 ? (int) contentLength : DEFAULT_INITIAL_BUFFER_SIZE); + byte[] buffer = new byte[4096]; + int len; + while ((len = instream.read(buffer)) > 0) { + outstream.write(buffer, 0, len); + } + outstream.close(); + setResponseStream(null); + this.responseBody = outstream.toByteArray(); + } + } + return this.responseBody; + } + + /** + * Returns the response body of the HTTP method, if any, as an {@link InputStream}. + * If response body is not available, returns null + * + * @return The response body + * + * @throws IOException If an I/O (transport) problem occurs while obtaining the + * response body. + */ + public InputStream getResponseBodyAsStream() throws IOException { + if (responseStream != null) { + return responseStream; + } + if (responseBody != null) { + InputStream byteResponseStream = new ByteArrayInputStream(responseBody); + LOG.debug("re-creating response stream from byte array"); + return byteResponseStream; + } + return null; + } + + /** + * Returns the response body of the HTTP method, if any, as a {@link String}. + * If response body is not available or cannot be read, returns null + * The string conversion on the data is done using the character encoding specified + * in Content-Type header. + * + * Note: This will cause the entire response body to be buffered in memory. A + * malicious server may easily exhaust all the VM memory. It is strongly + * recommended, to use getResponseAsStream if the content length of the response + * is unknown or resonably large. + * + * @return The response body. + * + * @throws IOException If an I/O (transport) problem occurs while obtaining the + * response body. + */ + public String getResponseBodyAsString() throws IOException { + byte[] rawdata = null; + if (responseAvailable()) { + rawdata = getResponseBody(); + } + if (rawdata != null) { + return EncodingUtil.getString(rawdata, getResponseCharSet()); + } else { + return null; + } + } + + /** + * Returns an array of the response footers that the HTTP method currently has + * in the order in which they were read. + * + * @return an array of footers + */ + public Header[] getResponseFooters() { + return getResponseTrailerHeaderGroup().getAllHeaders(); + } + + /** + * Gets the response footer associated with the given name. + * Footer name matching is case insensitive. + * null will be returned if either footerName is + * null or there is no matching footer for footerName + * or there are no footers available. If there are multiple footers + * with the same name, there values will be combined with the ',' separator + * as specified by RFC2616. + * + * @param footerName the footer name to match + * @return the matching footer + */ + public Header getResponseFooter(String footerName) { + if (footerName == null) { + return null; + } else { + return getResponseTrailerHeaderGroup().getCondensedHeader(footerName); + } + } + + /** + * Sets the response stream. + * @param responseStream The new response stream. + */ + protected void setResponseStream(InputStream responseStream) { + this.responseStream = responseStream; + } + + /** + * Returns a stream from which the body of the current response may be read. + * If the method has not yet been executed, ifresponseBodyConsumed
+ * has been called, or if the stream returned by a previous call has been closed,
+ * null
will be returned.
+ *
+ * @return the current response stream
+ */
+ protected InputStream getResponseStream() {
+ return responseStream;
+ }
+
+ /**
+ * Returns the status text (or "reason phrase") associated with the latest
+ * response.
+ *
+ * @return The status text.
+ */
+ public String getStatusText() {
+ return statusLine.getReasonPhrase();
+ }
+
+ /**
+ * Defines how strictly HttpClient follows the HTTP protocol specification
+ * (RFC 2616 and other relevant RFCs). In the strict mode HttpClient precisely
+ * implements the requirements of the specification, whereas in non-strict mode
+ * it attempts to mimic the exact behaviour of commonly used HTTP agents,
+ * which many HTTP servers expect.
+ *
+ * @param strictMode true for strict mode, false otherwise
+ *
+ * @deprecated Use {@link org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)}
+ * to exercise a more granular control over HTTP protocol strictness.
+ */
+ public void setStrictMode(boolean strictMode) {
+ if (strictMode) {
+ this.params.makeStrict();
+ } else {
+ this.params.makeLenient();
+ }
+ }
+
+ /**
+ * @deprecated Use {@link org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)}
+ * to exercise a more granular control over HTTP protocol strictness.
+ *
+ * @return false
+ */
+ public boolean isStrictMode() {
+ return false;
+ }
+
+ /**
+ * Adds the specified request header, NOT overwriting any previous value.
+ * Note that header-name matching is case insensitive.
+ *
+ * @param headerName the header's name
+ * @param headerValue the header's value
+ */
+ public void addRequestHeader(String headerName, String headerValue) {
+ addRequestHeader(new Header(headerName, headerValue));
+ }
+
+ /**
+ * Tests if the connection should be force-closed when no longer needed.
+ *
+ * @return true
if the connection must be closed
+ */
+ protected boolean isConnectionCloseForced() {
+ return this.connectionCloseForced;
+ }
+
+ /**
+ * Sets whether or not the connection should be force-closed when no longer
+ * needed. This value should only be set to true
in abnormal
+ * circumstances, such as HTTP protocol violations.
+ *
+ * @param b true
if the connection must be closed, false
+ * otherwise.
+ */
+ protected void setConnectionCloseForced(boolean b) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Force-close connection: " + b);
+ }
+ this.connectionCloseForced = b;
+ }
+
+ /**
+ * Tests if the connection should be closed after the method has been executed.
+ * The connection will be left open when using HTTP/1.1 or if Connection:
+ * keep-alive header was sent.
+ *
+ * @param conn the connection in question
+ *
+ * @return boolean true if we should close the connection.
+ */
+ protected boolean shouldCloseConnection(HttpConnection conn) {
+ // Connection must be closed due to an abnormal circumstance
+ if (isConnectionCloseForced()) {
+ LOG.debug("Should force-close connection.");
+ return true;
+ }
+
+ Header connectionHeader = null;
+ // In case being connected via a proxy server
+ if (!conn.isTransparent()) {
+ // Check for 'proxy-connection' directive
+ connectionHeader = responseHeaders.getFirstHeader("proxy-connection");
+ }
+ // In all cases Check for 'connection' directive
+ // some non-complaint proxy servers send it instread of
+ // expected 'proxy-connection' directive
+ if (connectionHeader == null) {
+ connectionHeader = responseHeaders.getFirstHeader("connection");
+ }
+ // In case the response does not contain any explict connection
+ // directives, check whether the request does
+ if (connectionHeader == null) {
+ connectionHeader = requestHeaders.getFirstHeader("connection");
+ }
+ if (connectionHeader != null) {
+ if (connectionHeader.getValue().equalsIgnoreCase("close")) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Should close connection in response to directive: "
+ + connectionHeader.getValue());
+ }
+ return true;
+ } else if (connectionHeader.getValue().equalsIgnoreCase("keep-alive")) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Should NOT close connection in response to directive: "
+ + connectionHeader.getValue());
+ }
+ return false;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Unknown directive: " + connectionHeader.toExternalForm());
+ }
+ }
+ }
+ LOG.debug("Resorting to protocol version default close connection policy");
+ // missing or invalid connection header, do the default
+ if (this.effectiveVersion.greaterEquals(HttpVersion.HTTP_1_1)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Should NOT close connection, using " + this.effectiveVersion.toString());
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Should close connection, using " + this.effectiveVersion.toString());
+ }
+ }
+ return this.effectiveVersion.lessEquals(HttpVersion.HTTP_1_0);
+ }
+
+ /**
+ * Tests if the this method is ready to be executed.
+ *
+ * @param state the {@link HttpState state} information associated with this method
+ * @param conn the {@link HttpConnection connection} to be used
+ * @throws HttpException If the method is in invalid state.
+ */
+ private void checkExecuteConditions(HttpState state, HttpConnection conn)
+ throws HttpException {
+
+ if (state == null) {
+ throw new IllegalArgumentException("HttpState parameter may not be null");
+ }
+ if (conn == null) {
+ throw new IllegalArgumentException("HttpConnection parameter may not be null");
+ }
+ if (this.aborted) {
+ throw new IllegalStateException("Method has been aborted");
+ }
+ if (!validate()) {
+ throw new ProtocolException("HttpMethodBase object not valid");
+ }
+ }
+
+ /**
+ * Executes this method using the specified HttpConnection
and
+ * HttpState
.
+ *
+ * @param state {@link HttpState state} information to associate with this
+ * request. Must be non-null.
+ * @param conn the {@link HttpConnection connection} to used to execute
+ * this HTTP method. Must be non-null.
+ *
+ * @return the integer status code if one was obtained, or -1
+ *
+ * @throws IOException if an I/O (transport) error occurs
+ * @throws HttpException if a protocol exception occurs.
+ */
+ public int execute(HttpState state, HttpConnection conn)
+ throws HttpException, IOException {
+
+ LOG.trace("enter HttpMethodBase.execute(HttpState, HttpConnection)");
+
+ // this is our connection now, assign it to a local variable so
+ // that it can be released later
+ this.responseConnection = conn;
+
+ checkExecuteConditions(state, conn);
+ this.statusLine = null;
+ this.connectionCloseForced = false;
+
+ conn.setLastResponseInputStream(null);
+
+ // determine the effective protocol version
+ if (this.effectiveVersion == null) {
+ this.effectiveVersion = this.params.getVersion();
+ }
+
+ writeRequest(state, conn);
+ this.requestSent = true;
+ readResponse(state, conn);
+ // the method has successfully executed
+ used = true;
+
+ return statusLine.getStatusCode();
+ }
+
+ /**
+ * Aborts the execution of this method.
+ *
+ * @since 3.0
+ */
+ public void abort() {
+ if (this.aborted) {
+ return;
+ }
+ this.aborted = true;
+ HttpConnection conn = this.responseConnection;
+ if (conn != null) {
+ conn.close();
+ }
+ }
+
+ /**
+ * Returns true if the HTTP method has been already {@link #execute executed},
+ * but not {@link #recycle recycled}.
+ *
+ * @return true if the method has been executed, false otherwise
+ */
+ public boolean hasBeenUsed() {
+ return used;
+ }
+
+ /**
+ * Recycles the HTTP method so that it can be used again.
+ * Note that all of the instance variables will be reset
+ * once this method has been called. This method will also
+ * release the connection being used by this HTTP method.
+ *
+ * @see #releaseConnection()
+ *
+ * @deprecated no longer supported and will be removed in the future
+ * version of HttpClient
+ */
+ public void recycle() {
+ LOG.trace("enter HttpMethodBase.recycle()");
+
+ releaseConnection();
+
+ path = null;
+ followRedirects = false;
+ doAuthentication = true;
+ queryString = null;
+ getRequestHeaderGroup().clear();
+ getResponseHeaderGroup().clear();
+ getResponseTrailerHeaderGroup().clear();
+ statusLine = null;
+ effectiveVersion = null;
+ aborted = false;
+ used = false;
+ params = new HttpMethodParams();
+ responseBody = null;
+ recoverableExceptionCount = 0;
+ connectionCloseForced = false;
+ hostAuthState.invalidate();
+ proxyAuthState.invalidate();
+ cookiespec = null;
+ requestSent = false;
+ }
+
+ /**
+ * Releases the connection being used by this HTTP method. In particular the
+ * connection is used to read the response(if there is one) and will be held
+ * until the response has been read. If the connection can be reused by other
+ * HTTP methods it is NOT closed at this point.
+ *
+ * @since 2.0
+ */
+ public void releaseConnection() {
+ try {
+ if (this.responseStream != null) {
+ try {
+ // FYI - this may indirectly invoke responseBodyConsumed.
+ this.responseStream.close();
+ } catch (IOException ignore) {
+ }
+ }
+ } finally {
+ ensureConnectionRelease();
+ }
+ }
+
+ /**
+ * Remove the request header associated with the given name. Note that
+ * header-name matching is case insensitive.
+ *
+ * @param headerName the header name
+ */
+ public void removeRequestHeader(String headerName) {
+
+ Header[] headers = getRequestHeaderGroup().getHeaders(headerName);
+ for (int i = 0; i < headers.length; i++) {
+ getRequestHeaderGroup().removeHeader(headers[i]);
+ }
+
+ }
+
+ /**
+ * Removes the given request header.
+ *
+ * @param header the header
+ */
+ public void removeRequestHeader(final Header header) {
+ if (header == null) {
+ return;
+ }
+ getRequestHeaderGroup().removeHeader(header);
+ }
+
+ // ---------------------------------------------------------------- Queries
+
+ /**
+ * Returns true the method is ready to execute, false otherwise.
+ *
+ * @return This implementation always returns true.
+ */
+ public boolean validate() {
+ return true;
+ }
+
+
+ /**
+ * Returns the actual cookie policy
+ *
+ * @param state HTTP state. TODO: to be removed in the future
+ *
+ * @return cookie spec
+ */
+ private CookieSpec getCookieSpec(final HttpState state) {
+ if (this.cookiespec == null) {
+ int i = state.getCookiePolicy();
+ if (i == -1) {
+ this.cookiespec = CookiePolicy.getCookieSpec(this.params.getCookiePolicy());
+ } else {
+ this.cookiespec = CookiePolicy.getSpecByPolicy(i);
+ }
+ this.cookiespec.setValidDateFormats(
+ (Collection)this.params.getParameter(HttpMethodParams.DATE_PATTERNS));
+ }
+ return this.cookiespec;
+ }
+
+ /**
+ * Generates Cookie request headers for those {@link Cookie cookie}s
+ * that match the given host, port and path.
+ *
+ * @param state the {@link HttpState state} information associated with this method
+ * @param conn the {@link HttpConnection connection} used to execute
+ * this HTTP method
+ *
+ * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
+ * can be recovered from.
+ * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
+ * cannot be recovered from.
+ */
+ protected void addCookieRequestHeader(HttpState state, HttpConnection conn)
+ throws IOException, HttpException {
+
+ LOG.trace("enter HttpMethodBase.addCookieRequestHeader(HttpState, "
+ + "HttpConnection)");
+
+ Header[] cookieheaders = getRequestHeaderGroup().getHeaders("Cookie");
+ for (int i = 0; i < cookieheaders.length; i++) {
+ Header cookieheader = cookieheaders[i];
+ if (cookieheader.isAutogenerated()) {
+ getRequestHeaderGroup().removeHeader(cookieheader);
+ }
+ }
+
+ CookieSpec matcher = getCookieSpec(state);
+ String host = this.params.getVirtualHost();
+ if (host == null) {
+ host = conn.getHost();
+ }
+ Cookie[] cookies = matcher.match(host, conn.getPort(),
+ getPath(), conn.isSecure(), state.getCookies());
+ if ((cookies != null) && (cookies.length > 0)) {
+ if (getParams().isParameterTrue(HttpMethodParams.SINGLE_COOKIE_HEADER)) {
+ // In strict mode put all cookies on the same header
+ String s = matcher.formatCookies(cookies);
+ getRequestHeaderGroup().addHeader(new Header("Cookie", s, true));
+ } else {
+ // In non-strict mode put each cookie on a separate header
+ for (int i = 0; i < cookies.length; i++) {
+ String s = matcher.formatCookie(cookies[i]);
+ getRequestHeaderGroup().addHeader(new Header("Cookie", s, true));
+ }
+ }
+ }
+ }
+
+ /**
+ * Generates Host request header, as long as no Host request
+ * header already exists.
+ *
+ * @param state the {@link HttpState state} information associated with this method
+ * @param conn the {@link HttpConnection connection} used to execute
+ * this HTTP method
+ *
+ * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
+ * can be recovered from.
+ * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
+ * cannot be recovered from.
+ */
+ protected void addHostRequestHeader(HttpState state, HttpConnection conn)
+ throws IOException, HttpException {
+ LOG.trace("enter HttpMethodBase.addHostRequestHeader(HttpState, "
+ + "HttpConnection)");
+
+ // Per 19.6.1.1 of RFC 2616, it is legal for HTTP/1.0 based
+ // applications to send the Host request-header.
+ // TODO: Add the ability to disable the sending of this header for
+ // HTTP/1.0 requests.
+ String host = this.params.getVirtualHost();
+ if (host != null) {
+ LOG.debug("Using virtual host name: " + host);
+ } else {
+ host = conn.getHost();
+ }
+ int port = conn.getPort();
+
+ // Note: RFC 2616 uses the term "internet host name" for what goes on the
+ // host line. It would seem to imply that host should be blank if the
+ // host is a number instead of an name. Based on the behavior of web
+ // browsers, and the fact that RFC 2616 never defines the phrase "internet
+ // host name", and the bad behavior of HttpClient that follows if we
+ // send blank, I interpret this as a small misstatement in the RFC, where
+ // they meant to say "internet host". So IP numbers get sent as host
+ // entries too. -- Eric Johnson 12/13/2002
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding Host request header");
+ }
+
+ //appends the port only if not using the default port for the protocol
+ if (conn.getProtocol().getDefaultPort() != port) {
+ host += (":" + port);
+ }
+
+ setRequestHeader("Host", host);
+ }
+
+ /**
+ * Generates Proxy-Connection: Keep-Alive request header when
+ * communicating via a proxy server.
+ *
+ * @param state the {@link HttpState state} information associated with this method
+ * @param conn the {@link HttpConnection connection} used to execute
+ * this HTTP method
+ *
+ * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
+ * can be recovered from.
+ * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
+ * cannot be recovered from.
+ */
+ protected void addProxyConnectionHeader(HttpState state,
+ HttpConnection conn)
+ throws IOException, HttpException {
+ LOG.trace("enter HttpMethodBase.addProxyConnectionHeader("
+ + "HttpState, HttpConnection)");
+ if (!conn.isTransparent()) {
+ if (getRequestHeader("Proxy-Connection") == null) {
+ addRequestHeader("Proxy-Connection", "Keep-Alive");
+ }
+ }
+ }
+
+ /**
+ * Generates all the required request {@link Header header}s
+ * to be submitted via the given {@link HttpConnection connection}.
+ *
+ * + * This implementation adds User-Agent, Host, + * Cookie, Authorization, Proxy-Authorization + * and Proxy-Connection headers, when appropriate. + *
+ * + *+ * Subclasses may want to override this method to to add additional + * headers, and may choose to invoke this implementation (via + * super) to add the "standard" headers. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #writeRequestHeaders + */ + protected void addRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter HttpMethodBase.addRequestHeaders(HttpState, " + + "HttpConnection)"); + + addUserAgentRequestHeader(state, conn); + addHostRequestHeader(state, conn); + addCookieRequestHeader(state, conn); + addProxyConnectionHeader(state, conn); + } + + /** + * Generates default User-Agent request header, as long as no + * User-Agent request header already exists. + * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + protected void addUserAgentRequestHeader(HttpState state, + HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter HttpMethodBase.addUserAgentRequestHeaders(HttpState, " + + "HttpConnection)"); + + if (getRequestHeader("User-Agent") == null) { + String agent = (String)getParams().getParameter(HttpMethodParams.USER_AGENT); + if (agent == null) { + agent = "Jakarta Commons-HttpClient"; + } + setRequestHeader("User-Agent", agent); + } + } + + /** + * Throws an {@link IllegalStateException} if the HTTP method has been already + * {@link #execute executed}, but not {@link #recycle recycled}. + * + * @throws IllegalStateException if the method has been used and not + * recycled + */ + protected void checkNotUsed() throws IllegalStateException { + if (used) { + throw new IllegalStateException("Already used."); + } + } + + /** + * Throws an {@link IllegalStateException} if the HTTP method has not been + * {@link #execute executed} since last {@link #recycle recycle}. + * + * + * @throws IllegalStateException if not used + */ + protected void checkUsed() throws IllegalStateException { + if (!used) { + throw new IllegalStateException("Not Used."); + } + } + + // ------------------------------------------------- Static Utility Methods + + /** + * Generates HTTP request line according to the specified attributes. + * + * @param connection the {@link HttpConnection connection} used to execute + * this HTTP method + * @param name the method name generate a request for + * @param requestPath the path string for the request + * @param query the query string for the request + * @param version the protocol version to use (e.g. HTTP/1.0) + * + * @return HTTP request line + */ + protected static String generateRequestLine(HttpConnection connection, + String name, String requestPath, String query, String version) { + LOG.trace("enter HttpMethodBase.generateRequestLine(HttpConnection, " + + "String, String, String, String)"); + + StringBuffer buf = new StringBuffer(); + // Append method name + buf.append(name); + buf.append(" "); + // Absolute or relative URL? + if (!connection.isTransparent()) { + Protocol protocol = connection.getProtocol(); + buf.append(protocol.getScheme().toLowerCase()); + buf.append("://"); + buf.append(connection.getHost()); + if ((connection.getPort() != -1) + && (connection.getPort() != protocol.getDefaultPort()) + ) { + buf.append(":"); + buf.append(connection.getPort()); + } + } + // Append path, if any + if (requestPath == null) { + buf.append("/"); + } else { + if (!connection.isTransparent() && !requestPath.startsWith("/")) { + buf.append("/"); + } + buf.append(requestPath); + } + // Append query, if any + if (query != null) { + if (query.indexOf("?") != 0) { + buf.append("?"); + } + buf.append(query); + } + // Append protocol + buf.append(" "); + buf.append(version); + buf.append("\r\n"); + + return buf.toString(); + } + + /** + * This method is invoked immediately after + * {@link #readResponseBody(HttpState,HttpConnection)} and can be overridden by + * sub-classes in order to provide custom body processing. + * + *+ * This implementation does nothing. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @see #readResponse + * @see #readResponseBody + */ + protected void processResponseBody(HttpState state, HttpConnection conn) { + } + + /** + * This method is invoked immediately after + * {@link #readResponseHeaders(HttpState,HttpConnection)} and can be overridden by + * sub-classes in order to provide custom response headers processing. + + *+ * This implementation will handle the Set-Cookie and + * Set-Cookie2 headers, if any, adding the relevant cookies to + * the given {@link HttpState}. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @see #readResponse + * @see #readResponseHeaders + */ + protected void processResponseHeaders(HttpState state, + HttpConnection conn) { + LOG.trace("enter HttpMethodBase.processResponseHeaders(HttpState, " + + "HttpConnection)"); + + Header[] headers = getResponseHeaderGroup().getHeaders("set-cookie2"); + //Only process old style set-cookie headers if new style headres + //are not present + if (headers.length == 0) { + headers = getResponseHeaderGroup().getHeaders("set-cookie"); + } + + CookieSpec parser = getCookieSpec(state); + String host = this.params.getVirtualHost(); + if (host == null) { + host = conn.getHost(); + } + for (int i = 0; i < headers.length; i++) { + Header header = headers[i]; + Cookie[] cookies = null; + try { + cookies = parser.parse( + host, + conn.getPort(), + getPath(), + conn.isSecure(), + header); + } catch (MalformedCookieException e) { + if (LOG.isWarnEnabled()) { + LOG.warn("Invalid cookie header: \"" + + header.getValue() + + "\". " + e.getMessage()); + } + } + if (cookies != null) { + for (int j = 0; j < cookies.length; j++) { + Cookie cookie = cookies[j]; + try { + parser.validate( + host, + conn.getPort(), + getPath(), + conn.isSecure(), + cookie); + state.addCookie(cookie); + if (LOG.isDebugEnabled()) { + LOG.debug("Cookie accepted: \"" + + parser.formatCookie(cookie) + "\""); + } + } catch (MalformedCookieException e) { + if (LOG.isWarnEnabled()) { + LOG.warn("Cookie rejected: \"" + parser.formatCookie(cookie) + + "\". " + e.getMessage()); + } + } + } + } + } + } + + /** + * This method is invoked immediately after + * {@link #readStatusLine(HttpState,HttpConnection)} and can be overridden by + * sub-classes in order to provide custom response status line processing. + * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @see #readResponse + * @see #readStatusLine + */ + protected void processStatusLine(HttpState state, HttpConnection conn) { + } + + /** + * Reads the response from the given {@link HttpConnection connection}. + * + *+ * The response is processed as the following sequence of actions: + * + *
+ * The current implementation wraps the socket level stream with + * an appropriate stream for the type of response (chunked, content-length, + * or auto-close). If there is no response body, the connection associated + * with the request will be returned to the connection manager. + *
+ * + *+ * Subclasses may want to override this method to to customize the + * processing. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #readResponse + * @see #processResponseBody + */ + protected void readResponseBody(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace( + "enter HttpMethodBase.readResponseBody(HttpState, HttpConnection)"); + + // assume we are not done with the connection if we get a stream + InputStream stream = readResponseBody(conn); + if (stream == null) { + // done using the connection! + responseBodyConsumed(); + } else { + conn.setLastResponseInputStream(stream); + setResponseStream(stream); + } + } + + /** + * Returns the response body as an {@link InputStream input stream} + * corresponding to the values of the Content-Length and + * Transfer-Encoding headers. If no response body is available + * returns null. + *+ * + * @see #readResponse + * @see #processResponseBody + * + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + private InputStream readResponseBody(HttpConnection conn) + throws HttpException, IOException { + + LOG.trace("enter HttpMethodBase.readResponseBody(HttpConnection)"); + + responseBody = null; + InputStream is = conn.getResponseInputStream(); + if (Wire.CONTENT_WIRE.enabled()) { + is = new WireLogInputStream(is, Wire.CONTENT_WIRE); + } + boolean canHaveBody = canResponseHaveBody(statusLine.getStatusCode()); + InputStream result = null; + Header transferEncodingHeader = responseHeaders.getFirstHeader("Transfer-Encoding"); + // We use Transfer-Encoding if present and ignore Content-Length. + // RFC2616, 4.4 item number 3 + if (transferEncodingHeader != null) { + + String transferEncoding = transferEncodingHeader.getValue(); + if (!"chunked".equalsIgnoreCase(transferEncoding) + && !"identity".equalsIgnoreCase(transferEncoding)) { + if (LOG.isWarnEnabled()) { + LOG.warn("Unsupported transfer encoding: " + transferEncoding); + } + } + HeaderElement[] encodings = transferEncodingHeader.getElements(); + // The chunked encoding must be the last one applied + // RFC2616, 14.41 + int len = encodings.length; + if ((len > 0) && ("chunked".equalsIgnoreCase(encodings[len - 1].getName()))) { + // if response body is empty + if (conn.isResponseAvailable(conn.getParams().getSoTimeout())) { + result = new ChunkedInputStream(is, this); + } else { + if (getParams().isParameterTrue(HttpMethodParams.STRICT_TRANSFER_ENCODING)) { + throw new ProtocolException("Chunk-encoded body declared but not sent"); + } else { + LOG.warn("Chunk-encoded body missing"); + } + } + } else { + LOG.info("Response content is not chunk-encoded"); + // The connection must be terminated by closing + // the socket as per RFC 2616, 3.6 + setConnectionCloseForced(true); + result = is; + } + } else { + long expectedLength = getResponseContentLength(); + if (expectedLength == -1) { + if (canHaveBody && this.effectiveVersion.greaterEquals(HttpVersion.HTTP_1_1)) { + Header connectionHeader = responseHeaders.getFirstHeader("Connection"); + String connectionDirective = null; + if (connectionHeader != null) { + connectionDirective = connectionHeader.getValue(); + } + if (!"close".equalsIgnoreCase(connectionDirective)) { + LOG.info("Response content length is not known"); + setConnectionCloseForced(true); + } + } + result = is; + } else { + result = new ContentLengthInputStream(is, expectedLength); + } + } + + // See if the response is supposed to have a response body + if (!canHaveBody) { + result = null; + } + // if there is a result - ALWAYS wrap it in an observer which will + // close the underlying stream as soon as it is consumed, and notify + // the watcher that the stream has been consumed. + if (result != null) { + + result = new AutoCloseInputStream( + result, + new ResponseConsumedWatcher() { + public void responseConsumed() { + responseBodyConsumed(); + } + } + ); + } + + return result; + } + + /** + * Reads the response headers from the given {@link HttpConnection connection}. + * + *
+ * Subclasses may want to override this method to to customize the + * processing. + *
+ * + *+ * "It must be possible to combine the multiple header fields into one + * "field-name: field-value" pair, without changing the semantics of the + * message, by appending each subsequent field-value to the first, each + * separated by a comma." - HTTP/1.0 (4.3) + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #readResponse + * @see #processResponseHeaders + */ + protected void readResponseHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter HttpMethodBase.readResponseHeaders(HttpState," + + "HttpConnection)"); + + getResponseHeaderGroup().clear(); + + Header[] headers = HttpParser.parseHeaders( + conn.getResponseInputStream(), getParams().getHttpElementCharset()); + if (Wire.HEADER_WIRE.enabled()) { + for (int i = 0; i < headers.length; i++) { + Wire.HEADER_WIRE.input(headers[i].toExternalForm()); + } + } + getResponseHeaderGroup().setHeaders(headers); + } + + /** + * Read the status line from the given {@link HttpConnection}, setting my + * {@link #getStatusCode status code} and {@link #getStatusText status + * text}. + * + *+ * Subclasses may want to override this method to to customize the + * processing. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see StatusLine + */ + protected void readStatusLine(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter HttpMethodBase.readStatusLine(HttpState, HttpConnection)"); + + final int maxGarbageLines = getParams(). + getIntParameter(HttpMethodParams.STATUS_LINE_GARBAGE_LIMIT, Integer.MAX_VALUE); + + //read out the HTTP status string + int count = 0; + String s; + do { + s = conn.readLine(getParams().getHttpElementCharset()); + if (s == null && count == 0) { + // The server just dropped connection on us + throw new NoHttpResponseException("The server " + conn.getHost() + + " failed to respond"); + } + if (Wire.HEADER_WIRE.enabled()) { + Wire.HEADER_WIRE.input(s + "\r\n"); + } + if (s != null && StatusLine.startsWithHTTP(s)) { + // Got one + break; + } else if (s == null || count >= maxGarbageLines) { + // Giving up + throw new ProtocolException("The server " + conn.getHost() + + " failed to respond with a valid HTTP response"); + } + count++; + } while(true); + + //create the status line from the status string + statusLine = new StatusLine(s); + + //check for a valid HTTP-Version + String versionStr = statusLine.getHttpVersion(); + if (getParams().isParameterFalse(HttpMethodParams.UNAMBIGUOUS_STATUS_LINE) + && versionStr.equals("HTTP")) { + getParams().setVersion(HttpVersion.HTTP_1_0); + if (LOG.isWarnEnabled()) { + LOG.warn("Ambiguous status line (HTTP protocol version missing):" + + statusLine.toString()); + } + } else { + this.effectiveVersion = HttpVersion.parse(versionStr); + } + + } + + // ------------------------------------------------------ Protected Methods + + /** + *+ * Sends the request via the given {@link HttpConnection connection}. + *
+ * + *+ * The request is written as the following sequence of actions: + *
+ * + *+ * Subclasses may want to override one or more of the above methods to to + * customize the processing. (Or they may choose to override this method + * if dramatically different processing is required.) + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + protected void writeRequest(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace( + "enter HttpMethodBase.writeRequest(HttpState, HttpConnection)"); + writeRequestLine(state, conn); + writeRequestHeaders(state, conn); + conn.writeLine(); // close head + if (Wire.HEADER_WIRE.enabled()) { + Wire.HEADER_WIRE.output("\r\n"); + } + + HttpVersion ver = getParams().getVersion(); + Header expectheader = getRequestHeader("Expect"); + String expectvalue = null; + if (expectheader != null) { + expectvalue = expectheader.getValue(); + } + if ((expectvalue != null) + && (expectvalue.compareToIgnoreCase("100-continue") == 0)) { + if (ver.greaterEquals(HttpVersion.HTTP_1_1)) { + + // make sure the status line and headers have been sent + conn.flushRequestOutputStream(); + + int readTimeout = conn.getParams().getSoTimeout(); + try { + conn.setSocketTimeout(RESPONSE_WAIT_TIME_MS); + readStatusLine(state, conn); + processStatusLine(state, conn); + readResponseHeaders(state, conn); + processResponseHeaders(state, conn); + + if (this.statusLine.getStatusCode() == HttpStatus.SC_CONTINUE) { + // Discard status line + this.statusLine = null; + LOG.debug("OK to continue received"); + } else { + return; + } + } catch (InterruptedIOException e) { + if (!ExceptionUtil.isSocketTimeoutException(e)) { + throw e; + } + // Most probably Expect header is not recongnized + // Remove the header to signal the method + // that it's okay to go ahead with sending data + removeRequestHeader("Expect"); + LOG.info("100 (continue) read timeout. Resume sending the request"); + } finally { + conn.setSocketTimeout(readTimeout); + } + + } else { + removeRequestHeader("Expect"); + LOG.info("'Expect: 100-continue' handshake is only supported by " + + "HTTP/1.1 or higher"); + } + } + + writeRequestBody(state, conn); + // make sure the entire request body has been sent + conn.flushRequestOutputStream(); + } + + /** + * Writes the request body to the given {@link HttpConnection connection}. + * + *+ * This method should return true if the request body was actually + * sent (or is empty), or false if it could not be sent for some + * reason. + *
+ * + *+ * This implementation writes nothing and returns true. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @return true + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + protected boolean writeRequestBody(HttpState state, HttpConnection conn) + throws IOException, HttpException { + return true; + } + + /** + * Writes the request headers to the given {@link HttpConnection connection}. + * + *+ * This implementation invokes {@link #addRequestHeaders(HttpState,HttpConnection)}, + * and then writes each header to the request stream. + *
+ * + *+ * Subclasses may want to override this method to to customize the + * processing. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #addRequestHeaders + * @see #getRequestHeaders + */ + protected void writeRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter HttpMethodBase.writeRequestHeaders(HttpState," + + "HttpConnection)"); + addRequestHeaders(state, conn); + + String charset = getParams().getHttpElementCharset(); + + Header[] headers = getRequestHeaders(); + for (int i = 0; i < headers.length; i++) { + String s = headers[i].toExternalForm(); + if (Wire.HEADER_WIRE.enabled()) { + Wire.HEADER_WIRE.output(s); + } + conn.print(s, charset); + } + } + + /** + * Writes the request line to the given {@link HttpConnection connection}. + * + *+ * Subclasses may want to override this method to to customize the + * processing. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #generateRequestLine + */ + protected void writeRequestLine(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace( + "enter HttpMethodBase.writeRequestLine(HttpState, HttpConnection)"); + String requestLine = getRequestLine(conn); + if (Wire.HEADER_WIRE.enabled()) { + Wire.HEADER_WIRE.output(requestLine); + } + conn.print(requestLine, getParams().getHttpElementCharset()); + } + + /** + * Returns the request line. + * + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @return The request line. + */ + private String getRequestLine(HttpConnection conn) { + return HttpMethodBase.generateRequestLine(conn, getName(), + getPath(), getQueryString(), this.effectiveVersion.toString()); + } + + /** + * Returns {@link HttpMethodParams HTTP protocol parameters} associated with this method. + * + * @return HTTP parameters. + * + * @since 3.0 + */ + public HttpMethodParams getParams() { + return this.params; + } + + /** + * Assigns {@link HttpMethodParams HTTP protocol parameters} for this method. + * + * @since 3.0 + * + * @see HttpMethodParams + */ + public void setParams(final HttpMethodParams params) { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + this.params = params; + } + + /** + * Returns the HTTP version used with this method (may be null + * if undefined, that is, the method has not been executed) + * + * @return HTTP version. + * + * @since 3.0 + */ + public HttpVersion getEffectiveVersion() { + return this.effectiveVersion; + } + + /** + * Per RFC 2616 section 4.3, some response can never contain a message + * body. + * + * @param status - the HTTP status code + * + * @return true if the message may contain a body, false if it can not + * contain a message body + */ + private static boolean canResponseHaveBody(int status) { + LOG.trace("enter HttpMethodBase.canResponseHaveBody(int)"); + + boolean result = true; + + if ((status >= 100 && status <= 199) || (status == 204) + || (status == 304)) { // NOT MODIFIED + result = false; + } + + return result; + } + + /** + * Returns proxy authentication realm, if it has been used during authentication process. + * Otherwise returns null. + * + * @return proxy authentication realm + * + * @deprecated use #getProxyAuthState() + */ + public String getProxyAuthenticationRealm() { + return this.proxyAuthState.getRealm(); + } + + /** + * Returns authentication realm, if it has been used during authentication process. + * Otherwise returns null. + * + * @return authentication realm + * + * @deprecated use #getHostAuthState() + */ + public String getAuthenticationRealm() { + return this.hostAuthState.getRealm(); + } + + /** + * Returns the character set from the Content-Type header. + * + * @param contentheader The content header. + * @return String The character set. + */ + protected String getContentCharSet(Header contentheader) { + LOG.trace("enter getContentCharSet( Header contentheader )"); + String charset = null; + if (contentheader != null) { + 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(); + } + } + } + if (charset == null) { + charset = getParams().getContentCharset(); + if (LOG.isDebugEnabled()) { + LOG.debug("Default charset used: " + charset); + } + } + return charset; + } + + + /** + * Returns the character encoding of the request from the Content-Type header. + * + * @return String The character set. + */ + public String getRequestCharSet() { + return getContentCharSet(getRequestHeader("Content-Type")); + } + + + /** + * Returns the character encoding of the response from the Content-Type header. + * + * @return String The character set. + */ + public String getResponseCharSet() { + return getContentCharSet(getResponseHeader("Content-Type")); + } + + /** + * @deprecated no longer used + * + * Returns the number of "recoverable" exceptions thrown and handled, to + * allow for monitoring the quality of the connection. + * + * @return The number of recoverable exceptions handled by the method. + */ + public int getRecoverableExceptionCount() { + return recoverableExceptionCount; + } + + /** + * A response has been consumed. + * + *The default behavior for this class is to check to see if the connection + * should be closed, and close if need be, and to ensure that the connection + * is returned to the connection manager - if and only if we are not still + * inside the execute call.
+ * + */ + protected void responseBodyConsumed() { + + // make sure this is the initial invocation of the notification, + // ignore subsequent ones. + responseStream = null; + if (responseConnection != null) { + responseConnection.setLastResponseInputStream(null); + + // At this point, no response data should be available. + // If there is data available, regard the connection as being + // unreliable and close it. + + if (shouldCloseConnection(responseConnection)) { + responseConnection.close(); + } else { + try { + if(responseConnection.isResponseAvailable()) { + boolean logExtraInput = + getParams().isParameterTrue(HttpMethodParams.WARN_EXTRA_INPUT); + + if(logExtraInput) { + LOG.warn("Extra response data detected - closing connection"); + } + responseConnection.close(); + } + } + catch (IOException e) { + LOG.warn(e.getMessage()); + responseConnection.close(); + } + } + } + this.connectionCloseForced = false; + ensureConnectionRelease(); + } + + /** + * Insure that the connection is released back to the pool. + */ + private void ensureConnectionRelease() { + if (responseConnection != null) { + responseConnection.releaseConnection(); + responseConnection = null; + } + } + + /** + * Returns the {@link HostConfiguration host configuration}. + * + * @return the host configuration + * + * @deprecated no longer applicable + */ + public HostConfiguration getHostConfiguration() { + HostConfiguration hostconfig = new HostConfiguration(); + hostconfig.setHost(this.httphost); + return hostconfig; + } + /** + * Sets the {@link HostConfiguration host configuration}. + * + * @param hostconfig The hostConfiguration to set + * + * @deprecated no longer applicable + */ + public void setHostConfiguration(final HostConfiguration hostconfig) { + if (hostconfig != null) { + this.httphost = new HttpHost( + hostconfig.getHost(), + hostconfig.getPort(), + hostconfig.getProtocol()); + } else { + this.httphost = null; + } + } + + /** + * Returns the {@link MethodRetryHandler retry handler} for this HTTP method + * + * @return the methodRetryHandler + * + * @deprecated use {@link HttpMethodParams} + */ + public MethodRetryHandler getMethodRetryHandler() { + return methodRetryHandler; + } + + /** + * Sets the {@link MethodRetryHandler retry handler} for this HTTP method + * + * @param handler the methodRetryHandler to use when this method executed + * + * @deprecated use {@link HttpMethodParams} + */ + public void setMethodRetryHandler(MethodRetryHandler handler) { + methodRetryHandler = handler; + } + + /** + * This method is a dirty hack intended to work around + * current (2.0) design flaw that prevents the user from + * obtaining correct status code, headers and response body from the + * preceding HTTP CONNECT method. + * + * TODO: Remove this crap as soon as possible + */ + void fakeResponse( + StatusLine statusline, + HeaderGroup responseheaders, + InputStream responseStream + ) { + // set used so that the response can be read + this.used = true; + this.statusLine = statusline; + this.responseHeaders = responseheaders; + this.responseBody = null; + this.responseStream = responseStream; + } + + /** + * Returns the target host {@link AuthState authentication state} + * + * @return host authentication state + * + * @since 3.0 + */ + public AuthState getHostAuthState() { + return this.hostAuthState; + } + + /** + * Returns the proxy {@link AuthState authentication state} + * + * @return host authentication state + * + * @since 3.0 + */ + public AuthState getProxyAuthState() { + return this.proxyAuthState; + } + + /** + * Tests whether the execution of this method has been aborted + * + * @return true if the execution of this method has been aborted, + * false otherwise + * + * @since 3.0 + */ + public boolean isAborted() { + return this.aborted; + } + + /** + * Returns true if the HTTP has been transmitted to the target + * server in its entirety, false otherwise. This flag can be useful + * for recovery logic. If the request has not been transmitted in its entirety, + * it is safe to retry the failed method. + * + * @return true if the request has been sent, false otherwise + */ + public boolean isRequestSent() { + return this.requestSent; + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodDirector.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodDirector.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodDirector.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,933 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodDirector.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * 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 + *true
if the connect was successful
+ *
+ * @throws IOException
+ * @throws HttpException
+ */
+ private boolean executeConnect()
+ throws IOException, HttpException {
+
+ this.connectMethod = new ConnectMethod();
+ this.connectMethod.getParams().setDefaults(this.hostConfiguration.getParams());
+
+ int code;
+ for (;;) {
+ if (!this.conn.isOpen()) {
+ this.conn.open();
+ }
+ if (this.params.isAuthenticationPreemptive()
+ || this.state.isAuthenticationPreemptive()) {
+ LOG.debug("Preemptively sending default basic credentials");
+ this.connectMethod.getProxyAuthState().setPreemptive();
+ this.connectMethod.getProxyAuthState().setAuthAttempted(true);
+ }
+ try {
+ authenticateProxy(this.connectMethod);
+ } catch (AuthenticationException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ applyConnectionParams(this.connectMethod);
+ this.connectMethod.execute(state, this.conn);
+ code = this.connectMethod.getStatusCode();
+ boolean retry = false;
+ AuthState authstate = this.connectMethod.getProxyAuthState();
+ authstate.setAuthRequested(code == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
+ if (authstate.isAuthRequested()) {
+ if (processAuthenticationResponse(this.connectMethod)) {
+ retry = true;
+ }
+ }
+ if (!retry) {
+ break;
+ }
+ if (this.connectMethod.getResponseBodyAsStream() != null) {
+ this.connectMethod.getResponseBodyAsStream().close();
+ }
+ }
+ if ((code >= 200) && (code < 300)) {
+ this.conn.tunnelCreated();
+ // Drop the connect method, as it is no longer needed
+ this.connectMethod = null;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Fake response
+ * @param method
+ * @return
+ */
+
+ private void fakeResponse(final HttpMethod method)
+ throws IOException, HttpException {
+ // What is to follow is an ugly hack.
+ // I REALLY hate having to resort to such
+ // an appalling trick
+ // The only feasible solution is to split monolithic
+ // HttpMethod into HttpRequest/HttpResponse pair.
+ // That would allow to execute CONNECT method
+ // behind the scene and return CONNECT HttpResponse
+ // object in response to the original request that
+ // contains the correct status line, headers &
+ // response body.
+ LOG.debug("CONNECT failed, fake the response for the original method");
+ // Pass the status, headers and response stream to the wrapped
+ // method.
+ // To ensure that the connection is not released more than once
+ // this method is still responsible for releasing the connection.
+ // This will happen when the response body is consumed, or when
+ // the wrapped method closes the response connection in
+ // releaseConnection().
+ if (method instanceof HttpMethodBase) {
+ ((HttpMethodBase) method).fakeResponse(
+ this.connectMethod.getStatusLine(),
+ this.connectMethod.getResponseHeaderGroup(),
+ this.connectMethod.getResponseBodyAsStream()
+ );
+ method.getProxyAuthState().setAuthScheme(
+ this.connectMethod.getProxyAuthState().getAuthScheme());
+ this.connectMethod = null;
+ } else {
+ releaseConnection = true;
+ LOG.warn(
+ "Unable to fake response on method as it is not derived from HttpMethodBase.");
+ }
+ }
+
+ /**
+ * Process the redirect response.
+ *
+ * @return true
if the redirect was successful
+ */
+ private boolean processRedirectResponse(final HttpMethod method)
+ throws RedirectException {
+ //get the location header to find out where to redirect to
+ Header locationHeader = method.getResponseHeader("location");
+ if (locationHeader == null) {
+ // got a redirect response, but no location header
+ LOG.error("Received redirect response " + method.getStatusCode()
+ + " but no location header");
+ return false;
+ }
+ String location = locationHeader.getValue();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Redirect requested to location '" + location + "'");
+ }
+
+ //rfc2616 demands the location value be a complete URI
+ //Location = "Location" ":" absoluteURI
+ URI redirectUri = null;
+ URI currentUri = null;
+
+ try {
+ currentUri = new URI(
+ this.conn.getProtocol().getScheme(),
+ null,
+ this.conn.getHost(),
+ this.conn.getPort(),
+ method.getPath()
+ );
+ redirectUri = new URI(location, true);
+ if (redirectUri.isRelativeURI()) {
+ if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
+ LOG.warn("Relative redirect location '" + location + "' not allowed");
+ return false;
+ } else {
+ //location is incomplete, use current values for defaults
+ LOG.debug("Redirect URI is not absolute - parsing as relative");
+ redirectUri = new URI(currentUri, redirectUri);
+ }
+ }
+ method.setURI(redirectUri);
+ hostConfiguration.setHost(redirectUri);
+ } catch (URIException e) {
+ LOG.warn("Redirected location '" + location + "' is malformed");
+ return false;
+ }
+
+ if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
+ if (this.redirectLocations == null) {
+ this.redirectLocations = new HashSet();
+ }
+ this.redirectLocations.add(currentUri);
+ try {
+ if(redirectUri.hasQuery()) {
+ redirectUri.setQuery(null);
+ }
+ } catch (URIException e) {
+ // Should never happen
+ return false;
+ }
+
+ if (this.redirectLocations.contains(redirectUri)) {
+ throw new CircularRedirectException("Circular redirect to '" +
+ redirectUri + "'");
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Redirecting from '" + currentUri.getEscapedURI()
+ + "' to '" + redirectUri.getEscapedURI());
+ }
+ //And finally invalidate the actual authentication scheme
+ method.getHostAuthState().invalidate();
+ return true;
+ }
+
+ /**
+ * Processes a response that requires authentication
+ *
+ * @param method the current {@link HttpMethod HTTP method}
+ *
+ * @return true if the authentication challenge can be responsed to,
+ * (that is, at least one of the requested authentication scheme is supported,
+ * and matching credentials have been found), false otherwise.
+ */
+ private boolean processAuthenticationResponse(final HttpMethod method) {
+ LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
+ + "HttpState, HttpConnection)");
+
+ try {
+ switch (method.getStatusCode()) {
+ case HttpStatus.SC_UNAUTHORIZED:
+ return processWWWAuthChallenge(method);
+ case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
+ return processProxyAuthChallenge(method);
+ default:
+ return false;
+ }
+ } catch (Exception e) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error(e.getMessage(), e);
+ }
+ return false;
+ }
+ }
+
+ private boolean processWWWAuthChallenge(final HttpMethod method)
+ throws MalformedChallengeException, AuthenticationException
+ {
+ AuthState authstate = method.getHostAuthState();
+ Map challenges = AuthChallengeParser.parseChallenges(
+ method.getResponseHeaders(WWW_AUTH_CHALLENGE));
+ if (challenges.isEmpty()) {
+ LOG.debug("Authentication challenge(s) not found");
+ return false;
+ }
+ AuthScheme authscheme = null;
+ try {
+ authscheme = this.authProcessor.processChallenge(authstate, challenges);
+ } catch (AuthChallengeException e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(e.getMessage());
+ }
+ }
+ if (authscheme == null) {
+ return false;
+ }
+ String host = method.getParams().getVirtualHost();
+ if (host == null) {
+ host = conn.getHost();
+ }
+ int port = conn.getPort();
+ AuthScope authscope = new AuthScope(
+ host, port,
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Authentication scope: " + authscope);
+ }
+ if (authstate.isAuthAttempted() && authscheme.isComplete()) {
+ // Already tried and failed
+ Credentials credentials = promptForCredentials(
+ authscheme, method.getParams(), authscope);
+ if (credentials == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failure authenticating with " + authscope);
+ }
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ authstate.setAuthAttempted(true);
+ Credentials credentials = this.state.getCredentials(authscope);
+ if (credentials == null) {
+ credentials = promptForCredentials(
+ authscheme, method.getParams(), authscope);
+ }
+ if (credentials == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("No credentials available for " + authscope);
+ }
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ private boolean processProxyAuthChallenge(final HttpMethod method)
+ throws MalformedChallengeException, AuthenticationException
+ {
+ AuthState authstate = method.getProxyAuthState();
+ Map proxyChallenges = AuthChallengeParser.parseChallenges(
+ method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
+ if (proxyChallenges.isEmpty()) {
+ LOG.debug("Proxy authentication challenge(s) not found");
+ return false;
+ }
+ AuthScheme authscheme = null;
+ try {
+ authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
+ } catch (AuthChallengeException e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(e.getMessage());
+ }
+ }
+ if (authscheme == null) {
+ return false;
+ }
+ AuthScope authscope = new AuthScope(
+ conn.getProxyHost(), conn.getProxyPort(),
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Proxy authentication scope: " + authscope);
+ }
+ if (authstate.isAuthAttempted() && authscheme.isComplete()) {
+ // Already tried and failed
+ Credentials credentials = promptForProxyCredentials(
+ authscheme, method.getParams(), authscope);
+ if (credentials == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failure authenticating with " + authscope);
+ }
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ authstate.setAuthAttempted(true);
+ Credentials credentials = this.state.getProxyCredentials(authscope);
+ if (credentials == null) {
+ credentials = promptForProxyCredentials(
+ authscheme, method.getParams(), authscope);
+ }
+ if (credentials == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("No credentials available for " + authscope);
+ }
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Tests if the {@link HttpMethod method} requires a redirect to another location.
+ *
+ * @param method HTTP method
+ *
+ * @return boolean true if a retry is needed, false otherwise.
+ */
+ private boolean isRedirectNeeded(final HttpMethod method) {
+ switch (method.getStatusCode()) {
+ case HttpStatus.SC_MOVED_TEMPORARILY:
+ case HttpStatus.SC_MOVED_PERMANENTLY:
+ case HttpStatus.SC_SEE_OTHER:
+ case HttpStatus.SC_TEMPORARY_REDIRECT:
+ LOG.debug("Redirect required");
+ if (method.getFollowRedirects()) {
+ return true;
+ } else {
+ LOG.info("Redirect requested but followRedirects is "
+ + "disabled");
+ return false;
+ }
+ default:
+ return false;
+ } //end of switch
+ }
+
+ /**
+ * Tests if the {@link HttpMethod method} requires authentication.
+ *
+ * @param method HTTP method
+ *
+ * @return boolean true if a retry is needed, false otherwise.
+ */
+ private boolean isAuthenticationNeeded(final HttpMethod method) {
+ method.getHostAuthState().setAuthRequested(
+ method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED);
+ method.getProxyAuthState().setAuthRequested(
+ method.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
+ if (method.getHostAuthState().isAuthRequested() ||
+ method.getProxyAuthState().isAuthRequested()) {
+ LOG.debug("Authorization required");
+ if (method.getDoAuthentication()) { //process authentication response
+ return true;
+ } else { //let the client handle the authenticaiton
+ LOG.info("Authentication requested but doAuthentication is "
+ + "disabled");
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private Credentials promptForCredentials(
+ final AuthScheme authScheme,
+ final HttpParams params,
+ final AuthScope authscope)
+ {
+ LOG.debug("Credentials required");
+ Credentials creds = null;
+ CredentialsProvider credProvider =
+ (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
+ if (credProvider != null) {
+ try {
+ creds = credProvider.getCredentials(
+ authScheme, authscope.getHost(), authscope.getPort(), false);
+ } catch (CredentialsNotAvailableException e) {
+ LOG.warn(e.getMessage());
+ }
+ if (creds != null) {
+ this.state.setCredentials(authscope, creds);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(authscope + " new credentials given");
+ }
+ }
+ } else {
+ LOG.debug("Credentials provider not available");
+ }
+ return creds;
+ }
+
+ private Credentials promptForProxyCredentials(
+ final AuthScheme authScheme,
+ final HttpParams params,
+ final AuthScope authscope)
+ {
+ LOG.debug("Proxy credentials required");
+ Credentials creds = null;
+ CredentialsProvider credProvider =
+ (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
+ if (credProvider != null) {
+ try {
+ creds = credProvider.getCredentials(
+ authScheme, authscope.getHost(), authscope.getPort(), true);
+ } catch (CredentialsNotAvailableException e) {
+ LOG.warn(e.getMessage());
+ }
+ if (creds != null) {
+ this.state.setProxyCredentials(authscope, creds);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(authscope + " new credentials given");
+ }
+ }
+ } else {
+ LOG.debug("Proxy credentials provider not available");
+ }
+ return creds;
+ }
+
+ /**
+ * @return
+ */
+ public HostConfiguration getHostConfiguration() {
+ return hostConfiguration;
+ }
+
+ /**
+ * @return
+ */
+ public HttpState getState() {
+ return state;
+ }
+
+ /**
+ * @return
+ */
+ public HttpConnectionManager getConnectionManager() {
+ return connectionManager;
+ }
+
+ /**
+ * @return
+ */
+ public HttpParams getParams() {
+ return this.params;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodRetryHandler.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodRetryHandler.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodRetryHandler.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,64 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodRetryHandler.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * Classes implementing this interface must synchronize access to shared + * data as methods of this interfrace may be executed from multiple threads + *
+ * + * @see HttpMethod#execute(HttpState, HttpConnection) + * + * @author Michael Becke + * @author Oleg Kalnichevski + */ +public interface HttpMethodRetryHandler { + + /** + * Determines if a method should be retried after an HttpRecoverableException + * occurs during execution. + * + * @param method the method being executed + * @param exception the exception that occurred + * @param executionCount the number of times this method has been + * unsuccessfully executed + * + * @returntrue
if the method should be retried, false
+ * otherwise
+ */
+ boolean retryMethod(HttpMethod method, IOException exception, int executionCount);
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpParser.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpParser.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpParser.java 22 Aug 2012 17:30:33 -0000 1.1
@@ -0,0 +1,224 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpParser.java,v 1.1 2012/08/22 17:30:33 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:33 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * null
is returned.
+ *
+ * @param inputStream the stream to read from
+ *
+ * @throws IOException if an I/O problem occurs
+ * @return a byte array from the stream
+ */
+ public static byte[] readRawLine(InputStream inputStream) throws IOException {
+ LOG.trace("enter HttpParser.readRawLine()");
+
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ int ch;
+ while ((ch = inputStream.read()) >= 0) {
+ buf.write(ch);
+ if (ch == '\n') { // be tolerant (RFC-2616 Section 19.3)
+ break;
+ }
+ }
+ if (buf.size() == 0) {
+ return null;
+ }
+ return buf.toByteArray();
+ }
+
+ /**
+ * Read up to "\n" from an (unchunked) input stream.
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ * If no input data available, null
is returned.
+ *
+ * @param inputStream the stream to read from
+ * @param charset charset of HTTP protocol elements
+ *
+ * @throws IOException if an I/O problem occurs
+ * @return a line from the stream
+ *
+ * @since 3.0
+ */
+ public static String readLine(InputStream inputStream, String charset) throws IOException {
+ LOG.trace("enter HttpParser.readLine(InputStream, String)");
+ byte[] rawdata = readRawLine(inputStream);
+ if (rawdata == null) {
+ return null;
+ }
+ // strip CR and LF from the end
+ int len = rawdata.length;
+ int offset = 0;
+ if (len > 0) {
+ if (rawdata[len - 1] == '\n') {
+ offset++;
+ if (len > 1) {
+ if (rawdata[len - 2] == '\r') {
+ offset++;
+ }
+ }
+ }
+ }
+ return EncodingUtil.getString(rawdata, 0, len - offset, charset);
+ }
+
+ /**
+ * Read up to "\n" from an (unchunked) input stream.
+ * If the stream ends before the line terminator is found,
+ * the last part of the string will still be returned.
+ * If no input data available, null
is returned
+ *
+ * @param inputStream the stream to read from
+ *
+ * @throws IOException if an I/O problem occurs
+ * @return a line from the stream
+ *
+ * @deprecated use #readLine(InputStream, String)
+ */
+
+ public static String readLine(InputStream inputStream) throws IOException {
+ LOG.trace("enter HttpParser.readLine(InputStream)");
+ return readLine(inputStream, "US-ASCII");
+ }
+
+ /**
+ * Parses headers from the given stream. Headers with the same name are not
+ * combined.
+ *
+ * @param is the stream to read headers from
+ * @param charset the charset to use for reading the data
+ *
+ * @return an array of headers in the order in which they were parsed
+ *
+ * @throws IOException if an IO error occurs while reading from the stream
+ * @throws HttpException if there is an error parsing a header value
+ *
+ * @since 3.0
+ */
+ public static Header[] parseHeaders(InputStream is, String charset) throws IOException, HttpException {
+ LOG.trace("enter HeaderParser.parseHeaders(InputStream, String)");
+
+ ArrayList headers = new ArrayList();
+ String name = null;
+ StringBuffer value = null;
+ for (; ;) {
+ String line = HttpParser.readLine(is, charset);
+ if ((line == null) || (line.trim().length() < 1)) {
+ break;
+ }
+
+ // Parse the header name and value
+ // Check for folded headers first
+ // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2
+ // discussion on folded headers
+ if ((line.charAt(0) == ' ') || (line.charAt(0) == '\t')) {
+ // we have continuation folded header
+ // so append value
+ if (value != null) {
+ value.append(' ');
+ value.append(line.trim());
+ }
+ } else {
+ // make sure we save the previous name,value pair if present
+ if (name != null) {
+ headers.add(new Header(name, value.toString()));
+ }
+
+ // Otherwise we should have normal HTTP header line
+ // Parse the header name and value
+ int colon = line.indexOf(":");
+ if (colon < 0) {
+ throw new ProtocolException("Unable to parse header: " + line);
+ }
+ name = line.substring(0, colon).trim();
+ value = new StringBuffer(line.substring(colon + 1).trim());
+ }
+
+ }
+
+ // make sure we save the last name,value pair if present
+ if (name != null) {
+ headers.add(new Header(name, value.toString()));
+ }
+
+ return (Header[]) headers.toArray(new Header[headers.size()]);
+ }
+
+ /**
+ * Parses headers from the given stream. Headers with the same name are not
+ * combined.
+ *
+ * @param is the stream to read headers from
+ *
+ * @return an array of headers in the order in which they were parsed
+ *
+ * @throws IOException if an IO error occurs while reading from the stream
+ * @throws HttpException if there is an error parsing a header value
+ *
+ * @deprecated use #parseHeaders(InputStream, String)
+ */
+ public static Header[] parseHeaders(InputStream is) throws IOException, HttpException {
+ LOG.trace("enter HeaderParser.parseHeaders(InputStream, String)");
+ return parseHeaders(is, "US-ASCII");
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpRecoverableException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpRecoverableException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpRecoverableException.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,63 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpRecoverableException.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * Signals that an HTTP or HttpClient exception has occurred. This + * exception may have been caused by a transient error and the request + * may be retried. It may be possible to retrieve the underlying transient + * error via the inherited {@link HttpException#getCause()} method. + *
+ * + * @deprecated no longer used + * + * @author Unascribed + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:35 $ + */ +public class HttpRecoverableException extends HttpException { + + /** + * Creates a new HttpRecoverableException with a null detail message. + */ + public HttpRecoverableException() { + super(); + } + + /** + * Creates a new HttpRecoverableException with the specified detail message. + * + * @param message exception message + */ + public HttpRecoverableException(String message) { + super(message); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpState.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpState.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpState.java 22 Aug 2012 17:30:33 -0000 1.1 @@ -0,0 +1,625 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpState.java,v 1.1 2012/08/22 17:30:33 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:33 $ + * + * ==================================================================== + * + * 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 + *+ * A container for HTTP attributes that may persist from request + * to request, such as {@link Cookie cookies} and authentication + * {@link Credentials credentials}. + *
+ * + * @author Remy Maucherat + * @author Rodney Waldhoff + * @author Jeff Dever + * @author Sean C. Sullivan + * @author Michael Becke + * @author Oleg Kalnichevski + * @author Mike Bowler + * @author Adrian Sutton + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:33 $ + * + */ +public class HttpState { + + // ----------------------------------------------------- Instance Variables + + /** + * Map of {@link Credentials credentials} by realm that this + * HTTP state contains. + */ + private HashMap credMap = new HashMap(); + + /** + * Map of {@link Credentials proxy credentials} by realm that this + * HTTP state contains + */ + private HashMap proxyCred = new HashMap(); + + /** + * Array of {@link Cookie cookies} that this HTTP state contains. + */ + private ArrayList cookies = new ArrayList(); + + private boolean preemptive = false; + + private int cookiePolicy = -1; + // -------------------------------------------------------- Class Variables + + /** + * The boolean system property name to turn on preemptive authentication. + * @deprecated This field and feature will be removed following HttpClient 3.0. + */ + public static final String PREEMPTIVE_PROPERTY = "httpclient.authentication.preemptive"; + + /** + * The default value for {@link #PREEMPTIVE_PROPERTY}. + * @deprecated This field and feature will be removed following HttpClient 3.0. + */ + public static final String PREEMPTIVE_DEFAULT = "false"; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(HttpState.class); + + /** + * Default constructor. + */ + public HttpState() { + super(); + } + + // ------------------------------------------------------------- Properties + + /** + * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies. + * If the given cookie has already expired it will not be added, but existing + * values will still be removed. + * + * @param cookie the {@link Cookie cookie} to be added + * + * @see #addCookies(Cookie[]) + * + */ + public synchronized void addCookie(Cookie cookie) { + LOG.trace("enter HttpState.addCookie(Cookie)"); + + if (cookie != null) { + // first remove any old cookie that is equivalent + for (Iterator it = cookies.iterator(); it.hasNext();) { + Cookie tmp = (Cookie) it.next(); + if (cookie.equals(tmp)) { + it.remove(); + break; + } + } + if (!cookie.isExpired()) { + cookies.add(cookie); + } + } + } + + /** + * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and + * in the given array order. If any of the given cookies has already expired it will + * not be added, but existing values will still be removed. + * + * @param cookies the {@link Cookie cookies} to be added + * + * @see #addCookie(Cookie) + * + * + */ + public synchronized void addCookies(Cookie[] cookies) { + LOG.trace("enter HttpState.addCookies(Cookie[])"); + + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + this.addCookie(cookies[i]); + } + } + } + + /** + * Returns an array of {@link Cookie cookies} that this HTTP + * state currently contains. + * + * @return an array of {@link Cookie cookies}. + * + * @see #getCookies(String, int, String, boolean) + * + */ + public synchronized Cookie[] getCookies() { + LOG.trace("enter HttpState.getCookies()"); + return (Cookie[]) (cookies.toArray(new Cookie[cookies.size()])); + } + + /** + * Returns an array of {@link Cookie cookies} in this HTTP + * state that match the given request parameters. + * + * @param domain the request domain + * @param port the request port + * @param path the request path + * @param securetrue
when using HTTPS
+ *
+ * @return an array of {@link Cookie cookies}.
+ *
+ * @see #getCookies()
+ *
+ * @deprecated use CookieSpec#match(String, int, String, boolean, Cookie)
+ */
+ public synchronized Cookie[] getCookies(
+ String domain,
+ int port,
+ String path,
+ boolean secure
+ ) {
+ LOG.trace("enter HttpState.getCookies(String, int, String, boolean)");
+
+ CookieSpec matcher = CookiePolicy.getDefaultSpec();
+ ArrayList list = new ArrayList(cookies.size());
+ for (int i = 0, m = cookies.size(); i < m; i++) {
+ Cookie cookie = (Cookie) (cookies.get(i));
+ if (matcher.match(domain, port, path, secure, cookie)) {
+ list.add(cookie);
+ }
+ }
+ return (Cookie[]) (list.toArray(new Cookie[list.size()]));
+ }
+
+ /**
+ * Removes all of {@link Cookie cookies} in this HTTP state
+ * that have expired according to the current system time.
+ *
+ * @see #purgeExpiredCookies(java.util.Date)
+ *
+ */
+ public synchronized boolean purgeExpiredCookies() {
+ LOG.trace("enter HttpState.purgeExpiredCookies()");
+ return purgeExpiredCookies(new Date());
+ }
+
+ /**
+ * Removes all of {@link Cookie cookies} in this HTTP state
+ * that have expired by the specified {@link java.util.Date date}.
+ *
+ * @param date The {@link java.util.Date date} to compare against.
+ *
+ * @return true if any cookies were purged.
+ *
+ * @see Cookie#isExpired(java.util.Date)
+ *
+ * @see #purgeExpiredCookies()
+ */
+ public synchronized boolean purgeExpiredCookies(Date date) {
+ LOG.trace("enter HttpState.purgeExpiredCookies(Date)");
+ boolean removed = false;
+ Iterator it = cookies.iterator();
+ while (it.hasNext()) {
+ if (((Cookie) (it.next())).isExpired(date)) {
+ it.remove();
+ removed = true;
+ }
+ }
+ return removed;
+ }
+
+
+ /**
+ * Returns the current {@link CookiePolicy cookie policy} for this
+ * HTTP state.
+ *
+ * @return The {@link CookiePolicy cookie policy}.
+ *
+ * @deprecated Use
+ * {@link org.apache.commons.httpclient.params.HttpMethodParams#getCookiePolicy()},
+ * {@link HttpMethod#getParams()}.
+ */
+
+ public int getCookiePolicy() {
+ return this.cookiePolicy;
+ }
+
+
+ /**
+ * Defines whether preemptive authentication should be
+ * attempted.
+ *
+ * @param value true if preemptive authentication should be
+ * attempted, false otherwise.
+ *
+ * @deprecated Use
+ * {@link org.apache.commons.httpclient.params.HttpClientParams#setAuthenticationPreemptive(boolean)},
+ * {@link HttpClient#getParams()}.
+ */
+
+ public void setAuthenticationPreemptive(boolean value) {
+ this.preemptive = value;
+ }
+
+
+ /**
+ * Returns true if preemptive authentication should be
+ * attempted, false otherwise.
+ *
+ * @return boolean flag.
+ *
+ * @deprecated Use
+ * {@link org.apache.commons.httpclient.params.HttpClientParams#isAuthenticationPreemptive()},
+ * {@link HttpClient#getParams()}.
+ */
+
+ public boolean isAuthenticationPreemptive() {
+ return this.preemptive;
+ }
+
+
+ /**
+ * Sets the current {@link CookiePolicy cookie policy} for this HTTP
+ * state to one of the following supported policies:
+ * {@link CookiePolicy#COMPATIBILITY},
+ * {@link CookiePolicy#NETSCAPE_DRAFT} or
+ * {@link CookiePolicy#RFC2109}.
+ *
+ * @param policy new {@link CookiePolicy cookie policy}
+ *
+ * @deprecated
+ * Use {@link org.apache.commons.httpclient.params.HttpMethodParams#setCookiePolicy(String)},
+ * {@link HttpMethod#getParams()}.
+ */
+
+ public void setCookiePolicy(int policy) {
+ this.cookiePolicy = policy;
+ }
+
+ /**
+ * Sets the {@link Credentials credentials} for the given authentication
+ * realm on the given host. The null
realm signifies default
+ * credentials for the given host, which should be used when no
+ * {@link Credentials credentials} have been explictly supplied for the
+ * challenging realm. The null
host signifies default
+ * credentials, which should be used when no {@link Credentials credentials}
+ * have been explictly supplied for the challenging host. Any previous
+ * credentials for the given realm on the given host will be overwritten.
+ *
+ * @param realm the authentication realm
+ * @param host the host the realm belongs to
+ * @param credentials the authentication {@link Credentials credentials}
+ * for the given realm.
+ *
+ * @see #getCredentials(String, String)
+ * @see #setProxyCredentials(String, String, Credentials)
+ *
+ * @deprecated use #setCredentials(AuthScope, Credentials)
+ */
+
+ public synchronized void setCredentials(String realm, String host, Credentials credentials) {
+ LOG.trace("enter HttpState.setCredentials(String, String, Credentials)");
+ credMap.put(new AuthScope(host, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME), credentials);
+ }
+
+ /**
+ * Sets the {@link Credentials credentials} for the given authentication
+ * scope. Any previous credentials for the given scope will be overwritten.
+ *
+ * @param authscope the {@link AuthScope authentication scope}
+ * @param credentials the authentication {@link Credentials credentials}
+ * for the given scope.
+ *
+ * @see #getCredentials(AuthScope)
+ * @see #setProxyCredentials(AuthScope, Credentials)
+ *
+ * @since 3.0
+ */
+ public synchronized void setCredentials(final AuthScope authscope, final Credentials credentials) {
+ if (authscope == null) {
+ throw new IllegalArgumentException("Authentication scope may not be null");
+ }
+ LOG.trace("enter HttpState.setCredentials(AuthScope, Credentials)");
+ credMap.put(authscope, credentials);
+ }
+
+ /**
+ * Find matching {@link Credentials credentials} for the given authentication scope.
+ *
+ * @param map the credentials hash map
+ * @param token the {@link AuthScope authentication scope}
+ * @return the credentials
+ *
+ */
+ private static Credentials matchCredentials(final HashMap map, final AuthScope authscope) {
+ // see if we get a direct hit
+ Credentials creds = (Credentials)map.get(authscope);
+ if (creds == null) {
+ // Nope.
+ // Do a full scan
+ int bestMatchFactor = -1;
+ AuthScope bestMatch = null;
+ Iterator items = map.keySet().iterator();
+ while (items.hasNext()) {
+ AuthScope current = (AuthScope)items.next();
+ int factor = authscope.match(current);
+ if (factor > bestMatchFactor) {
+ bestMatchFactor = factor;
+ bestMatch = current;
+ }
+ }
+ if (bestMatch != null) {
+ creds = (Credentials)map.get(bestMatch);
+ }
+ }
+ return creds;
+ }
+
+ /**
+ * Get the {@link Credentials credentials} for the given authentication scope on the
+ * given host.
+ *
+ * If the realm exists on host, return the coresponding credentials.
+ * If the host exists with a null realm, return the corresponding
+ * credentials.
+ * If the realm exists with a null host, return the
+ * corresponding credentials. If the realm does not exist, return
+ * the default Credentials. If there are no default credentials, return
+ * null
.
+ *
+ * @param realm the authentication realm
+ * @param host the host the realm is on
+ * @return the credentials
+ *
+ * @see #setCredentials(String, String, Credentials)
+ *
+ * @deprecated use #getCredentials(AuthScope)
+ */
+
+ public synchronized Credentials getCredentials(String realm, String host) {
+ LOG.trace("enter HttpState.getCredentials(String, String");
+ return matchCredentials(this.credMap,
+ new AuthScope(host, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME));
+ }
+
+ /**
+ * Get the {@link Credentials credentials} for the given authentication scope.
+ *
+ * @param authscope the {@link AuthScope authentication scope}
+ * @return the credentials
+ *
+ * @see #setCredentials(AuthScope, Credentials)
+ *
+ * @since 3.0
+ */
+ public synchronized Credentials getCredentials(final AuthScope authscope) {
+ if (authscope == null) {
+ throw new IllegalArgumentException("Authentication scope may not be null");
+ }
+ LOG.trace("enter HttpState.getCredentials(AuthScope)");
+ return matchCredentials(this.credMap, authscope);
+ }
+
+ /**
+ * Sets the {@link Credentials credentials} for the given proxy authentication
+ * realm on the given proxy host. The null
proxy realm signifies
+ * default credentials for the given proxy host, which should be used when no
+ * {@link Credentials credentials} have been explictly supplied for the
+ * challenging proxy realm. The null
proxy host signifies default
+ * credentials, which should be used when no {@link Credentials credentials}
+ * have been explictly supplied for the challenging proxy host. Any previous
+ * credentials for the given proxy realm on the given proxy host will be
+ * overwritten.
+ *
+ * @param realm the authentication realm
+ * @param proxyHost the proxy host
+ * @param credentials the authentication credentials for the given realm
+ *
+ * @see #getProxyCredentials(AuthScope)
+ * @see #setCredentials(AuthScope, Credentials)
+ *
+ * @deprecated use #setProxyCredentials(AuthScope, Credentials)
+ */
+ public synchronized void setProxyCredentials(
+ String realm,
+ String proxyHost,
+ Credentials credentials
+ ) {
+ LOG.trace("enter HttpState.setProxyCredentials(String, String, Credentials");
+ proxyCred.put(new AuthScope(proxyHost, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME), credentials);
+ }
+
+ /**
+ * Sets the {@link Credentials proxy credentials} for the given authentication
+ * realm. Any previous credentials for the given realm will be overwritten.
+ *
+ * @param authscope the {@link AuthScope authentication scope}
+ * @param credentials the authentication {@link Credentials credentials}
+ * for the given realm.
+ *
+ * @see #getProxyCredentials(AuthScope)
+ * @see #setCredentials(AuthScope, Credentials)
+ *
+ * @since 3.0
+ */
+ public synchronized void setProxyCredentials(final AuthScope authscope,
+ final Credentials credentials)
+ {
+ if (authscope == null) {
+ throw new IllegalArgumentException("Authentication scope may not be null");
+ }
+ LOG.trace("enter HttpState.setProxyCredentials(AuthScope, Credentials)");
+ proxyCred.put(authscope, credentials);
+ }
+
+ /**
+ * Get the {@link Credentials credentials} for the proxy host with the given
+ * authentication scope.
+ *
+ * If the realm exists on host, return the coresponding credentials.
+ * If the host exists with a null realm, return the corresponding
+ * credentials.
+ * If the realm exists with a null host, return the
+ * corresponding credentials. If the realm does not exist, return
+ * the default Credentials. If there are no default credentials, return
+ * null
.
+ *
+ * @param realm the authentication realm
+ * @param proxyHost the proxy host the realm is on
+ * @return the credentials
+ * @see #setProxyCredentials(String, String, Credentials)
+ *
+ * @deprecated use #getProxyCredentials(AuthScope)
+ */
+ public synchronized Credentials getProxyCredentials(String realm, String proxyHost) {
+ LOG.trace("enter HttpState.getCredentials(String, String");
+ return matchCredentials(this.proxyCred,
+ new AuthScope(proxyHost, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME));
+ }
+
+ /**
+ * Get the {@link Credentials proxy credentials} for the given authentication scope.
+ *
+ * @param authscope the {@link AuthScope authentication scope}
+ * @return the credentials
+ *
+ * @see #setProxyCredentials(AuthScope, Credentials)
+ *
+ * @since 3.0
+ */
+ public synchronized Credentials getProxyCredentials(final AuthScope authscope) {
+ if (authscope == null) {
+ throw new IllegalArgumentException("Authentication scope may not be null");
+ }
+ LOG.trace("enter HttpState.getProxyCredentials(AuthScope)");
+ return matchCredentials(this.proxyCred, authscope);
+ }
+
+ /**
+ * Returns a string representation of this HTTP state.
+ *
+ * @return The string representation of the HTTP state.
+ *
+ * @see java.lang.Object#toString()
+ */
+ public synchronized String toString() {
+ StringBuffer sbResult = new StringBuffer();
+
+ sbResult.append("[");
+ sbResult.append(getCredentialsStringRepresentation(proxyCred));
+ sbResult.append(" | ");
+ sbResult.append(getCredentialsStringRepresentation(credMap));
+ sbResult.append(" | ");
+ sbResult.append(getCookiesStringRepresentation(cookies));
+ sbResult.append("]");
+
+ String strResult = sbResult.toString();
+
+ return strResult;
+ }
+
+ /**
+ * Returns a string representation of the credentials.
+ * @param credMap The credentials.
+ * @return The string representation.
+ */
+ private static String getCredentialsStringRepresentation(final Map credMap) {
+ StringBuffer sbResult = new StringBuffer();
+ Iterator iter = credMap.keySet().iterator();
+ while (iter.hasNext()) {
+ Object key = iter.next();
+ Credentials cred = (Credentials) credMap.get(key);
+ if (sbResult.length() > 0) {
+ sbResult.append(", ");
+ }
+ sbResult.append(key);
+ sbResult.append("#");
+ sbResult.append(cred.toString());
+ }
+ return sbResult.toString();
+ }
+
+ /**
+ * Returns a string representation of the cookies.
+ * @param cookies The cookies
+ * @return The string representation.
+ */
+ private static String getCookiesStringRepresentation(final List cookies) {
+ StringBuffer sbResult = new StringBuffer();
+ Iterator iter = cookies.iterator();
+ while (iter.hasNext()) {
+ Cookie ck = (Cookie) iter.next();
+ if (sbResult.length() > 0) {
+ sbResult.append("#");
+ }
+ sbResult.append(ck.toExternalForm());
+ }
+ return sbResult.toString();
+ }
+
+ /**
+ * Clears all credentials.
+ */
+ public void clearCredentials() {
+ this.credMap.clear();
+ }
+
+ /**
+ * Clears all proxy credentials.
+ */
+ public void clearProxyCredentials() {
+ this.proxyCred.clear();
+ }
+
+ /**
+ * Clears all cookies.
+ */
+ public void clearCookies() {
+ this.cookies.clear();
+ }
+
+ /**
+ * Clears the state information (all cookies, credentials and proxy credentials).
+ */
+ public void clear() {
+ clearCookies();
+ clearCredentials();
+ clearProxyCredentials();
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpStatus.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpStatus.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpStatus.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,311 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpStatus.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * escaped
is null
+ * @see #getProtocolCharset
+ */
+ public HttpURL(char[] escaped, String charset)
+ throws URIException, NullPointerException {
+ protocolCharset = charset;
+ parseUriReference(new String(escaped), true);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTP URL as an escaped form of a character array.
+ *
+ * @param escaped the HTTP URL character sequence
+ * @throws URIException If {@link #checkValid()} fails
+ * @throws NullPointerException if escaped
is null
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(char[] escaped) throws URIException, NullPointerException {
+ parseUriReference(new String(escaped), true);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTP URL from a given string with the given charset to do
+ * escape encoding.
+ *
+ * @param original the HTTP URL string
+ * @param charset the charset string to do escape encoding
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getProtocolCharset
+ */
+ public HttpURL(String original, String charset) throws URIException {
+ protocolCharset = charset;
+ parseUriReference(original, false);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTP URL from a given string.
+ *
+ * @param original the HTTP URL string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String original) throws URIException {
+ parseUriReference(original, false);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String host, int port, String path) throws URIException {
+ this(null, null, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String host, int port, String path, String query)
+ throws URIException {
+
+ this(null, null, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String user, String password, String host)
+ throws URIException {
+
+ this(user, password, host, -1, null, null, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String user, String password, String host, int port)
+ throws URIException {
+
+ this(user, password, host, port, null, null, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String user, String password, String host, int port,
+ String path) throws URIException {
+
+ this(user, password, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query The query string.
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String user, String password, String host, int port,
+ String path, String query) throws URIException {
+
+ this(user, password, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param host the host string
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String host, String path, String query, String fragment)
+ throws URIException {
+
+ this(null, null, host, -1, path, query, fragment);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String userinfo, String host, String path, String query,
+ String fragment) throws URIException {
+
+ this(userinfo, host, -1, path, query, fragment);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String userinfo, String host, int port, String path)
+ throws URIException {
+
+ this(userinfo, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String userinfo, String host, int port, String path,
+ String query) throws URIException {
+
+ this(userinfo, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String userinfo, String host, int port, String path,
+ String query, String fragment) throws URIException {
+
+ // validate and contruct the URI character sequence
+ StringBuffer buff = new StringBuffer();
+ if (userinfo != null || host != null || port != -1) {
+ _scheme = DEFAULT_SCHEME; // in order to verify the own protocol
+ buff.append(_default_scheme);
+ buff.append("://");
+ if (userinfo != null) {
+ buff.append(userinfo);
+ buff.append('@');
+ }
+ if (host != null) {
+ buff.append(URIUtil.encode(host, URI.allowed_host));
+ if (port != -1 || port != DEFAULT_PORT) {
+ buff.append(':');
+ buff.append(port);
+ }
+ }
+ }
+ if (path != null) { // accept empty path
+ if (scheme != null && !path.startsWith("/")) {
+ throw new URIException(URIException.PARSING,
+ "abs_path requested");
+ }
+ buff.append(URIUtil.encode(path, URI.allowed_abs_path));
+ }
+ if (query != null) {
+ buff.append('?');
+ buff.append(URIUtil.encode(query, URI.allowed_query));
+ }
+ if (fragment != null) {
+ buff.append('#');
+ buff.append(URIUtil.encode(fragment, URI.allowed_fragment));
+ }
+ parseUriReference(buff.toString(), true);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpURL(String user, String password, String host, int port,
+ String path, String query, String fragment) throws URIException {
+ this(toUserinfo(user, password), host, port, path, query, fragment);
+ }
+
+ protected static String toUserinfo(String user, String password) throws URIException {
+ if (user == null) return null;
+ StringBuffer usrinfo = new StringBuffer(20); //sufficient for real world
+ usrinfo.append(URIUtil.encode(user, URI.allowed_within_userinfo));
+ if (password == null) return usrinfo.toString();
+ usrinfo.append(':');
+ usrinfo.append(URIUtil.encode(password, URI.allowed_within_userinfo));
+ return usrinfo.toString();
+ }
+
+
+ /**
+ * Construct a HTTP URL with a given relative URL string.
+ *
+ * @param base the base HttpURL
+ * @param relative the relative HTTP URL string
+ * @throws URIException If {@link #checkValid()} fails
+ */
+ public HttpURL(HttpURL base, String relative) throws URIException {
+ this(base, new HttpURL(relative));
+ }
+
+
+ /**
+ * Construct a HTTP URL with a given relative URL.
+ *
+ * @param base the base HttpURL
+ * @param relative the relative HttpURL
+ * @throws URIException If {@link #checkValid()} fails
+ */
+ public HttpURL(HttpURL base, HttpURL relative) throws URIException {
+ super(base, relative);
+ checkValid();
+ }
+
+ // -------------------------------------------------------------- Constants
+
+ /**
+ * Default scheme for HTTP URL.
+ */
+ public static final char[] DEFAULT_SCHEME = { 'h', 't', 't', 'p' };
+
+ /**
+ * Default scheme for HTTP URL.
+ * @deprecated Use {@link #DEFAULT_SCHEME} instead. This one doesn't
+ * conform to the project naming conventions.
+ */
+ public static final char[] _default_scheme = DEFAULT_SCHEME;
+
+ /**
+ * Default port for HTTP URL.
+ */
+ public static final int DEFAULT_PORT = 80;
+
+ /**
+ * Default port for HTTP URL.
+ * @deprecated Use {@link #DEFAULT_PORT} instead. This one doesn't conform
+ * to the project naming conventions.
+ */
+ public static final int _default_port = DEFAULT_PORT;
+
+ /**
+ * The serialVersionUID.
+ */
+ static final long serialVersionUID = -7158031098595039459L;
+
+ // ------------------------------------------------------------- The scheme
+
+ /**
+ * Get the scheme. You can get the scheme explicitly.
+ *
+ * @return the scheme
+ */
+ public char[] getRawScheme() {
+ return (_scheme == null) ? null : HttpURL.DEFAULT_SCHEME;
+ }
+
+
+ /**
+ * Get the scheme. You can get the scheme explicitly.
+ *
+ * @return the scheme null if empty or undefined
+ */
+ public String getScheme() {
+ return (_scheme == null) ? null : new String(HttpURL.DEFAULT_SCHEME);
+ }
+
+ // --------------------------------------------------------------- The port
+
+ /**
+ * Get the port number.
+ * @return the port number
+ */
+ public int getPort() {
+ return (_port == -1) ? HttpURL.DEFAULT_PORT : _port;
+ }
+
+ // ----------------------------------------------------------- The userinfo
+
+ /**
+ * Set the raw-escaped user and password.
+ *
+ * @param escapedUser the raw-escaped user
+ * @param escapedPassword the raw-escaped password; could be null
+ * @throws URIException escaped user not valid or user required; escaped
+ * password not valid or username missed
+ */
+ public void setRawUserinfo(char[] escapedUser, char[] escapedPassword)
+ throws URIException {
+
+ if (escapedUser == null || escapedUser.length == 0) {
+ throw new URIException(URIException.PARSING, "user required");
+ }
+ if (!validate(escapedUser, within_userinfo)
+ || ((escapedPassword != null)
+ && !validate(escapedPassword, within_userinfo))) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped userinfo not valid");
+ }
+ String username = new String(escapedUser);
+ String password = (escapedPassword == null)
+ ? null : new String(escapedPassword);
+ String userinfo = username + ((password == null) ? "" : ":" + password);
+ String hostname = new String(getRawHost());
+ String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
+ String authority = userinfo + "@" + hostport;
+ _userinfo = userinfo.toCharArray();
+ _authority = authority.toCharArray();
+ setURI();
+ }
+
+
+ /**
+ * Set the raw-escaped user and password.
+ *
+ * @param escapedUser the escaped user
+ * @param escapedPassword the escaped password; could be null
+ * @throws URIException escaped user not valid or user required; escaped
+ * password not valid or username missed
+ * @throws NullPointerException null user
+ */
+ public void setEscapedUserinfo(String escapedUser, String escapedPassword)
+ throws URIException, NullPointerException {
+
+ setRawUserinfo(escapedUser.toCharArray(), (escapedPassword == null)
+ ? null : escapedPassword.toCharArray());
+ }
+
+
+ /**
+ * Set the user and password.
+ *
+ * @param user the user
+ * @param password the password; could be null
+ * @throws URIException encoding error or username missed
+ * @throws NullPointerException null user
+ */
+ public void setUserinfo(String user, String password)
+ throws URIException, NullPointerException {
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+ setRawUserinfo(encode(user, within_userinfo, charset),
+ (password == null)
+ ? null
+ : encode(password, within_userinfo, charset));
+ }
+
+
+ /**
+ * Set the raw-escaped user.
+ *
+ * @param escapedUser the raw-escaped user
+ * @throws URIException escaped user not valid or user required
+ */
+ public void setRawUser(char[] escapedUser) throws URIException {
+ if (escapedUser == null || escapedUser.length == 0) {
+ throw new URIException(URIException.PARSING, "user required");
+ }
+ if (!validate(escapedUser, within_userinfo)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped user not valid");
+ }
+ String username = new String(escapedUser);
+ String password = new String(getRawPassword());
+ String userinfo = username + ((password == null) ? "" : ":" + password);
+ String hostname = new String(getRawHost());
+ String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
+ String authority = userinfo + "@" + hostport;
+ _userinfo = userinfo.toCharArray();
+ _authority = authority.toCharArray();
+ setURI();
+ }
+
+
+ /**
+ * Set the escaped user string.
+ *
+ * @param escapedUser the escaped user string
+ * @throws URIException escaped user not valid
+ * @throws NullPointerException null user
+ */
+ public void setEscapedUser(String escapedUser)
+ throws URIException, NullPointerException {
+ setRawUser(escapedUser.toCharArray());
+ }
+
+
+ /**
+ * Set the user string.
+ *
+ * @param user the user string
+ * @throws URIException user encoding error
+ * @throws NullPointerException null user
+ */
+ public void setUser(String user) throws URIException, NullPointerException {
+ setRawUser(encode(user, allowed_within_userinfo, getProtocolCharset()));
+ }
+
+
+ /**
+ * Get the raw-escaped user.
+ *
+ * @return the raw-escaped user
+ */
+ public char[] getRawUser() {
+ if (_userinfo == null || _userinfo.length == 0) {
+ return null;
+ }
+ int to = indexFirstOf(_userinfo, ':');
+ // String.indexOf(':', 0, _userinfo.length, _userinfo, 0, 1, 0);
+ if (to == -1) {
+ return _userinfo; // only user.
+ }
+ char[] result = new char[to];
+ System.arraycopy(_userinfo, 0, result, 0, to);
+ return result;
+ }
+
+
+ /**
+ * Get the escaped user
+ *
+ * @return the escaped user
+ */
+ public String getEscapedUser() {
+ char[] user = getRawUser();
+ return (user == null) ? null : new String(user);
+ }
+
+
+ /**
+ * Get the user.
+ *
+ * @return the user name
+ * @throws URIException If {@link #decode} fails
+ */
+ public String getUser() throws URIException {
+ char[] user = getRawUser();
+ return (user == null) ? null : decode(user, getProtocolCharset());
+ }
+
+
+ /**
+ * Set the raw-escaped password.
+ *
+ * @param escapedPassword the raw-escaped password; could be null
+ * @throws URIException escaped password not valid or username missed
+ */
+ public void setRawPassword(char[] escapedPassword) throws URIException {
+ if (escapedPassword != null
+ && !validate(escapedPassword, within_userinfo)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped password not valid");
+ }
+ if (getRawUser() == null || getRawUser().length == 0) {
+ throw new URIException(URIException.PARSING, "username required");
+ }
+ String username = new String(getRawUser());
+ String password = new String(escapedPassword);
+ // an emtpy string is allowed as a password
+ String userinfo = username + ((password == null) ? "" : ":" + password);
+ String hostname = new String(getRawHost());
+ String hostport = (_port == -1) ? hostname : hostname + ":" + _port;
+ String authority = userinfo + "@" + hostport;
+ _userinfo = userinfo.toCharArray();
+ _authority = authority.toCharArray();
+ setURI();
+ }
+
+
+ /**
+ * Set the escaped password string.
+ *
+ * @param escapedPassword the escaped password string; could be null
+ * @throws URIException escaped password not valid or username missed
+ */
+ public void setEscapedPassword(String escapedPassword) throws URIException {
+ setRawPassword((escapedPassword == null) ? null
+ : escapedPassword.toCharArray());
+ }
+
+
+ /**
+ * Set the password string.
+ *
+ * @param password the password string; could be null
+ * @throws URIException encoding error or username missed
+ */
+ public void setPassword(String password) throws URIException {
+ setRawPassword((password == null) ? null : encode(password,
+ allowed_within_userinfo, getProtocolCharset()));
+ }
+
+
+ /**
+ * Get the raw-escaped password.
+ *
+ * @return the raw-escaped password
+ */
+ public char[] getRawPassword() {
+ int from = indexFirstOf(_userinfo, ':');
+ if (from == -1) {
+ return null; // null or only user.
+ }
+ int len = _userinfo.length - from - 1;
+ char[] result = new char[len];
+ System.arraycopy(_userinfo, from + 1, result, 0, len);
+ return result;
+ }
+
+
+ /**
+ * Get the escaped password.
+ *
+ * @return the escaped password
+ */
+ public String getEscapedPassword() {
+ char[] password = getRawPassword();
+ return (password == null) ? null : new String(password);
+ }
+
+
+ /**
+ * Get the password.
+ *
+ * @return the password
+ * @throws URIException If {@link #decode(char[],String)} fails.
+ */
+ public String getPassword() throws URIException {
+ char[] password = getRawPassword();
+ return (password == null) ? null : decode(password,
+ getProtocolCharset());
+ }
+
+ // --------------------------------------------------------------- The path
+
+ /**
+ * Get the raw-escaped current hierarchy level.
+ *
+ * @return the raw-escaped current hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public char[] getRawCurrentHierPath() throws URIException {
+ return (_path == null || _path.length == 0) ? rootPath
+ : super.getRawCurrentHierPath(_path);
+ }
+
+
+ /**
+ * Get the level above the this hierarchy level.
+ *
+ * @return the raw above hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public char[] getRawAboveHierPath() throws URIException {
+ char[] path = getRawCurrentHierPath();
+ return (path == null || path.length == 0) ? rootPath : getRawCurrentHierPath(path);
+ }
+
+
+ /**
+ * Get the raw escaped path.
+ *
+ * @return the path '/' if empty or undefined
+ */
+ public char[] getRawPath() {
+ char[] path = super.getRawPath();
+ return (path == null || path.length == 0) ? rootPath : path;
+ }
+
+ // -------------------------------------------------------------- The query
+
+ /**
+ * Set the query as the name and value pair.
+ *
+ * @param queryName the query string.
+ * @param queryValue the query string.
+ * @throws URIException incomplete trailing escape pattern
+ * Or unsupported character encoding
+ * @throws NullPointerException null query
+ * @see #encode
+ */
+ public void setQuery(String queryName, String queryValue)
+ throws URIException, NullPointerException {
+
+ StringBuffer buff = new StringBuffer();
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+ buff.append(encode(queryName, allowed_within_query, charset));
+ buff.append('=');
+ buff.append(encode(queryValue, allowed_within_query, charset));
+ _query = buff.toString().toCharArray();
+ setURI();
+ }
+
+
+ /**
+ * Set the query as the name and value pairs.
+ *
+ * @param queryName the array of the query string.
+ * @param queryValue the array of the query string.
+ * @throws URIException incomplete trailing escape pattern,
+ * unsupported character encoding or wrong array size
+ * @throws NullPointerException null query
+ * @see #encode
+ */
+ public void setQuery(String[] queryName, String[] queryValue)
+ throws URIException, NullPointerException {
+
+ int length = queryName.length;
+ if (length != queryValue.length) {
+ throw new URIException("wrong array size of query");
+ }
+
+ StringBuffer buff = new StringBuffer();
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+ for (int i = 0; i < length; i++) {
+ buff.append(encode(queryName[i], allowed_within_query, charset));
+ buff.append('=');
+ buff.append(encode(queryValue[i], allowed_within_query, charset));
+ if (i + 1 < length) {
+ buff.append('&');
+ }
+ }
+ _query = buff.toString().toCharArray();
+ setURI();
+ }
+
+ // ---------------------------------------------------------------- Utility
+
+ /**
+ * Verify the valid class use for construction.
+ *
+ * @throws URIException the wrong scheme use
+ */
+ protected void checkValid() throws URIException {
+ // could be explicit protocol or undefined.
+ if (!(equals(_scheme, DEFAULT_SCHEME) || _scheme == null)) {
+ throw new URIException(URIException.PARSING, "wrong class use");
+ }
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpVersion.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpVersion.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpVersion.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,248 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpVersion.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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 version, as specified in RFC 2616.
+ *+ * HTTP uses a "<major>.<minor>" numbering scheme to indicate + * versions of the protocol. The protocol versioning policy is intended to + * allow the sender to indicate the format of a message and its capacity for + * understanding further HTTP communication, rather than the features + * obtained via that communication. No change is made to the version + * number for the addition of message components which do not affect + * communication behavior or which only add to extensible field values. + * The <minor> number is incremented when the changes made to the + * protocol add features which do not change the general message parsing + * algorithm, but which may add to the message semantics and imply + * additional capabilities of the sender. The <major> number is + * incremented when the format of a message within the protocol is + * changed. See RFC 2145 [36] for a fuller explanation. + *
+ *+ * The version of an HTTP message is indicated by an HTTP-Version field + * in the first line of the message. + *
+ *+ * HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT + *+ *
+ * Note that the major and minor numbers MUST be treated as separate + * integers and that each MAY be incremented higher than a single digit. + * Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is + * lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and + * MUST NOT be sent. + *
+ * + * @author Oleg Kalnichevski + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:34 $ + * + * @since 3.0 + */ +public class HttpVersion implements Comparable { + + /** Major version number of the HTTP protocol */ + private int major = 0; + + /** Minor version number of the HTTP protocol */ + private int minor = 0; + + /** HTTP protocol version 0.9 */ + public static final HttpVersion HTTP_0_9 = new HttpVersion(0, 9); + + /** HTTP protocol version 1.0 */ + public static final HttpVersion HTTP_1_0 = new HttpVersion(1, 0); + + /** HTTP protocol version 1.1 */ + public static final HttpVersion HTTP_1_1 = new HttpVersion(1, 1); + + /** + * Create an HTTP protocol version designator. + * + * @param major the major version number of the HTTP protocol + * @param minor the minor version number of the HTTP protocol + * + * @throws IllegalArgumentException if either major or minor version number is negative + */ + public HttpVersion(int major, int minor) { + if (major < 0) { + throw new IllegalArgumentException("HTTP major version number may not be negative"); + } + this.major = major; + if (minor < 0) { + throw new IllegalArgumentException("HTTP minor version number may not be negative"); + } + this.minor = minor; + } + + /** + * Returns the major version number of the HTTP protocol. + * + * @return the major version number. + */ + public int getMajor() { + return major; + } + + /** + * Returns the minor version number of the HTTP protocol. + * + * @return the minor version number. + */ + public int getMinor() { + return minor; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return this.major * 100000 + this.minor; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof HttpVersion)) { + return false; + } + return equals((HttpVersion)obj); + } + + /** + * Compares this HTTP protocol version with another one. + * + * @param anotherVer the version to be compared with. + * + * @return a negative integer, zero, or a positive integer as this version is less than, + * equal to, or greater than the specified version. + */ + public int compareTo(HttpVersion anotherVer) { + if (anotherVer == null) { + throw new IllegalArgumentException("Version parameter may not be null"); + } + int delta = getMajor() - anotherVer.getMajor(); + if (delta == 0) { + delta = getMinor() - anotherVer.getMinor(); + } + return delta; + } + + /** + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(Object o) { + return compareTo((HttpVersion)o); + } + + /** + * Test if the HTTP protocol version is equal to the given number. + * + * @return true if HTTP protocol version is given to the given number, + * false otherwise. + */ + public boolean equals(HttpVersion version) { + return compareTo(version) == 0; + } + + /** + * Test if the HTTP protocol version is greater or equal to the given number. + * + * @return true if HTTP protocol version is greater or equal given to the + * given number, false otherwise. + */ + public boolean greaterEquals(HttpVersion version) { + return compareTo(version) >= 0; + } + + /** + * Test if the HTTP protocol version is less or equal to the given number. + * + * @return true if HTTP protocol version is less or equal to given to the + * given number, false otherwise. + */ + public boolean lessEquals(HttpVersion version) { + return compareTo(version) <= 0; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("HTTP/"); + buffer.append(this.major); + buffer.append('.'); + buffer.append(this.minor); + return buffer.toString(); + } + + /** + * Parses the textual representation of the given HTTP protocol version. + * + * @return HTTP protocol version. + * + * @throws ProtocolException if the string is not a valid HTTP protocol version. + */ + public static HttpVersion parse(final String s) throws ProtocolException { + if (s == null) { + throw new IllegalArgumentException("String may not be null"); + } + if (!s.startsWith("HTTP/")) { + throw new ProtocolException("Invalid HTTP version string: " + s); + } + int major, minor; + + int i1 = "HTTP/".length(); + int i2 = s.indexOf(".", i1); + if (i2 == -1) { + throw new ProtocolException("Invalid HTTP version number: " + s); + } + try { + major = Integer.parseInt(s.substring(i1, i2)); + } catch (NumberFormatException e) { + throw new ProtocolException("Invalid HTTP major version number: " + s); + } + i1 = i2 + 1; + i2 = s.length(); + try { + minor = Integer.parseInt(s.substring(i1, i2)); + } catch (NumberFormatException e) { + throw new ProtocolException("Invalid HTTP minor version number: " + s); + } + return new HttpVersion(major, minor); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpsURL.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpsURL.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpsURL.java 22 Aug 2012 17:30:35 -0000 1.1 @@ -0,0 +1,472 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpsURL.java,v 1.1 2012/08/22 17:30:35 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:35 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *escaped
is null
+ * @see #getProtocolCharset
+ */
+ public HttpsURL(char[] escaped, String charset)
+ throws URIException, NullPointerException {
+ protocolCharset = charset;
+ parseUriReference(new String(escaped), true);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTPS URL as an escaped form of a character array.
+ *
+ * @param escaped the HTTPS URL character sequence
+ * @throws URIException If {@link #checkValid()} fails
+ * @throws NullPointerException if escaped
is null
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(char[] escaped) throws URIException, NullPointerException {
+ parseUriReference(new String(escaped), true);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTPS URL from a given string with the given charset to do
+ * escape encoding.
+ *
+ * @param original the HTTPS URL string
+ * @param charset the charset to do escape encoding
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getProtocolCharset
+ */
+ public HttpsURL(String original, String charset) throws URIException {
+ protocolCharset = charset;
+ parseUriReference(original, false);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTPS URL from a given string.
+ *
+ * @param original the HTTPS URL string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String original) throws URIException {
+ parseUriReference(original, false);
+ checkValid();
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String host, int port, String path) throws URIException {
+ this(null, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String host, int port, String path, String query)
+ throws URIException {
+
+ this(null, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String user, String password, String host)
+ throws URIException {
+
+ this(user, password, host, -1, null, null, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String user, String password, String host, int port)
+ throws URIException {
+
+ this(user, password, host, port, null, null, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String user, String password, String host, int port,
+ String path) throws URIException {
+
+ this(user, password, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query The query string.
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String user, String password, String host, int port,
+ String path, String query) throws URIException {
+
+ this(user, password, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * @param host the host string
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String host, String path, String query, String fragment)
+ throws URIException {
+
+ this(null, host, -1, path, query, fragment);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String userinfo, String host, String path, String query,
+ String fragment) throws URIException {
+
+ this(userinfo, host, -1, path, query, fragment);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String userinfo, String host, int port, String path)
+ throws URIException {
+
+ this(userinfo, host, port, path, null, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String userinfo, String host, int port, String path,
+ String query) throws URIException {
+
+ this(userinfo, host, port, path, query, null);
+ }
+
+
+ /**
+ * Construct a HTTPS URL from given components.
+ *
+ * Note: The userinfo
format is normally
+ * <username>:<password>
where
+ * username and password must both be URL escaped.
+ *
+ * @param userinfo the userinfo string whose parts are URL escaped
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String userinfo, String host, int port, String path,
+ String query, String fragment) throws URIException {
+
+ // validate and contruct the URI character sequence
+ StringBuffer buff = new StringBuffer();
+ if (userinfo != null || host != null || port != -1) {
+ _scheme = DEFAULT_SCHEME; // in order to verify the own protocol
+ buff.append(_default_scheme);
+ buff.append("://");
+ if (userinfo != null) {
+ buff.append(userinfo);
+ buff.append('@');
+ }
+ if (host != null) {
+ buff.append(URIUtil.encode(host, URI.allowed_host));
+ if (port != -1 || port != DEFAULT_PORT) {
+ buff.append(':');
+ buff.append(port);
+ }
+ }
+ }
+ if (path != null) { // accept empty path
+ if (scheme != null && !path.startsWith("/")) {
+ throw new URIException(URIException.PARSING,
+ "abs_path requested");
+ }
+ buff.append(URIUtil.encode(path, URI.allowed_abs_path));
+ }
+ if (query != null) {
+ buff.append('?');
+ buff.append(URIUtil.encode(query, URI.allowed_query));
+ }
+ if (fragment != null) {
+ buff.append('#');
+ buff.append(URIUtil.encode(fragment, URI.allowed_fragment));
+ }
+ parseUriReference(buff.toString(), true);
+ checkValid();
+ }
+
+ /**
+ * Construct a HTTP URL from given components.
+ *
+ * @param user the user name
+ * @param password his or her password
+ * @param host the host string
+ * @param port the port number
+ * @param path the path string
+ * @param query the query string
+ * @param fragment the fragment string
+ * @throws URIException If {@link #checkValid()} fails
+ * @see #getDefaultProtocolCharset
+ */
+ public HttpsURL(String user, String password, String host, int port,
+ String path, String query, String fragment) throws URIException {
+ this(HttpURL.toUserinfo(user, password), host, port, path, query, fragment);
+ }
+
+ /**
+ * Construct a HTTPS URL with a given relative HTTPS URL string.
+ *
+ * @param base the base HttpsURL
+ * @param relative the relative HTTPS URL string
+ * @throws URIException If {@link #checkValid()} fails
+ */
+ public HttpsURL(HttpsURL base, String relative) throws URIException {
+ this(base, new HttpsURL(relative));
+ }
+
+
+ /**
+ * Construct a HTTPS URL with a given relative URL.
+ *
+ * @param base the base HttpsURL
+ * @param relative the relative HttpsURL
+ * @throws URIException If {@link #checkValid()} fails
+ */
+ public HttpsURL(HttpsURL base, HttpsURL relative) throws URIException {
+ super(base, relative);
+ checkValid();
+ }
+
+ // -------------------------------------------------------------- Constants
+
+ /**
+ * Default scheme for HTTPS URL.
+ */
+ public static final char[] DEFAULT_SCHEME = { 'h', 't', 't', 'p', 's' };
+
+ /**
+ * Default scheme for HTTPS URL.
+ * @deprecated Use {@link #DEFAULT_SCHEME} instead. This one doesn't
+ * conform to the project naming conventions.
+ */
+ public static final char[] _default_scheme = DEFAULT_SCHEME;
+
+
+ /**
+ * Default port for HTTPS URL.
+ */
+ public static final int DEFAULT_PORT = 443;
+
+ /**
+ * Default port for HTTPS URL.
+ * @deprecated Use {@link #DEFAULT_PORT} instead. This one doesn't conform
+ * to the project naming conventions.
+ */
+ public static final int _default_port = DEFAULT_PORT;
+
+
+ /**
+ * The serialVersionUID.
+ */
+ static final long serialVersionUID = 887844277028676648L;
+
+ // ------------------------------------------------------------- The scheme
+
+ /**
+ * Get the scheme. You can get the scheme explicitly.
+ *
+ * @return the scheme
+ */
+ public char[] getRawScheme() {
+ return (_scheme == null) ? null : HttpsURL.DEFAULT_SCHEME;
+ }
+
+
+ /**
+ * Get the scheme. You can get the scheme explicitly.
+ *
+ * @return the scheme null if empty or undefined
+ */
+ public String getScheme() {
+ return (_scheme == null) ? null : new String(HttpsURL.DEFAULT_SCHEME);
+ }
+
+ // --------------------------------------------------------------- The port
+
+ /**
+ * Get the port number.
+ * @return the port number
+ */
+ public int getPort() {
+ return (_port == -1) ? HttpsURL.DEFAULT_PORT : _port;
+ }
+
+ // ---------------------------------------------------------------- Utility
+
+ /**
+ * Verify the valid class use for construction.
+ *
+ * @throws URIException the wrong scheme use
+ */
+ protected void checkValid() throws URIException {
+ // could be explicit protocol or undefined.
+ if (!(equals(_scheme, DEFAULT_SCHEME) || _scheme == null)) {
+ throw new URIException(URIException.PARSING, "wrong class use");
+ }
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MethodRetryHandler.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MethodRetryHandler.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MethodRetryHandler.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,67 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MethodRetryHandler.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * true
if the method should be retried, false
+ * otherwise
+ */
+ boolean retryMethod(
+ HttpMethod method,
+ HttpConnection connection,
+ HttpRecoverableException recoverableException,
+ int executionCount,
+ boolean requestSent);
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,1636 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * A static reference to the connection manager will also be stored. To ensure that + * the connection manager can be GCed {@link #removeReferenceToConnection(HttpConnection)} + * should be called for all connections that the connection manager is storing a reference + * to.
+ * + * @param connection the connection to create a reference for + * @param hostConfiguration the connection's host config + * @param connectionPool the connection pool that created the connection + * + * @see #removeReferenceToConnection(HttpConnection) + */ + private static void storeReferenceToConnection( + HttpConnectionWithReference connection, + HostConfiguration hostConfiguration, + ConnectionPool connectionPool + ) { + + ConnectionSource source = new ConnectionSource(); + source.connectionPool = connectionPool; + source.hostConfiguration = hostConfiguration; + + synchronized (REFERENCE_TO_CONNECTION_SOURCE) { + + // start the reference queue thread if needed + if (REFERENCE_QUEUE_THREAD == null) { + REFERENCE_QUEUE_THREAD = new ReferenceQueueThread(); + REFERENCE_QUEUE_THREAD.start(); + } + + REFERENCE_TO_CONNECTION_SOURCE.put( + connection.reference, + source + ); + } + } + + /** + * Closes and releases all connections currently checked out of the given connection pool. + * @param connectionPool the connection pool to shutdown the connections for + */ + private static void shutdownCheckedOutConnections(ConnectionPool connectionPool) { + + // keep a list of the connections to be closed + ArrayList connectionsToClose = new ArrayList(); + + synchronized (REFERENCE_TO_CONNECTION_SOURCE) { + + Iterator referenceIter = REFERENCE_TO_CONNECTION_SOURCE.keySet().iterator(); + while (referenceIter.hasNext()) { + Reference ref = (Reference) referenceIter.next(); + ConnectionSource source = + (ConnectionSource) REFERENCE_TO_CONNECTION_SOURCE.get(ref); + if (source.connectionPool == connectionPool) { + referenceIter.remove(); + HttpConnection connection = (HttpConnection) ref.get(); + if (connection != null) { + connectionsToClose.add(connection); + } + } + } + } + + // close and release the connections outside of the synchronized block to + // avoid holding the lock for too long + for (Iterator i = connectionsToClose.iterator(); i.hasNext();) { + HttpConnection connection = (HttpConnection) i.next(); + connection.close(); + // remove the reference to the connection manager. this ensures + // that the we don't accidentally end up here again + connection.setHttpConnectionManager(null); + connection.releaseConnection(); + } + } + + /** + * Removes the reference being stored for the given connection. This method should be called + * when the connection manager again has a direct reference to the connection. + * + * @param connection the connection to remove the reference for + * + * @see #storeReferenceToConnection(HttpConnection, HostConfiguration, ConnectionPool) + */ + private static void removeReferenceToConnection(HttpConnectionWithReference connection) { + + synchronized (REFERENCE_TO_CONNECTION_SOURCE) { + REFERENCE_TO_CONNECTION_SOURCE.remove(connection.reference); + } + } + + + // ----------------------------------------------------- Instance Variables + + /** + * Collection of parameters associated with this connection manager. + */ + private HttpConnectionManagerParams params = new HttpConnectionManagerParams(); + + /** Connection Pool */ + private ConnectionPool connectionPool; + + private boolean shutdown = false; + + + // ----------------------------------------------------------- Constructors + + /** + * No-args constructor + */ + public MultiThreadedHttpConnectionManager() { + this.connectionPool = new ConnectionPool(); + synchronized(ALL_CONNECTION_MANAGERS) { + ALL_CONNECTION_MANAGERS.put(this, null); + } + } + + + // ------------------------------------------------------- Instance Methods + + /** + * Shuts down the connection manager and releases all resources. All connections associated + * with this class will be closed and released. + * + *The connection manager can no longer be used once shutdown. + * + *
Calling this method more than once will have no effect.
+ */
+ public synchronized void shutdown() {
+ synchronized (connectionPool) {
+ if (!shutdown) {
+ shutdown = true;
+ connectionPool.shutdown();
+ }
+ }
+ }
+
+ /**
+ * Gets the staleCheckingEnabled value to be set on HttpConnections that are created.
+ *
+ * @return true
if stale checking will be enabled on HttpConnections
+ *
+ * @see HttpConnection#isStaleCheckingEnabled()
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#isStaleCheckingEnabled()},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public boolean isConnectionStaleCheckingEnabled() {
+ return this.params.isStaleCheckingEnabled();
+ }
+
+ /**
+ * Sets the staleCheckingEnabled value to be set on HttpConnections that are created.
+ *
+ * @param connectionStaleCheckingEnabled true
if stale checking will be enabled
+ * on HttpConnections
+ *
+ * @see HttpConnection#setStaleCheckingEnabled(boolean)
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#setStaleCheckingEnabled(boolean)},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
+ this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
+ }
+
+ /**
+ * Sets the maximum number of connections allowed for a given
+ * HostConfiguration. Per RFC 2616 section 8.1.4, this value defaults to 2.
+ *
+ * @param maxHostConnections the number of connections allowed for each
+ * hostConfiguration
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#setDefaultMaxConnectionsPerHost(int)},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public void setMaxConnectionsPerHost(int maxHostConnections) {
+ this.params.setDefaultMaxConnectionsPerHost(maxHostConnections);
+ }
+
+ /**
+ * Gets the maximum number of connections allowed for a given
+ * hostConfiguration.
+ *
+ * @return The maximum number of connections allowed for a given
+ * hostConfiguration.
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#getDefaultMaxConnectionsPerHost()},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public int getMaxConnectionsPerHost() {
+ return this.params.getDefaultMaxConnectionsPerHost();
+ }
+
+ /**
+ * Sets the maximum number of connections allowed for this connection manager.
+ *
+ * @param maxTotalConnections the maximum number of connections allowed
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#setMaxTotalConnections(int)},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public void setMaxTotalConnections(int maxTotalConnections) {
+ this.params.getMaxTotalConnections();
+ }
+
+ /**
+ * Gets the maximum number of connections allowed for this connection manager.
+ *
+ * @return The maximum number of connections allowed
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#getMaxTotalConnections()},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public int getMaxTotalConnections() {
+ return this.params.getMaxTotalConnections();
+ }
+
+ /**
+ * @see HttpConnectionManager#getConnection(HostConfiguration)
+ */
+ public HttpConnection getConnection(HostConfiguration hostConfiguration) {
+
+ while (true) {
+ try {
+ return getConnectionWithTimeout(hostConfiguration, 0);
+ } catch (ConnectionPoolTimeoutException e) {
+ // we'll go ahead and log this, but it should never happen. HttpExceptions
+ // are only thrown when the timeout occurs and since we have no timeout
+ // it should never happen.
+ LOG.debug(
+ "Unexpected exception while waiting for connection",
+ e
+ );
+ }
+ }
+ }
+
+ /**
+ * @see HttpConnectionManager#getConnectionWithTimeout(HostConfiguration, long)
+ *
+ * @since 3.0
+ */
+ public HttpConnection getConnectionWithTimeout(HostConfiguration hostConfiguration,
+ long timeout) throws ConnectionPoolTimeoutException {
+
+ LOG.trace("enter HttpConnectionManager.getConnectionWithTimeout(HostConfiguration, long)");
+
+ if (hostConfiguration == null) {
+ throw new IllegalArgumentException("hostConfiguration is null");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("HttpConnectionManager.getConnection: config = "
+ + hostConfiguration + ", timeout = " + timeout);
+ }
+
+ final HttpConnection conn = doGetConnection(hostConfiguration, timeout);
+
+ // wrap the connection in an adapter so we can ensure it is used
+ // only once
+ return new HttpConnectionAdapter(conn);
+ }
+
+ /**
+ * @see HttpConnectionManager#getConnection(HostConfiguration, long)
+ *
+ * @deprecated Use #getConnectionWithTimeout(HostConfiguration, long)
+ */
+ public HttpConnection getConnection(HostConfiguration hostConfiguration,
+ long timeout) throws HttpException {
+
+ LOG.trace("enter HttpConnectionManager.getConnection(HostConfiguration, long)");
+ try {
+ return getConnectionWithTimeout(hostConfiguration, timeout);
+ } catch(ConnectionPoolTimeoutException e) {
+ throw new HttpException(e.getMessage());
+ }
+ }
+
+ /**
+ * Gets a connection or waits if one is not available. A connection is
+ * available if one exists that is not being used or if fewer than
+ * maxHostConnections have been created in the connectionPool, and fewer
+ * than maxTotalConnections have been created in all connectionPools.
+ *
+ * @param hostConfiguration The host configuration.
+ * @param timeout the number of milliseconds to wait for a connection, 0 to
+ * wait indefinitely
+ *
+ * @return HttpConnection an available connection
+ *
+ * @throws HttpException if a connection does not become available in
+ * 'timeout' milliseconds
+ */
+ private HttpConnection doGetConnection(HostConfiguration hostConfiguration,
+ long timeout) throws ConnectionPoolTimeoutException {
+
+ HttpConnection connection = null;
+
+ int maxHostConnections = this.params.getMaxConnectionsPerHost(hostConfiguration);
+ int maxTotalConnections = this.params.getMaxTotalConnections();
+
+ synchronized (connectionPool) {
+
+ // we clone the hostConfiguration
+ // so that it cannot be changed once the connection has been retrieved
+ hostConfiguration = new HostConfiguration(hostConfiguration);
+ HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration);
+ WaitingThread waitingThread = null;
+
+ boolean useTimeout = (timeout > 0);
+ long timeToWait = timeout;
+ long startWait = 0;
+ long endWait = 0;
+
+ while (connection == null) {
+
+ if (shutdown) {
+ throw new IllegalStateException("Connection factory has been shutdown.");
+ }
+
+ // happen to have a free connection with the right specs
+ //
+ if (hostPool.freeConnections.size() > 0) {
+ connection = connectionPool.getFreeConnection(hostConfiguration);
+
+ // have room to make more
+ //
+ } else if ((hostPool.numConnections < maxHostConnections)
+ && (connectionPool.numConnections < maxTotalConnections)) {
+
+ connection = connectionPool.createConnection(hostConfiguration);
+
+ // have room to add host connection, and there is at least one free
+ // connection that can be liberated to make overall room
+ //
+ } else if ((hostPool.numConnections < maxHostConnections)
+ && (connectionPool.freeConnections.size() > 0)) {
+
+ connectionPool.deleteLeastUsedConnection();
+ connection = connectionPool.createConnection(hostConfiguration);
+
+ // otherwise, we have to wait for one of the above conditions to
+ // become true
+ //
+ } else {
+ // TODO: keep track of which hostConfigurations have waiting
+ // threads, so they avoid being sacrificed before necessary
+
+ try {
+
+ if (useTimeout && timeToWait <= 0) {
+ throw new ConnectionPoolTimeoutException("Timeout waiting for connection");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Unable to get a connection, waiting..., hostConfig=" + hostConfiguration);
+ }
+
+ if (waitingThread == null) {
+ waitingThread = new WaitingThread();
+ waitingThread.hostConnectionPool = hostPool;
+ waitingThread.thread = Thread.currentThread();
+ }
+
+ if (useTimeout) {
+ startWait = System.currentTimeMillis();
+ }
+
+ hostPool.waitingThreads.addLast(waitingThread);
+ connectionPool.waitingThreads.addLast(waitingThread);
+ connectionPool.wait(timeToWait);
+
+ // we have not been interrupted so we need to remove ourselves from the
+ // wait queue
+ hostPool.waitingThreads.remove(waitingThread);
+ connectionPool.waitingThreads.remove(waitingThread);
+ } catch (InterruptedException e) {
+ // do nothing
+ } finally {
+ if (useTimeout) {
+ endWait = System.currentTimeMillis();
+ timeToWait -= (endWait - startWait);
+ }
+ }
+ }
+ }
+ }
+ return connection;
+ }
+
+ /**
+ * Gets the total number of pooled connections for the given host configuration. This
+ * is the total number of connections that have been created and are still in use
+ * by this connection manager for the host configuration. This value will
+ * not exceed the {@link #getMaxConnectionsPerHost() maximum number of connections per
+ * host}.
+ *
+ * @param hostConfiguration The host configuration
+ * @return The total number of pooled connections
+ */
+ public int getConnectionsInPool(HostConfiguration hostConfiguration) {
+ synchronized (connectionPool) {
+ HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration);
+ return hostPool.numConnections;
+ }
+ }
+
+ /**
+ * Gets the total number of pooled connections. This is the total number of
+ * connections that have been created and are still in use by this connection
+ * manager. This value will not exceed the {@link #getMaxTotalConnections()
+ * maximum number of connections}.
+ *
+ * @return the total number of pooled connections
+ */
+ public int getConnectionsInPool() {
+ synchronized (connectionPool) {
+ return connectionPool.numConnections;
+ }
+ }
+
+ /**
+ * Gets the number of connections in use for this configuration.
+ *
+ * @param hostConfiguration the key that connections are tracked on
+ * @return the number of connections in use
+ *
+ * @deprecated Use {@link #getConnectionsInPool(HostConfiguration)}
+ */
+ public int getConnectionsInUse(HostConfiguration hostConfiguration) {
+ return getConnectionsInPool(hostConfiguration);
+ }
+
+ /**
+ * Gets the total number of connections in use.
+ *
+ * @return the total number of connections in use
+ *
+ * @deprecated Use {@link #getConnectionsInPool()}
+ */
+ public int getConnectionsInUse() {
+ return getConnectionsInPool();
+ }
+
+ /**
+ * Deletes all closed connections. Only connections currently owned by the connection
+ * manager are processed.
+ *
+ * @see HttpConnection#isOpen()
+ *
+ * @since 3.0
+ */
+ public void deleteClosedConnections() {
+ connectionPool.deleteClosedConnections();
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void closeIdleConnections(long idleTimeout) {
+ connectionPool.closeIdleConnections(idleTimeout);
+ }
+
+ /**
+ * Make the given HttpConnection available for use by other requests.
+ * If another thread is blocked in getConnection() that could use this
+ * connection, it will be woken up.
+ *
+ * @param conn the HttpConnection to make available.
+ */
+ public void releaseConnection(HttpConnection conn) {
+ LOG.trace("enter HttpConnectionManager.releaseConnection(HttpConnection)");
+
+ if (conn instanceof HttpConnectionAdapter) {
+ // connections given out are wrapped in an HttpConnectionAdapter
+ conn = ((HttpConnectionAdapter) conn).getWrappedConnection();
+ } else {
+ // this is okay, when an HttpConnectionAdapter is released
+ // is releases the real connection
+ }
+
+ // make sure that the response has been read.
+ SimpleHttpConnectionManager.finishLastResponse(conn);
+
+ connectionPool.freeConnection(conn);
+ }
+
+ /**
+ * Gets the host configuration for a connection.
+ * @param conn the connection to get the configuration of
+ * @return a new HostConfiguration
+ */
+ private HostConfiguration configurationForConnection(HttpConnection conn) {
+
+ HostConfiguration connectionConfiguration = new HostConfiguration();
+
+ connectionConfiguration.setHost(
+ conn.getHost(),
+ conn.getPort(),
+ conn.getProtocol()
+ );
+ if (conn.getLocalAddress() != null) {
+ connectionConfiguration.setLocalAddress(conn.getLocalAddress());
+ }
+ if (conn.getProxyHost() != null) {
+ connectionConfiguration.setProxy(conn.getProxyHost(), conn.getProxyPort());
+ }
+
+ return connectionConfiguration;
+ }
+
+ /**
+ * Returns {@link HttpConnectionManagerParams parameters} associated
+ * with this connection manager.
+ *
+ * @since 3.0
+ *
+ * @see HttpConnectionManagerParams
+ */
+ public HttpConnectionManagerParams getParams() {
+ return this.params;
+ }
+
+ /**
+ * Assigns {@link HttpConnectionManagerParams parameters} for this
+ * connection manager.
+ *
+ * @since 3.0
+ *
+ * @see HttpConnectionManagerParams
+ */
+ public void setParams(final HttpConnectionManagerParams params) {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ this.params = params;
+ }
+
+ /**
+ * Global Connection Pool, including per-host pools
+ */
+ private class ConnectionPool {
+
+ /** The list of free connections */
+ private LinkedList freeConnections = new LinkedList();
+
+ /** The list of WaitingThreads waiting for a connection */
+ private LinkedList waitingThreads = new LinkedList();
+
+ /**
+ * Map where keys are {@link HostConfiguration}s and values are {@link
+ * HostConnectionPool}s
+ */
+ private final Map mapHosts = new HashMap();
+
+ private IdleConnectionHandler idleConnectionHandler = new IdleConnectionHandler();
+
+ /** The number of created connections */
+ private int numConnections = 0;
+
+ /**
+ * Cleans up all connection pool resources.
+ */
+ public synchronized void shutdown() {
+
+ // close all free connections
+ Iterator iter = freeConnections.iterator();
+ while (iter.hasNext()) {
+ HttpConnection conn = (HttpConnection) iter.next();
+ iter.remove();
+ conn.close();
+ }
+
+ // close all connections that have been checked out
+ shutdownCheckedOutConnections(this);
+
+ // interrupt all waiting threads
+ iter = waitingThreads.iterator();
+ while (iter.hasNext()) {
+ WaitingThread waiter = (WaitingThread) iter.next();
+ iter.remove();
+ waiter.thread.interrupt();
+ }
+
+ // clear out map hosts
+ mapHosts.clear();
+
+ // remove all references to connections
+ idleConnectionHandler.removeAll();
+ }
+
+ /**
+ * Creates a new connection and returns it for use of the calling method.
+ *
+ * @param hostConfiguration the configuration for the connection
+ * @return a new connection or null
if none are available
+ */
+ public synchronized HttpConnection createConnection(HostConfiguration hostConfiguration) {
+ HostConnectionPool hostPool = getHostPool(hostConfiguration);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Allocating new connection, hostConfig=" + hostConfiguration);
+ }
+ HttpConnectionWithReference connection = new HttpConnectionWithReference(
+ hostConfiguration);
+ connection.getParams().setDefaults(MultiThreadedHttpConnectionManager.this.params);
+ connection.setHttpConnectionManager(MultiThreadedHttpConnectionManager.this);
+ numConnections++;
+ hostPool.numConnections++;
+
+ // store a reference to this connection so that it can be cleaned up
+ // in the event it is not correctly released
+ storeReferenceToConnection(connection, hostConfiguration, this);
+ return connection;
+ }
+
+ /**
+ * Handles cleaning up for a lost connection with the given config. Decrements any
+ * connection counts and notifies waiting threads, if appropriate.
+ *
+ * @param config the host configuration of the connection that was lost
+ */
+ public synchronized void handleLostConnection(HostConfiguration config) {
+ HostConnectionPool hostPool = getHostPool(config);
+ hostPool.numConnections--;
+
+ numConnections--;
+ notifyWaitingThread(config);
+ }
+
+ /**
+ * Get the pool (list) of connections available for the given hostConfig.
+ *
+ * @param hostConfiguration the configuraton for the connection pool
+ * @return a pool (list) of connections available for the given config
+ */
+ public synchronized HostConnectionPool getHostPool(HostConfiguration hostConfiguration) {
+ LOG.trace("enter HttpConnectionManager.ConnectionPool.getHostPool(HostConfiguration)");
+
+ // Look for a list of connections for the given config
+ HostConnectionPool listConnections = (HostConnectionPool)
+ mapHosts.get(hostConfiguration);
+ if (listConnections == null) {
+ // First time for this config
+ listConnections = new HostConnectionPool();
+ listConnections.hostConfiguration = hostConfiguration;
+ mapHosts.put(hostConfiguration, listConnections);
+ }
+
+ return listConnections;
+ }
+
+ /**
+ * If available, get a free connection for this host
+ *
+ * @param hostConfiguration the configuraton for the connection pool
+ * @return an available connection for the given config
+ */
+ public synchronized HttpConnection getFreeConnection(HostConfiguration hostConfiguration) {
+
+ HttpConnectionWithReference connection = null;
+
+ HostConnectionPool hostPool = getHostPool(hostConfiguration);
+
+ if (hostPool.freeConnections.size() > 0) {
+ connection = (HttpConnectionWithReference) hostPool.freeConnections.removeFirst();
+ freeConnections.remove(connection);
+ // store a reference to this connection so that it can be cleaned up
+ // in the event it is not correctly released
+ storeReferenceToConnection(connection, hostConfiguration, this);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Getting free connection, hostConfig=" + hostConfiguration);
+ }
+
+ // remove the connection from the timeout handler
+ idleConnectionHandler.remove(connection);
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("There were no free connections to get, hostConfig="
+ + hostConfiguration);
+ }
+ return connection;
+ }
+
+ /**
+ * Deletes all closed connections.
+ */
+ public synchronized void deleteClosedConnections() {
+
+ Iterator iter = freeConnections.iterator();
+
+ while (iter.hasNext()) {
+ HttpConnection conn = (HttpConnection) iter.next();
+ if (!conn.isOpen()) {
+ iter.remove();
+ deleteConnection(conn);
+ }
+ }
+ }
+
+ /**
+ * Closes idle connections.
+ * @param idleTimeout
+ */
+ public synchronized void closeIdleConnections(long idleTimeout) {
+ idleConnectionHandler.closeIdleConnections(idleTimeout);
+ }
+
+ /**
+ * Deletes the given connection. This will remove all reference to the connection
+ * so that it can be GCed.
+ *
+ *
Note: Does not remove the connection from the freeConnections list. It + * is assumed that the caller has already handled this case.
+ * + * @param connection The connection to delete + */ + private synchronized void deleteConnection(HttpConnection connection) { + + HostConfiguration connectionConfiguration = configurationForConnection(connection); + + if (LOG.isDebugEnabled()) { + LOG.debug("Reclaiming connection, hostConfig=" + connectionConfiguration); + } + + connection.close(); + + HostConnectionPool hostPool = getHostPool(connectionConfiguration); + + hostPool.freeConnections.remove(connection); + hostPool.numConnections--; + numConnections--; + + // remove the connection from the timeout handler + idleConnectionHandler.remove(connection); + } + + /** + * Close and delete an old, unused connection to make room for a new one. + */ + public synchronized void deleteLeastUsedConnection() { + + HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); + + if (connection != null) { + deleteConnection(connection); + } else if (LOG.isDebugEnabled()) { + LOG.debug("Attempted to reclaim an unused connection but there were none."); + } + } + + /** + * Notifies a waiting thread that a connection for the given configuration is + * available. + * @param configuration the host config to use for notifying + * @see #notifyWaitingThread(HostConnectionPool) + */ + public synchronized void notifyWaitingThread(HostConfiguration configuration) { + notifyWaitingThread(getHostPool(configuration)); + } + + /** + * Notifies a waiting thread that a connection for the given configuration is + * available. This will wake a thread waiting in this host pool or if there is not + * one a thread in the connection pool will be notified. + * + * @param hostPool the host pool to use for notifying + */ + public synchronized void notifyWaitingThread(HostConnectionPool hostPool) { + + // find the thread we are going to notify, we want to ensure that each + // waiting thread is only interrupted once so we will remove it from + // all wait queues before interrupting it + WaitingThread waitingThread = null; + + if (hostPool.waitingThreads.size() > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug("Notifying thread waiting on host pool, hostConfig=" + + hostPool.hostConfiguration); + } + waitingThread = (WaitingThread) hostPool.waitingThreads.removeFirst(); + waitingThreads.remove(waitingThread); + } else if (waitingThreads.size() > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug("No-one waiting on host pool, notifying next waiting thread."); + } + waitingThread = (WaitingThread) waitingThreads.removeFirst(); + waitingThread.hostConnectionPool.waitingThreads.remove(waitingThread); + } else if (LOG.isDebugEnabled()) { + LOG.debug("Notifying no-one, there are no waiting threads"); + } + + if (waitingThread != null) { + waitingThread.thread.interrupt(); + } + } + + /** + * Marks the given connection as free. + * @param conn a connection that is no longer being used + */ + public void freeConnection(HttpConnection conn) { + + HostConfiguration connectionConfiguration = configurationForConnection(conn); + + if (LOG.isDebugEnabled()) { + LOG.debug("Freeing connection, hostConfig=" + connectionConfiguration); + } + + synchronized (this) { + + if (shutdown) { + // the connection manager has been shutdown, release the connection's + // resources and get out of here + conn.close(); + return; + } + + HostConnectionPool hostPool = getHostPool(connectionConfiguration); + + // Put the connect back in the available list and notify a waiter + hostPool.freeConnections.add(conn); + if (hostPool.numConnections == 0) { + // for some reason this connection pool didn't already exist + LOG.error("Host connection pool not found, hostConfig=" + + connectionConfiguration); + hostPool.numConnections = 1; + } + + freeConnections.add(conn); + // we can remove the reference to this connection as we have control over + // it again. this also ensures that the connection manager can be GCed + removeReferenceToConnection((HttpConnectionWithReference) conn); + if (numConnections == 0) { + // for some reason this connection pool didn't already exist + LOG.error("Host connection pool not found, hostConfig=" + + connectionConfiguration); + numConnections = 1; + } + + // register the connection with the timeout handler + idleConnectionHandler.add(conn); + + notifyWaitingThread(hostPool); + } + } + } + + /** + * A simple struct-like class to combine the objects needed to release a connection's + * resources when claimed by the garbage collector. + */ + private static class ConnectionSource { + + /** The connection pool that created the connection */ + public ConnectionPool connectionPool; + + /** The connection's host configuration */ + public HostConfiguration hostConfiguration; + } + + /** + * A simple struct-like class to combine the connection list and the count + * of created connections. + */ + private static class HostConnectionPool { + /** The hostConfig this pool is for */ + public HostConfiguration hostConfiguration; + + /** The list of free connections */ + public LinkedList freeConnections = new LinkedList(); + + /** The list of WaitingThreads for this host */ + public LinkedList waitingThreads = new LinkedList(); + + /** The number of created connections */ + public int numConnections = 0; + } + + /** + * A simple struct-like class to combine the waiting thread and the connection + * pool it is waiting on. + */ + private static class WaitingThread { + /** The thread that is waiting for a connection */ + public Thread thread; + + /** The connection pool the thread is waiting for */ + public HostConnectionPool hostConnectionPool; + } + + /** + * A thread for listening for HttpConnections reclaimed by the garbage + * collector. + */ + private static class ReferenceQueueThread extends Thread { + + private boolean shutdown = false; + + /** + * Create an instance and make this a daemon thread. + */ + public ReferenceQueueThread() { + setDaemon(true); + setName("MultiThreadedHttpConnectionManager cleanup"); + } + + public void shutdown() { + this.shutdown = true; + } + + /** + * Handles cleaning up for the given connection reference. + * + * @param ref the reference to clean up + */ + private void handleReference(Reference ref) { + + ConnectionSource source = null; + + synchronized (REFERENCE_TO_CONNECTION_SOURCE) { + source = (ConnectionSource) REFERENCE_TO_CONNECTION_SOURCE.remove(ref); + } + // only clean up for this reference if it is still associated with + // a ConnectionSource + if (source != null) { + if (LOG.isDebugEnabled()) { + LOG.debug( + "Connection reclaimed by garbage collector, hostConfig=" + + source.hostConfiguration); + } + + source.connectionPool.handleLostConnection(source.hostConfiguration); + } + } + + /** + * Start execution. + */ + public void run() { + while (!shutdown) { + try { + // remove the next reference and process it, a timeout + // is used so that the thread does not block indefinitely + // and therefore keep the thread from shutting down + Reference ref = REFERENCE_QUEUE.remove(1000); + if (ref != null) { + handleReference(ref); + } + } catch (InterruptedException e) { + LOG.debug("ReferenceQueueThread interrupted", e); + } + } + } + + } + + /** + * A connection that keeps a reference to itself. + */ + private static class HttpConnectionWithReference extends HttpConnection { + + public WeakReference reference = new WeakReference(this, REFERENCE_QUEUE); + + /** + * @param hostConfiguration + */ + public HttpConnectionWithReference(HostConfiguration hostConfiguration) { + super(hostConfiguration); + } + + } + + /** + * An HttpConnection wrapper that ensures a connection cannot be used + * once released. + */ + private static class HttpConnectionAdapter extends HttpConnection { + + // the wrapped connection + private HttpConnection wrappedConnection; + + /** + * Creates a new HttpConnectionAdapter. + * @param connection the connection to be wrapped + */ + public HttpConnectionAdapter(HttpConnection connection) { + super(connection.getHost(), connection.getPort(), connection.getProtocol()); + this.wrappedConnection = connection; + } + + /** + * Tests if the wrapped connection is still available. + * @return boolean + */ + protected boolean hasConnection() { + return wrappedConnection != null; + } + + /** + * @return HttpConnection + */ + HttpConnection getWrappedConnection() { + return wrappedConnection; + } + + public void close() { + if (hasConnection()) { + wrappedConnection.close(); + } else { + // do nothing + } + } + + public InetAddress getLocalAddress() { + if (hasConnection()) { + return wrappedConnection.getLocalAddress(); + } else { + return null; + } + } + + /** + * @deprecated + */ + public boolean isStaleCheckingEnabled() { + if (hasConnection()) { + return wrappedConnection.isStaleCheckingEnabled(); + } else { + return false; + } + } + + public void setLocalAddress(InetAddress localAddress) { + if (hasConnection()) { + wrappedConnection.setLocalAddress(localAddress); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public void setStaleCheckingEnabled(boolean staleCheckEnabled) { + if (hasConnection()) { + wrappedConnection.setStaleCheckingEnabled(staleCheckEnabled); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public String getHost() { + if (hasConnection()) { + return wrappedConnection.getHost(); + } else { + return null; + } + } + + public HttpConnectionManager getHttpConnectionManager() { + if (hasConnection()) { + return wrappedConnection.getHttpConnectionManager(); + } else { + return null; + } + } + + public InputStream getLastResponseInputStream() { + if (hasConnection()) { + return wrappedConnection.getLastResponseInputStream(); + } else { + return null; + } + } + + public int getPort() { + if (hasConnection()) { + return wrappedConnection.getPort(); + } else { + return -1; + } + } + + public Protocol getProtocol() { + if (hasConnection()) { + return wrappedConnection.getProtocol(); + } else { + return null; + } + } + + public String getProxyHost() { + if (hasConnection()) { + return wrappedConnection.getProxyHost(); + } else { + return null; + } + } + + public int getProxyPort() { + if (hasConnection()) { + return wrappedConnection.getProxyPort(); + } else { + return -1; + } + } + + public OutputStream getRequestOutputStream() + throws IOException, IllegalStateException { + if (hasConnection()) { + return wrappedConnection.getRequestOutputStream(); + } else { + return null; + } + } + + public InputStream getResponseInputStream() + throws IOException, IllegalStateException { + if (hasConnection()) { + return wrappedConnection.getResponseInputStream(); + } else { + return null; + } + } + + public boolean isOpen() { + if (hasConnection()) { + return wrappedConnection.isOpen(); + } else { + return false; + } + } + + public boolean closeIfStale() throws IOException { + if (hasConnection()) { + return wrappedConnection.closeIfStale(); + } else { + return false; + } + } + + public boolean isProxied() { + if (hasConnection()) { + return wrappedConnection.isProxied(); + } else { + return false; + } + } + + public boolean isResponseAvailable() throws IOException { + if (hasConnection()) { + return wrappedConnection.isResponseAvailable(); + } else { + return false; + } + } + + public boolean isResponseAvailable(int timeout) throws IOException { + if (hasConnection()) { + return wrappedConnection.isResponseAvailable(timeout); + } else { + return false; + } + } + + public boolean isSecure() { + if (hasConnection()) { + return wrappedConnection.isSecure(); + } else { + return false; + } + } + + public boolean isTransparent() { + if (hasConnection()) { + return wrappedConnection.isTransparent(); + } else { + return false; + } + } + + public void open() throws IOException { + if (hasConnection()) { + wrappedConnection.open(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public void print(String data) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.print(data); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void printLine() + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.printLine(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public void printLine(String data) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.printLine(data); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public String readLine() throws IOException, IllegalStateException { + if (hasConnection()) { + return wrappedConnection.readLine(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public String readLine(String charset) throws IOException, IllegalStateException { + if (hasConnection()) { + return wrappedConnection.readLine(charset); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void releaseConnection() { + if (!isLocked() && hasConnection()) { + HttpConnection wrappedConnection = this.wrappedConnection; + this.wrappedConnection = null; + wrappedConnection.releaseConnection(); + } else { + // do nothing + } + } + + /** + * @deprecated + */ + public void setConnectionTimeout(int timeout) { + if (hasConnection()) { + wrappedConnection.setConnectionTimeout(timeout); + } else { + // do nothing + } + } + + public void setHost(String host) throws IllegalStateException { + if (hasConnection()) { + wrappedConnection.setHost(host); + } else { + // do nothing + } + } + + public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) { + if (hasConnection()) { + wrappedConnection.setHttpConnectionManager(httpConnectionManager); + } else { + // do nothing + } + } + + public void setLastResponseInputStream(InputStream inStream) { + if (hasConnection()) { + wrappedConnection.setLastResponseInputStream(inStream); + } else { + // do nothing + } + } + + public void setPort(int port) throws IllegalStateException { + if (hasConnection()) { + wrappedConnection.setPort(port); + } else { + // do nothing + } + } + + public void setProtocol(Protocol protocol) { + if (hasConnection()) { + wrappedConnection.setProtocol(protocol); + } else { + // do nothing + } + } + + public void setProxyHost(String host) throws IllegalStateException { + if (hasConnection()) { + wrappedConnection.setProxyHost(host); + } else { + // do nothing + } + } + + public void setProxyPort(int port) throws IllegalStateException { + if (hasConnection()) { + wrappedConnection.setProxyPort(port); + } else { + // do nothing + } + } + + /** + * @deprecated + */ + public void setSoTimeout(int timeout) + throws SocketException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.setSoTimeout(timeout); + } else { + // do nothing + } + } + + /** + * @deprecated + */ + public void shutdownOutput() { + if (hasConnection()) { + wrappedConnection.shutdownOutput(); + } else { + // do nothing + } + } + + public void tunnelCreated() throws IllegalStateException, IOException { + if (hasConnection()) { + wrappedConnection.tunnelCreated(); + } else { + // do nothing + } + } + + public void write(byte[] data, int offset, int length) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.write(data, offset, length); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void write(byte[] data) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.write(data); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void writeLine() + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.writeLine(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void writeLine(byte[] data) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.writeLine(data); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void flushRequestOutputStream() throws IOException { + if (hasConnection()) { + wrappedConnection.flushRequestOutputStream(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public int getSoTimeout() throws SocketException { + if (hasConnection()) { + return wrappedConnection.getSoTimeout(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public String getVirtualHost() { + if (hasConnection()) { + return wrappedConnection.getVirtualHost(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public void setVirtualHost(String host) throws IllegalStateException { + if (hasConnection()) { + wrappedConnection.setVirtualHost(host); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public int getSendBufferSize() throws SocketException { + if (hasConnection()) { + return wrappedConnection.getSendBufferSize(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /** + * @deprecated + */ + public void setSendBufferSize(int sendBufferSize) throws SocketException { + if (hasConnection()) { + wrappedConnection.setSendBufferSize(sendBufferSize); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public HttpConnectionParams getParams() { + if (hasConnection()) { + return wrappedConnection.getParams(); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void setParams(final HttpConnectionParams params) { + if (hasConnection()) { + wrappedConnection.setParams(params); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /* (non-Javadoc) + * @see org.apache.commons.httpclient.HttpConnection#print(java.lang.String, java.lang.String) + */ + public void print(String data, String charset) throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.print(data, charset); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /* (non-Javadoc) + * @see org.apache.commons.httpclient.HttpConnection#printLine(java.lang.String, java.lang.String) + */ + public void printLine(String data, String charset) + throws IOException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.printLine(data, charset); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + /* (non-Javadoc) + * @see org.apache.commons.httpclient.HttpConnection#setSocketTimeout(int) + */ + public void setSocketTimeout(int timeout) throws SocketException, IllegalStateException { + if (hasConnection()) { + wrappedConnection.setSocketTimeout(timeout); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + } + +} + Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NTCredentials.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NTCredentials.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NTCredentials.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,191 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NTCredentials.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *true
if all of the credentials match.
+ */
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (super.equals(o) ) {
+ if (o instanceof NTCredentials) {
+ NTCredentials that = (NTCredentials) o;
+
+ return LangUtils.equals(this.domain, that.domain)
+ && LangUtils.equals(this.host, that.host);
+ }
+ }
+
+ return false;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NameValuePair.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NameValuePair.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NameValuePair.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,151 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NameValuePair.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * A simple class encapsulating a name/value pair.
+ * + * @author B.C. Holmes + * @author Sean C. Sullivan + * @author Mike Bowler + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:35 $ + * + */ +public class NameValuePair implements Serializable { + + // ----------------------------------------------------------- Constructors + + /** + * Default constructor. + * + */ + public NameValuePair() { + this (null, null); + } + + /** + * Constructor. + * @param name The name. + * @param value The value. + */ + public NameValuePair(String name, String value) { + this.name = name; + this.value = value; + } + + // ----------------------------------------------------- Instance Variables + + /** + * Name. + */ + private String name = null; + + /** + * Value. + */ + private String value = null; + + // ------------------------------------------------------------- Properties + + /** + * Set the name. + * + * @param name The new name + * @see #getName() + */ + public void setName(String name) { + this.name = name; + } + + + /** + * Return the name. + * + * @return String name The name + * @see #setName(String) + */ + public String getName() { + return name; + } + + + /** + * Set the value. + * + * @param value The new value. + */ + public void setValue(String value) { + this.value = value; + } + + + /** + * Return the current value. + * + * @return String value The current value. + */ + public String getValue() { + return value; + } + + // --------------------------------------------------------- Public Methods + + /** + * Get a String representation of this pair. + * @return A string representation. + */ + public String toString() { + return ("name=" + name + ", " + "value=" + value); + } + + public boolean equals(final Object object) { + if (object == null) return false; + if (this == object) return true; + if (object instanceof NameValuePair) { + NameValuePair that = (NameValuePair) object; + return LangUtils.equals(this.name, that.name) + && LangUtils.equals(this.value, that.value); + } else { + return false; + } + } + + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.name); + hash = LangUtils.hashCode(hash, this.value); + return hash; + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NoHttpResponseException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NoHttpResponseException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NoHttpResponseException.java 22 Aug 2012 17:30:35 -0000 1.1 @@ -0,0 +1,77 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NoHttpResponseException.java,v 1.1 2012/08/22 17:30:35 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:35 $ + * + * ==================================================================== + * + * 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 + *+ * Signals that the target server failed to respond with a valid HTTP response. + *
+ * + * @author Oleg Kalnichevski + * + * @version $Revision: 1.1 $ + */ +public class NoHttpResponseException extends IOException { + + /** + * Creates a new NoHttpResponseException with a null detail message. + */ + public NoHttpResponseException() { + super(); + } + + /** + * Creates a new NoHttpResponseException with the specified detail message. + * + * @param message exception message + */ + public NoHttpResponseException(String message) { + super(message); + } + + /** + * Creates a new NoHttpResponseException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + * + * @since 3.0 + */ + public NoHttpResponseException(String message, Throwable cause) { + super(message); + // If we're running on JDK 1.4 or later, tell Throwable what the cause was + ExceptionUtil.initCause(this, cause); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProtocolException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProtocolException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProtocolException.java 22 Aug 2012 17:30:35 -0000 1.1 @@ -0,0 +1,68 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProtocolException.java,v 1.1 2012/08/22 17:30:35 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:35 $ + * + * ==================================================================== + * + * 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 + *+ * Even though HTTP CONNECT proxying is generally used for HTTPS tunneling, the returned + * socket will not have been wrapped in an SSL socket. + *
+ * + *+ * Both the proxy and destination hosts must be set via the + * {@link #getHostConfiguration() host configuration} prior to calling this method. + *
+ * + * @return the connect response + * + * @throws IOException + * @throws HttpException + * + * @see #getHostConfiguration() + */ + public ConnectResponse connect() throws IOException, HttpException { + + if (getHostConfiguration().getProxyHost() == null) { + throw new IllegalStateException("proxy host must be configured"); + } + if (getHostConfiguration().getHost() == null) { + throw new IllegalStateException("destination host must be configured"); + } + + ConnectMethod method = new ConnectMethod(); + method.getParams().setDefaults(getParams()); + + DummyConnectionManager connectionManager = new DummyConnectionManager(); + connectionManager.setConnectionParams(getParams()); + + HttpMethodDirector director = new HttpMethodDirector( + connectionManager, + getHostConfiguration(), + getParams(), + getState() + ); + + director.executeMethod(method); + + ConnectResponse response = new ConnectResponse(); + response.setConnectMethod(method); + + // only set the socket if the connect was successful + if (method.getStatusCode() == HttpStatus.SC_OK) { + response.setSocket(connectionManager.getConnection().getSocket()); + } else { + connectionManager.getConnection().close(); + } + + return response; + } + + /** + * Contains the method used to execute the connect along with the created socket. + */ + public static class ConnectResponse { + + private ConnectMethod connectMethod; + + private Socket socket; + + private ConnectResponse() {} + + /** + * Gets the method that was used to execute the connect. This method is useful for + * analyzing the proxy's response when a connect fails. + * + * @return the connectMethod. + */ + public ConnectMethod getConnectMethod() { + return connectMethod; + } + /** + * @param connectMethod The connectMethod to set. + */ + private void setConnectMethod(ConnectMethod connectMethod) { + this.connectMethod = connectMethod; + } + /** + * Gets the socket connected and authenticated (if appropriate) to the configured + * HTTP proxy, ornull
if a connection could not be made. It is the
+ * responsibility of the user to close this socket when it is no longer needed.
+ *
+ * @return the socket.
+ */
+ public Socket getSocket() {
+ return socket;
+ }
+ /**
+ * @param socket The socket to set.
+ */
+ private void setSocket(Socket socket) {
+ this.socket = socket;
+ }
+ }
+
+ /**
+ * A connection manager that creates a single connection. Meant to be used only once.
+ */
+ static class DummyConnectionManager implements HttpConnectionManager {
+
+ private HttpConnection httpConnection;
+
+ private HttpParams connectionParams;
+
+ public void closeIdleConnections(long idleTimeout) {
+ }
+
+ public HttpConnection getConnection() {
+ return httpConnection;
+ }
+
+ public void setConnectionParams(HttpParams httpParams) {
+ this.connectionParams = httpParams;
+ }
+
+ public HttpConnection getConnectionWithTimeout(
+ HostConfiguration hostConfiguration, long timeout) {
+
+ httpConnection = new HttpConnection(hostConfiguration);
+ httpConnection.setHttpConnectionManager(this);
+ httpConnection.getParams().setDefaults(connectionParams);
+ return httpConnection;
+ }
+
+ /**
+ * @deprecated
+ */
+ public HttpConnection getConnection(HostConfiguration hostConfiguration, long timeout)
+ throws HttpException {
+ return getConnectionWithTimeout(hostConfiguration, timeout);
+ }
+
+ public HttpConnection getConnection(HostConfiguration hostConfiguration) {
+ return getConnectionWithTimeout(hostConfiguration, -1);
+ }
+
+ public void releaseConnection(HttpConnection conn) {
+ }
+
+ public HttpConnectionManagerParams getParams() {
+ return null;
+ }
+
+ public void setParams(HttpConnectionManagerParams params) {
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyHost.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyHost.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyHost.java 22 Aug 2012 17:30:33 -0000 1.1
@@ -0,0 +1,82 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyHost.java,v 1.1 2012/08/22 17:30:33 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:33 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * null
.
+ * @param port the port. Value -1
can be used to set default protocol port
+ */
+ public ProxyHost(final String hostname, int port) {
+ super(hostname, port, Protocol.getProtocol("http"));
+ }
+
+ /**
+ * Constructor for HttpHost.
+ *
+ * @param hostname the hostname (IP or DNS name). Can be null
.
+ */
+ public ProxyHost(final String hostname) {
+ this(hostname, -1);
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ public Object clone() {
+ return new ProxyHost(this);
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/RedirectException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/RedirectException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/RedirectException.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,67 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/RedirectException.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * When one of the three types of {@link java.io.InputStream}, one of + * AutoCloseInputStream (package), {@link ContentLengthInputStream}, or + * {@link ChunkedInputStream} finishes with its content, either because + * all content has been consumed, or because it was explicitly closed, + * it notifies its corresponding method via this interface.
+ * + * @see ContentLengthInputStream + * @see ChunkedInputStream + * @author Eric Johnson + */ +interface ResponseConsumedWatcher { + + /** + * A response has been consumed. + */ + void responseConsumed(); +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/SimpleHttpConnectionManager.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/SimpleHttpConnectionManager.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/SimpleHttpConnectionManager.java 22 Aug 2012 17:30:34 -0000 1.1 @@ -0,0 +1,246 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/SimpleHttpConnectionManager.java,v 1.1 2012/08/22 17:30:34 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:34 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *true
if stale checking will be enabled on HttpConections
+ *
+ * @see HttpConnection#isStaleCheckingEnabled()
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#isStaleCheckingEnabled()},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public boolean isConnectionStaleCheckingEnabled() {
+ return this.params.isStaleCheckingEnabled();
+ }
+
+ /**
+ * Sets the staleCheckingEnabled value to be set on HttpConnections that are created.
+ *
+ * @param connectionStaleCheckingEnabled true
if stale checking will be enabled
+ * on HttpConections
+ *
+ * @see HttpConnection#setStaleCheckingEnabled(boolean)
+ *
+ * @deprecated Use {@link HttpConnectionManagerParams#setStaleCheckingEnabled(boolean)},
+ * {@link HttpConnectionManager#getParams()}.
+ */
+ public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
+ this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
+ }
+
+ /**
+ * @see HttpConnectionManager#getConnectionWithTimeout(HostConfiguration, long)
+ *
+ * @since 3.0
+ */
+ public HttpConnection getConnectionWithTimeout(
+ HostConfiguration hostConfiguration, long timeout) {
+
+ if (httpConnection == null) {
+ httpConnection = new HttpConnection(hostConfiguration);
+ httpConnection.setHttpConnectionManager(this);
+ httpConnection.getParams().setDefaults(this.params);
+ } else {
+
+ // make sure the host and proxy are correct for this connection
+ // close it and set the values if they are not
+ if (!hostConfiguration.hostEquals(httpConnection)
+ || !hostConfiguration.proxyEquals(httpConnection)) {
+
+ if (httpConnection.isOpen()) {
+ httpConnection.close();
+ }
+
+ httpConnection.setHost(hostConfiguration.getHost());
+ httpConnection.setPort(hostConfiguration.getPort());
+ httpConnection.setProtocol(hostConfiguration.getProtocol());
+ httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());
+
+ httpConnection.setProxyHost(hostConfiguration.getProxyHost());
+ httpConnection.setProxyPort(hostConfiguration.getProxyPort());
+ } else {
+ finishLastResponse(httpConnection);
+ }
+ }
+
+ // remove the connection from the timeout handler
+ idleStartTime = Long.MAX_VALUE;
+
+ if (inUse) LOG.warn(MISUSE_MESSAGE);
+ inUse = true;
+
+ return httpConnection;
+ }
+
+ /**
+ * @see HttpConnectionManager#getConnection(HostConfiguration, long)
+ *
+ * @deprecated Use #getConnectionWithTimeout(HostConfiguration, long)
+ */
+ public HttpConnection getConnection(
+ HostConfiguration hostConfiguration, long timeout) {
+ return getConnectionWithTimeout(hostConfiguration, timeout);
+ }
+
+ /**
+ * @see HttpConnectionManager#releaseConnection(org.apache.commons.httpclient.HttpConnection)
+ */
+ public void releaseConnection(HttpConnection conn) {
+ if (conn != httpConnection) {
+ throw new IllegalStateException("Unexpected release of an unknown connection.");
+ }
+
+ finishLastResponse(httpConnection);
+
+ inUse = false;
+
+ // track the time the connection was made idle
+ idleStartTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Returns {@link HttpConnectionManagerParams parameters} associated
+ * with this connection manager.
+ *
+ * @since 2.1
+ *
+ * @see HttpConnectionManagerParams
+ */
+ public HttpConnectionManagerParams getParams() {
+ return this.params;
+ }
+
+ /**
+ * Assigns {@link HttpConnectionManagerParams parameters} for this
+ * connection manager.
+ *
+ * @since 2.1
+ *
+ * @see HttpConnectionManagerParams
+ */
+ public void setParams(final HttpConnectionManagerParams params) {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ this.params = params;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void closeIdleConnections(long idleTimeout) {
+ long maxIdleTime = System.currentTimeMillis() - idleTimeout;
+ if (idleStartTime <= maxIdleTime) {
+ httpConnection.close();
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/StatusLine.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/StatusLine.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/StatusLine.java 22 Aug 2012 17:30:33 -0000 1.1
@@ -0,0 +1,184 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/StatusLine.java,v 1.1 2012/08/22 17:30:33 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:33 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * 6.1 Status-Line + * + * The first line of a Response message is the Status-Line, consisting + * of the protocol version followed by a numeric status code and its + * associated textual phrase, with each element separated by SP + * characters. No CR or LF is allowed except in the final CRLF sequence. + * + * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF + *+ *
+ * This class is immutable and is inherently thread safe.
+ *
+ * @see HttpStatus
+ * @author Jeff Dever
+ * @author Mike Bowler
+ * @version $Id: StatusLine.java,v 1.1 2012/08/22 17:30:33 marcin Exp $
+ * @since 2.0
+ */
+public class StatusLine {
+
+ // ----------------------------------------------------- Instance Variables
+
+ /** The original Status-Line. */
+ private final String statusLine;
+
+ /** The HTTP-Version. */
+ private final String httpVersion;
+
+ /** The Status-Code. */
+ private final int statusCode;
+
+ /** The Reason-Phrase. */
+ private final String reasonPhrase;
+
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Default constructor.
+ *
+ * @param statusLine the status line returned from the HTTP server
+ * @throws HttpException if the status line is invalid
+ */
+ public StatusLine(final String statusLine) throws HttpException {
+
+ int length = statusLine.length();
+ int at = 0;
+ int start = 0;
+ try {
+ while (Character.isWhitespace(statusLine.charAt(at))) {
+ ++at;
+ ++start;
+ }
+ if (!"HTTP".equals(statusLine.substring(at, at += 4))) {
+ throw new HttpException("Status-Line '" + statusLine
+ + "' does not start with HTTP");
+ }
+ //handle the HTTP-Version
+ at = statusLine.indexOf(" ", at);
+ if (at <= 0) {
+ throw new ProtocolException(
+ "Unable to parse HTTP-Version from the status line: '"
+ + statusLine + "'");
+ }
+ this.httpVersion = (statusLine.substring(start, at)).toUpperCase();
+
+ //advance through spaces
+ while (statusLine.charAt(at) == ' ') {
+ at++;
+ }
+
+ //handle the Status-Code
+ int to = statusLine.indexOf(" ", at);
+ if (to < 0) {
+ to = length;
+ }
+ try {
+ this.statusCode = Integer.parseInt(statusLine.substring(at, to));
+ } catch (NumberFormatException e) {
+ throw new ProtocolException(
+ "Unable to parse status code from status line: '"
+ + statusLine + "'");
+ }
+ //handle the Reason-Phrase
+ at = to + 1;
+ if (at < length) {
+ this.reasonPhrase = statusLine.substring(at).trim();
+ } else {
+ this.reasonPhrase = "";
+ }
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new HttpException("Status-Line '" + statusLine + "' is not valid");
+ }
+ //save the original Status-Line
+ this.statusLine = statusLine;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * @return the Status-Code
+ */
+ public final int getStatusCode() {
+ return statusCode;
+ }
+
+ /**
+ * @return the HTTP-Version
+ */
+ public final String getHttpVersion() {
+ return httpVersion;
+ }
+
+ /**
+ * @return the Reason-Phrase
+ */
+ public final String getReasonPhrase() {
+ return reasonPhrase;
+ }
+
+ /**
+ * Return a string representation of this object.
+ * @return a string represenation of this object.
+ */
+ public final String toString() {
+ return statusLine;
+ }
+
+ /**
+ * Tests if the string starts with 'HTTP' signature.
+ * @param s string to test
+ * @return true if the line starts with 'HTTP'
+ * signature, false otherwise.
+ */
+ public static boolean startsWithHTTP(final String s) {
+ try {
+ int at = 0;
+ while (Character.isWhitespace(s.charAt(at))) {
+ ++at;
+ }
+ return ("HTTP".equals(s.substring(at, at + 4)));
+ } catch (StringIndexOutOfBoundsException e) {
+ return false;
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URI.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URI.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URI.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,3956 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URI.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ *
+ * A URI is always in an "escaped" form, since escaping or unescaping a + * completed URI might change its semantics. + *
+ * Implementers should be careful not to escape or unescape the same string + * more than once, since unescaping an already unescaped string might lead to + * misinterpreting a percent data character as another escaped character, + * or vice versa in the case of escaping an already escaped string. + *
+ * In order to avoid these problems, data types used as follows: + *
+ * URI character sequence: char + * octet sequence: byte + * original character sequence: String + *
+ * + * So, a URI is a sequence of characters as an array of a char type, which + * is not always represented as a sequence of octets as an array of byte. + *
+ * + * URI Syntactic Components + *
+ * - In general, written as follows: + * Absolute URI = <scheme>:<scheme-specific-part> + * Generic URI = <scheme>://<authority><path>?<query> + * + * - Syntax + * absoluteURI = scheme ":" ( hier_part | opaque_part ) + * hier_part = ( net_path | abs_path ) [ "?" query ] + * net_path = "//" authority [ abs_path ] + * abs_path = "/" path_segments + *
+ * + * The following examples illustrate URI that are in common use. + *
+ * ftp://ftp.is.co.za/rfc/rfc1808.txt + * -- ftp scheme for File Transfer Protocol services + * gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles + * -- gopher scheme for Gopher and Gopher+ Protocol services + * http://www.math.uio.no/faq/compression-faq/part1.html + * -- http scheme for Hypertext Transfer Protocol services + * mailto:mduerst@ifi.unizh.ch + * -- mailto scheme for electronic mail addresses + * news:comp.infosystems.www.servers.unix + * -- news scheme for USENET news groups and articles + * telnet://melvyl.ucop.edu/ + * -- telnet scheme for interactive services via the TELNET Protocol + *+ * Please, notice that there are many modifications from URL(RFC 1738) and + * relative URL(RFC 1808). + *
+ * The expressions for a URI + *
+ * For escaped URI forms + * - URI(char[]) // constructor + * - char[] getRawXxx() // method + * - String getEscapedXxx() // method + * - String toString() // method + *+ * For unescaped URI forms + * - URI(String) // constructor + * - String getXXX() // method + *
+ *
+ * @author Sung-Gu
+ * @author Mike Bowler
+ * @version $Revision: 1.1 $ $Date: 2002/03/14 15:14:01
+ */
+public class URI implements Cloneable, Comparable, Serializable {
+
+
+ // ----------------------------------------------------------- Constructors
+
+ /** Create an instance as an internal use */
+ protected URI() {
+ }
+
+ /**
+ * Construct a URI from a string with the given charset. The input string can
+ * be either in escaped or unescaped form.
+ *
+ * @param s URI character sequence
+ * @param escaped true if URI character sequence is in escaped form.
+ * false otherwise.
+ * @param charset the charset string to do escape encoding, if required
+ *
+ * @throws URIException If the URI cannot be created.
+ * @throws NullPointerException if input string is null
+ *
+ * @see #getProtocolCharset
+ *
+ * @since 3.0
+ */
+ public URI(String s, boolean escaped, String charset)
+ throws URIException, NullPointerException {
+ protocolCharset = charset;
+ parseUriReference(s, escaped);
+ }
+
+ /**
+ * Construct a URI from a string with the given charset. The input string can
+ * be either in escaped or unescaped form.
+ *
+ * @param s URI character sequence
+ * @param escaped true if URI character sequence is in escaped form.
+ * false otherwise.
+ *
+ * @throws URIException If the URI cannot be created.
+ * @throws NullPointerException if input string is null
+ *
+ * @see #getProtocolCharset
+ *
+ * @since 3.0
+ */
+ public URI(String s, boolean escaped)
+ throws URIException, NullPointerException {
+ parseUriReference(s, escaped);
+ }
+
+ /**
+ * Construct a URI as an escaped form of a character array with the given
+ * charset.
+ *
+ * @param escaped the URI character sequence
+ * @param charset the charset string to do escape encoding
+ * @throws URIException If the URI cannot be created.
+ * @throws NullPointerException if escaped
is null
+ * @see #getProtocolCharset
+ *
+ * @deprecated Use #URI(String, boolean, String)
+ */
+ public URI(char[] escaped, String charset)
+ throws URIException, NullPointerException {
+ protocolCharset = charset;
+ parseUriReference(new String(escaped), true);
+ }
+
+
+ /**
+ * Construct a URI as an escaped form of a character array.
+ * An URI can be placed within double-quotes or angle brackets like
+ * "http://test.com/" and <http://test.com/>
+ *
+ * @param escaped the URI character sequence
+ * @throws URIException If the URI cannot be created.
+ * @throws NullPointerException if escaped
is null
+ * @see #getDefaultProtocolCharset
+ *
+ * @deprecated Use #URI(String, boolean)
+ */
+ public URI(char[] escaped)
+ throws URIException, NullPointerException {
+ parseUriReference(new String(escaped), true);
+ }
+
+
+ /**
+ * Construct a URI from the given string with the given charset.
+ *
+ * @param original the string to be represented to URI character sequence
+ * It is one of absoluteURI and relativeURI.
+ * @param charset the charset string to do escape encoding
+ * @throws URIException If the URI cannot be created.
+ * @see #getProtocolCharset
+ *
+ * @deprecated Use #URI(String, boolean, String)
+ */
+ public URI(String original, String charset) throws URIException {
+ protocolCharset = charset;
+ parseUriReference(original, false);
+ }
+
+
+ /**
+ * Construct a URI from the given string.
+ *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + *
+ * An URI can be placed within double-quotes or angle brackets like + * "http://test.com/" and <http://test.com/> + * + * @param original the string to be represented to URI character sequence + * It is one of absoluteURI and relativeURI. + * @throws URIException If the URI cannot be created. + * @see #getDefaultProtocolCharset + * + * @deprecated Use #URI(String, boolean) + */ + public URI(String original) throws URIException { + parseUriReference(original, false); + } + + + /** + * Construct a general URI from the given components. + *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + * absoluteURI = scheme ":" ( hier_part | opaque_part ) + * opaque_part = uric_no_slash *uric + *
+ * It's for absolute URI = <scheme>:<scheme-specific-part># + * <fragment>. + * + * @param scheme the scheme string + * @param schemeSpecificPart scheme_specific_part + * @param fragment the fragment string + * @throws URIException If the URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String schemeSpecificPart, String fragment) + throws URIException { + + // validate and contruct the URI character sequence + if (scheme == null) { + throw new URIException(URIException.PARSING, "scheme required"); + } + char[] s = scheme.toLowerCase().toCharArray(); + if (validate(s, URI.scheme)) { + _scheme = s; // is_absoluteURI + } else { + throw new URIException(URIException.PARSING, "incorrect scheme"); + } + _opaque = encode(schemeSpecificPart, allowed_opaque_part, + getProtocolCharset()); + // Set flag + _is_opaque_part = true; + _fragment = fragment.toCharArray(); + + setURI(); + } + + + /** + * Construct a general URI from the given components. + *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + * absoluteURI = scheme ":" ( hier_part | opaque_part ) + * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + * hier_part = ( net_path | abs_path ) [ "?" query ] + *
+ * It's for absolute URI = <scheme>:<path>?<query>#< + * fragment> and relative URI = <path>?<query>#<fragment + * >. + * + * @param scheme the scheme string + * @param authority the authority string + * @param path the path string + * @param query the query string + * @param fragment the fragment string + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String authority, String path, String query, + String fragment) throws URIException { + + // validate and contruct the URI character sequence + StringBuffer buff = new StringBuffer(); + if (scheme != null) { + buff.append(scheme); + buff.append(':'); + } + if (authority != null) { + buff.append("//"); + buff.append(authority); + } + if (path != null) { // accept empty path + if ((scheme != null || authority != null) + && !path.startsWith("/")) { + throw new URIException(URIException.PARSING, + "abs_path requested"); + } + buff.append(path); + } + if (query != null) { + buff.append('?'); + buff.append(query); + } + if (fragment != null) { + buff.append('#'); + buff.append(fragment); + } + parseUriReference(buff.toString(), false); + } + + + /** + * Construct a general URI from the given components. + * + * @param scheme the scheme string + * @param userinfo the userinfo string + * @param host the host string + * @param port the port number + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String userinfo, String host, int port) + throws URIException { + + this(scheme, userinfo, host, port, null, null, null); + } + + + /** + * Construct a general URI from the given components. + * + * @param scheme the scheme string + * @param userinfo the userinfo string + * @param host the host string + * @param port the port number + * @param path the path string + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String userinfo, String host, int port, + String path) throws URIException { + + this(scheme, userinfo, host, port, path, null, null); + } + + + /** + * Construct a general URI from the given components. + * + * @param scheme the scheme string + * @param userinfo the userinfo string + * @param host the host string + * @param port the port number + * @param path the path string + * @param query the query string + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String userinfo, String host, int port, + String path, String query) throws URIException { + + this(scheme, userinfo, host, port, path, query, null); + } + + + /** + * Construct a general URI from the given components. + * + * @param scheme the scheme string + * @param userinfo the userinfo string + * @param host the host string + * @param port the port number + * @param path the path string + * @param query the query string + * @param fragment the fragment string + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String userinfo, String host, int port, + String path, String query, String fragment) throws URIException { + + this(scheme, (host == null) ? null + : ((userinfo != null) ? userinfo + '@' : "") + host + + ((port != -1) ? ":" + port : ""), path, query, fragment); + } + + + /** + * Construct a general URI from the given components. + * + * @param scheme the scheme string + * @param host the host string + * @param path the path string + * @param fragment the fragment string + * @throws URIException If the new URI cannot be created. + * @see #getDefaultProtocolCharset + */ + public URI(String scheme, String host, String path, String fragment) + throws URIException { + + this(scheme, host, path, null, fragment); + } + + + /** + * Construct a general URI with the given relative URI string. + * + * @param base the base URI + * @param relative the relative URI string + * @throws URIException If the new URI cannot be created. + * + * @deprecated Use #URI(URI, String, boolean) + */ + public URI(URI base, String relative) throws URIException { + this(base, new URI(relative)); + } + + + /** + * Construct a general URI with the given relative URI string. + * + * @param base the base URI + * @param relative the relative URI string + * @param escaped true if URI character sequence is in escaped form. + * false otherwise. + * + * @throws URIException If the new URI cannot be created. + * + * @since 3.0 + */ + public URI(URI base, String relative, boolean escaped) throws URIException { + this(base, new URI(relative, escaped)); + } + + + /** + * Construct a general URI with the given relative URI. + *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + *
+ * Resolving Relative References to Absolute Form. + * + * Examples of Resolving Relative URI References + * + * Within an object with a well-defined base URI of + *
+ * http://a/b/c/d;p?q + *
+ * the relative URI would be resolved as follows: + * + * Normal Examples + * + *
+ * g:h = g:h + * g = http://a/b/c/g + * ./g = http://a/b/c/g + * g/ = http://a/b/c/g/ + * /g = http://a/g + * //g = http://g + * ?y = http://a/b/c/?y + * g?y = http://a/b/c/g?y + * #s = (current document)#s + * g#s = http://a/b/c/g#s + * g?y#s = http://a/b/c/g?y#s + * ;x = http://a/b/c/;x + * g;x = http://a/b/c/g;x + * g;x?y#s = http://a/b/c/g;x?y#s + * . = http://a/b/c/ + * ./ = http://a/b/c/ + * .. = http://a/b/ + * ../ = http://a/b/ + * ../g = http://a/b/g + * ../.. = http://a/ + * ../../ = http://a/ + * ../../g = http://a/g + *
+ *
+ * Some URI schemes do not allow a hierarchical syntax matching the
+ *
+ */
+ protected static final BitSet digit = new BitSet(256);
+ // Static initializer for digit
+ static {
+ for (int i = '0'; i <= '9'; i++) {
+ digit.set(i);
+ }
+ }
+
+
+ /**
+ * BitSet for alpha.
+ *
+ */
+ protected static final BitSet alpha = new BitSet(256);
+ // Static initializer for alpha
+ static {
+ for (int i = 'a'; i <= 'z'; i++) {
+ alpha.set(i);
+ }
+ for (int i = 'A'; i <= 'Z'; i++) {
+ alpha.set(i);
+ }
+ }
+
+
+ /**
+ * BitSet for alphanum (join of alpha & digit).
+ *
+ */
+ protected static final BitSet alphanum = new BitSet(256);
+ // Static initializer for alphanum
+ static {
+ alphanum.or(alpha);
+ alphanum.or(digit);
+ }
+
+
+ /**
+ * BitSet for hex.
+ *
+ */
+ protected static final BitSet hex = new BitSet(256);
+ // Static initializer for hex
+ static {
+ hex.or(digit);
+ for (int i = 'a'; i <= 'f'; i++) {
+ hex.set(i);
+ }
+ for (int i = 'A'; i <= 'F'; i++) {
+ hex.set(i);
+ }
+ }
+
+
+ /**
+ * BitSet for escaped.
+ *
+ */
+ protected static final BitSet escaped = new BitSet(256);
+ // Static initializer for escaped
+ static {
+ escaped.or(percent);
+ escaped.or(hex);
+ }
+
+
+ /**
+ * BitSet for mark.
+ *
+ */
+ protected static final BitSet mark = new BitSet(256);
+ // Static initializer for mark
+ static {
+ mark.set('-');
+ mark.set('_');
+ mark.set('.');
+ mark.set('!');
+ mark.set('~');
+ mark.set('*');
+ mark.set('\'');
+ mark.set('(');
+ mark.set(')');
+ }
+
+
+ /**
+ * Data characters that are allowed in a URI but do not have a reserved
+ * purpose are called unreserved.
+ *
+ */
+ protected static final BitSet unreserved = new BitSet(256);
+ // Static initializer for unreserved
+ static {
+ unreserved.or(alphanum);
+ unreserved.or(mark);
+ }
+
+
+ /**
+ * BitSet for reserved.
+ *
+ */
+ protected static final BitSet reserved = new BitSet(256);
+ // Static initializer for reserved
+ static {
+ reserved.set(';');
+ reserved.set('/');
+ reserved.set('?');
+ reserved.set(':');
+ reserved.set('@');
+ reserved.set('&');
+ reserved.set('=');
+ reserved.set('+');
+ reserved.set('$');
+ reserved.set(',');
+ }
+
+
+ /**
+ * BitSet for uric.
+ *
+ */
+ protected static final BitSet uric = new BitSet(256);
+ // Static initializer for uric
+ static {
+ uric.or(reserved);
+ uric.or(unreserved);
+ uric.or(escaped);
+ }
+
+
+ /**
+ * BitSet for fragment (alias for uric).
+ *
+ */
+ protected static final BitSet fragment = uric;
+
+
+ /**
+ * BitSet for query (alias for uric).
+ *
+ */
+ protected static final BitSet query = uric;
+
+
+ /**
+ * BitSet for pchar.
+ *
+ */
+ protected static final BitSet pchar = new BitSet(256);
+ // Static initializer for pchar
+ static {
+ pchar.or(unreserved);
+ pchar.or(escaped);
+ pchar.set(':');
+ pchar.set('@');
+ pchar.set('&');
+ pchar.set('=');
+ pchar.set('+');
+ pchar.set('$');
+ pchar.set(',');
+ }
+
+
+ /**
+ * BitSet for param (alias for pchar).
+ *
+ */
+ protected static final BitSet param = pchar;
+
+
+ /**
+ * BitSet for segment.
+ *
+ */
+ protected static final BitSet segment = new BitSet(256);
+ // Static initializer for segment
+ static {
+ segment.or(pchar);
+ segment.set(';');
+ segment.or(param);
+ }
+
+
+ /**
+ * BitSet for path segments.
+ *
+ */
+ protected static final BitSet path_segments = new BitSet(256);
+ // Static initializer for path_segments
+ static {
+ path_segments.set('/');
+ path_segments.or(segment);
+ }
+
+
+ /**
+ * URI absolute path.
+ *
+ */
+ protected static final BitSet abs_path = new BitSet(256);
+ // Static initializer for abs_path
+ static {
+ abs_path.set('/');
+ abs_path.or(path_segments);
+ }
+
+
+ /**
+ * URI bitset for encoding typical non-slash characters.
+ *
+ */
+ protected static final BitSet uric_no_slash = new BitSet(256);
+ // Static initializer for uric_no_slash
+ static {
+ uric_no_slash.or(unreserved);
+ uric_no_slash.or(escaped);
+ uric_no_slash.set(';');
+ uric_no_slash.set('?');
+ uric_no_slash.set(';');
+ uric_no_slash.set('@');
+ uric_no_slash.set('&');
+ uric_no_slash.set('=');
+ uric_no_slash.set('+');
+ uric_no_slash.set('$');
+ uric_no_slash.set(',');
+ }
+
+
+ /**
+ * URI bitset that combines uric_no_slash and uric.
+ *
+ */
+ protected static final BitSet opaque_part = new BitSet(256);
+ // Static initializer for opaque_part
+ static {
+ // it's generous. because first character must not include a slash
+ opaque_part.or(uric_no_slash);
+ opaque_part.or(uric);
+ }
+
+
+ /**
+ * URI bitset that combines absolute path and opaque part.
+ *
+ */
+ protected static final BitSet path = new BitSet(256);
+ // Static initializer for path
+ static {
+ path.or(abs_path);
+ path.or(opaque_part);
+ }
+
+
+ /**
+ * Port, a logical alias for digit.
+ */
+ protected static final BitSet port = digit;
+
+
+ /**
+ * Bitset that combines digit and dot fo IPv$address.
+ *
+ */
+ protected static final BitSet IPv4address = new BitSet(256);
+ // Static initializer for IPv4address
+ static {
+ IPv4address.or(digit);
+ IPv4address.set('.');
+ }
+
+
+ /**
+ * RFC 2373.
+ *
+ */
+ protected static final BitSet IPv6address = new BitSet(256);
+ // Static initializer for IPv6address reference
+ static {
+ IPv6address.or(hex); // hexpart
+ IPv6address.set(':');
+ IPv6address.or(IPv4address);
+ }
+
+
+ /**
+ * RFC 2732, 2373.
+ *
+ */
+ protected static final BitSet IPv6reference = new BitSet(256);
+ // Static initializer for IPv6reference
+ static {
+ IPv6reference.set('[');
+ IPv6reference.or(IPv6address);
+ IPv6reference.set(']');
+ }
+
+
+ /**
+ * BitSet for toplabel.
+ *
+ */
+ protected static final BitSet toplabel = new BitSet(256);
+ // Static initializer for toplabel
+ static {
+ toplabel.or(alphanum);
+ toplabel.set('-');
+ }
+
+
+ /**
+ * BitSet for domainlabel.
+ *
+ */
+ protected static final BitSet domainlabel = toplabel;
+
+
+ /**
+ * BitSet for hostname.
+ *
+ */
+ protected static final BitSet hostname = new BitSet(256);
+ // Static initializer for hostname
+ static {
+ hostname.or(toplabel);
+ // hostname.or(domainlabel);
+ hostname.set('.');
+ }
+
+
+ /**
+ * BitSet for host.
+ *
+ */
+ protected static final BitSet host = new BitSet(256);
+ // Static initializer for host
+ static {
+ host.or(hostname);
+ // host.or(IPv4address);
+ host.or(IPv6reference); // IPv4address
+ }
+
+
+ /**
+ * BitSet for hostport.
+ *
+ */
+ protected static final BitSet hostport = new BitSet(256);
+ // Static initializer for hostport
+ static {
+ hostport.or(host);
+ hostport.set(':');
+ hostport.or(port);
+ }
+
+
+ /**
+ * Bitset for userinfo.
+ *
+ */
+ protected static final BitSet userinfo = new BitSet(256);
+ // Static initializer for userinfo
+ static {
+ userinfo.or(unreserved);
+ userinfo.or(escaped);
+ userinfo.set(';');
+ userinfo.set(':');
+ userinfo.set('&');
+ userinfo.set('=');
+ userinfo.set('+');
+ userinfo.set('$');
+ userinfo.set(',');
+ }
+
+
+ /**
+ * BitSet for within the userinfo component like user and password.
+ */
+ public static final BitSet within_userinfo = new BitSet(256);
+ // Static initializer for within_userinfo
+ static {
+ within_userinfo.or(userinfo);
+ within_userinfo.clear(';'); // reserved within authority
+ within_userinfo.clear(':');
+ within_userinfo.clear('@');
+ within_userinfo.clear('?');
+ within_userinfo.clear('/');
+ }
+
+
+ /**
+ * Bitset for server.
+ *
+ */
+ protected static final BitSet server = new BitSet(256);
+ // Static initializer for server
+ static {
+ server.or(userinfo);
+ server.set('@');
+ server.or(hostport);
+ }
+
+
+ /**
+ * BitSet for reg_name.
+ *
+ */
+ protected static final BitSet reg_name = new BitSet(256);
+ // Static initializer for reg_name
+ static {
+ reg_name.or(unreserved);
+ reg_name.or(escaped);
+ reg_name.set('$');
+ reg_name.set(',');
+ reg_name.set(';');
+ reg_name.set(':');
+ reg_name.set('@');
+ reg_name.set('&');
+ reg_name.set('=');
+ reg_name.set('+');
+ }
+
+
+ /**
+ * BitSet for authority.
+ *
+ */
+ protected static final BitSet authority = new BitSet(256);
+ // Static initializer for authority
+ static {
+ authority.or(server);
+ authority.or(reg_name);
+ }
+
+
+ /**
+ * BitSet for scheme.
+ *
+ */
+ protected static final BitSet scheme = new BitSet(256);
+ // Static initializer for scheme
+ static {
+ scheme.or(alpha);
+ scheme.or(digit);
+ scheme.set('+');
+ scheme.set('-');
+ scheme.set('.');
+ }
+
+
+ /**
+ * BitSet for rel_segment.
+ *
+ */
+ protected static final BitSet rel_segment = new BitSet(256);
+ // Static initializer for rel_segment
+ static {
+ rel_segment.or(unreserved);
+ rel_segment.or(escaped);
+ rel_segment.set(';');
+ rel_segment.set('@');
+ rel_segment.set('&');
+ rel_segment.set('=');
+ rel_segment.set('+');
+ rel_segment.set('$');
+ rel_segment.set(',');
+ }
+
+
+ /**
+ * BitSet for rel_path.
+ *
+ */
+ protected static final BitSet rel_path = new BitSet(256);
+ // Static initializer for rel_path
+ static {
+ rel_path.or(rel_segment);
+ rel_path.or(abs_path);
+ }
+
+
+ /**
+ * BitSet for net_path.
+ *
+ */
+ protected static final BitSet net_path = new BitSet(256);
+ // Static initializer for net_path
+ static {
+ net_path.set('/');
+ net_path.or(authority);
+ net_path.or(abs_path);
+ }
+
+
+ /**
+ * BitSet for hier_part.
+ *
+ */
+ protected static final BitSet hier_part = new BitSet(256);
+ // Static initializer for hier_part
+ static {
+ hier_part.or(net_path);
+ hier_part.or(abs_path);
+ // hier_part.set('?'); aleady included
+ hier_part.or(query);
+ }
+
+
+ /**
+ * BitSet for relativeURI.
+ *
+ */
+ protected static final BitSet relativeURI = new BitSet(256);
+ // Static initializer for relativeURI
+ static {
+ relativeURI.or(net_path);
+ relativeURI.or(abs_path);
+ relativeURI.or(rel_path);
+ // relativeURI.set('?'); aleady included
+ relativeURI.or(query);
+ }
+
+
+ /**
+ * BitSet for absoluteURI.
+ *
+ */
+ protected static final BitSet absoluteURI = new BitSet(256);
+ // Static initializer for absoluteURI
+ static {
+ absoluteURI.or(scheme);
+ absoluteURI.set(':');
+ absoluteURI.or(hier_part);
+ absoluteURI.or(opaque_part);
+ }
+
+
+ /**
+ * BitSet for URI-reference.
+ *
+ */
+ protected static final BitSet URI_reference = new BitSet(256);
+ // Static initializer for URI_reference
+ static {
+ URI_reference.or(absoluteURI);
+ URI_reference.or(relativeURI);
+ URI_reference.set('#');
+ URI_reference.or(fragment);
+ }
+
+ // ---------------------------- Characters disallowed within the URI syntax
+ // Excluded US-ASCII Characters are like control, space, delims and unwise
+
+ /**
+ * BitSet for control.
+ */
+ public static final BitSet control = new BitSet(256);
+ // Static initializer for control
+ static {
+ for (int i = 0; i <= 0x1F; i++) {
+ control.set(i);
+ }
+ control.set(0x7F);
+ }
+
+ /**
+ * BitSet for space.
+ */
+ public static final BitSet space = new BitSet(256);
+ // Static initializer for space
+ static {
+ space.set(0x20);
+ }
+
+
+ /**
+ * BitSet for delims.
+ */
+ public static final BitSet delims = new BitSet(256);
+ // Static initializer for delims
+ static {
+ delims.set('<');
+ delims.set('>');
+ delims.set('#');
+ delims.set('%');
+ delims.set('"');
+ }
+
+
+ /**
+ * BitSet for unwise.
+ */
+ public static final BitSet unwise = new BitSet(256);
+ // Static initializer for unwise
+ static {
+ unwise.set('{');
+ unwise.set('}');
+ unwise.set('|');
+ unwise.set('\\');
+ unwise.set('^');
+ unwise.set('[');
+ unwise.set(']');
+ unwise.set('`');
+ }
+
+
+ /**
+ * Disallowed rel_path before escaping.
+ */
+ public static final BitSet disallowed_rel_path = new BitSet(256);
+ // Static initializer for disallowed_rel_path
+ static {
+ disallowed_rel_path.or(uric);
+ disallowed_rel_path.andNot(rel_path);
+ }
+
+
+ /**
+ * Disallowed opaque_part before escaping.
+ */
+ public static final BitSet disallowed_opaque_part = new BitSet(256);
+ // Static initializer for disallowed_opaque_part
+ static {
+ disallowed_opaque_part.or(uric);
+ disallowed_opaque_part.andNot(opaque_part);
+ }
+
+ // ----------------------- Characters allowed within and for each component
+
+ /**
+ * Those characters that are allowed for the authority component.
+ */
+ public static final BitSet allowed_authority = new BitSet(256);
+ // Static initializer for allowed_authority
+ static {
+ allowed_authority.or(authority);
+ allowed_authority.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed for the opaque_part.
+ */
+ public static final BitSet allowed_opaque_part = new BitSet(256);
+ // Static initializer for allowed_opaque_part
+ static {
+ allowed_opaque_part.or(opaque_part);
+ allowed_opaque_part.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed for the reg_name.
+ */
+ public static final BitSet allowed_reg_name = new BitSet(256);
+ // Static initializer for allowed_reg_name
+ static {
+ allowed_reg_name.or(reg_name);
+ // allowed_reg_name.andNot(percent);
+ allowed_reg_name.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed for the userinfo component.
+ */
+ public static final BitSet allowed_userinfo = new BitSet(256);
+ // Static initializer for allowed_userinfo
+ static {
+ allowed_userinfo.or(userinfo);
+ // allowed_userinfo.andNot(percent);
+ allowed_userinfo.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed for within the userinfo component.
+ */
+ public static final BitSet allowed_within_userinfo = new BitSet(256);
+ // Static initializer for allowed_within_userinfo
+ static {
+ allowed_within_userinfo.or(within_userinfo);
+ allowed_within_userinfo.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed for the IPv6reference component.
+ * The characters '[', ']' in IPv6reference should be excluded.
+ */
+ public static final BitSet allowed_IPv6reference = new BitSet(256);
+ // Static initializer for allowed_IPv6reference
+ static {
+ allowed_IPv6reference.or(IPv6reference);
+ // allowed_IPv6reference.andNot(unwise);
+ allowed_IPv6reference.clear('[');
+ allowed_IPv6reference.clear(']');
+ }
+
+
+ /**
+ * Those characters that are allowed for the host component.
+ * The characters '[', ']' in IPv6reference should be excluded.
+ */
+ public static final BitSet allowed_host = new BitSet(256);
+ // Static initializer for allowed_host
+ static {
+ allowed_host.or(hostname);
+ allowed_host.or(allowed_IPv6reference);
+ }
+
+
+ /**
+ * Those characters that are allowed for the authority component.
+ */
+ public static final BitSet allowed_within_authority = new BitSet(256);
+ // Static initializer for allowed_within_authority
+ static {
+ allowed_within_authority.or(server);
+ allowed_within_authority.or(reg_name);
+ allowed_within_authority.clear(';');
+ allowed_within_authority.clear(':');
+ allowed_within_authority.clear('@');
+ allowed_within_authority.clear('?');
+ allowed_within_authority.clear('/');
+ }
+
+
+ /**
+ * Those characters that are allowed for the abs_path.
+ */
+ public static final BitSet allowed_abs_path = new BitSet(256);
+ // Static initializer for allowed_abs_path
+ static {
+ allowed_abs_path.or(abs_path);
+ // allowed_abs_path.set('/'); // aleady included
+ allowed_abs_path.andNot(percent);
+ }
+
+
+ /**
+ * Those characters that are allowed for the rel_path.
+ */
+ public static final BitSet allowed_rel_path = new BitSet(256);
+ // Static initializer for allowed_rel_path
+ static {
+ allowed_rel_path.or(rel_path);
+ allowed_rel_path.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed within the path.
+ */
+ public static final BitSet allowed_within_path = new BitSet(256);
+ // Static initializer for allowed_within_path
+ static {
+ allowed_within_path.or(abs_path);
+ allowed_within_path.clear('/');
+ allowed_within_path.clear(';');
+ allowed_within_path.clear('=');
+ allowed_within_path.clear('?');
+ }
+
+
+ /**
+ * Those characters that are allowed for the query component.
+ */
+ public static final BitSet allowed_query = new BitSet(256);
+ // Static initializer for allowed_query
+ static {
+ allowed_query.or(uric);
+ allowed_query.clear('%');
+ }
+
+
+ /**
+ * Those characters that are allowed within the query component.
+ */
+ public static final BitSet allowed_within_query = new BitSet(256);
+ // Static initializer for allowed_within_query
+ static {
+ allowed_within_query.or(allowed_query);
+ allowed_within_query.andNot(reserved); // excluded 'reserved'
+ }
+
+
+ /**
+ * Those characters that are allowed for the fragment component.
+ */
+ public static final BitSet allowed_fragment = new BitSet(256);
+ // Static initializer for allowed_fragment
+ static {
+ allowed_fragment.or(uric);
+ allowed_fragment.clear('%');
+ }
+
+ // ------------------------------------------- Flags for this URI-reference
+
+ // TODO: Figure out what all these variables are for and provide javadoc
+
+ // URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ // absoluteURI = scheme ":" ( hier_part | opaque_part )
+ protected boolean _is_hier_part;
+ protected boolean _is_opaque_part;
+ // relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+ // hier_part = ( net_path | abs_path ) [ "?" query ]
+ protected boolean _is_net_path;
+ protected boolean _is_abs_path;
+ protected boolean _is_rel_path;
+ // net_path = "//" authority [ abs_path ]
+ // authority = server | reg_name
+ protected boolean _is_reg_name;
+ protected boolean _is_server; // = _has_server
+ // server = [ [ userinfo "@" ] hostport ]
+ // host = hostname | IPv4address | IPv6reference
+ protected boolean _is_hostname;
+ protected boolean _is_IPv4address;
+ protected boolean _is_IPv6reference;
+
+ // ------------------------------------------ Character and escape encoding
+
+ /**
+ * Encodes URI string.
+ *
+ * This is a two mapping, one from original characters to octets, and
+ * subsequently a second from octets to URI characters:
+ *
+ *
+ * An escaped octet is encoded as a character triplet, consisting of the
+ * percent character "%" followed by the two hexadecimal digits
+ * representing the octet code. For example, "%20" is the escaped
+ * encoding for the US-ASCII space character.
+ *
+ * Conversion from the local filesystem character set to UTF-8 will
+ * normally involve a two step process. First convert the local character
+ * set to the UCS; then convert the UCS to UTF-8.
+ * The first step in the process can be performed by maintaining a mapping
+ * table that includes the local character set code and the corresponding
+ * UCS code.
+ * The next step is to convert the UCS character code to the UTF-8 encoding.
+ *
+ * Mapping between vendor codepages can be done in a very similar manner
+ * as described above.
+ *
+ * The only time escape encodings can allowedly be made is when a URI is
+ * being created from its component parts. The escape and validate methods
+ * are internally performed within this method.
+ *
+ * @param original the original character sequence
+ * @param allowed those characters that are allowed within a component
+ * @param charset the protocol charset
+ * @return URI character sequence
+ * @throws URIException null component or unsupported character encoding
+ */
+
+ protected static char[] encode(String original, BitSet allowed,
+ String charset) throws URIException {
+ if (original == null) {
+ throw new IllegalArgumentException("Original string may not be null");
+ }
+ if (allowed == null) {
+ throw new IllegalArgumentException("Allowed bitset may not be null");
+ }
+ byte[] rawdata = URLCodec.encodeUrl(allowed, EncodingUtil.getBytes(original, charset));
+ return EncodingUtil.getAsciiString(rawdata).toCharArray();
+ }
+
+ /**
+ * Decodes URI encoded string.
+ *
+ * This is a two mapping, one from URI characters to octets, and
+ * subsequently a second from octets to original characters:
+ *
+ *
+ * A URI must be separated into its components before the escaped
+ * characters within those components can be allowedly decoded.
+ *
+ * Notice that there is a chance that URI characters that are non UTF-8
+ * may be parsed as valid UTF-8. A recent non-scientific analysis found
+ * that EUC encoded Japanese words had a 2.7% false reading; SJIS had a
+ * 0.0005% false reading; other encoding such as ASCII or KOI-8 have a 0%
+ * false reading.
+ *
+ * The percent "%" character always has the reserved purpose of being
+ * the escape indicator, it must be escaped as "%25" in order to be used
+ * as data within a URI.
+ *
+ * The unescape method is internally performed within this method.
+ *
+ * @param component the URI character sequence
+ * @param charset the protocol charset
+ * @return original character sequence
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ */
+ protected static String decode(char[] component, String charset)
+ throws URIException {
+ if (component == null) {
+ throw new IllegalArgumentException("Component array of chars may not be null");
+ }
+ return decode(new String(component), charset);
+ }
+
+ /**
+ * Decodes URI encoded string.
+ *
+ * This is a two mapping, one from URI characters to octets, and
+ * subsequently a second from octets to original characters:
+ *
+ *
+ * A URI must be separated into its components before the escaped
+ * characters within those components can be allowedly decoded.
+ *
+ * Notice that there is a chance that URI characters that are non UTF-8
+ * may be parsed as valid UTF-8. A recent non-scientific analysis found
+ * that EUC encoded Japanese words had a 2.7% false reading; SJIS had a
+ * 0.0005% false reading; other encoding such as ASCII or KOI-8 have a 0%
+ * false reading.
+ *
+ * The percent "%" character always has the reserved purpose of being
+ * the escape indicator, it must be escaped as "%25" in order to be used
+ * as data within a URI.
+ *
+ * The unescape method is internally performed within this method.
+ *
+ * @param component the URI character sequence
+ * @param charset the protocol charset
+ * @return original character sequence
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ *
+ * @since 3.0
+ */
+ protected static String decode(String component, String charset)
+ throws URIException {
+ if (component == null) {
+ throw new IllegalArgumentException("Component array of chars may not be null");
+ }
+ byte[] rawdata = null;
+ try {
+ rawdata = URLCodec.decodeUrl(EncodingUtil.getAsciiBytes(component));
+ } catch (DecoderException e) {
+ throw new URIException(e.getMessage());
+ }
+ return EncodingUtil.getString(rawdata, charset);
+ }
+ /**
+ * Pre-validate the unescaped URI string within a specific component.
+ *
+ * @param component the component string within the component
+ * @param disallowed those characters disallowed within the component
+ * @return if true, it doesn't have the disallowed characters
+ * if false, the component is undefined or an incorrect one
+ */
+ protected boolean prevalidate(String component, BitSet disallowed) {
+ // prevalidate the given component by disallowed characters
+ if (component == null) {
+ return false; // undefined
+ }
+ char[] target = component.toCharArray();
+ for (int i = 0; i < target.length; i++) {
+ if (disallowed.get(target[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Validate the URI characters within a specific component.
+ * The component must be performed after escape encoding. Or it doesn't
+ * include escaped characters.
+ *
+ * @param component the characters sequence within the component
+ * @param generous those characters that are allowed within a component
+ * @return if true, it's the correct URI character sequence
+ */
+ protected boolean validate(char[] component, BitSet generous) {
+ // validate each component by generous characters
+ return validate(component, 0, -1, generous);
+ }
+
+
+ /**
+ * Validate the URI characters within a specific component.
+ * The component must be performed after escape encoding. Or it doesn't
+ * include escaped characters.
+ *
+ * It's not that much strict, generous. The strict validation might be
+ * performed before being called this method.
+ *
+ * @param component the characters sequence within the component
+ * @param soffset the starting offset of the given component
+ * @param eoffset the ending offset of the given component
+ * if -1, it means the length of the component
+ * @param generous those characters that are allowed within a component
+ * @return if true, it's the correct URI character sequence
+ */
+ protected boolean validate(char[] component, int soffset, int eoffset,
+ BitSet generous) {
+ // validate each component by generous characters
+ if (eoffset == -1) {
+ eoffset = component.length - 1;
+ }
+ for (int i = soffset; i <= eoffset; i++) {
+ if (!generous.get(component[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * In order to avoid any possilbity of conflict with non-ASCII characters,
+ * Parse a URI reference as a
+ * The following line is the regular expression for breaking-down a URI
+ * reference into its components.
+ *
+ * For example, matching the above expression to
+ * http://jakarta.apache.org/ietf/uri/#Related
+ * results in the following subexpression matches:
+ *
+ *
+ * @param original the original character sequence
+ * @param escaped
+ */
+ int at = indexFirstOf(tmp, isStartedFromPath ? "/?#" : ":/?#", from);
+ if (at == -1) {
+ at = 0;
+ }
+
+ /*
+ * Parse the scheme.
+ *
+ */
+ if (at > 0 && at < length && tmp.charAt(at) == ':') {
+ char[] target = tmp.substring(0, at).toLowerCase().toCharArray();
+ if (validate(target, scheme)) {
+ _scheme = target;
+ } else {
+ throw new URIException("incorrect scheme");
+ }
+ from = ++at;
+ }
+
+ /*
+ * Parse the authority component.
+ *
+ */
+ // Reset flags
+ _is_net_path = _is_abs_path = _is_rel_path = _is_hier_part = false;
+ if (0 <= at && at < length && tmp.charAt(at) == '/') {
+ // Set flag
+ _is_hier_part = true;
+ if (at + 2 < length && tmp.charAt(at + 1) == '/') {
+ // the temporary index to start the search from
+ int next = indexFirstOf(tmp, "/?#", at + 2);
+ if (next == -1) {
+ next = (tmp.substring(at + 2).length() == 0) ? at + 2
+ : tmp.length();
+ }
+ parseAuthority(tmp.substring(at + 2, next), escaped);
+ from = at = next;
+ // Set flag
+ _is_net_path = true;
+ }
+ if (from == at) {
+ // Set flag
+ _is_abs_path = true;
+ }
+ }
+
+ /*
+ * Parse the path component.
+ *
+ */
+ if (from < length) {
+ // rel_path = rel_segment [ abs_path ]
+ int next = indexFirstOf(tmp, "?#", from);
+ if (next == -1) {
+ next = tmp.length();
+ }
+ if (!_is_abs_path) {
+ if (!escaped
+ && prevalidate(tmp.substring(from, next), disallowed_rel_path)
+ || escaped
+ && validate(tmp.substring(from, next).toCharArray(), rel_path)) {
+ // Set flag
+ _is_rel_path = true;
+ } else if (!escaped
+ && prevalidate(tmp.substring(from, next), disallowed_opaque_part)
+ || escaped
+ && validate(tmp.substring(from, next).toCharArray(), opaque_part)) {
+ // Set flag
+ _is_opaque_part = true;
+ } else {
+ // the path component may be empty
+ _path = null;
+ }
+ }
+ if (escaped) {
+ setRawPath(tmp.substring(from, next).toCharArray());
+ } else {
+ setPath(tmp.substring(from, next));
+ }
+ at = next;
+ }
+
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+
+ /*
+ * Parse the query component.
+ *
+ */
+ if (0 <= at && at + 1 < length && tmp.charAt(at) == '?') {
+ int next = tmp.indexOf('#', at + 1);
+ if (next == -1) {
+ next = tmp.length();
+ }
+ _query = (escaped) ? tmp.substring(at + 1, next).toCharArray()
+ : encode(tmp.substring(at + 1, next), allowed_query, charset);
+ at = next;
+ }
+
+ /*
+ * Parse the fragment component.
+ *
+ */
+ if (0 <= at && at + 1 <= length && tmp.charAt(at) == '#') {
+ if (at + 1 == length) { // empty fragment
+ _fragment = "".toCharArray();
+ } else {
+ _fragment = (escaped) ? tmp.substring(at + 1).toCharArray()
+ : encode(tmp.substring(at + 1), allowed_fragment, charset);
+ }
+ }
+
+ // set this URI.
+ setURI();
+ }
+
+
+ /**
+ * Get the earlier index that to be searched for the first occurrance in
+ * one of any of the given string.
+ *
+ * @param s the string to be indexed
+ * @param delims the delimiters used to index
+ * @return the earlier index if there are delimiters
+ */
+ protected int indexFirstOf(String s, String delims) {
+ return indexFirstOf(s, delims, -1);
+ }
+
+
+ /**
+ * Get the earlier index that to be searched for the first occurrance in
+ * one of any of the given string.
+ *
+ * @param s the string to be indexed
+ * @param delims the delimiters used to index
+ * @param offset the from index
+ * @return the earlier index if there are delimiters
+ */
+ protected int indexFirstOf(String s, String delims, int offset) {
+ if (s == null || s.length() == 0) {
+ return -1;
+ }
+ if (delims == null || delims.length() == 0) {
+ return -1;
+ }
+ // check boundaries
+ if (offset < 0) {
+ offset = 0;
+ } else if (offset > s.length()) {
+ return -1;
+ }
+ // s is never null
+ int min = s.length();
+ char[] delim = delims.toCharArray();
+ for (int i = 0; i < delim.length; i++) {
+ int at = s.indexOf(delim[i], offset);
+ if (at >= 0 && at < min) {
+ min = at;
+ }
+ }
+ return (min == s.length()) ? -1 : min;
+ }
+
+
+ /**
+ * Get the earlier index that to be searched for the first occurrance in
+ * one of any of the given array.
+ *
+ * @param s the character array to be indexed
+ * @param delim the delimiter used to index
+ * @return the ealier index if there are a delimiter
+ */
+ protected int indexFirstOf(char[] s, char delim) {
+ return indexFirstOf(s, delim, 0);
+ }
+
+
+ /**
+ * Get the earlier index that to be searched for the first occurrance in
+ * one of any of the given array.
+ *
+ * @param s the character array to be indexed
+ * @param delim the delimiter used to index
+ * @param offset The offset.
+ * @return the ealier index if there is a delimiter
+ */
+ protected int indexFirstOf(char[] s, char delim, int offset) {
+ if (s == null || s.length == 0) {
+ return -1;
+ }
+ // check boundaries
+ if (offset < 0) {
+ offset = 0;
+ } else if (offset > s.length) {
+ return -1;
+ }
+ for (int i = offset; i < s.length; i++) {
+ if (s[i] == delim) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Parse the authority component.
+ *
+ * @param original the original character sequence of authority component
+ * @param escaped
+ * The character set used to store files SHALL remain a local decision and
+ * MAY depend on the capability of local operating systems. Prior to the
+ * exchange of URIs they SHOULD be converted into a ISO/IEC 10646 format
+ * and UTF-8 encoded. This approach, while allowing international exchange
+ * of URIs, will still allow backward compatibility with older systems
+ * because the code set positions for ASCII characters are identical to the
+ * one byte sequence in UTF-8.
+ *
+ * An individual URI scheme may require a single charset, define a default
+ * charset, or provide a way to indicate the charset used.
+ *
+ *
+ * Always all the time, the setter method is always succeeded and throws
+ *
+ * An individual URI scheme may require a single charset, define a default
+ * charset, or provide a way to indicate the charset used.
+ *
+ * To work globally either requires support of a number of character sets
+ * and to be able to convert between them, or the use of a single preferred
+ * character set.
+ * For support of global compatibility it is STRONGLY RECOMMENDED that
+ * clients and servers use UTF-8 encoding when exchanging URIs.
+ *
+ * @return the default charset string
+ */
+ public static String getDefaultProtocolCharset() {
+ return defaultProtocolCharset;
+ }
+
+
+ /**
+ * Get the protocol charset used by this current URI instance.
+ * It was set by the constructor for this instance. If it was not set by
+ * contructor, it will return the default protocol charset.
+ *
+ * @return the protocol charset string
+ * @see #getDefaultProtocolCharset
+ */
+ public String getProtocolCharset() {
+ return (protocolCharset != null)
+ ? protocolCharset
+ : defaultProtocolCharset;
+ }
+
+
+ /**
+ * Set the default charset of the document.
+ *
+ * Notice that it will be possible to contain mixed characters (e.g.
+ * ftp://host/KoreanNamespace/ChineseResource). To handle the Bi-directional
+ * display of these character sets, the protocol charset could be simply
+ * used again. Because it's not yet implemented that the insertion of BIDI
+ * control characters at different points during composition is extracted.
+ *
+ *
+ * Always all the time, the setter method is always succeeded and throws
+ *
+ *
+ * @param escapedAuthority the raw escaped authority
+ * @throws URIException If {@link
+ * #parseAuthority(java.lang.String,boolean)} fails
+ * @throws NullPointerException null authority
+ */
+ public void setRawAuthority(char[] escapedAuthority)
+ throws URIException, NullPointerException {
+
+ parseAuthority(new String(escapedAuthority), true);
+ setURI();
+ }
+
+
+ /**
+ * Set the authority. It can be one type of server, hostport, hostname,
+ * IPv4address, IPv6reference and reg_name.
+ * Note that there is no setAuthority method by the escape encoding reason.
+ *
+ * @param escapedAuthority the escaped authority string
+ * @throws URIException If {@link
+ * #parseAuthority(java.lang.String,boolean)} fails
+ */
+ public void setEscapedAuthority(String escapedAuthority)
+ throws URIException {
+
+ parseAuthority(escapedAuthority, true);
+ setURI();
+ }
+
+
+ /**
+ * Get the raw-escaped authority.
+ *
+ * @return the raw-escaped authority
+ */
+ public char[] getRawAuthority() {
+ return _authority;
+ }
+
+
+ /**
+ * Get the escaped authority.
+ *
+ * @return the escaped authority
+ */
+ public String getEscapedAuthority() {
+ return (_authority == null) ? null : new String(_authority);
+ }
+
+
+ /**
+ * Get the authority.
+ *
+ * @return the authority
+ * @throws URIException If {@link #decode} fails
+ */
+ public String getAuthority() throws URIException {
+ return (_authority == null) ? null : decode(_authority,
+ getProtocolCharset());
+ }
+
+ // ----------------------------------------------------------- The userinfo
+
+ /**
+ * Get the raw-escaped userinfo.
+ *
+ * @return the raw-escaped userinfo
+ * @see #getAuthority
+ */
+ public char[] getRawUserinfo() {
+ return _userinfo;
+ }
+
+
+ /**
+ * Get the escaped userinfo.
+ *
+ * @return the escaped userinfo
+ * @see #getAuthority
+ */
+ public String getEscapedUserinfo() {
+ return (_userinfo == null) ? null : new String(_userinfo);
+ }
+
+
+ /**
+ * Get the userinfo.
+ *
+ * @return the userinfo
+ * @throws URIException If {@link #decode} fails
+ * @see #getAuthority
+ */
+ public String getUserinfo() throws URIException {
+ return (_userinfo == null) ? null : decode(_userinfo,
+ getProtocolCharset());
+ }
+
+ // --------------------------------------------------------------- The host
+
+ /**
+ * Get the host.
+ *
+ *
+ * @return the host
+ * @see #getAuthority
+ */
+ public char[] getRawHost() {
+ return _host;
+ }
+
+
+ /**
+ * Get the host.
+ *
+ *
+ * @return the host
+ * @throws URIException If {@link #decode} fails
+ * @see #getAuthority
+ */
+ public String getHost() throws URIException {
+ if (_host != null) {
+ return decode(_host, getProtocolCharset());
+ } else {
+ return null;
+ }
+ }
+
+ // --------------------------------------------------------------- The port
+
+ /**
+ * Get the port. In order to get the specfic default port, the specific
+ * protocol-supported class extended from the URI class should be used.
+ * It has the server-based naming authority.
+ *
+ * @return the port
+ * if -1, it has the default port for the scheme or the server-based
+ * naming authority is not supported in the specific URI.
+ */
+ public int getPort() {
+ return _port;
+ }
+
+ // --------------------------------------------------------------- The path
+
+ /**
+ * Set the raw-escaped path.
+ *
+ * @param escapedPath the path character sequence
+ * @throws URIException encoding error or not proper for initial instance
+ * @see #encode
+ */
+ public void setRawPath(char[] escapedPath) throws URIException {
+ if (escapedPath == null || escapedPath.length == 0) {
+ _path = _opaque = escapedPath;
+ setURI();
+ return;
+ }
+ // remove the fragment identifier
+ escapedPath = removeFragmentIdentifier(escapedPath);
+ if (_is_net_path || _is_abs_path) {
+ if (escapedPath[0] != '/') {
+ throw new URIException(URIException.PARSING,
+ "not absolute path");
+ }
+ if (!validate(escapedPath, abs_path)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped absolute path not valid");
+ }
+ _path = escapedPath;
+ } else if (_is_rel_path) {
+ int at = indexFirstOf(escapedPath, '/');
+ if (at == 0) {
+ throw new URIException(URIException.PARSING, "incorrect path");
+ }
+ if (at > 0 && !validate(escapedPath, 0, at - 1, rel_segment)
+ && !validate(escapedPath, at, -1, abs_path)
+ || at < 0 && !validate(escapedPath, 0, -1, rel_segment)) {
+
+ throw new URIException(URIException.ESCAPING,
+ "escaped relative path not valid");
+ }
+ _path = escapedPath;
+ } else if (_is_opaque_part) {
+ if (!uric_no_slash.get(escapedPath[0])
+ && !validate(escapedPath, 1, -1, uric)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped opaque part not valid");
+ }
+ _opaque = escapedPath;
+ } else {
+ throw new URIException(URIException.PARSING, "incorrect path");
+ }
+ setURI();
+ }
+
+
+ /**
+ * Set the escaped path.
+ *
+ * @param escapedPath the escaped path string
+ * @throws URIException encoding error or not proper for initial instance
+ * @see #encode
+ */
+ public void setEscapedPath(String escapedPath) throws URIException {
+ if (escapedPath == null) {
+ _path = _opaque = null;
+ setURI();
+ return;
+ }
+ setRawPath(escapedPath.toCharArray());
+ }
+
+
+ /**
+ * Set the path.
+ *
+ * @param path the path string
+ * @throws URIException set incorrectly or fragment only
+ * @see #encode
+ */
+ public void setPath(String path) throws URIException {
+
+ if (path == null || path.length() == 0) {
+ _path = _opaque = (path == null) ? null : path.toCharArray();
+ setURI();
+ return;
+ }
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+
+ if (_is_net_path || _is_abs_path) {
+ _path = encode(path, allowed_abs_path, charset);
+ } else if (_is_rel_path) {
+ StringBuffer buff = new StringBuffer(path.length());
+ int at = path.indexOf('/');
+ if (at == 0) { // never 0
+ throw new URIException(URIException.PARSING,
+ "incorrect relative path");
+ }
+ if (at > 0) {
+ buff.append(encode(path.substring(0, at), allowed_rel_path,
+ charset));
+ buff.append(encode(path.substring(at), allowed_abs_path,
+ charset));
+ } else {
+ buff.append(encode(path, allowed_rel_path, charset));
+ }
+ _path = buff.toString().toCharArray();
+ } else if (_is_opaque_part) {
+ StringBuffer buf = new StringBuffer();
+ buf.insert(0, encode(path.substring(0, 1), uric_no_slash, charset));
+ buf.insert(1, encode(path.substring(1), uric, charset));
+ _opaque = buf.toString().toCharArray();
+ } else {
+ throw new URIException(URIException.PARSING, "incorrect path");
+ }
+ setURI();
+ }
+
+
+ /**
+ * Resolve the base and relative path.
+ *
+ * @param basePath a character array of the basePath
+ * @param relPath a character array of the relPath
+ * @return the resolved path
+ * @throws URIException no more higher path level to be resolved
+ */
+ protected char[] resolvePath(char[] basePath, char[] relPath)
+ throws URIException {
+
+ // REMINDME: paths are never null
+ String base = (basePath == null) ? "" : new String(basePath);
+ int at = base.lastIndexOf('/');
+ if (at != -1) {
+ basePath = base.substring(0, at + 1).toCharArray();
+ }
+ // _path could be empty
+ if (relPath == null || relPath.length == 0) {
+ return normalize(basePath);
+ } else if (relPath[0] == '/') {
+ return normalize(relPath);
+ } else {
+ StringBuffer buff = new StringBuffer(base.length()
+ + relPath.length);
+ buff.append((at != -1) ? base.substring(0, at + 1) : "/");
+ buff.append(relPath);
+ return normalize(buff.toString().toCharArray());
+ }
+ }
+
+
+ /**
+ * Get the raw-escaped current hierarchy level in the given path.
+ * If the last namespace is a collection, the slash mark ('/') should be
+ * ended with at the last character of the path string.
+ *
+ * @param path the path
+ * @return the current hierarchy level
+ * @throws URIException no hierarchy level
+ */
+ protected char[] getRawCurrentHierPath(char[] path) throws URIException {
+
+ if (_is_opaque_part) {
+ throw new URIException(URIException.PARSING, "no hierarchy level");
+ }
+ if (path == null) {
+ throw new URIException(URIException.PARSING, "empty path");
+ }
+ String buff = new String(path);
+ int first = buff.indexOf('/');
+ int last = buff.lastIndexOf('/');
+ if (last == 0) {
+ return rootPath;
+ } else if (first != last && last != -1) {
+ return buff.substring(0, last).toCharArray();
+ }
+ // FIXME: it could be a document on the server side
+ return path;
+ }
+
+
+ /**
+ * Get the raw-escaped current hierarchy level.
+ *
+ * @return the raw-escaped current hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public char[] getRawCurrentHierPath() throws URIException {
+ return (_path == null) ? null : getRawCurrentHierPath(_path);
+ }
+
+
+ /**
+ * Get the escaped current hierarchy level.
+ *
+ * @return the escaped current hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public String getEscapedCurrentHierPath() throws URIException {
+ char[] path = getRawCurrentHierPath();
+ return (path == null) ? null : new String(path);
+ }
+
+
+ /**
+ * Get the current hierarchy level.
+ *
+ * @return the current hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ * @see #decode
+ */
+ public String getCurrentHierPath() throws URIException {
+ char[] path = getRawCurrentHierPath();
+ return (path == null) ? null : decode(path, getProtocolCharset());
+ }
+
+
+ /**
+ * Get the level above the this hierarchy level.
+ *
+ * @return the raw above hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public char[] getRawAboveHierPath() throws URIException {
+ char[] path = getRawCurrentHierPath();
+ return (path == null) ? null : getRawCurrentHierPath(path);
+ }
+
+
+ /**
+ * Get the level above the this hierarchy level.
+ *
+ * @return the raw above hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ */
+ public String getEscapedAboveHierPath() throws URIException {
+ char[] path = getRawAboveHierPath();
+ return (path == null) ? null : new String(path);
+ }
+
+
+ /**
+ * Get the level above the this hierarchy level.
+ *
+ * @return the above hierarchy level
+ * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
+ * @see #decode
+ */
+ public String getAboveHierPath() throws URIException {
+ char[] path = getRawAboveHierPath();
+ return (path == null) ? null : decode(path, getProtocolCharset());
+ }
+
+
+ /**
+ * Get the raw-escaped path.
+ *
+ *
+ * @return the raw-escaped path
+ */
+ public char[] getRawPath() {
+ return _is_opaque_part ? _opaque : _path;
+ }
+
+
+ /**
+ * Get the escaped path.
+ *
+ *
+ * @return the escaped path string
+ */
+ public String getEscapedPath() {
+ char[] path = getRawPath();
+ return (path == null) ? null : new String(path);
+ }
+
+
+ /**
+ * Get the path.
+ *
+ * @return the path string
+ * @throws URIException If {@link #decode} fails.
+ * @see #decode
+ */
+ public String getPath() throws URIException {
+ char[] path = getRawPath();
+ return (path == null) ? null : decode(path, getProtocolCharset());
+ }
+
+
+ /**
+ * Get the raw-escaped basename of the path.
+ *
+ * @return the raw-escaped basename
+ */
+ public char[] getRawName() {
+ if (_path == null) {
+ return null;
+ }
+
+ int at = 0;
+ for (int i = _path.length - 1; i >= 0; i--) {
+ if (_path[i] == '/') {
+ at = i + 1;
+ break;
+ }
+ }
+ int len = _path.length - at;
+ char[] basename = new char[len];
+ System.arraycopy(_path, at, basename, 0, len);
+ return basename;
+ }
+
+
+ /**
+ * Get the escaped basename of the path.
+ *
+ * @return the escaped basename string
+ */
+ public String getEscapedName() {
+ char[] basename = getRawName();
+ return (basename == null) ? null : new String(basename);
+ }
+
+
+ /**
+ * Get the basename of the path.
+ *
+ * @return the basename string
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #decode
+ */
+ public String getName() throws URIException {
+ char[] basename = getRawName();
+ return (basename == null) ? null : decode(getRawName(),
+ getProtocolCharset());
+ }
+
+ // ----------------------------------------------------- The path and query
+
+ /**
+ * Get the raw-escaped path and query.
+ *
+ * @return the raw-escaped path and query
+ */
+ public char[] getRawPathQuery() {
+
+ if (_path == null && _query == null) {
+ return null;
+ }
+ StringBuffer buff = new StringBuffer();
+ if (_path != null) {
+ buff.append(_path);
+ }
+ if (_query != null) {
+ buff.append('?');
+ buff.append(_query);
+ }
+ return buff.toString().toCharArray();
+ }
+
+
+ /**
+ * Get the escaped query.
+ *
+ * @return the escaped path and query string
+ */
+ public String getEscapedPathQuery() {
+ char[] rawPathQuery = getRawPathQuery();
+ return (rawPathQuery == null) ? null : new String(rawPathQuery);
+ }
+
+
+ /**
+ * Get the path and query.
+ *
+ * @return the path and query string.
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #decode
+ */
+ public String getPathQuery() throws URIException {
+ char[] rawPathQuery = getRawPathQuery();
+ return (rawPathQuery == null) ? null : decode(rawPathQuery,
+ getProtocolCharset());
+ }
+
+ // -------------------------------------------------------------- The query
+
+ /**
+ * Set the raw-escaped query.
+ *
+ * @param escapedQuery the raw-escaped query
+ * @throws URIException escaped query not valid
+ */
+ public void setRawQuery(char[] escapedQuery) throws URIException {
+ if (escapedQuery == null || escapedQuery.length == 0) {
+ _query = escapedQuery;
+ setURI();
+ return;
+ }
+ // remove the fragment identifier
+ escapedQuery = removeFragmentIdentifier(escapedQuery);
+ if (!validate(escapedQuery, query)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped query not valid");
+ }
+ _query = escapedQuery;
+ setURI();
+ }
+
+
+ /**
+ * Set the escaped query string.
+ *
+ * @param escapedQuery the escaped query string
+ * @throws URIException escaped query not valid
+ */
+ public void setEscapedQuery(String escapedQuery) throws URIException {
+ if (escapedQuery == null) {
+ _query = null;
+ setURI();
+ return;
+ }
+ setRawQuery(escapedQuery.toCharArray());
+ }
+
+
+ /**
+ * Set the query.
+ *
+ * When a query string is not misunderstood the reserved special characters
+ * ("&", "=", "+", ",", and "$") within a query component, it is
+ * recommended to use in encoding the whole query with this method.
+ *
+ * The additional APIs for the special purpose using by the reserved
+ * special characters used in each protocol are implemented in each protocol
+ * classes inherited from
+ * The optional fragment identifier is not part of a URI, but is often used
+ * in conjunction with a URI.
+ *
+ * The format and interpretation of fragment identifiers is dependent on
+ * the media type [RFC2046] of the retrieval result.
+ *
+ * A fragment identifier is only meaningful when a URI reference is
+ * intended for retrieval and the result of that retrieval is a document
+ * for which the identified fragment is consistently defined.
+ *
+ * @return the raw-escaped fragment
+ */
+ public char[] getRawFragment() {
+ return _fragment;
+ }
+
+
+ /**
+ * Get the escaped fragment.
+ *
+ * @return the escaped fragment string
+ */
+ public String getEscapedFragment() {
+ return (_fragment == null) ? null : new String(_fragment);
+ }
+
+
+ /**
+ * Get the fragment.
+ *
+ * @return the fragment string
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #decode
+ */
+ public String getFragment() throws URIException {
+ return (_fragment == null) ? null : decode(_fragment,
+ getProtocolCharset());
+ }
+
+ // ------------------------------------------------------------- Utilities
+
+ /**
+ * Remove the fragment identifier of the given component.
+ *
+ * @param component the component that a fragment may be included
+ * @return the component that the fragment identifier is removed
+ */
+ protected char[] removeFragmentIdentifier(char[] component) {
+ if (component == null) {
+ return null;
+ }
+ int lastIndex = new String(component).indexOf('#');
+ if (lastIndex != -1) {
+ component = new String(component).substring(0,
+ lastIndex).toCharArray();
+ }
+ return component;
+ }
+
+
+ /**
+ * Normalize the given hier path part.
+ *
+ * Algorithm taken from URI reference parser at
+ * http://www.apache.org/~fielding/uri/rev-2002/issues.html.
+ *
+ * @param path the path to normalize
+ * @return the normalized path
+ * @throws URIException no more higher path level to be normalized
+ */
+ protected char[] normalize(char[] path) throws URIException {
+
+ if (path == null) {
+ return null;
+ }
+
+ String normalized = new String(path);
+
+ // If the buffer begins with "./" or "../", the "." or ".." is removed.
+ if (normalized.startsWith("./")) {
+ normalized = normalized.substring(1);
+ } else if (normalized.startsWith("../")) {
+ normalized = normalized.substring(2);
+ } else if (normalized.startsWith("..")) {
+ normalized = normalized.substring(2);
+ }
+
+ // All occurrences of "/./" in the buffer are replaced with "/"
+ int index = -1;
+ while ((index = normalized.indexOf("/./")) != -1) {
+ normalized = normalized.substring(0, index) + normalized.substring(index + 2);
+ }
+
+ // If the buffer ends with "/.", the "." is removed.
+ if (normalized.endsWith("/.")) {
+ normalized = normalized.substring(0, normalized.length() - 1);
+ }
+
+ int startIndex = 0;
+
+ // All occurrences of "/
+ * To copy the identical
+ * It is clearly unwise to use a URL that contains a password which is
+ * intended to be secret. In particular, the use of a password within
+ * the 'userinfo' component of a URL is strongly disrecommended except
+ * in those rare cases where the 'password' parameter is intended to be
+ * public.
+ *
+ * When you want to get each part of the userinfo, you need to use the
+ * specific methods in the specific URL. It depends on the specific URL.
+ *
+ * @return the URI character sequence
+ */
+ public char[] getRawURI() {
+ return _uri;
+ }
+
+
+ /**
+ * It can be gotten the URI character sequence. It's escaped.
+ * For the purpose of the protocol to be transported, it will be useful.
+ *
+ * @return the escaped URI string
+ */
+ public String getEscapedURI() {
+ return (_uri == null) ? null : new String(_uri);
+ }
+
+
+ /**
+ * It can be gotten the URI character sequence.
+ *
+ * @return the original URI string
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #decode
+ */
+ public String getURI() throws URIException {
+ return (_uri == null) ? null : decode(_uri, getProtocolCharset());
+ }
+
+
+ /**
+ * Get the URI reference character sequence.
+ *
+ * @return the URI reference character sequence
+ */
+ public char[] getRawURIReference() {
+ if (_fragment == null) {
+ return _uri;
+ }
+ if (_uri == null) {
+ return _fragment;
+ }
+ // if _uri != null && _fragment != null
+ String uriReference = new String(_uri) + "#" + new String(_fragment);
+ return uriReference.toCharArray();
+ }
+
+
+ /**
+ * Get the escaped URI reference string.
+ *
+ * @return the escaped URI reference string
+ */
+ public String getEscapedURIReference() {
+ char[] uriReference = getRawURIReference();
+ return (uriReference == null) ? null : new String(uriReference);
+ }
+
+
+ /**
+ * Get the original URI reference string.
+ *
+ * @return the original URI reference string
+ * @throws URIException If {@link #decode} fails.
+ */
+ public String getURIReference() throws URIException {
+ char[] uriReference = getRawURIReference();
+ return (uriReference == null) ? null : decode(uriReference,
+ getProtocolCharset());
+ }
+
+
+ /**
+ * Get the escaped URI string.
+ *
+ * On the document, the URI-reference form is only used without the userinfo
+ * component like http://jakarta.apache.org/ by the security reason.
+ * But the URI-reference form with the userinfo component could be parsed.
+ *
+ * In other words, this URI and any its subclasses must not expose the
+ * URI-reference expression with the userinfo component like
+ * http://user:password@hostport/restricted_zone.
+ * The distribution of this class is Servlets.com. It was originally
+ * written by Jason Hunter [jhunter at acm.org] and used by with permission.
+ */
+ public static class LocaleToCharsetMap {
+
+ /** A mapping of language code to charset */
+ private static final Hashtable LOCALE_TO_CHARSET_MAP;
+ static {
+ LOCALE_TO_CHARSET_MAP = new Hashtable();
+ LOCALE_TO_CHARSET_MAP.put("ar", "ISO-8859-6");
+ LOCALE_TO_CHARSET_MAP.put("be", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("bg", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("ca", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("cs", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("da", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("de", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("el", "ISO-8859-7");
+ LOCALE_TO_CHARSET_MAP.put("en", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("es", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("et", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("fi", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("fr", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("hr", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("hu", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("is", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("it", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("iw", "ISO-8859-8");
+ LOCALE_TO_CHARSET_MAP.put("ja", "Shift_JIS");
+ LOCALE_TO_CHARSET_MAP.put("ko", "EUC-KR");
+ LOCALE_TO_CHARSET_MAP.put("lt", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("lv", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("mk", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("nl", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("no", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("pl", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("pt", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("ro", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("ru", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("sh", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("sk", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("sl", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("sq", "ISO-8859-2");
+ LOCALE_TO_CHARSET_MAP.put("sr", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("sv", "ISO-8859-1");
+ LOCALE_TO_CHARSET_MAP.put("tr", "ISO-8859-9");
+ LOCALE_TO_CHARSET_MAP.put("uk", "ISO-8859-5");
+ LOCALE_TO_CHARSET_MAP.put("zh", "GB2312");
+ LOCALE_TO_CHARSET_MAP.put("zh_TW", "Big5");
+ }
+
+ /**
+ * Get the preferred charset for the given locale.
+ *
+ * @param locale the locale
+ * @return the preferred charset or null if the locale is not
+ * recognized.
+ */
+ public static String getCharset(Locale locale) {
+ // try for an full name match (may include country)
+ String charset =
+ (String) LOCALE_TO_CHARSET_MAP.get(locale.toString());
+ if (charset != null) {
+ return charset;
+ }
+
+ // if a full name didn't match, try just the language
+ charset = (String) LOCALE_TO_CHARSET_MAP.get(locale.getLanguage());
+ return charset; // may be null
+ }
+
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URIException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URIException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URIException.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,177 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URIException.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * Username and password {@link Credentials}.
+ The HttpClient component supports the client-side of
+ RFC 1945 (HTTP/1.0) and
+ RFC 2616 (HTTP/1.1),
+ several related specifications
+ (RFC 2109 (Cookies),
+ RFC 2617 (HTTP Authentication),
+ etc.), and provides a framework by which new request types (methods) or HTTP
+ extensions can can be easily created or supported.
+
+ The basis for the abstraction is provided by three types:
+
+ and several simple bean-style classes:
+
+ {@link org.apache.commons.httpclient.HttpClient} provides a
+ simple "user-agent" implementation that will suffice for many
+ applications, but whose use is not required.
+
+ HttpClient also provides several utilities that may be
+ useful when extending the framework:
+ The following specifications are provided:
+ *
+ * If several schemes are returned in the WWW-Authenticate
+ * or Proxy-Authenticate header, this parameter defines which
+ * {@link AuthScheme authentication schemes} takes precedence over others.
+ * The first item in the collection represents the most preferred
+ * {@link AuthScheme authentication scheme}, the last item represents the ID
+ * of the least preferred one.
+ *
+ * Please note that custom authentication preferences, if used, need to be updated accordingly
+ * for the new {@link AuthScheme authentication scheme} to take effect.
+ *
+ * This interface represents an abstract challenge-response oriented
+ * authentication scheme.
+ *
+ * An authentication scheme should be able to support the following
+ * functions:
+ *
+ * Authentication schemes may ignore method name and URI parameters
+ * if they are not relevant for the given authentication mechanism
+ *
+ * Authentication schemes may be stateful involving a series of
+ * challenge-response exchanges
+ * Additionally, the ID should take into account any changes to the
+ * authentication challenge and return a different value when appropriate.
+ * For example when the realm changes in basic authentication it should be
+ * considered a different authentication attempt and a different value should
+ * be returned.
+ * Abstract authentication scheme class that implements {@link AuthScheme}
+ * interface and provides a default contstructor.
+ *
+ * Basic authentication scheme as defined in RFC 2617.
+ *
+ * Credentials provider interface can be used to provide {@link
+ * org.apache.commons.httpclient.HttpMethod HTTP method} with a means to request
+ * authentication credentials if no credentials have been given or given
+ * credentials are incorrect.
+ *
+ * HttpClient makes no provisions to check whether the same credentials have
+ * been tried already. It is a responsibility of the custom credentials provider
+ * to keep track of authentication attempts and to ensure that credentials known
+ * to be invalid are not retried. HttpClient will simply store the set of
+ * credentials returned by the custom credentials provider in the
+ * {@link org.apache.commons.httpclient.HttpState http state} object and will
+ * attempt to use these credentials for all subsequent requests with the given
+ * authentication scope.
+ *
+ * Classes implementing this interface must synchronize access to shared data as
+ * methods of this interfrace may be executed from multiple threads
+ *
+ * This parameter expects a value of type {@link CredentialsProvider}.
+ *
+ * Digest authentication scheme as defined in RFC 2617.
+ * Both MD5 (default) and MD5-sess are supported.
+ * Currently only qop=auth or no qop is supported. qop=auth-int
+ * is unsupported. If auth and auth-int are provided, auth is
+ * used.
+ *
+ * Credential charset is configured via the
+ * {@link org.apache.commons.httpclient.params.HttpMethodParams#CREDENTIAL_CHARSET credential
+ * charset} parameter. Since the digest username is included as clear text in the generated
+ * Authentication header, the charset of the username must be compatible with the
+ * {@link org.apache.commons.httpclient.params.HttpMethodParams#HTTP_ELEMENT_CHARSET http element
+ * charset}.
+ *
+ * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+ * "8" | "9"
+ *
+ * alpha = lowalpha | upalpha
+ *
+ * alphanum = alpha | digit
+ *
+ * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
+ * "a" | "b" | "c" | "d" | "e" | "f"
+ *
+ * escaped = "%" hex hex
+ *
+ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
+ * "(" | ")"
+ *
+ * unreserved = alphanum | mark
+ *
+ * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ * "$" | ","
+ *
+ * uric = reserved | unreserved | escaped
+ *
+ * fragment = *uric
+ *
+ * query = *uric
+ *
+ * pchar = unreserved | escaped |
+ * ":" | "@" | "&" | "=" | "+" | "$" | ","
+ *
+ * param = *pchar
+ *
+ * segment = *pchar *( ";" param )
+ *
+ * path_segments = segment *( "/" segment )
+ *
+ * abs_path = "/" path_segments
+ *
+ * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+ * "&" | "=" | "+" | "$" | ","
+ *
+ * opaque_part = uric_no_slash *uric
+ *
+ * path = [ abs_path | opaque_part ]
+ *
+ * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
+ *
+ * IPv6address = hexpart [ ":" IPv4address ]
+ *
+ * IPv6reference = "[" IPv6address "]"
+ *
+ * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ *
+ * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ *
+ * hostname = *( domainlabel "." ) toplabel [ "." ]
+ *
+ * host = hostname | IPv4address | IPv6reference
+ *
+ * hostport = host [ ":" port ]
+ *
+ * userinfo = *( unreserved | escaped |
+ * ";" | ":" | "&" | "=" | "+" | "$" | "," )
+ *
+ * server = [ [ userinfo "@" ] hostport ]
+ *
+ * reg_name = 1*( unreserved | escaped | "$" | "," |
+ * ";" | ":" | "@" | "&" | "=" | "+" )
+ *
+ * authority = server | reg_name
+ *
+ * scheme = alpha *( alpha | digit | "+" | "-" | "." )
+ *
+ * rel_segment = 1*( unreserved | escaped |
+ * ";" | "@" | "&" | "=" | "+" | "$" | "," )
+ *
+ * rel_path = rel_segment [ abs_path ]
+ *
+ * net_path = "//" authority [ abs_path ]
+ *
+ * hier_part = ( net_path | abs_path ) [ "?" query ]
+ *
+ * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+ *
+ * absoluteURI = scheme ":" ( hier_part | opaque_part )
+ *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ *
+ * original character sequence->octet sequence->URI character sequence
+ *
+ * URI character sequence->octet sequence->original character sequence
+ *
+ * URI character sequence->octet sequence->original character sequence
+ *
String
with the character
+ * encoding of the local system or the document.
+ *
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ * 12 3 4 5 6 7 8 9
+ *
+ * $1 = http:
+ * scheme = $2 = http
+ * $3 = //jakarta.apache.org
+ * authority = $4 = jakarta.apache.org
+ * path = $5 = /ietf/uri/
+ * $6 =
true
if original
is escaped
+ * @throws URIException If an error occurs.
+ */
+ protected void parseUriReference(String original, boolean escaped)
+ throws URIException {
+
+ // validate and contruct the URI character sequence
+ if (original == null) {
+ throw new URIException("URI-Reference required");
+ }
+
+ /* @
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ */
+ String tmp = original.trim();
+
+ /*
+ * The length of the string sequence of characters.
+ * It may not be equal to the length of the byte array.
+ */
+ int length = tmp.length();
+
+ /*
+ * Remove the delimiters like angle brackets around an URI.
+ */
+ if (length > 0) {
+ char[] firstDelimiter = { tmp.charAt(0) };
+ if (validate(firstDelimiter, delims)) {
+ if (length >= 2) {
+ char[] lastDelimiter = { tmp.charAt(length - 1) };
+ if (validate(lastDelimiter, delims)) {
+ tmp = tmp.substring(1, length - 1);
+ length = length - 2;
+ }
+ }
+ }
+ }
+
+ /*
+ * The starting index
+ */
+ int from = 0;
+
+ /*
+ * The test flag whether the URI is started from the path component.
+ */
+ boolean isStartedFromPath = false;
+ int atColon = tmp.indexOf(':');
+ int atSlash = tmp.indexOf('/');
+ if (atColon <= 0 || (atSlash >= 0 && atSlash < atColon)) {
+ isStartedFromPath = true;
+ }
+
+ /*
+ *
+ * @@@@@@@@
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ *
+ * scheme = $2 = http
+ * @
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ *
+ * authority = $4 = jakarta.apache.org
+ * @@
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ *
+ * path = $5 = /ietf/uri/
+ * @@@@@@
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ *
+ * query = $7 =
+ * fragment = $9 = Related
+ * @@@@@@@@
+ * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ *
true
if original
is escaped
+ * @throws URIException If an error occurs.
+ */
+ protected void parseAuthority(String original, boolean escaped)
+ throws URIException {
+
+ // Reset flags
+ _is_reg_name = _is_server =
+ _is_hostname = _is_IPv4address = _is_IPv6reference = false;
+
+ // set the charset to do escape encoding
+ String charset = getProtocolCharset();
+
+ boolean hasPort = true;
+ int from = 0;
+ int next = original.indexOf('@');
+ if (next != -1) { // neither -1 and 0
+ // each protocol extented from URI supports the specific userinfo
+ _userinfo = (escaped) ? original.substring(0, next).toCharArray()
+ : encode(original.substring(0, next), allowed_userinfo,
+ charset);
+ from = next + 1;
+ }
+ next = original.indexOf('[', from);
+ if (next >= from) {
+ next = original.indexOf(']', from);
+ if (next == -1) {
+ throw new URIException(URIException.PARSING, "IPv6reference");
+ } else {
+ next++;
+ }
+ // In IPv6reference, '[', ']' should be excluded
+ _host = (escaped) ? original.substring(from, next).toCharArray()
+ : encode(original.substring(from, next), allowed_IPv6reference,
+ charset);
+ // Set flag
+ _is_IPv6reference = true;
+ } else { // only for !_is_IPv6reference
+ next = original.indexOf(':', from);
+ if (next == -1) {
+ next = original.length();
+ hasPort = false;
+ }
+ // REMINDME: it doesn't need the pre-validation
+ _host = original.substring(from, next).toCharArray();
+ if (validate(_host, IPv4address)) {
+ // Set flag
+ _is_IPv4address = true;
+ } else if (validate(_host, hostname)) {
+ // Set flag
+ _is_hostname = true;
+ } else {
+ // Set flag
+ _is_reg_name = true;
+ }
+ }
+ if (_is_reg_name) {
+ // Reset flags for a server-based naming authority
+ _is_server = _is_hostname = _is_IPv4address =
+ _is_IPv6reference = false;
+ // set a registry-based naming authority
+ _authority = (escaped) ? original.toString().toCharArray()
+ : encode(original.toString(), allowed_reg_name, charset);
+ } else {
+ if (original.length() - 1 > next && hasPort
+ && original.charAt(next) == ':') { // not empty
+ from = next + 1;
+ try {
+ _port = Integer.parseInt(original.substring(from));
+ } catch (NumberFormatException error) {
+ throw new URIException(URIException.PARSING,
+ "invalid port number");
+ }
+ }
+ // set a server-based naming authority
+ StringBuffer buf = new StringBuffer();
+ if (_userinfo != null) { // has_userinfo
+ buf.append(_userinfo);
+ buf.append('@');
+ }
+ if (_host != null) {
+ buf.append(_host);
+ if (_port != -1) {
+ buf.append(':');
+ buf.append(_port);
+ }
+ }
+ _authority = buf.toString().toCharArray();
+ // Set flag
+ _is_server = true;
+ }
+ }
+
+
+ /**
+ * Once it's parsed successfully, set this URI.
+ *
+ * @see #getRawURI
+ */
+ protected void setURI() {
+ // set _uri
+ StringBuffer buf = new StringBuffer();
+ // ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ if (_scheme != null) {
+ buf.append(_scheme);
+ buf.append(':');
+ }
+ if (_is_net_path) {
+ buf.append("//");
+ if (_authority != null) { // has_authority
+ if (_userinfo != null) { // by default, remove userinfo part
+ if (_host != null) {
+ buf.append(_host);
+ if (_port != -1) {
+ buf.append(':');
+ buf.append(_port);
+ }
+ }
+ } else {
+ buf.append(_authority);
+ }
+ }
+ }
+ if (_opaque != null && _is_opaque_part) {
+ buf.append(_opaque);
+ } else if (_path != null) {
+ // _is_hier_part or _is_relativeURI
+ if (_path.length != 0) {
+ buf.append(_path);
+ }
+ }
+ if (_query != null) { // has_query
+ buf.append('?');
+ buf.append(_query);
+ }
+ // ignore the fragment identifier
+ _uri = buf.toString().toCharArray();
+ hash = 0;
+ }
+
+ // ----------------------------------------------------------- Test methods
+
+
+ /**
+ * Tell whether or not this URI is absolute.
+ *
+ * @return true iif this URI is absoluteURI
+ */
+ public boolean isAbsoluteURI() {
+ return (_scheme != null);
+ }
+
+
+ /**
+ * Tell whether or not this URI is relative.
+ *
+ * @return true iif this URI is relativeURI
+ */
+ public boolean isRelativeURI() {
+ return (_scheme == null);
+ }
+
+
+ /**
+ * Tell whether or not the absoluteURI of this URI is hier_part.
+ *
+ * @return true iif the absoluteURI is hier_part
+ */
+ public boolean isHierPart() {
+ return _is_hier_part;
+ }
+
+
+ /**
+ * Tell whether or not the absoluteURI of this URI is opaque_part.
+ *
+ * @return true iif the absoluteURI is opaque_part
+ */
+ public boolean isOpaquePart() {
+ return _is_opaque_part;
+ }
+
+
+ /**
+ * Tell whether or not the relativeURI or heir_part of this URI is net_path.
+ * It's the same function as the has_authority() method.
+ *
+ * @return true iif the relativeURI or heir_part is net_path
+ * @see #hasAuthority
+ */
+ public boolean isNetPath() {
+ return _is_net_path || (_authority != null);
+ }
+
+
+ /**
+ * Tell whether or not the relativeURI or hier_part of this URI is abs_path.
+ *
+ * @return true iif the relativeURI or hier_part is abs_path
+ */
+ public boolean isAbsPath() {
+ return _is_abs_path;
+ }
+
+
+ /**
+ * Tell whether or not the relativeURI of this URI is rel_path.
+ *
+ * @return true iif the relativeURI is rel_path
+ */
+ public boolean isRelPath() {
+ return _is_rel_path;
+ }
+
+
+ /**
+ * Tell whether or not this URI has authority.
+ * It's the same function as the is_net_path() method.
+ *
+ * @return true iif this URI has authority
+ * @see #isNetPath
+ */
+ public boolean hasAuthority() {
+ return (_authority != null) || _is_net_path;
+ }
+
+ /**
+ * Tell whether or not the authority component of this URI is reg_name.
+ *
+ * @return true iif the authority component is reg_name
+ */
+ public boolean isRegName() {
+ return _is_reg_name;
+ }
+
+
+ /**
+ * Tell whether or not the authority component of this URI is server.
+ *
+ * @return true iif the authority component is server
+ */
+ public boolean isServer() {
+ return _is_server;
+ }
+
+
+ /**
+ * Tell whether or not this URI has userinfo.
+ *
+ * @return true iif this URI has userinfo
+ */
+ public boolean hasUserinfo() {
+ return (_userinfo != null);
+ }
+
+
+ /**
+ * Tell whether or not the host part of this URI is hostname.
+ *
+ * @return true iif the host part is hostname
+ */
+ public boolean isHostname() {
+ return _is_hostname;
+ }
+
+
+ /**
+ * Tell whether or not the host part of this URI is IPv4address.
+ *
+ * @return true iif the host part is IPv4address
+ */
+ public boolean isIPv4address() {
+ return _is_IPv4address;
+ }
+
+
+ /**
+ * Tell whether or not the host part of this URI is IPv6reference.
+ *
+ * @return true iif the host part is IPv6reference
+ */
+ public boolean isIPv6reference() {
+ return _is_IPv6reference;
+ }
+
+
+ /**
+ * Tell whether or not this URI has query.
+ *
+ * @return true iif this URI has query
+ */
+ public boolean hasQuery() {
+ return (_query != null);
+ }
+
+
+ /**
+ * Tell whether or not this URI has fragment.
+ *
+ * @return true iif this URI has fragment
+ */
+ public boolean hasFragment() {
+ return (_fragment != null);
+ }
+
+
+ // ---------------------------------------------------------------- Charset
+
+
+ /**
+ * Set the default charset of the protocol.
+ * DefaultCharsetChanged
exception.
+ *
+ * So API programmer must follow the following way:
+ *
+ *
+ * The API programmer is responsible to set the correct charset.
+ * And each application should remember its own charset to support.
+ *
+ * @param charset the default charset for each protocol
+ * @throws DefaultCharsetChanged default charset changed
+ */
+ public static void setDefaultProtocolCharset(String charset)
+ throws DefaultCharsetChanged {
+
+ defaultProtocolCharset = charset;
+ throw new DefaultCharsetChanged(DefaultCharsetChanged.PROTOCOL_CHARSET,
+ "the default protocol charset changed");
+ }
+
+
+ /**
+ * Get the default charset of the protocol.
+ *
+ * import org.apache.util.URI$DefaultCharsetChanged;
+ * .
+ * .
+ * .
+ * try {
+ * URI.setDefaultProtocolCharset("UTF-8");
+ * } catch (DefaultCharsetChanged cc) {
+ * // CASE 1: the exception could be ignored, when it is set by user
+ * if (cc.getReasonCode() == DefaultCharsetChanged.PROTOCOL_CHARSET) {
+ * // CASE 2: let user know the default protocol charset changed
+ * } else {
+ * // CASE 2: let user know the default document charset changed
+ * }
+ * }
+ *
DefaultCharsetChanged
exception.
+ *
+ * So API programmer must follow the following way:
+ *
+ *
+ * The API programmer is responsible to set the correct charset.
+ * And each application should remember its own charset to support.
+ *
+ * @param charset the default charset for the document
+ * @throws DefaultCharsetChanged default charset changed
+ */
+ public static void setDefaultDocumentCharset(String charset)
+ throws DefaultCharsetChanged {
+
+ defaultDocumentCharset = charset;
+ throw new DefaultCharsetChanged(DefaultCharsetChanged.DOCUMENT_CHARSET,
+ "the default document charset changed");
+ }
+
+
+ /**
+ * Get the recommended default charset of the document.
+ *
+ * @return the default charset string
+ */
+ public static String getDefaultDocumentCharset() {
+ return defaultDocumentCharset;
+ }
+
+
+ /**
+ * Get the default charset of the document by locale.
+ *
+ * @return the default charset string by locale
+ */
+ public static String getDefaultDocumentCharsetByLocale() {
+ return defaultDocumentCharsetByLocale;
+ }
+
+
+ /**
+ * Get the default charset of the document by platform.
+ *
+ * @return the default charset string by platform
+ */
+ public static String getDefaultDocumentCharsetByPlatform() {
+ return defaultDocumentCharsetByPlatform;
+ }
+
+ // ------------------------------------------------------------- The scheme
+
+ /**
+ * Get the scheme.
+ *
+ * @return the scheme
+ */
+ public char[] getRawScheme() {
+ return _scheme;
+ }
+
+
+ /**
+ * Get the scheme.
+ *
+ * @return the scheme
+ * null if undefined scheme
+ */
+ public String getScheme() {
+ return (_scheme == null) ? null : new String(_scheme);
+ }
+
+ // ---------------------------------------------------------- The authority
+
+ /**
+ * Set the authority. It can be one type of server, hostport, hostname,
+ * IPv4address, IPv6reference and reg_name.
+ *
+ * import org.apache.util.URI$DefaultCharsetChanged;
+ * .
+ * .
+ * .
+ * try {
+ * URI.setDefaultDocumentCharset("EUC-KR");
+ * } catch (DefaultCharsetChanged cc) {
+ * // CASE 1: the exception could be ignored, when it is set by user
+ * if (cc.getReasonCode() == DefaultCharsetChanged.DOCUMENT_CHARSET) {
+ * // CASE 2: let user know the default document charset changed
+ * } else {
+ * // CASE 2: let user know the default protocol charset changed
+ * }
+ * }
+ *
+ * authority = server | reg_name
+ *
+ * host = hostname | IPv4address | IPv6reference
+ *
+ * host = hostname | IPv4address | IPv6reference
+ *
+ * path = [ abs_path | opaque_part ]
+ *
+ * path = [ abs_path | opaque_part ]
+ * abs_path = "/" path_segments
+ * opaque_part = uric_no_slash *uric
+ *
+ * path = [ abs_path | opaque_part ]
+ *
URI
. So refer to the same-named APIs
+ * implemented in each specific protocol instance.
+ *
+ * @param query the query string.
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #encode
+ */
+ public void setQuery(String query) throws URIException {
+ if (query == null || query.length() == 0) {
+ _query = (query == null) ? null : query.toCharArray();
+ setURI();
+ return;
+ }
+ setRawQuery(encode(query, allowed_query, getProtocolCharset()));
+ }
+
+
+ /**
+ * Get the raw-escaped query.
+ *
+ * @return the raw-escaped query
+ */
+ public char[] getRawQuery() {
+ return _query;
+ }
+
+
+ /**
+ * Get the escaped query.
+ *
+ * @return the escaped query string
+ */
+ public String getEscapedQuery() {
+ return (_query == null) ? null : new String(_query);
+ }
+
+
+ /**
+ * Get the query.
+ *
+ * @return the query string.
+ * @throws URIException incomplete trailing escape pattern or unsupported
+ * character encoding
+ * @see #decode
+ */
+ public String getQuery() throws URIException {
+ return (_query == null) ? null : decode(_query, getProtocolCharset());
+ }
+
+ // ----------------------------------------------------------- The fragment
+
+ /**
+ * Set the raw-escaped fragment.
+ *
+ * @param escapedFragment the raw-escaped fragment
+ * @throws URIException escaped fragment not valid
+ */
+ public void setRawFragment(char[] escapedFragment) throws URIException {
+ if (escapedFragment == null || escapedFragment.length == 0) {
+ _fragment = escapedFragment;
+ hash = 0;
+ return;
+ }
+ if (!validate(escapedFragment, fragment)) {
+ throw new URIException(URIException.ESCAPING,
+ "escaped fragment not valid");
+ }
+ _fragment = escapedFragment;
+ hash = 0;
+ }
+
+
+ /**
+ * Set the escaped fragment string.
+ *
+ * @param escapedFragment the escaped fragment string
+ * @throws URIException escaped fragment not valid
+ */
+ public void setEscapedFragment(String escapedFragment) throws URIException {
+ if (escapedFragment == null) {
+ _fragment = null;
+ hash = 0;
+ return;
+ }
+ setRawFragment(escapedFragment.toCharArray());
+ }
+
+
+ /**
+ * Set the fragment.
+ *
+ * @param fragment the fragment string.
+ * @throws URIException If an error occurs.
+ */
+ public void setFragment(String fragment) throws URIException {
+ if (fragment == null || fragment.length() == 0) {
+ _fragment = (fragment == null) ? null : fragment.toCharArray();
+ hash = 0;
+ return;
+ }
+ _fragment = encode(fragment, allowed_fragment, getProtocolCharset());
+ hash = 0;
+ }
+
+
+ /**
+ * Get the raw-escaped fragment.
+ * String
.
+ * URI
object including the userinfo
+ * component, it should be used.
+ *
+ * @return a clone of this instance
+ */
+ public synchronized Object clone() {
+
+ URI instance = new URI();
+
+ instance._uri = _uri;
+ instance._scheme = _scheme;
+ instance._opaque = _opaque;
+ instance._authority = _authority;
+ instance._userinfo = _userinfo;
+ instance._host = _host;
+ instance._port = _port;
+ instance._path = _path;
+ instance._query = _query;
+ instance._fragment = _fragment;
+ // the charset to do escape encoding for this instance
+ instance.protocolCharset = protocolCharset;
+ // flags
+ instance._is_hier_part = _is_hier_part;
+ instance._is_opaque_part = _is_opaque_part;
+ instance._is_net_path = _is_net_path;
+ instance._is_abs_path = _is_abs_path;
+ instance._is_rel_path = _is_rel_path;
+ instance._is_reg_name = _is_reg_name;
+ instance._is_server = _is_server;
+ instance._is_hostname = _is_hostname;
+ instance._is_IPv4address = _is_IPv4address;
+ instance._is_IPv6reference = _is_IPv6reference;
+
+ return instance;
+ }
+
+ // ------------------------------------------------------------ Get the URI
+
+ /**
+ * It can be gotten the URI character sequence. It's raw-escaped.
+ * For the purpose of the protocol to be transported, it will be useful.
+ *
+ * It means that the API client programmer should extract each user and
+ * password to access manually. Probably it will be supported in the each
+ * subclass, however, not a whole URI-reference expression.
+ *
+ * @return the escaped URI string
+ * @see #clone()
+ */
+ public String toString() {
+ return getEscapedURI();
+ }
+
+
+ // ------------------------------------------------------------ Inner class
+
+ /**
+ * The charset-changed normal operation to represent to be required to
+ * alert to user the fact the default charset is changed.
+ */
+ public static class DefaultCharsetChanged extends RuntimeException {
+
+ // ------------------------------------------------------- constructors
+
+ /**
+ * The constructor with a reason string and its code arguments.
+ *
+ * @param reasonCode the reason code
+ * @param reason the reason
+ */
+ public DefaultCharsetChanged(int reasonCode, String reason) {
+ super(reason);
+ this.reason = reason;
+ this.reasonCode = reasonCode;
+ }
+
+ // ---------------------------------------------------------- constants
+
+ /** No specified reason code. */
+ public static final int UNKNOWN = 0;
+
+ /** Protocol charset changed. */
+ public static final int PROTOCOL_CHARSET = 1;
+
+ /** Document charset changed. */
+ public static final int DOCUMENT_CHARSET = 2;
+
+ // ------------------------------------------------- instance variables
+
+ /** The reason code. */
+ private int reasonCode;
+
+ /** The reason message. */
+ private String reason;
+
+ // ------------------------------------------------------------ methods
+
+ /**
+ * Get the reason code.
+ *
+ * @return the reason code
+ */
+ public int getReasonCode() {
+ return reasonCode;
+ }
+
+ /**
+ * Get the reason message.
+ *
+ * @return the reason message
+ */
+ public String getReason() {
+ return reason;
+ }
+
+ }
+
+
+ /**
+ * A mapping to determine the (somewhat arbitrarily) preferred charset for a
+ * given locale. Supports all locales recognized in JDK 1.1.
+ * true
if the object is equivalent.
+ */
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ // note - to allow for sub-classing, this checks that class is the same
+ // rather than do "instanceof".
+ if (this.getClass().equals(o.getClass())) {
+ UsernamePasswordCredentials that = (UsernamePasswordCredentials) o;
+
+ if (LangUtils.equals(this.userName, that.userName)
+ && LangUtils.equals(this.password, that.password) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Wire.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Wire.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Wire.java 22 Aug 2012 17:30:34 -0000 1.1
@@ -0,0 +1,165 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Wire.java,v 1.1 2012/08/22 17:30:34 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:34 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * Classes and interfaces supporting the client side of the HTTP protocol.
+
+
+
+
+
+
+
+
HttpClient Configuration with Java Properties
+ Java properties can be set at run time with the -Dname=value
+ command line arguments to the application that uses HttpClient.
+ These properties can also be set programaticly by calling
+
System.getProperties().setProperty(name, value)
.
+ This is the list of properties that HttpClient recognizes:
+
+
+
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeException.java 22 Aug 2012 17:30:36 -0000 1.1
@@ -0,0 +1,68 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeException.java,v 1.1 2012/08/22 17:30:36 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:36 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ *
+ Name
+ Type
+ Effect
+
+ httpclient.useragent
+ String
+ Sets the User-Agent string to be sent on every HTTP request.
+
+ httpclient.authentication.preemptive
+ boolean
+ Sends authorization credentials without requiring explicit requests
+ from the web server
+
+ *
+ *
+ * @author Oleg Kalnichevski
+ *
+ * @version $Revision: 1.1 $
+ * @since 3.0
+ */
+public abstract class AuthPolicy {
+
+ private static final HashMap SCHEMES = new HashMap();
+ private static final ArrayList SCHEME_LIST = new ArrayList();
+
+ /**
+ * The key used to look up the list of IDs of supported {@link AuthScheme
+ * authentication schemes} in their order of preference. The scheme IDs are
+ * stored in a {@link java.util.Collection} as {@link java.lang.String}s.
+ *
+ *
+ *
+ * null
.
+ *
+ * @return the authentication realm
+ */
+ String getRealm();
+
+ /**
+ * Returns a String identifying the authentication challenge. This is
+ * used, in combination with the host and port to determine if
+ * authorization has already been attempted or not. Schemes which
+ * require multiple requests to complete the authentication should
+ * return a different value for each stage in the request.
+ *
+ * basic
+ */
+ public String getSchemeName() {
+ return "basic";
+ }
+
+ /**
+ * Processes the Basic challenge.
+ *
+ * @param challenge the challenge string
+ *
+ * @throws MalformedChallengeException is thrown if the authentication challenge
+ * is malformed
+ *
+ * @since 3.0
+ */
+ public void processChallenge(String challenge)
+ throws MalformedChallengeException
+ {
+ super.processChallenge(challenge);
+ this.complete = true;
+ }
+
+ /**
+ * Tests if the Basic authentication process has been completed.
+ *
+ * @return true if Basic authorization has been processed,
+ * false otherwise.
+ *
+ * @since 3.0
+ */
+ public boolean isComplete() {
+ return this.complete;
+ }
+
+ /**
+ * Produces basic authorization string for the given set of
+ * {@link Credentials}.
+ *
+ * @param credentials The set of credentials to be used for athentication
+ * @param method Method name is ignored by the basic authentication scheme
+ * @param uri URI is ignored by the basic authentication scheme
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for this authentication scheme
+ * @throws AuthenticationException if authorization string cannot
+ * be generated due to an authentication failure
+ *
+ * @return a basic authorization string
+ *
+ * @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
+ */
+ public String authenticate(Credentials credentials, String method, String uri)
+ throws AuthenticationException {
+
+ LOG.trace("enter BasicScheme.authenticate(Credentials, String, String)");
+
+ UsernamePasswordCredentials usernamepassword = null;
+ try {
+ usernamepassword = (UsernamePasswordCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for basic authentication: "
+ + credentials.getClass().getName());
+ }
+ return BasicScheme.authenticate(usernamepassword);
+ }
+
+ /**
+ * Returns false. Basic authentication scheme is request based.
+ *
+ * @return false.
+ *
+ * @since 3.0
+ */
+ public boolean isConnectionBased() {
+ return false;
+ }
+
+ /**
+ * Produces basic authorization string for the given set of {@link Credentials}.
+ *
+ * @param credentials The set of credentials to be used for athentication
+ * @param method The method being authenticated
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for this authentication scheme
+ * @throws AuthenticationException if authorization string cannot
+ * be generated due to an authentication failure
+ *
+ * @return a basic authorization string
+ *
+ * @since 3.0
+ */
+ public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
+
+ LOG.trace("enter BasicScheme.authenticate(Credentials, HttpMethod)");
+
+ if (method == null) {
+ throw new IllegalArgumentException("Method may not be null");
+ }
+ UsernamePasswordCredentials usernamepassword = null;
+ try {
+ usernamepassword = (UsernamePasswordCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for basic authentication: "
+ + credentials.getClass().getName());
+ }
+ return BasicScheme.authenticate(
+ usernamepassword,
+ method.getParams().getCredentialCharset());
+ }
+
+ /**
+ * @deprecated Use {@link #authenticate(UsernamePasswordCredentials, String)}
+ *
+ * Returns a basic Authorization header value for the given
+ * {@link UsernamePasswordCredentials}.
+ *
+ * @param credentials The credentials to encode.
+ *
+ * @return a basic authorization string
+ */
+ public static String authenticate(UsernamePasswordCredentials credentials) {
+ return authenticate(credentials, "ISO-8859-1");
+ }
+
+ /**
+ * Returns a basic Authorization header value for the given
+ * {@link UsernamePasswordCredentials} and charset.
+ *
+ * @param credentials The credentials to encode.
+ * @param charset The charset to use for encoding the credentials
+ *
+ * @return a basic authorization string
+ *
+ * @since 3.0
+ */
+ public static String authenticate(UsernamePasswordCredentials credentials, String charset) {
+
+ LOG.trace("enter BasicScheme.authenticate(UsernamePasswordCredentials, String)");
+
+ if (credentials == null) {
+ throw new IllegalArgumentException("Credentials may not be null");
+ }
+ if (charset == null || charset.length() == 0) {
+ throw new IllegalArgumentException("charset may not be null or empty");
+ }
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(credentials.getUserName());
+ buffer.append(":");
+ buffer.append(credentials.getPassword());
+
+ return "Basic " + EncodingUtil.getAsciiString(
+ Base64.encodeBase64(EncodingUtil.getBytes(buffer.toString(), charset)));
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsNotAvailableException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsNotAvailableException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsNotAvailableException.java 22 Aug 2012 17:30:36 -0000 1.1
@@ -0,0 +1,67 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsNotAvailableException.java,v 1.1 2012/08/22 17:30:36 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:36 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * digest
+ */
+ public String getSchemeName() {
+ return "digest";
+ }
+
+ /**
+ * Returns false. Digest authentication scheme is request based.
+ *
+ * @return false.
+ *
+ * @since 3.0
+ */
+ public boolean isConnectionBased() {
+ return false;
+ }
+
+ /**
+ * Produces a digest authorization string for the given set of
+ * {@link Credentials}, method name and URI.
+ *
+ * @param credentials A set of credentials to be used for athentication
+ * @param method the name of the method that requires authorization.
+ * @param uri The URI for which authorization is needed.
+ *
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for this authentication scheme
+ * @throws AuthenticationException if authorization string cannot
+ * be generated due to an authentication failure
+ *
+ * @return a digest authorization string
+ *
+ * @see org.apache.commons.httpclient.HttpMethod#getName()
+ * @see org.apache.commons.httpclient.HttpMethod#getPath()
+ *
+ * @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
+ */
+ public String authenticate(Credentials credentials, String method, String uri)
+ throws AuthenticationException {
+
+ LOG.trace("enter DigestScheme.authenticate(Credentials, String, String)");
+
+ UsernamePasswordCredentials usernamepassword = null;
+ try {
+ usernamepassword = (UsernamePasswordCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for digest authentication: "
+ + credentials.getClass().getName());
+ }
+ getParameters().put("methodname", method);
+ getParameters().put("uri", uri);
+ String digest = createDigest(
+ usernamepassword.getUserName(),
+ usernamepassword.getPassword());
+ return "Digest " + createDigestHeader(usernamepassword.getUserName(), digest);
+ }
+
+ /**
+ * Produces a digest authorization string for the given set of
+ * {@link Credentials}, method name and URI.
+ *
+ * @param credentials A set of credentials to be used for athentication
+ * @param method The method being authenticated
+ *
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for this authentication scheme
+ * @throws AuthenticationException if authorization string cannot
+ * be generated due to an authentication failure
+ *
+ * @return a digest authorization string
+ *
+ * @since 3.0
+ */
+ public String authenticate(Credentials credentials, HttpMethod method)
+ throws AuthenticationException {
+
+ LOG.trace("enter DigestScheme.authenticate(Credentials, HttpMethod)");
+
+ UsernamePasswordCredentials usernamepassword = null;
+ try {
+ usernamepassword = (UsernamePasswordCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for digest authentication: "
+ + credentials.getClass().getName());
+ }
+ getParameters().put("methodname", method.getName());
+ getParameters().put("uri", method.getPath());
+ String charset = getParameter("charset");
+ if (charset == null) {
+ getParameters().put("charset", method.getParams().getCredentialCharset());
+ }
+ String digest = createDigest(
+ usernamepassword.getUserName(),
+ usernamepassword.getPassword());
+ return "Digest " + createDigestHeader(usernamepassword.getUserName(),
+ digest);
+ }
+
+ /**
+ * Creates an MD5 response digest.
+ *
+ * @param uname Username
+ * @param pwd Password
+ * @param charset The credential charset
+ *
+ * @return The created digest as string. This will be the response tag's
+ * value in the Authentication HTTP header.
+ * @throws AuthenticationException when MD5 is an unsupported algorithm
+ */
+ private String createDigest(final String uname, final String pwd) throws AuthenticationException {
+
+ LOG.trace("enter DigestScheme.createDigest(String, String, Map)");
+
+ final String digAlg = "MD5";
+
+ // Collecting required tokens
+ String uri = getParameter("uri");
+ String realm = getParameter("realm");
+ String nonce = getParameter("nonce");
+ String qop = getParameter("qop");
+ String method = getParameter("methodname");
+ String algorithm = getParameter("algorithm");
+ // If an algorithm is not specified, default to MD5.
+ if (algorithm == null) {
+ algorithm = "MD5";
+ }
+ // If an charset is not specified, default to ISO-8859-1.
+ String charset = getParameter("charset");
+ if (charset == null) {
+ charset = "ISO-8859-1";
+ }
+
+ if (qopVariant == QOP_AUTH_INT) {
+ LOG.warn("qop=auth-int is not supported");
+ throw new AuthenticationException(
+ "Unsupported qop in HTTP Digest authentication");
+ }
+
+ MessageDigest md5Helper;
+
+ try {
+ md5Helper = MessageDigest.getInstance(digAlg);
+ } catch (Exception e) {
+ throw new AuthenticationException(
+ "Unsupported algorithm in HTTP Digest authentication: "
+ + digAlg);
+ }
+
+ // 3.2.2.2: Calculating digest
+ StringBuffer tmp = new StringBuffer(uname.length() + realm.length() + pwd.length() + 2);
+ tmp.append(uname);
+ tmp.append(':');
+ tmp.append(realm);
+ tmp.append(':');
+ tmp.append(pwd);
+ // unq(username-value) ":" unq(realm-value) ":" passwd
+ String a1 = tmp.toString();
+ //a1 is suitable for MD5 algorithm
+ if(algorithm.equals("MD5-sess")) {
+ // H( unq(username-value) ":" unq(realm-value) ":" passwd )
+ // ":" unq(nonce-value)
+ // ":" unq(cnonce-value)
+
+ String tmp2=encode(md5Helper.digest(EncodingUtil.getBytes(a1, charset)));
+ StringBuffer tmp3 = new StringBuffer(tmp2.length() + nonce.length() + cnonce.length() + 2);
+ tmp3.append(tmp2);
+ tmp3.append(':');
+ tmp3.append(nonce);
+ tmp3.append(':');
+ tmp3.append(cnonce);
+ a1 = tmp3.toString();
+ } else if(!algorithm.equals("MD5")) {
+ LOG.warn("Unhandled algorithm " + algorithm + " requested");
+ }
+ String md5a1 = encode(md5Helper.digest(EncodingUtil.getBytes(a1, charset)));
+
+ String a2 = null;
+ if (qopVariant == QOP_AUTH_INT) {
+ LOG.error("Unhandled qop auth-int");
+ //we do not have access to the entity-body or its hash
+ //TODO: add Method ":" digest-uri-value ":" H(entity-body)
+ } else {
+ a2 = method + ":" + uri;
+ }
+ String md5a2 = encode(md5Helper.digest(EncodingUtil.getAsciiBytes(a2)));
+
+ // 3.2.2.1
+ String serverDigestValue;
+ if (qopVariant == QOP_MISSING) {
+ LOG.debug("Using null qop method");
+ StringBuffer tmp2 = new StringBuffer(md5a1.length() + nonce.length() + md5a2.length());
+ tmp2.append(md5a1);
+ tmp2.append(':');
+ tmp2.append(nonce);
+ tmp2.append(':');
+ tmp2.append(md5a2);
+ serverDigestValue = tmp2.toString();
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Using qop method " + qop);
+ }
+ String qopOption = getQopVariantString();
+ StringBuffer tmp2 = new StringBuffer(md5a1.length() + nonce.length()
+ + NC.length() + cnonce.length() + qopOption.length() + md5a2.length() + 5);
+ tmp2.append(md5a1);
+ tmp2.append(':');
+ tmp2.append(nonce);
+ tmp2.append(':');
+ tmp2.append(NC);
+ tmp2.append(':');
+ tmp2.append(cnonce);
+ tmp2.append(':');
+ tmp2.append(qopOption);
+ tmp2.append(':');
+ tmp2.append(md5a2);
+ serverDigestValue = tmp2.toString();
+ }
+
+ String serverDigest =
+ encode(md5Helper.digest(EncodingUtil.getAsciiBytes(serverDigestValue)));
+
+ return serverDigest;
+ }
+
+ /**
+ * Creates digest-response header as defined in RFC2617.
+ *
+ * @param uname Username
+ * @param digest The response tag's value as String.
+ *
+ * @return The digest-response as String.
+ */
+ private String createDigestHeader(final String uname, final String digest)
+ throws AuthenticationException {
+
+ LOG.trace("enter DigestScheme.createDigestHeader(String, Map, "
+ + "String)");
+
+ String uri = getParameter("uri");
+ String realm = getParameter("realm");
+ String nonce = getParameter("nonce");
+ String opaque = getParameter("opaque");
+ String response = digest;
+ String algorithm = getParameter("algorithm");
+
+ 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) {
+ params.add(new NameValuePair("qop", getQopVariantString()));
+ params.add(new NameValuePair("nc", NC));
+ params.add(new NameValuePair("cnonce", this.cnonce));
+ }
+ if (algorithm != null) {
+ params.add(new NameValuePair("algorithm", algorithm));
+ }
+ if (opaque != null) {
+ 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(", ");
+ }
+ boolean noQuotes = "nc".equals(param.getName()) ||
+ "qop".equals(param.getName());
+ this.formatter.setAlwaysUseQuotes(!noQuotes);
+ this.formatter.format(buffer, param);
+ }
+ return buffer.toString();
+ }
+
+ private String getQopVariantString() {
+ String qopOption;
+ if (qopVariant == QOP_AUTH_INT) {
+ qopOption = "auth-int";
+ } else {
+ qopOption = "auth";
+ }
+ return qopOption;
+ }
+
+ /**
+ * Encodes the 128 bit (16 bytes) MD5 digest into a 32 characters long
+ * String
according to RFC 2617.
+ *
+ * @param binaryData array containing the digest
+ * @return encoded MD5, or null
if encoding failed
+ */
+ private static String encode(byte[] binaryData) {
+ LOG.trace("enter DigestScheme.encode(byte[])");
+
+ if (binaryData.length != 16) {
+ return null;
+ }
+
+ char[] buffer = new char[32];
+ for (int i = 0; i < 16; i++) {
+ int low = (int) (binaryData[i] & 0x0f);
+ int high = (int) ((binaryData[i] & 0xf0) >> 4);
+ buffer[i * 2] = HEXADECIMAL[high];
+ buffer[(i * 2) + 1] = HEXADECIMAL[low];
+ }
+
+ return new String(buffer);
+ }
+
+
+ /**
+ * Creates a random cnonce value based on the current time.
+ *
+ * @return The cnonce value as String.
+ * @throws HttpClientError if MD5 algorithm is not supported.
+ */
+ public static String createCnonce() {
+ LOG.trace("enter DigestScheme.createCnonce()");
+
+ String cnonce;
+ final String digAlg = "MD5";
+ MessageDigest md5Helper;
+
+ try {
+ md5Helper = MessageDigest.getInstance(digAlg);
+ } catch (NoSuchAlgorithmException e) {
+ throw new HttpClientError(
+ "Unsupported algorithm in HTTP Digest authentication: "
+ + digAlg);
+ }
+
+ cnonce = Long.toString(System.currentTimeMillis());
+ cnonce = encode(md5Helper.digest(EncodingUtil.getAsciiBytes(cnonce)));
+
+ return cnonce;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthRealm.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthRealm.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthRealm.java 22 Aug 2012 17:30:36 -0000 1.1
@@ -0,0 +1,56 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthRealm.java,v 1.1 2012/08/22 17:30:36 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:36 $
+ *
+ * ====================================================================
+ *
+ * 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
+ *
+ * A client SHOULD assume that all paths at or deeper than the depth of the
+ * last symbolic element in the path field of the Request-URI also are within
+ * the protection space specified by the basic realm value of the current
+ * challenge. A client MAY preemptively send the corresponding Authorization
+ * header with requests for resources in that space without receipt of another
+ * challenge from the server. Similarly, when a client sends a request to a
+ * proxy, it may reuse a userid and password in the Proxy-Authorization header
+ * field without receiving another challenge from the proxy server.
+ *
+ *
NTLM
,
+ * Digest
, Basic
schemes are recognized.
+ * The NTLM
scheme is considered the strongest and is
+ * preferred to all others. The Digest
scheme is preferred to
+ * the Basic
one which provides no encryption for credentials.
+ * The Basic
scheme is used only if it is the only one
+ * supported.
+ *
+ * @param challenges The array of authentication challenges
+ *
+ * @return The strongest authentication scheme supported
+ *
+ * @throws MalformedChallengeException is thrown if an authentication
+ * challenge is malformed
+ * @throws UnsupportedOperationException when none of challenge types
+ * available is supported.
+ *
+ * @deprecated Use {@link AuthChallengeParser#parseChallenges(Header[])} and
+ * {@link AuthPolicy#getAuthScheme(String)}
+ */
+ public static AuthScheme selectAuthScheme(final Header[] challenges)
+ throws MalformedChallengeException {
+ LOG.trace("enter HttpAuthenticator.selectAuthScheme(Header[])");
+ if (challenges == null) {
+ throw new IllegalArgumentException("Array of challenges may not be null");
+ }
+ if (challenges.length == 0) {
+ throw new IllegalArgumentException("Array of challenges may not be empty");
+ }
+ String challenge = null;
+ Map challengemap = new HashMap(challenges.length);
+ for (int i = 0; i < challenges.length; i++) {
+ challenge = challenges[i].getValue();
+ String s = AuthChallengeParser.extractScheme(challenge);
+ challengemap.put(s, challenge);
+ }
+ challenge = (String) challengemap.get("ntlm");
+ if (challenge != null) {
+ return new NTLMScheme(challenge);
+ }
+ challenge = (String) challengemap.get("digest");
+ if (challenge != null) {
+ return new DigestScheme(challenge);
+ }
+ challenge = (String) challengemap.get("basic");
+ if (challenge != null) {
+ return new BasicScheme(challenge);
+ }
+ throw new UnsupportedOperationException(
+ "Authentication scheme(s) not supported: " + challengemap.toString());
+ }
+
+ private static boolean doAuthenticateDefault(
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state,
+ boolean proxy)
+ throws AuthenticationException {
+ if (method == null) {
+ throw new IllegalArgumentException("HTTP method may not be null");
+ }
+ if (state == null) {
+ throw new IllegalArgumentException("HTTP state may not be null");
+ }
+ String host = null;
+ if (conn != null) {
+ host = proxy ? conn.getProxyHost() : conn.getHost();
+ }
+ Credentials credentials = proxy
+ ? state.getProxyCredentials(null, host) : state.getCredentials(null, host);
+ if (credentials == null) {
+ return false;
+ }
+ if (!(credentials instanceof UsernamePasswordCredentials)) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for basic authentication: "
+ + credentials.toString());
+ }
+ String auth = BasicScheme.authenticate(
+ (UsernamePasswordCredentials) credentials,
+ method.getParams().getCredentialCharset());
+ if (auth != null) {
+ String s = proxy ? PROXY_AUTH_RESP : WWW_AUTH_RESP;
+ Header header = new Header(s, auth, true);
+ method.addRequestHeader(header);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Attempt to provide default authentication credentials
+ * to the given method in the given context using basic
+ * authentication scheme.
+ *
+ * @param method the HttpMethod which requires authentication
+ * @param conn the connection to a specific host. This parameter
+ * may be null if default credentials (not specific
+ * to any particular host) are to be used
+ * @param state the HttpState object providing Credentials
+ *
+ * @return true if the Authenticate response header
+ * was added
+ *
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for basic scheme
+ * @throws AuthenticationException when a parsing or other error occurs
+ *
+ * @see HttpState#setCredentials(String,String,Credentials)
+ *
+ * @deprecated use AuthScheme
+ */
+ public static boolean authenticateDefault(
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state)
+ throws AuthenticationException {
+ LOG.trace(
+ "enter HttpAuthenticator.authenticateDefault(HttpMethod, HttpConnection, HttpState)");
+ return doAuthenticateDefault(method, conn, state, false);
+ }
+
+
+ /**
+ * Attempt to provide default proxy authentication credentials
+ * to the given method in the given context using basic
+ * authentication scheme.
+ *
+ * @param method the HttpMethod which requires authentication
+ * @param conn the connection to a specific host. This parameter
+ * may be null if default credentials (not specific
+ * to any particular host) are to be used
+ * @param state the HttpState object providing Credentials
+ *
+ * @return true if the Proxy-Authenticate response header
+ * was added
+ *
+ * @throws InvalidCredentialsException if authentication credentials
+ * are not valid or not applicable for basic scheme
+ * @throws AuthenticationException when a parsing or other error occurs
+
+ * @see HttpState#setCredentials(String,String,Credentials)
+ *
+ * @deprecated use AuthScheme
+ */
+ public static boolean authenticateProxyDefault(
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state)
+ throws AuthenticationException {
+ LOG.trace("enter HttpAuthenticator.authenticateProxyDefault(HttpMethod, HttpState)");
+ return doAuthenticateDefault(method, conn, state, true);
+ }
+
+
+ private static boolean doAuthenticate(
+ AuthScheme authscheme,
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state,
+ boolean proxy)
+ throws AuthenticationException {
+ if (authscheme == null) {
+ throw new IllegalArgumentException("Authentication scheme may not be null");
+ }
+ if (method == null) {
+ throw new IllegalArgumentException("HTTP method may not be null");
+ }
+ if (state == null) {
+ throw new IllegalArgumentException("HTTP state may not be null");
+ }
+ String host = null;
+ if (conn != null) {
+ if (proxy) {
+ host = conn.getProxyHost();
+ } else {
+ host = method.getParams().getVirtualHost();
+ if (host == null) {
+ host = conn.getHost();
+ }
+ }
+ }
+ String realm = authscheme.getRealm();
+ if (LOG.isDebugEnabled()) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Using credentials for ");
+ if (realm == null) {
+ buffer.append("default");
+ } else {
+ buffer.append('\'');
+ buffer.append(realm);
+ buffer.append('\'');
+ }
+ buffer.append(" authentication realm at ");
+ buffer.append(host);
+ LOG.debug(buffer.toString());
+ }
+ Credentials credentials = proxy
+ ? state.getProxyCredentials(realm, host)
+ : state.getCredentials(realm, host);
+ if (credentials == null) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("No credentials available for the ");
+ if (realm == null) {
+ buffer.append("default");
+ } else {
+ buffer.append('\'');
+ buffer.append(realm);
+ buffer.append('\'');
+ }
+ buffer.append(" authentication realm at ");
+ buffer.append(host);
+ throw new CredentialsNotAvailableException(buffer.toString());
+ }
+ String auth = authscheme.authenticate(credentials, method);
+ if (auth != null) {
+ String s = proxy ? PROXY_AUTH_RESP : WWW_AUTH_RESP;
+ Header header = new Header(s, auth, true);
+ method.addRequestHeader(header);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Attempt to provide requisite authentication credentials to the
+ * given method in the given context using the given
+ * authentication scheme.
+ *
+ * @param authscheme The authentication scheme to be used
+ * @param method The HttpMethod which requires authentication
+ * @param conn the connection to a specific host. This parameter
+ * may be null if default credentials (not specific
+ * to any particular host) are to be used
+ * @param state The HttpState object providing Credentials
+ *
+ * @return true if the Authenticate response header was added
+ *
+ * @throws CredentialsNotAvailableException if authentication credentials
+ * required to respond to the authentication challenge are not available
+ * @throws AuthenticationException when a parsing or other error occurs
+
+ * @see HttpState#setCredentials(String,String,Credentials)
+ *
+ * @deprecated use AuthScheme
+ */
+ public static boolean authenticate(
+ AuthScheme authscheme,
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state)
+ throws AuthenticationException {
+ LOG.trace(
+ "enter HttpAuthenticator.authenticate(AuthScheme, HttpMethod, HttpConnection, "
+ + "HttpState)");
+ return doAuthenticate(authscheme, method, conn, state, false);
+ }
+
+
+ /**
+ * Attempt to provide requisite proxy authentication credentials
+ * to the given method in the given context using
+ * the given authentication scheme.
+ *
+ * @param authscheme The authentication scheme to be used
+ * @param method the HttpMethod which requires authentication
+ * @param conn the connection to a specific host. This parameter
+ * may be null if default credentials (not specific
+ * to any particular host) are to be used
+ * @param state the HttpState object providing Credentials
+ *
+ * @return true if the Proxy-Authenticate response header
+ * was added
+ *
+ * @throws CredentialsNotAvailableException if authentication credentials
+ * required to respond to the authentication challenge are not available
+ * @throws AuthenticationException when a parsing or other error occurs
+
+ * @see HttpState#setCredentials(String,String,Credentials)
+ *
+ * @deprecated use AuthScheme
+ */
+ public static boolean authenticateProxy(
+ AuthScheme authscheme,
+ HttpMethod method,
+ HttpConnection conn,
+ HttpState state
+ ) throws AuthenticationException {
+ LOG.trace("enter HttpAuthenticator.authenticateProxy(AuthScheme, HttpMethod, HttpState)");
+ return doAuthenticate(authscheme, method, conn, state, true);
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/InvalidCredentialsException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/InvalidCredentialsException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/InvalidCredentialsException.java 22 Aug 2012 17:30:35 -0000 1.1
@@ -0,0 +1,67 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/InvalidCredentialsException.java,v 1.1 2012/08/22 17:30:35 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:35 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * + * This class provides methods for generating authentication + * challenge responses for the NTLM authentication protocol. The NTLM + * protocol is a proprietary Microsoft protocol and as such no RFC + * exists for it. This class is based upon the reverse engineering + * efforts of a wide range of people.
+ * + *Please note that an implementation of JCE must be correctly installed and configured when + * using NTLM support.
+ * + *This class should not be used externally to HttpClient as it's API is specifically + * designed to work with HttpClient's use case, in particular it's connection management.
+ * + * @author Adrian Sutton + * @author Jeff Dever + * @author Mike Bowler + * + * @version $Revision: 1.1 $ $Date: 2012/08/22 17:30:36 $ + * @since 3.0 + */ +final class NTLM { + + /** Character encoding */ + public static final String DEFAULT_CHARSET = "ASCII"; + + /** The current response */ + private byte[] currentResponse; + + /** The current position */ + private int currentPosition = 0; + + /** The character set to use for encoding the credentials */ + private String credentialCharset = DEFAULT_CHARSET; + + /** + * Returns the response for the given message. + * + * @param message the message that was received from the server. + * @param username the username to authenticate with. + * @param password the password to authenticate with. + * @param host The host. + * @param domain the NT domain to authenticate in. + * @return The response. + * @throws HttpException If the messages cannot be retrieved. + */ + public final String getResponseFor(String message, + String username, String password, String host, String domain) + throws AuthenticationException { + + final String response; + if (message == null || message.trim().equals("")) { + response = getType1Message(host, domain); + } else { + response = getType3Message(username, password, host, domain, + parseType2Message(message)); + } + return response; + } + + /** + * Return the cipher for the specified key. + * @param key The key. + * @return Cipher The cipher. + * @throws AuthenticationException If the cipher cannot be retrieved. + */ + private Cipher getCipher(byte[] key) throws AuthenticationException { + try { + final Cipher ecipher = Cipher.getInstance("DES/ECB/NoPadding"); + key = setupKey(key); + ecipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DES")); + return ecipher; + } catch (NoSuchAlgorithmException e) { + throw new AuthenticationException("DES encryption is not available.", e); + } catch (InvalidKeyException e) { + throw new AuthenticationException("Invalid key for DES encryption.", e); + } catch (NoSuchPaddingException e) { + throw new AuthenticationException( + "NoPadding option for DES is not available.", e); + } + } + + /** + * Adds parity bits to the key. + * @param key56 The key + * @return The modified key. + */ + private byte[] setupKey(byte[] key56) { + byte[] key = new byte[8]; + key[0] = (byte) ((key56[0] >> 1) & 0xff); + key[1] = (byte) ((((key56[0] & 0x01) << 6) + | (((key56[1] & 0xff) >> 2) & 0xff)) & 0xff); + key[2] = (byte) ((((key56[1] & 0x03) << 5) + | (((key56[2] & 0xff) >> 3) & 0xff)) & 0xff); + key[3] = (byte) ((((key56[2] & 0x07) << 4) + | (((key56[3] & 0xff) >> 4) & 0xff)) & 0xff); + key[4] = (byte) ((((key56[3] & 0x0f) << 3) + | (((key56[4] & 0xff) >> 5) & 0xff)) & 0xff); + key[5] = (byte) ((((key56[4] & 0x1f) << 2) + | (((key56[5] & 0xff) >> 6) & 0xff)) & 0xff); + key[6] = (byte) ((((key56[5] & 0x3f) << 1) + | (((key56[6] & 0xff) >> 7) & 0xff)) & 0xff); + key[7] = (byte) (key56[6] & 0x7f); + + for (int i = 0; i < key.length; i++) { + key[i] = (byte) (key[i] << 1); + } + return key; + } + + /** + * Encrypt the data. + * @param key The key. + * @param bytes The data + * @return byte[] The encrypted data + * @throws HttpException If {@link Cipher.doFinal(byte[])} fails + */ + private byte[] encrypt(byte[] key, byte[] bytes) + throws AuthenticationException { + Cipher ecipher = getCipher(key); + try { + byte[] enc = ecipher.doFinal(bytes); + return enc; + } catch (IllegalBlockSizeException e) { + throw new AuthenticationException("Invalid block size for DES encryption.", e); + } catch (BadPaddingException e) { + throw new AuthenticationException("Data not padded correctly for DES encryption.", e); + } + } + + /** + * Prepares the object to create a response of the given length. + * @param length the length of the response to prepare. + */ + private void prepareResponse(int length) { + currentResponse = new byte[length]; + currentPosition = 0; + } + + /** + * Adds the given byte to the response. + * @param b the byte to add. + */ + private void addByte(byte b) { + currentResponse[currentPosition] = b; + currentPosition++; + } + + /** + * Adds the given bytes to the response. + * @param bytes the bytes to add. + */ + private void addBytes(byte[] bytes) { + for (int i = 0; i < bytes.length; i++) { + currentResponse[currentPosition] = bytes[i]; + currentPosition++; + } + } + + /** + * Returns the response that has been generated after shrinking the array if + * required and base64 encodes the response. + * @return The response as above. + */ + private String getResponse() { + byte[] resp; + if (currentResponse.length > currentPosition) { + byte[] tmp = new byte[currentPosition]; + for (int i = 0; i < currentPosition; i++) { + tmp[i] = currentResponse[i]; + } + resp = tmp; + } else { + resp = currentResponse; + } + return EncodingUtil.getAsciiString(Base64.encodeBase64(resp)); + } + + /** + * Creates the first message (type 1 message) in the NTLM authentication sequence. + * This message includes the user name, domain and host for the authentication session. + * + * @param host the computer name of the host requesting authentication. + * @param domain The domain to authenticate with. + * @return String the message to add to the HTTP request header. + */ + public String getType1Message(String host, String domain) { + host = host.toUpperCase(); + domain = domain.toUpperCase(); + byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET); + byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET); + + int finalLength = 32 + hostBytes.length + domainBytes.length; + prepareResponse(finalLength); + + // The initial id string. + byte[] protocol = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET); + addBytes(protocol); + addByte((byte) 0); + + // Type + addByte((byte) 1); + addByte((byte) 0); + addByte((byte) 0); + addByte((byte) 0); + + // Flags + addByte((byte) 6); + addByte((byte) 82); + addByte((byte) 0); + addByte((byte) 0); + + // Domain length (first time). + int iDomLen = domainBytes.length; + byte[] domLen = convertShort(iDomLen); + addByte(domLen[0]); + addByte(domLen[1]); + + // Domain length (second time). + addByte(domLen[0]); + addByte(domLen[1]); + + // Domain offset. + byte[] domOff = convertShort(hostBytes.length + 32); + addByte(domOff[0]); + addByte(domOff[1]); + addByte((byte) 0); + addByte((byte) 0); + + // Host length (first time). + byte[] hostLen = convertShort(hostBytes.length); + addByte(hostLen[0]); + addByte(hostLen[1]); + + // Host length (second time). + addByte(hostLen[0]); + addByte(hostLen[1]); + + // Host offset (always 32). + byte[] hostOff = convertShort(32); + addByte(hostOff[0]); + addByte(hostOff[1]); + addByte((byte) 0); + addByte((byte) 0); + + // Host String. + addBytes(hostBytes); + + // Domain String. + addBytes(domainBytes); + + return getResponse(); + } + + /** + * Extracts the server nonce out of the given message type 2. + * + * @param message the String containing the base64 encoded message. + * @return an array of 8 bytes that the server sent to be used when + * hashing the password. + */ + public byte[] parseType2Message(String message) { + // Decode the message first. + byte[] msg = Base64.decodeBase64(EncodingUtil.getBytes(message, DEFAULT_CHARSET)); + byte[] nonce = new byte[8]; + // The nonce is the 8 bytes starting from the byte in position 24. + for (int i = 0; i < 8; i++) { + nonce[i] = msg[i + 24]; + } + return nonce; + } + + /** + * Creates the type 3 message using the given server nonce. The type 3 message includes all the + * information for authentication, host, domain, username and the result of encrypting the + * nonce sent by the server using the user's password as the key. + * + * @param user The user name. This should not include the domain name. + * @param password The password. + * @param host The host that is originating the authentication request. + * @param domain The domain to authenticate within. + * @param nonce the 8 byte array the server sent. + * @return The type 3 message. + * @throws AuthenticationException If {@encrypt(byte[],byte[])} fails. + */ + public String getType3Message(String user, String password, + String host, String domain, byte[] nonce) + throws AuthenticationException { + + int ntRespLen = 0; + int lmRespLen = 24; + domain = domain.toUpperCase(); + host = host.toUpperCase(); + user = user.toUpperCase(); + byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET); + byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET); + byte[] userBytes = EncodingUtil.getBytes(user, credentialCharset); + int domainLen = domainBytes.length; + int hostLen = hostBytes.length; + int userLen = userBytes.length; + int finalLength = 64 + ntRespLen + lmRespLen + domainLen + + userLen + hostLen; + prepareResponse(finalLength); + byte[] ntlmssp = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET); + addBytes(ntlmssp); + addByte((byte) 0); + addByte((byte) 3); + addByte((byte) 0); + addByte((byte) 0); + addByte((byte) 0); + + // LM Resp Length (twice) + addBytes(convertShort(24)); + addBytes(convertShort(24)); + + // LM Resp Offset + addBytes(convertShort(finalLength - 24)); + addByte((byte) 0); + addByte((byte) 0); + + // NT Resp Length (twice) + addBytes(convertShort(0)); + addBytes(convertShort(0)); + + // NT Resp Offset + addBytes(convertShort(finalLength)); + addByte((byte) 0); + addByte((byte) 0); + + // Domain length (twice) + addBytes(convertShort(domainLen)); + addBytes(convertShort(domainLen)); + + // Domain offset. + addBytes(convertShort(64)); + addByte((byte) 0); + addByte((byte) 0); + + // User Length (twice) + addBytes(convertShort(userLen)); + addBytes(convertShort(userLen)); + + // User offset + addBytes(convertShort(64 + domainLen)); + addByte((byte) 0); + addByte((byte) 0); + + // Host length (twice) + addBytes(convertShort(hostLen)); + addBytes(convertShort(hostLen)); + + // Host offset + addBytes(convertShort(64 + domainLen + userLen)); + + for (int i = 0; i < 6; i++) { + addByte((byte) 0); + } + + // Message length + addBytes(convertShort(finalLength)); + addByte((byte) 0); + addByte((byte) 0); + + // Flags + addByte((byte) 6); + addByte((byte) 82); + addByte((byte) 0); + addByte((byte) 0); + + addBytes(domainBytes); + addBytes(userBytes); + addBytes(hostBytes); + addBytes(hashPassword(password, nonce)); + return getResponse(); + } + + /** + * Creates the LANManager and NT response for the given password using the + * given nonce. + * @param password the password to create a hash for. + * @param nonce the nonce sent by the server. + * @return The response. + * @throws HttpException If {@link #encrypt(byte[],byte[])} fails. + */ + private byte[] hashPassword(String password, byte[] nonce) + throws AuthenticationException { + byte[] passw = EncodingUtil.getBytes(password.toUpperCase(), credentialCharset); + byte[] lmPw1 = new byte[7]; + byte[] lmPw2 = new byte[7]; + + int len = passw.length; + if (len > 7) { + len = 7; + } + + int idx; + for (idx = 0; idx < len; idx++) { + lmPw1[idx] = passw[idx]; + } + for (; idx < 7; idx++) { + lmPw1[idx] = (byte) 0; + } + + len = passw.length; + if (len > 14) { + len = 14; + } + for (idx = 7; idx < len; idx++) { + lmPw2[idx - 7] = passw[idx]; + } + for (; idx < 14; idx++) { + lmPw2[idx - 7] = (byte) 0; + } + + // Create LanManager hashed Password + byte[] magic = { + (byte) 0x4B, (byte) 0x47, (byte) 0x53, (byte) 0x21, + (byte) 0x40, (byte) 0x23, (byte) 0x24, (byte) 0x25 + }; + + byte[] lmHpw1; + lmHpw1 = encrypt(lmPw1, magic); + + byte[] lmHpw2 = encrypt(lmPw2, magic); + + byte[] lmHpw = new byte[21]; + for (int i = 0; i < lmHpw1.length; i++) { + lmHpw[i] = lmHpw1[i]; + } + for (int i = 0; i < lmHpw2.length; i++) { + lmHpw[i + 8] = lmHpw2[i]; + } + for (int i = 0; i < 5; i++) { + lmHpw[i + 16] = (byte) 0; + } + + // Create the responses. + byte[] lmResp = new byte[24]; + calcResp(lmHpw, nonce, lmResp); + + return lmResp; + } + + /** + * Takes a 21 byte array and treats it as 3 56-bit DES keys. The 8 byte + * plaintext is encrypted with each key and the resulting 24 bytes are + * stored in the results array. + * + * @param keys The keys. + * @param plaintext The plain text to encrypt. + * @param results Where the results are stored. + * @throws AuthenticationException If {@link #encrypt(byte[],byte[])} fails. + */ + private void calcResp(byte[] keys, byte[] plaintext, byte[] results) + throws AuthenticationException { + byte[] keys1 = new byte[7]; + byte[] keys2 = new byte[7]; + byte[] keys3 = new byte[7]; + for (int i = 0; i < 7; i++) { + keys1[i] = keys[i]; + } + + for (int i = 0; i < 7; i++) { + keys2[i] = keys[i + 7]; + } + + for (int i = 0; i < 7; i++) { + keys3[i] = keys[i + 14]; + } + byte[] results1 = encrypt(keys1, plaintext); + + byte[] results2 = encrypt(keys2, plaintext); + + byte[] results3 = encrypt(keys3, plaintext); + + for (int i = 0; i < 8; i++) { + results[i] = results1[i]; + } + for (int i = 0; i < 8; i++) { + results[i + 8] = results2[i]; + } + for (int i = 0; i < 8; i++) { + results[i + 16] = results3[i]; + } + } + + /** + * Converts a given number to a two byte array in little endian order. + * @param num the number to convert. + * @return The byte representation of num in little endian order. + */ + private byte[] convertShort(int num) { + byte[] val = new byte[2]; + String hex = Integer.toString(num, 16); + while (hex.length() < 4) { + hex = "0" + hex; + } + String low = hex.substring(2, 4); + String high = hex.substring(0, 2); + + val[0] = (byte) Integer.parseInt(low, 16); + val[1] = (byte) Integer.parseInt(high, 16); + return val; + } + + /** + * @return Returns the credentialCharset. + */ + public String getCredentialCharset() { + return credentialCharset; + } + + /** + * @param credentialCharset The credentialCharset to set. + */ + public void setCredentialCharset(String credentialCharset) { + this.credentialCharset = credentialCharset; + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLMScheme.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLMScheme.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLMScheme.java 22 Aug 2012 17:30:36 -0000 1.1 @@ -0,0 +1,354 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLMScheme.java,v 1.1 2012/08/22 17:30:36 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:36 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *ntlm
+ */
+ public String getSchemeName() {
+ return "ntlm";
+ }
+
+ /**
+ * The concept of an authentication realm is not supported by the NTLM
+ * authentication scheme. Always returns null
.
+ *
+ * @return null
+ */
+ public String getRealm() {
+ return null;
+ }
+
+ /**
+ * Returns a String identifying the authentication challenge. This is
+ * used, in combination with the host and port to determine if
+ * authorization has already been attempted or not. Schemes which
+ * require multiple requests to complete the authentication should
+ * return a different value for each stage in the request.
+ *
+ * Additionally, the ID should take into account any changes to the + * authentication challenge and return a different value when appropriate. + * For example when the realm changes in basic authentication it should be + * considered a different authentication attempt and a different value should + * be returned.
+ * + * @return String a String identifying the authentication challenge. The + * returned value may be null. + * + * @deprecated no longer used + */ + public String getID() { + return ntlmchallenge; + } + + /** + * Returns the authentication parameter with the given name, if available. + * + *There are no valid parameters for NTLM authentication so this method always returns + * null.
+ * + * @param name The name of the parameter to be returned + * + * @return the parameter with the given name + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + return null; + } + + /** + * Returns true. NTLM authentication scheme is connection based. + * + * @return true. + * + * @since 3.0 + */ + public boolean isConnectionBased() { + return true; + } + + /** + * Create a NTLM authorization string for the given + * challenge and NT credentials. + * + * @param challenge The challenge. + * @param credentials {@link NTCredentials} + * + * @return a ntlm authorization string + * @throws AuthenticationException is thrown if authentication fails + * + * @deprecated Use non-static {@link #authenticate(Credentials, HttpMethod)} + */ + public static String authenticate( + final NTCredentials credentials, final String challenge) + throws AuthenticationException { + + LOG.trace("enter NTLMScheme.authenticate(NTCredentials, String)"); + + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null"); + } + + NTLM ntlm = new NTLM(); + String s = ntlm.getResponseFor(challenge, + credentials.getUserName(), credentials.getPassword(), + credentials.getHost(), credentials.getDomain()); + return "NTLM " + s; + } + + /** + * Create a NTLM authorization string for the given + * challenge and NT credentials. + * + * @param challenge The challenge. + * @param credentials {@link NTCredentials} + * @param charset The charset to use for encoding the credentials + * + * @return a ntlm authorization string + * @throws AuthenticationException is thrown if authentication fails + * + * @deprecated Use non-static {@link #authenticate(Credentials, HttpMethod)} + * + * @since 3.0 + */ + public static String authenticate( + final NTCredentials credentials, + final String challenge, + String charset + ) throws AuthenticationException { + + LOG.trace("enter NTLMScheme.authenticate(NTCredentials, String)"); + + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null"); + } + + NTLM ntlm = new NTLM(); + ntlm.setCredentialCharset(charset); + String s = ntlm.getResponseFor( + challenge, + credentials.getUserName(), + credentials.getPassword(), + credentials.getHost(), + credentials.getDomain()); + return "NTLM " + s; + } + + /** + * Produces NTLM authorization string for the given set of + * {@link Credentials}. + * + * @param credentials The set of credentials to be used for athentication + * @param method Method name is ignored by the NTLM authentication scheme + * @param uri URI is ignored by the NTLM authentication scheme + * @throws InvalidCredentialsException if authentication credentials + * are not valid or not applicable for this authentication scheme + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return an NTLM authorization string + * + * @deprecated Use {@link #authenticate(Credentials, HttpMethod)} + */ + public String authenticate(Credentials credentials, String method, String uri) + throws AuthenticationException { + LOG.trace("enter NTLMScheme.authenticate(Credentials, String, String)"); + + NTCredentials ntcredentials = null; + try { + ntcredentials = (NTCredentials) credentials; + } catch (ClassCastException e) { + throw new InvalidCredentialsException( + "Credentials cannot be used for NTLM authentication: " + + credentials.getClass().getName()); + } + return NTLMScheme.authenticate(ntcredentials, this.ntlmchallenge); + } + + /** + * Produces NTLM authorization string for the given set of + * {@link Credentials}. + * + * @param credentials The set of credentials to be used for athentication + * @param method The method being authenticated + * + * @throws InvalidCredentialsException if authentication credentials + * are not valid or not applicable for this authentication scheme + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return an NTLM authorization string + * + * @since 3.0 + */ + public String authenticate( + Credentials credentials, + HttpMethod method + ) throws AuthenticationException { + LOG.trace("enter NTLMScheme.authenticate(Credentials, HttpMethod)"); + + if (this.state == UNINITIATED) { + throw new IllegalStateException("NTLM authentication process has not been initiated"); + } + + NTCredentials ntcredentials = null; + try { + ntcredentials = (NTCredentials) credentials; + } catch (ClassCastException e) { + throw new InvalidCredentialsException( + "Credentials cannot be used for NTLM authentication: " + + credentials.getClass().getName()); + } + NTLM ntlm = new NTLM(); + ntlm.setCredentialCharset(method.getParams().getCredentialCharset()); + String response = null; + if (this.state == INITIATED || this.state == FAILED) { + response = ntlm.getType1Message( + ntcredentials.getHost(), + ntcredentials.getDomain()); + this.state = TYPE1_MSG_GENERATED; + } else { + response = ntlm.getType3Message( + ntcredentials.getUserName(), + ntcredentials.getPassword(), + ntcredentials.getHost(), + ntcredentials.getDomain(), + ntlm.parseType2Message(this.ntlmchallenge)); + this.state = TYPE3_MSG_GENERATED; + } + return "NTLM " + response; + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/RFC2617Scheme.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/RFC2617Scheme.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/RFC2617Scheme.java 22 Aug 2012 17:30:35 -0000 1.1 @@ -0,0 +1,154 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/RFC2617Scheme.java,v 1.1 2012/08/22 17:30:35 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:35 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *+ * Abstract authentication scheme class that lays foundation for all + * RFC 2617 compliant authetication schemes and provides capabilities common + * to all authentication schemes defined in RFC 2617. + *
+ * + * @author Oleg Kalnichevski +*/ +public abstract class RFC2617Scheme implements AuthScheme { + + /** + * Authentication parameter map. + */ + private Map params = null; + + /** + * Default constructor for RFC2617 compliant authetication schemes. + * + * @since 3.0 + */ + public RFC2617Scheme() { + super(); + } + + /** + * Default constructor for RFC2617 compliant authetication schemes. + * + * @param challenge authentication challenge + * + * @throws MalformedChallengeException is thrown if the authentication challenge + * is malformed + * + * @deprecated Use parameterless constructor and {@link AuthScheme#processChallenge(String)} + * method + */ + public RFC2617Scheme(final String challenge) throws MalformedChallengeException { + super(); + processChallenge(challenge); + } + + /** + * Processes the given challenge token. Some authentication schemes + * may involve multiple challenge-response exchanges. Such schemes must be able + * to maintain the state information when dealing with sequential challenges + * + * @param challenge the challenge string + * + * @throws MalformedChallengeException is thrown if the authentication challenge + * is malformed + * + * @since 3.0 + */ + public void processChallenge(final String challenge) throws MalformedChallengeException { + String s = AuthChallengeParser.extractScheme(challenge); + if (!s.equalsIgnoreCase(getSchemeName())) { + throw new MalformedChallengeException( + "Invalid " + getSchemeName() + " challenge: " + challenge); + } + this.params = AuthChallengeParser.extractParams(challenge); + } + + /** + * Returns authentication parameters map. Keys in the map are lower-cased. + * + * @return the map of authentication parameters + */ + protected Map getParameters() { + return this.params; + } + + /** + * Returns authentication parameter with the given name, if available. + * + * @param name The name of the parameter to be returned + * + * @return the parameter with the given name + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + if (this.params == null) { + return null; + } + return (String) this.params.get(name.toLowerCase()); + } + + /** + * Returns authentication realm. The realm may not be null. + * + * @return the authentication realm + */ + public String getRealm() { + return getParameter("realm"); + } + + /** + * Returns a String identifying the authentication challenge. This is + * used, in combination with the host and port to determine if + * authorization has already been attempted or not. Schemes which + * require multiple requests to complete the authentication should + * return a different value for each stage in the request. + * + *Additionally, the ID should take into account any changes to the + * authentication challenge and return a different value when appropriate. + * For example when the realm changes in basic authentication it should be + * considered a different authentication attempt and a different value should + * be returned.
+ * + *This method simply returns the realm for the challenge.
+ * + * @return String a String identifying the authentication challenge. The + * returned value may be null. + * + * @deprecated no longer used + */ + public String getID() { + return getRealm(); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/package.html 22 Aug 2012 17:30:36 -0000 1.1 @@ -0,0 +1,11 @@ + + +RFC 2109 specification is used per default. Other supported specification + * can be chosen when appropriate or set default when desired + *
The following specifications are provided: + *
Supported versions: + *
Cookie management specification must define + *
This method will not perform the validation of the resultant + * {@link Cookie}s
+ * + * @see #validate(String, int, String, boolean, Cookie) + * + * @param host the host which sent the Set-Cookie header + * @param port the port which sent the Set-Cookie header + * @param path the path which sent the Set-Cookie header + * @param secure true when the Set-Cookie header + * was received over secure conection + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the Set-Cookie value + * @throws MalformedCookieException if an exception occurs during parsing + * @throws IllegalArgumentException if an input parameter is illegal + */ + Cookie[] parse(String host, int port, String path, boolean secure, + final String header) + throws MalformedCookieException, IllegalArgumentException; + + /** + * Parse the "Set-Cookie" Header into an array of Cookies. + * + *This method will not perform the validation of the resultant + * {@link Cookie}s
+ * + * @see #validate(String, int, String, boolean, Cookie) + * + * @param host the host which sent the Set-Cookie header + * @param port the port which sent the Set-Cookie header + * @param path the path which sent the Set-Cookie header + * @param secure true when the Set-Cookie header + * was received over secure conection + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the header + * @throws MalformedCookieException if an exception occurs during parsing + * @throws IllegalArgumentException if an input parameter is illegal + */ + Cookie[] parse(String host, int port, String path, boolean secure, + final Header header) + throws MalformedCookieException, IllegalArgumentException; + + /** + * Parse the cookie attribute and update the corresponsing Cookie + * properties. + * + * @param attribute cookie attribute from the Set-Cookie + * @param cookie the to be updated + * @throws MalformedCookieException if an exception occurs during parsing + * @throws IllegalArgumentException if an input parameter is illegal + */ + void parseAttribute(NameValuePair attribute, Cookie cookie) + throws MalformedCookieException, IllegalArgumentException; + + /** + * Validate the cookie according to validation rules defined by the + * cookie specification. + * + * @param host the host from which the {@link Cookie} was received + * @param port the port from which the {@link Cookie} was received + * @param path the path from which the {@link Cookie} was received + * @param secure true when the {@link Cookie} was received + * using a secure connection + * @param cookie the Cookie to validate + * @throws MalformedCookieException if the cookie is invalid + * @throws IllegalArgumentException if an input parameter is illegal + */ + void validate(String host, int port, String path, boolean secure, + final Cookie cookie) + throws MalformedCookieException, IllegalArgumentException; + + + /** + * Sets the {@link Collection} of date patterns used for parsing. The String patterns must be + * compatible with {@link java.text.SimpleDateFormat}. + * + * @param datepatterns collection of date patterns + */ + void setValidDateFormats(Collection datepatterns); + + /** + * Returns the {@link Collection} of date patterns used for parsing. The String patterns are compatible + * with the {@link java.text.SimpleDateFormat}. + * + * @return collection of date patterns + */ + Collection getValidDateFormats(); + + /** + * Determines if a Cookie matches a location. + * + * @param host the host to which the request is being submitted + * @param port the port to which the request is being submitted + * @param path the path to which the request is being submitted + * @param secure true if the request is using a secure connection + * @param cookie the Cookie to be matched + * + * @return true if the cookie should be submitted with a request + * with given attributes, false otherwise. + */ + boolean match(String host, int port, String path, boolean secure, + final Cookie cookie); + + /** + * Determines which of an array of Cookies matches a location. + * + * @param host the host to which the request is being submitted + * @param port the port to which the request is being submitted + * (currenlty ignored) + * @param path the path to which the request is being submitted + * @param secure true if the request is using a secure protocol + * @param cookies an array of Cookies to be matched + * + * @return true if the cookie should be submitted with a request + * with given attributes, false otherwise. + */ + Cookie[] match(String host, int port, String path, boolean secure, + final Cookie cookies[]); + + /** + * Performs domain-match as defined by the cookie specification. + * @param host The target host. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + * + * @since 3.0 + */ + boolean domainMatch(String host, String domain); + + /** + * Performs path-match as defined by the cookie specification. + * @param path The target path. + * @param topmostPath The cookie path attribute. + * @return true if the paths match + * + * @since 3.0 + */ + boolean pathMatch(String path, String topmostPath); + + /** + * Create a "Cookie" header value for an array of cookies. + * + * @param cookie the cookie to be formatted as string + * @return a string suitable for sending in a "Cookie" header. + */ + String formatCookie(Cookie cookie); + + /** + * Create a "Cookie" header value for an array of cookies. + * + * @param cookies the Cookies to be formatted + * @return a string suitable for sending in a Cookie header. + * @throws IllegalArgumentException if an input parameter is illegal + */ + String formatCookies(Cookie[] cookies) throws IllegalArgumentException; + + /** + * Create a "Cookie" Header for an array of Cookies. + * + * @param cookies the Cookies format into a Cookie header + * @return a Header for the given Cookies. + * @throws IllegalArgumentException if an input parameter is illegal + */ + Header formatCookieHeader(Cookie[] cookies) throws IllegalArgumentException; + + /** + * Create a "Cookie" Header for single Cookie. + * + * @param cookie the Cookie format as a Cookie header + * @return a Cookie header. + * @throws IllegalArgumentException if an input parameter is illegal + */ + Header formatCookieHeader(Cookie cookie) throws IllegalArgumentException; + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpecBase.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpecBase.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,658 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpecBase.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *The syntax for the Set-Cookie response header is: + * + *
+ * set-cookie = "Set-Cookie:" cookies + * cookies = 1#cookie + * cookie = NAME "=" VALUE * (";" cookie-av) + * NAME = attr + * VALUE = value + * cookie-av = "Comment" "=" value + * | "Domain" "=" value + * | "Max-Age" "=" value + * | "Path" "=" value + * | "Secure" + * | "Version" "=" 1*DIGIT + *+ * + * @param host the host from which the Set-Cookie value was + * received + * @param port the port from which the Set-Cookie value was + * received + * @param path the path from which the Set-Cookie value was + * received + * @param secure true when the Set-Cookie value was + * received over secure conection + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the Set-Cookie value + * @throws MalformedCookieException if an exception occurs during parsing + */ + public Cookie[] parse(String host, int port, String path, + boolean secure, final String header) + throws MalformedCookieException { + + LOG.trace("enter CookieSpecBase.parse(" + + "String, port, path, boolean, Header)"); + + if (host == null) { + throw new IllegalArgumentException( + "Host of origin may not be null"); + } + if (host.trim().equals("")) { + throw new IllegalArgumentException( + "Host of origin may not be blank"); + } + if (port < 0) { + throw new IllegalArgumentException("Invalid port: " + port); + } + if (path == null) { + throw new IllegalArgumentException( + "Path of origin may not be null."); + } + if (header == null) { + throw new IllegalArgumentException("Header may not be null."); + } + + if (path.trim().equals("")) { + path = PATH_DELIM; + } + host = host.toLowerCase(); + + String defaultPath = path; + int lastSlashIndex = defaultPath.lastIndexOf(PATH_DELIM); + if (lastSlashIndex >= 0) { + if (lastSlashIndex == 0) { + //Do not remove the very first slash + lastSlashIndex = 1; + } + 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 { + DateUtil.parseDate(header.substring(i1, i2), this.datepatterns); + 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]; + + for (int i = 0; i < headerElements.length; i++) { + + HeaderElement headerelement = headerElements[i]; + Cookie cookie = null; + try { + cookie = new Cookie(host, + headerelement.getName(), + headerelement.getValue(), + defaultPath, + null, + false); + } catch (IllegalArgumentException e) { + throw new MalformedCookieException(e.getMessage()); + } + // cycle through the parameters + NameValuePair[] parameters = headerelement.getParameters(); + // could be null. In case only a header element and no parameters. + if (parameters != null) { + + for (int j = 0; j < parameters.length; j++) { + parseAttribute(parameters[j], cookie); + } + } + cookies[i] = cookie; + } + return cookies; + } + + + /** + * Parse the "Set-Cookie" {@link Header} into an array of {@link + * Cookie}s. + * + *
The syntax for the Set-Cookie response header is: + * + *
+ * set-cookie = "Set-Cookie:" cookies + * cookies = 1#cookie + * cookie = NAME "=" VALUE * (";" cookie-av) + * NAME = attr + * VALUE = value + * cookie-av = "Comment" "=" value + * | "Domain" "=" value + * | "Max-Age" "=" value + * | "Path" "=" value + * | "Secure" + * | "Version" "=" 1*DIGIT + *+ * + * @param host the host from which the Set-Cookie header was + * received + * @param port the port from which the Set-Cookie header was + * received + * @param path the path from which the Set-Cookie header was + * received + * @param secure true when the Set-Cookie header was + * received over secure conection + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the "Set-Cookie" + * header + * @throws MalformedCookieException if an exception occurs during parsing + */ + public Cookie[] parse( + String host, int port, String path, boolean secure, final Header header) + throws MalformedCookieException { + + LOG.trace("enter CookieSpecBase.parse(" + + "String, port, path, boolean, String)"); + if (header == null) { + throw new IllegalArgumentException("Header may not be null."); + } + return parse(host, port, path, secure, header.getValue()); + } + + + /** + * Parse the cookie attribute and update the corresponsing {@link Cookie} + * properties. + * + * @param attribute {@link HeaderElement} cookie attribute from the + * Set- Cookie + * @param cookie {@link Cookie} to be updated + * @throws MalformedCookieException if an exception occurs during parsing + */ + + public void parseAttribute( + final NameValuePair attribute, final Cookie cookie) + throws MalformedCookieException { + + if (attribute == null) { + throw new IllegalArgumentException("Attribute may not be null."); + } + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null."); + } + final String paramName = attribute.getName().toLowerCase(); + String paramValue = attribute.getValue(); + + if (paramName.equals("path")) { + + if ((paramValue == null) || (paramValue.trim().equals(""))) { + paramValue = "/"; + } + cookie.setPath(paramValue); + cookie.setPathAttributeSpecified(true); + + } else if (paramName.equals("domain")) { + + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for domain attribute"); + } + if (paramValue.trim().equals("")) { + throw new MalformedCookieException( + "Blank value for domain attribute"); + } + cookie.setDomain(paramValue); + cookie.setDomainAttributeSpecified(true); + + } else if (paramName.equals("max-age")) { + + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for max-age attribute"); + } + int age; + try { + age = Integer.parseInt(paramValue); + } catch (NumberFormatException e) { + throw new MalformedCookieException ("Invalid max-age " + + "attribute: " + e.getMessage()); + } + cookie.setExpiryDate( + new Date(System.currentTimeMillis() + age * 1000L)); + + } else if (paramName.equals("secure")) { + + cookie.setSecure(true); + + } else if (paramName.equals("comment")) { + + cookie.setComment(paramValue); + + } else if (paramName.equals("expires")) { + + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for expires attribute"); + } + + try { + cookie.setExpiryDate(DateUtil.parseDate(paramValue, this.datepatterns)); + } catch (DateParseException dpe) { + LOG.debug("Error parsing cookie date", dpe); + throw new MalformedCookieException( + "Unable to parse expiration date parameter: " + + paramValue); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("Unrecognized cookie attribute: " + + attribute.toString()); + } + } + } + + + public Collection getValidDateFormats() { + return this.datepatterns; + } + + public void setValidDateFormats(final Collection datepatterns) { + this.datepatterns = datepatterns; + } + + /** + * Performs most common {@link Cookie} validation + * + * @param host the host from which the {@link Cookie} was received + * @param port the port from which the {@link Cookie} was received + * @param path the path from which the {@link Cookie} was received + * @param secure true when the {@link Cookie} was received using a + * secure connection + * @param cookie The cookie to validate. + * @throws MalformedCookieException if an exception occurs during + * validation + */ + + public void validate(String host, int port, String path, + boolean secure, final Cookie cookie) + throws MalformedCookieException { + + LOG.trace("enter CookieSpecBase.validate(" + + "String, port, path, boolean, Cookie)"); + if (host == null) { + throw new IllegalArgumentException( + "Host of origin may not be null"); + } + if (host.trim().equals("")) { + throw new IllegalArgumentException( + "Host of origin may not be blank"); + } + if (port < 0) { + throw new IllegalArgumentException("Invalid port: " + port); + } + if (path == null) { + throw new IllegalArgumentException( + "Path of origin may not be null."); + } + if (path.trim().equals("")) { + path = PATH_DELIM; + } + host = host.toLowerCase(); + // check version + if (cookie.getVersion() < 0) { + throw new MalformedCookieException ("Illegal version number " + + cookie.getValue()); + } + + // security check... we musn't allow the server to give us an + // invalid domain scope + + // Validate the cookies domain attribute. NOTE: Domains without + // any dots are allowed to support hosts on private LANs that don't + // have DNS names. Since they have no dots, to domain-match the + // request-host and domain must be identical for the cookie to sent + // back to the origin-server. + if (host.indexOf(".") >= 0) { + // Not required to have at least two dots. RFC 2965. + // A Set-Cookie2 with Domain=ajax.com will be accepted. + + // domain must match host + if (!host.endsWith(cookie.getDomain())) { + String s = cookie.getDomain(); + if (s.startsWith(".")) { + s = s.substring(1, s.length()); + } + if (!host.equals(s)) { + throw new MalformedCookieException( + "Illegal domain attribute \"" + cookie.getDomain() + + "\". Domain of origin: \"" + host + "\""); + } + } + } else { + if (!host.equals(cookie.getDomain())) { + throw new MalformedCookieException( + "Illegal domain attribute \"" + cookie.getDomain() + + "\". Domain of origin: \"" + host + "\""); + } + } + + // another security check... we musn't allow the server to give us a + // cookie that doesn't match this path + + if (!path.startsWith(cookie.getPath())) { + throw new MalformedCookieException( + "Illegal path attribute \"" + cookie.getPath() + + "\". Path of origin: \"" + path + "\""); + } + } + + + /** + * Return true if the cookie should be submitted with a request + * with given attributes, false otherwise. + * @param host the host to which the request is being submitted + * @param port the port to which the request is being submitted (ignored) + * @param path the path to which the request is being submitted + * @param secure true if the request is using a secure connection + * @param cookie {@link Cookie} to be matched + * @return true if the cookie matches the criterium + */ + + public boolean match(String host, int port, String path, + boolean secure, final Cookie cookie) { + + LOG.trace("enter CookieSpecBase.match(" + + "String, int, String, boolean, Cookie"); + + if (host == null) { + throw new IllegalArgumentException( + "Host of origin may not be null"); + } + if (host.trim().equals("")) { + throw new IllegalArgumentException( + "Host of origin may not be blank"); + } + if (port < 0) { + throw new IllegalArgumentException("Invalid port: " + port); + } + if (path == null) { + throw new IllegalArgumentException( + "Path of origin may not be null."); + } + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (path.trim().equals("")) { + path = PATH_DELIM; + } + host = host.toLowerCase(); + if (cookie.getDomain() == null) { + LOG.warn("Invalid cookie state: domain not specified"); + return false; + } + if (cookie.getPath() == null) { + LOG.warn("Invalid cookie state: path not specified"); + return false; + } + + return + // only add the cookie if it hasn't yet expired + (cookie.getExpiryDate() == null + || cookie.getExpiryDate().after(new Date())) + // and the domain pattern matches + && (domainMatch(host, cookie.getDomain())) + // and the path is null or matching + && (pathMatch(path, cookie.getPath())) + // and if the secure flag is set, only if the request is + // actually secure + && (cookie.getSecure() ? secure : true); + } + + /** + * Performs domain-match as implemented in common browsers. + * @param host The target host. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + */ + public boolean domainMatch(final String host, String domain) { + if (host.equals(domain)) { + return true; + } + if (!domain.startsWith(".")) { + domain = "." + domain; + } + return host.endsWith(domain) || host.equals(domain.substring(1)); + } + + /** + * Performs path-match as implemented in common browsers. + * @param path The target path. + * @param topmostPath The cookie path attribute. + * @return true if the paths match + */ + public boolean pathMatch(final String path, final String topmostPath) { + boolean match = path.startsWith (topmostPath); + // if there is a match and these values are not exactly the same we have + // to make sure we're not matcing "/foobar" and "/foo" + if (match && path.length() != topmostPath.length()) { + if (!topmostPath.endsWith(PATH_DELIM)) { + match = (path.charAt(topmostPath.length()) == PATH_DELIM_CHAR); + } + } + return match; + } + + /** + * Return an array of {@link Cookie}s that should be submitted with a + * request with given attributes, false otherwise. + * @param host the host to which the request is being submitted + * @param port the port to which the request is being submitted (currently + * ignored) + * @param path the path to which the request is being submitted + * @param secure true if the request is using a secure protocol + * @param cookies an array of Cookies to be matched + * @return an array of Cookies matching the criterium + */ + + public Cookie[] match(String host, int port, String path, + boolean secure, final Cookie cookies[]) { + + LOG.trace("enter CookieSpecBase.match(" + + "String, int, String, boolean, Cookie[])"); + + if (cookies == null) { + return null; + } + List matching = new LinkedList(); + for (int i = 0; i < cookies.length; i++) { + if (match(host, port, path, secure, cookies[i])) { + addInPathOrder(matching, cookies[i]); + } + } + return (Cookie[]) matching.toArray(new Cookie[matching.size()]); + } + + + /** + * Adds the given cookie into the given list in descending path order. That + * is, more specific path to least specific paths. This may not be the + * fastest algorythm, but it'll work OK for the small number of cookies + * we're generally dealing with. + * + * @param list - the list to add the cookie to + * @param addCookie - the Cookie to add to list + */ + private static void addInPathOrder(List list, Cookie addCookie) { + int i = 0; + + for (i = 0; i < list.size(); i++) { + Cookie c = (Cookie) list.get(i); + if (addCookie.compare(addCookie, c) > 0) { + break; + } + } + list.add(i, addCookie); + } + + /** + * Return a string suitable for sending in a "Cookie" header + * @param cookie a {@link Cookie} to be formatted as string + * @return a string suitable for sending in a "Cookie" header. + */ + public String formatCookie(Cookie cookie) { + LOG.trace("enter CookieSpecBase.formatCookie(Cookie)"); + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + StringBuffer buf = new StringBuffer(); + buf.append(cookie.getName()); + buf.append("="); + String s = cookie.getValue(); + if (s != null) { + buf.append(s); + } + return buf.toString(); + } + + /** + * Create a "Cookie" header value containing all {@link Cookie}s in + * cookies suitable for sending in a "Cookie" header + * @param cookies an array of {@link Cookie}s to be formatted + * @return a string suitable for sending in a Cookie header. + * @throws IllegalArgumentException if an input parameter is illegal + */ + + public String formatCookies(Cookie[] cookies) + throws IllegalArgumentException { + LOG.trace("enter CookieSpecBase.formatCookies(Cookie[])"); + if (cookies == null) { + throw new IllegalArgumentException("Cookie array may not be null"); + } + if (cookies.length == 0) { + throw new IllegalArgumentException("Cookie array may not be empty"); + } + + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < cookies.length; i++) { + if (i > 0) { + buffer.append("; "); + } + buffer.append(formatCookie(cookies[i])); + } + return buffer.toString(); + } + + + /** + * Create a "Cookie" {@link Header} containing all {@link Cookie}s + * in cookies. + * @param cookies an array of {@link Cookie}s to be formatted as a " + * Cookie" header + * @return a "Cookie" {@link Header}. + */ + public Header formatCookieHeader(Cookie[] cookies) { + LOG.trace("enter CookieSpecBase.formatCookieHeader(Cookie[])"); + return new Header("Cookie", formatCookies(cookies)); + } + + + /** + * Create a "Cookie" {@link Header} containing the {@link Cookie}. + * @param cookie Cookies to be formatted as a Cookie + * header + * @return a Cookie header. + */ + public Header formatCookieHeader(Cookie cookie) { + LOG.trace("enter CookieSpecBase.formatCookieHeader(Cookie)"); + return new Header("Cookie", formatCookie(cookie)); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/IgnoreCookiesSpec.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/IgnoreCookiesSpec.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/IgnoreCookiesSpec.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,152 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/IgnoreCookiesSpec.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *
null
+ */
+ public Collection getValidDateFormats() {
+ return null;
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void setValidDateFormats(Collection datepatterns) {
+ }
+
+ /**
+ * @return null
+ */
+ public String formatCookie(Cookie cookie) {
+ return null;
+ }
+
+ /**
+ * @return null
+ */
+ public Header formatCookieHeader(Cookie cookie) throws IllegalArgumentException {
+ return null;
+ }
+
+ /**
+ * @return null
+ */
+ public Header formatCookieHeader(Cookie[] cookies) throws IllegalArgumentException {
+ return null;
+ }
+
+ /**
+ * @return null
+ */
+ public String formatCookies(Cookie[] cookies) throws IllegalArgumentException {
+ return null;
+ }
+
+ /**
+ * @return false
+ */
+ public boolean match(String host, int port, String path, boolean secure, Cookie cookie) {
+ return false;
+ }
+
+ /**
+ * Returns an empty {@link Cookie cookie} array. All parameters are ignored.
+ */
+ public Cookie[] match(String host, int port, String path, boolean secure, Cookie[] cookies) {
+ return new Cookie[0];
+ }
+
+ /**
+ * Returns an empty {@link Cookie cookie} array. All parameters are ignored.
+ */
+ public Cookie[] parse(String host, int port, String path, boolean secure, Header header)
+ throws MalformedCookieException, IllegalArgumentException {
+ return new Cookie[0];
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void parseAttribute(NameValuePair attribute, Cookie cookie)
+ throws MalformedCookieException, IllegalArgumentException {
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void validate(String host, int port, String path, boolean secure, Cookie cookie)
+ throws MalformedCookieException, IllegalArgumentException {
+ }
+
+ /**
+ * @return false
+ */
+ public boolean domainMatch(final String host, final String domain) {
+ return false;
+ }
+
+ /**
+ * @return false
+ */
+ public boolean pathMatch(final String path, final String topmostPath) {
+ return false;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/MalformedCookieException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/MalformedCookieException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/MalformedCookieException.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,72 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/MalformedCookieException.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * Netscape cookie draft specific cookie management functions + * + * @author B.C. Holmes + * @author Park, Sung-Gu + * @author Doug Sale + * @author Rod Waldhoff + * @author dIon Gillard + * @author Sean C. Sullivan + * @author John Evans + * @author Marc A. Saegesser + * @author Oleg Kalnichevski + * @author Mike Bowler + * + * @since 2.0 + */ + +public class NetscapeDraftSpec extends CookieSpecBase { + + /** Default constructor */ + public NetscapeDraftSpec() { + super(); + } + + /** + * Parses the Set-Cookie value into an array of Cookies. + * + *
Syntax of the Set-Cookie HTTP Response Header:
+ * + *This is the format a CGI script would use to add to + * the HTTP headers a new piece of data which is to be stored by + * the client for later retrieval.
+ * + *+ * Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure + *+ * + *
Please note that Netscape draft specification does not fully + * conform to the HTTP header format. Netscape draft does not specify + * whether multiple cookies may be sent in one header. Hence, comma + * character may be present in unquoted cookie value or unquoted + * parameter value.
+ * + * @link http://wp.netscape.com/newsref/std/cookie_spec.html + * + * @param host the host from which the Set-Cookie value was + * received + * @param port the port from which the Set-Cookie value was + * received + * @param path the path from which the Set-Cookie value was + * received + * @param secure true when the Set-Cookie value was + * received over secure conection + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the Set-Cookie value + * @throws MalformedCookieException if an exception occurs during parsing + * + * @since 3.0 + */ + public Cookie[] parse(String host, int port, String path, + boolean secure, final String header) + throws MalformedCookieException { + + LOG.trace("enter NetscapeDraftSpec.parse(String, port, path, boolean, Header)"); + + if (host == null) { + throw new IllegalArgumentException("Host of origin may not be null"); + } + if (host.trim().equals("")) { + throw new IllegalArgumentException("Host of origin may not be blank"); + } + if (port < 0) { + throw new IllegalArgumentException("Invalid port: " + port); + } + if (path == null) { + throw new IllegalArgumentException("Path of origin may not be null."); + } + if (header == null) { + throw new IllegalArgumentException("Header may not be null."); + } + + if (path.trim().equals("")) { + path = PATH_DELIM; + } + host = host.toLowerCase(); + + String defaultPath = path; + int lastSlashIndex = defaultPath.lastIndexOf(PATH_DELIM); + if (lastSlashIndex >= 0) { + if (lastSlashIndex == 0) { + //Do not remove the very first slash + lastSlashIndex = 1; + } + defaultPath = defaultPath.substring(0, lastSlashIndex); + } + HeaderElement headerelement = new HeaderElement(header.toCharArray()); + Cookie cookie = new Cookie(host, + headerelement.getName(), + headerelement.getValue(), + defaultPath, + null, + false); + // cycle through the parameters + NameValuePair[] parameters = headerelement.getParameters(); + // could be null. In case only a header element and no parameters. + if (parameters != null) { + for (int j = 0; j < parameters.length; j++) { + parseAttribute(parameters[j], cookie); + } + } + return new Cookie[] {cookie}; + } + + + /** + * Parse the cookie attribute and update the corresponsing {@link Cookie} + * properties as defined by the Netscape draft specification + * + * @param attribute {@link NameValuePair} cookie attribute from the + * Set- Cookie + * @param cookie {@link Cookie} to be updated + * @throws MalformedCookieException if an exception occurs during parsing + */ + public void parseAttribute( + final NameValuePair attribute, final Cookie cookie) + throws MalformedCookieException { + + if (attribute == null) { + throw new IllegalArgumentException("Attribute may not be null."); + } + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null."); + } + final String paramName = attribute.getName().toLowerCase(); + final String paramValue = attribute.getValue(); + + if (paramName.equals("expires")) { + + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for expires attribute"); + } + try { + DateFormat expiryFormat = new SimpleDateFormat( + "EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US); + Date date = expiryFormat.parse(paramValue); + cookie.setExpiryDate(date); + } catch (ParseException e) { + throw new MalformedCookieException("Invalid expires " + + "attribute: " + e.getMessage()); + } + } else { + super.parseAttribute(attribute, cookie); + } + } + + /** + * Performs domain-match as described in the Netscape draft. + * @param host The target host. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + */ + public boolean domainMatch(final String host, final String domain) { + return host.endsWith(domain); + } + + /** + * Performs Netscape draft compliant {@link Cookie} validation + * + * @param host the host from which the {@link Cookie} was received + * @param port the port from which the {@link Cookie} was received + * @param path the path from which the {@link Cookie} was received + * @param secure true when the {@link Cookie} was received + * using a secure connection + * @param cookie The cookie to validate. + * @throws MalformedCookieException if an exception occurs during + * validation + */ + public void validate(String host, int port, String path, + boolean secure, final Cookie cookie) + throws MalformedCookieException { + + LOG.trace("enterNetscapeDraftCookieProcessor " + + "RCF2109CookieProcessor.validate(Cookie)"); + // Perform generic validation + super.validate(host, port, path, secure, cookie); + // Perform Netscape Cookie draft specific validation + if (host.indexOf(".") >= 0) { + int domainParts = new StringTokenizer(cookie.getDomain(), ".") + .countTokens(); + + if (isSpecialDomain(cookie.getDomain())) { + if (domainParts < 2) { + throw new MalformedCookieException("Domain attribute \"" + + cookie.getDomain() + + "\" violates the Netscape cookie specification for " + + "special domains"); + } + } else { + if (domainParts < 3) { + throw new MalformedCookieException("Domain attribute \"" + + cookie.getDomain() + + "\" violates the Netscape cookie specification"); + } + } + } + } + + /** + * Checks if the given domain is in one of the seven special + * top level domains defined by the Netscape cookie specification. + * @param domain The domain. + * @return True if the specified domain is "special" + */ + private static boolean isSpecialDomain(final String domain) { + final String ucDomain = domain.toUpperCase(); + if (ucDomain.endsWith(".COM") + || ucDomain.endsWith(".EDU") + || ucDomain.endsWith(".NET") + || ucDomain.endsWith(".GOV") + || ucDomain.endsWith(".MIL") + || ucDomain.endsWith(".ORG") + || ucDomain.endsWith(".INT")) { + return true; + } + return false; + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2109Spec.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2109Spec.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2109Spec.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,285 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2109Spec.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *RFC 2109 specific cookie management functions + * + * @author B.C. Holmes + * @author Park, Sung-Gu + * @author Doug Sale + * @author Rod Waldhoff + * @author dIon Gillard + * @author Sean C. Sullivan + * @author John Evans + * @author Marc A. Saegesser + * @author Oleg Kalnichevski + * @author Mike Bowler + * + * @since 2.0 + */ + +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. + * + * @param attribute {@link NameValuePair} cookie attribute from the + * Set- Cookie + * @param cookie {@link Cookie} to be updated + * @throws MalformedCookieException if an exception occurs during parsing + */ + public void parseAttribute( + final NameValuePair attribute, final Cookie cookie) + throws MalformedCookieException { + + if (attribute == null) { + throw new IllegalArgumentException("Attribute may not be null."); + } + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null."); + } + final String paramName = attribute.getName().toLowerCase(); + final String paramValue = attribute.getValue(); + + if (paramName.equals("path")) { + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for path attribute"); + } + if (paramValue.trim().equals("")) { + throw new MalformedCookieException( + "Blank value for path attribute"); + } + cookie.setPath(paramValue); + cookie.setPathAttributeSpecified(true); + } else if (paramName.equals("version")) { + + if (paramValue == null) { + throw new MalformedCookieException( + "Missing value for version attribute"); + } + try { + cookie.setVersion(Integer.parseInt(paramValue)); + } catch (NumberFormatException e) { + throw new MalformedCookieException("Invalid version: " + + e.getMessage()); + } + + } else { + super.parseAttribute(attribute, cookie); + } + } + + /** + * Performs RFC 2109 compliant {@link Cookie} validation + * + * @param host the host from which the {@link Cookie} was received + * @param port the port from which the {@link Cookie} was received + * @param path the path from which the {@link Cookie} was received + * @param secure true when the {@link Cookie} was received using a + * secure connection + * @param cookie The cookie to validate + * @throws MalformedCookieException if an exception occurs during + * validation + */ + public void validate(String host, int port, String path, + boolean secure, final Cookie cookie) throws MalformedCookieException { + + LOG.trace("enter RFC2109Spec.validate(String, int, String, " + + "boolean, Cookie)"); + + // Perform generic validation + super.validate(host, port, path, secure, cookie); + // Perform RFC 2109 specific validation + + if (cookie.getName().indexOf(' ') != -1) { + throw new MalformedCookieException("Cookie name may not contain blanks"); + } + if (cookie.getName().startsWith("$")) { + throw new MalformedCookieException("Cookie name may not start with $"); + } + + if (cookie.isDomainAttributeSpecified() + && (!cookie.getDomain().equals(host))) { + + // domain must start with dot + if (!cookie.getDomain().startsWith(".")) { + throw new MalformedCookieException("Domain attribute \"" + + cookie.getDomain() + + "\" violates RFC 2109: domain must start with a dot"); + } + // domain must have at least one embedded dot + int dotIndex = cookie.getDomain().indexOf('.', 1); + if (dotIndex < 0 || dotIndex == cookie.getDomain().length() - 1) { + throw new MalformedCookieException("Domain attribute \"" + + cookie.getDomain() + + "\" violates RFC 2109: domain must contain an embedded dot"); + } + host = host.toLowerCase(); + if (!host.endsWith(cookie.getDomain())) { + throw new MalformedCookieException( + "Illegal domain attribute \"" + cookie.getDomain() + + "\". Domain of origin: \"" + host + "\""); + } + // host minus domain may not contain any dots + String hostWithoutDomain = host.substring(0, host.length() + - cookie.getDomain().length()); + if (hostWithoutDomain.indexOf('.') != -1) { + throw new MalformedCookieException("Domain attribute \"" + + cookie.getDomain() + + "\" violates RFC 2109: host minus domain may not contain any dots"); + } + } + } + + /** + * Performs domain-match as defined by the RFC2109. + * @param host The target host. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + * + * @since 3.0 + */ + public boolean domainMatch(String host, String domain) { + boolean match = host.equals(domain) + || (domain.startsWith(".") && host.endsWith(domain)); + + return match; + } + + /** + * Return a name/value string suitable for sending in a "Cookie" + * header as defined in RFC 2109 for backward compatibility with cookie + * version 0 + * @param buffer The string buffer to use for output + * @param param The parameter. + * @param version The cookie version + */ + private void formatParam(final StringBuffer buffer, final NameValuePair param, int version) { + if (version < 1) { + buffer.append(param.getName()); + buffer.append("="); + if (param.getValue() != null) { + buffer.append(param.getValue()); + } + } else { + this.formatter.format(buffer, param); + } + } + + /** + * Return a string suitable for sending in a "Cookie" header + * as defined in RFC 2109 for backward compatibility with cookie version 0 + * @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. + */ + 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.getPath() != null) && cookie.isPathAttributeSpecified()) { + buffer.append("; "); + formatParam(buffer, new NameValuePair("$Path", cookie.getPath()), version); + } + if ((cookie.getDomain() != null) + && cookie.isDomainAttributeSpecified()) { + buffer.append("; "); + formatParam(buffer, new NameValuePair("$Domain", cookie.getDomain()), version); + } + } + + /** + * Return a string suitable for sending in a "Cookie" header as + * defined in RFC 2109 + * @param cookie a {@link Cookie} to be formatted as string + * @return a string suitable for sending in a "Cookie" header. + */ + public String formatCookie(Cookie cookie) { + LOG.trace("enter RFC2109Spec.formatCookie(Cookie)"); + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + int version = cookie.getVersion(); + StringBuffer buffer = new StringBuffer(); + formatParam(buffer, + new NameValuePair("$Version", Integer.toString(version)), + version); + buffer.append("; "); + formatCookieAsVer(buffer, cookie, version); + return buffer.toString(); + } + + /** + * Create a RFC 2109 compliant "Cookie" header value containing all + * {@link Cookie}s in cookies suitable for sending in a "Cookie" + * header + * @param cookies an array of {@link Cookie}s to be formatted + * @return a string suitable for sending in a Cookie header. + */ + public String formatCookies(Cookie[] cookies) { + LOG.trace("enter RFC2109Spec.formatCookieHeader(Cookie[])"); + int version = Integer.MAX_VALUE; + // Pick the lowerest common denominator + for (int i = 0; i < cookies.length; i++) { + Cookie cookie = cookies[i]; + if (cookie.getVersion() < version) { + version = cookie.getVersion(); + } + } + final StringBuffer buffer = new StringBuffer(); + formatParam(buffer, + new NameValuePair("$Version", Integer.toString(version)), + version); + for (int i = 0; i < cookies.length; i++) { + buffer.append("; "); + formatCookieAsVer(buffer, cookies[i], version); + } + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/package.html 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,11 @@ + + +
+null
.
+ */
+ public ByteArrayRequestEntity(byte[] content, String contentType) {
+ super();
+ if (content == null) {
+ throw new IllegalArgumentException("The content cannot be null");
+ }
+ this.content = content;
+ this.contentType = contentType;
+ }
+
+ /**
+ * @return true
+ */
+ public boolean isRepeatable() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType()
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream)
+ */
+ public void writeRequest(OutputStream out) throws IOException {
+ out.write(content);
+ }
+
+ /**
+ * @return The length of the content.
+ */
+ public long getContentLength() {
+ return content.length;
+ }
+
+ /**
+ * @return Returns the content.
+ */
+ public byte[] getContent() {
+ return content;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/DeleteMethod.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/DeleteMethod.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/DeleteMethod.java 22 Aug 2012 17:30:37 -0000 1.1
@@ -0,0 +1,95 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/DeleteMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:37 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * The HTTP DELETE method is defined in section 9.7 of + * RFC2616: + *
+ * The DELETE method requests that the origin server delete the resource + * identified by the Request-URI. This method MAY be overridden by human + * intervention (or other means) on the origin server. + *+ * + * + * @author Remy Maucherat + * @author B.C. Holmes + * @author Jeff Dever + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class DeleteMethod + extends HttpMethodBase { + + + // ----------------------------------------------------------- Constructors + + + /** + * No-arg constructor. + * + * @since 1.0 + */ + public DeleteMethod() { + } + + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 1.0 + */ + public DeleteMethod(String uri) { + super(uri); + } + + + // ----------------------------------------------------- HttpMethod Methods + + /** + * Returns "DELETE". + * @return "DELETE" + * + * @since 2.0 + */ + public String getName() { + return "DELETE"; + } + + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java 22 Aug 2012 17:30:36 -0000 1.1 @@ -0,0 +1,547 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java,v 1.1 2012/08/22 17:30:36 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:36 $ + * + * ==================================================================== + * + * Copyright 2003-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 + *
requestBodyStream
or one of
+ * CONTENT_LENGTH_AUTO
and CONTENT_LENGTH_CHUNKED
.
+ *
+ * @deprecated
+ */
+ private long requestContentLength = InputStreamRequestEntity.CONTENT_LENGTH_AUTO;
+
+ private boolean chunked = false;
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * No-arg constructor.
+ *
+ * @since 2.0
+ */
+ public EntityEnclosingMethod() {
+ super();
+ setFollowRedirects(false);
+ }
+
+ /**
+ * Constructor specifying a URI.
+ *
+ * @param uri either an absolute or relative URI
+ *
+ * @since 2.0
+ */
+ public EntityEnclosingMethod(String uri) {
+ super(uri);
+ setFollowRedirects(false);
+ }
+
+ /**
+ * Returns true if there is a request body to be sent.
+ *
+ * This method must be overridden by sub-classes that implement + * alternative request content input methods + *
+ * + * @return boolean + * + * @since 2.0beta1 + */ + protected boolean hasRequestContent() { + LOG.trace("enter EntityEnclosingMethod.hasRequestContent()"); + return (this.requestEntity != null) + || (this.requestStream != null) + || (this.requestString != null); + } + + /** + * Clears the request body. + * + *This method must be overridden by sub-classes that implement + * alternative request content input methods.
+ * + * @since 2.0beta1 + */ + protected void clearRequestBody() { + LOG.trace("enter EntityEnclosingMethod.clearRequestBody()"); + this.requestStream = null; + this.requestString = null; + this.requestEntity = null; + } + + /** + * Generates the request body. + * + *This method must be overridden by sub-classes that implement + * alternative request content input methods.
+ * + * @return request body as an array of bytes. If the request content + * has not been set, returns null. + * + * @since 2.0beta1 + */ + protected byte[] generateRequestBody() { + LOG.trace("enter EntityEnclosingMethod.renerateRequestBody()"); + return null; + } + + protected RequestEntity generateRequestEntity() { + + byte[] requestBody = generateRequestBody(); + if (requestBody != null) { + // use the request body, if it exists. + // this is just for backwards compatability + this.requestEntity = new ByteArrayRequestEntity(requestBody); + } else if (this.requestStream != null) { + this.requestEntity = new InputStreamRequestEntity( + requestStream, + requestContentLength); + this.requestStream = null; + } else if (this.requestString != null) { + String charset = getRequestCharSet(); + try { + this.requestEntity = new StringRequestEntity( + requestString, null, charset); + } catch (UnsupportedEncodingException e) { + if (LOG.isWarnEnabled()) { + LOG.warn(charset + " not supported"); + } + this.requestEntity = new StringRequestEntity( + requestString); + } + } + + return this.requestEntity; + } + + /** + * Entity enclosing requests cannot be redirected without user intervention + * according to RFC 2616. + * + * @returnfalse
.
+ *
+ * @since 2.0
+ */
+ public boolean getFollowRedirects() {
+ return false;
+ }
+
+
+ /**
+ * Entity enclosing requests cannot be redirected without user intervention
+ * according to RFC 2616.
+ *
+ * @param followRedirects must always be false
+ */
+ public void setFollowRedirects(boolean followRedirects) {
+ if (followRedirects == true) {
+ throw new IllegalArgumentException("Entity enclosing requests cannot be redirected without user intervention");
+ }
+ super.setFollowRedirects(false);
+ }
+
+ /**
+ * Sets length information about the request body.
+ *
+ * + * Note: If you specify a content length the request is unbuffered. This + * prevents redirection and automatic retry if a request fails the first + * time. This means that the HttpClient can not perform authorization + * automatically but will throw an Exception. You will have to set the + * necessary 'Authorization' or 'Proxy-Authorization' headers manually. + *
+ * + * @param length size in bytes or any of CONTENT_LENGTH_AUTO, + * CONTENT_LENGTH_CHUNKED. If number of bytes or CONTENT_LENGTH_CHUNKED + * is specified the content will not be buffered internally and the + * Content-Length header of the request will be used. In this case + * the user is responsible to supply the correct content length. + * If CONTENT_LENGTH_AUTO is specified the request will be buffered + * before it is sent over the network. + * + * @deprecated Use {@link #setContentChunked(boolean)} or + * {@link #setRequestEntity(RequestEntity)} + */ + public void setRequestContentLength(int length) { + LOG.trace("enter EntityEnclosingMethod.setRequestContentLength(int)"); + this.requestContentLength = length; + } + + /** + * Returns the request's charset. The charset is parsed from the request entity's + * content type, unless the content type header has been set manually. + * + * @see RequestEntity#getContentType() + * + * @since 3.0 + */ + public String getRequestCharSet() { + if (getRequestHeader("Content-Type") == null) { + // check the content type from request entity + // We can't call getRequestEntity() since it will probably call + // this method. + if (this.requestEntity != null) { + return getContentCharSet( + new Header("Content-Type", requestEntity.getContentType())); + } else { + return super.getRequestCharSet(); + } + } else { + return super.getRequestCharSet(); + } + } + + /** + * Sets length information about the request body. + * + *+ * Note: If you specify a content length the request is unbuffered. This + * prevents redirection and automatic retry if a request fails the first + * time. This means that the HttpClient can not perform authorization + * automatically but will throw an Exception. You will have to set the + * necessary 'Authorization' or 'Proxy-Authorization' headers manually. + *
+ * + * @param length size in bytes or any of CONTENT_LENGTH_AUTO, + * CONTENT_LENGTH_CHUNKED. If number of bytes or CONTENT_LENGTH_CHUNKED + * is specified the content will not be buffered internally and the + * Content-Length header of the request will be used. In this case + * the user is responsible to supply the correct content length. + * If CONTENT_LENGTH_AUTO is specified the request will be buffered + * before it is sent over the network. + * + * @deprecated Use {@link #setContentChunked(boolean)} or + * {@link #setRequestEntity(RequestEntity)} + */ + public void setRequestContentLength(long length) { + LOG.trace("enter EntityEnclosingMethod.setRequestContentLength(int)"); + this.requestContentLength = length; + } + + /** + * Sets whether or not the content should be chunked. + * + * @param chunkedtrue
if the content should be chunked
+ *
+ * @since 3.0
+ */
+ public void setContentChunked(boolean chunked) {
+ this.chunked = chunked;
+ }
+
+ /**
+ * Returns the length of the request body.
+ *
+ * @return number of bytes in the request body
+ */
+ protected long getRequestContentLength() {
+ LOG.trace("enter EntityEnclosingMethod.getRequestContentLength()");
+
+ if (!hasRequestContent()) {
+ return 0;
+ }
+ if (this.chunked) {
+ return -1;
+ }
+ if (this.requestEntity == null) {
+ this.requestEntity = generateRequestEntity();
+ }
+ return (this.requestEntity == null) ? 0 : this.requestEntity.getContentLength();
+ }
+
+ /**
+ * Populates the request headers map to with additional
+ * {@link org.apache.commons.httpclient.Header headers} to be submitted to
+ * the given {@link HttpConnection}.
+ *
+ * + * This implementation adds tt>Content-Length or Transfer-Encoding + * headers. + *
+ * + *+ * Subclasses may want to override this method to to add additional + * headers, and may choose to invoke this implementation (via + * super) to add the "standard" headers. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #writeRequestHeaders + * + * @since 3.0 + */ + protected void addRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter EntityEnclosingMethod.addRequestHeaders(HttpState, " + + "HttpConnection)"); + + super.addRequestHeaders(state, conn); + addContentLengthRequestHeader(state, conn); + + // only use the content type of the request entity if it has not already been + // set manually + if (getRequestHeader("Content-Type") == null) { + RequestEntity requestEntity = getRequestEntity(); + if (requestEntity != null && requestEntity.getContentType() != null) { + setRequestHeader("Content-Type", requestEntity.getContentType()); + } + } + } + + /** + * Generates Content-Length or Transfer-Encoding: Chunked + * request header, as long as no Content-Length request header + * already exists. + * + * @param state current state of http requests + * @param conn the connection to use for I/O + * + * @throws IOException when errors occur reading or writing to/from the + * connection + * @throws HttpException when a recoverable error occurs + */ + protected void addContentLengthRequestHeader(HttpState state, + HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter EntityEnclosingMethod.addContentLengthRequestHeader(" + + "HttpState, HttpConnection)"); + + if ((getRequestHeader("content-length") == null) + && (getRequestHeader("Transfer-Encoding") == null)) { + long len = getRequestContentLength(); + if (len < 0) { + if (getEffectiveVersion().greaterEquals(HttpVersion.HTTP_1_1)) { + addRequestHeader("Transfer-Encoding", "chunked"); + } else { + throw new ProtocolException(getEffectiveVersion() + + " does not support chunk encoding"); + } + } else { + addRequestHeader("Content-Length", String.valueOf(len)); + } + } + } + + /** + * Sets the request body to be the specified inputstream. + * + * @param body Request body content as {@link java.io.InputStream} + * + * @deprecated use {@link #setRequestEntity(RequestEntity)} + */ + public void setRequestBody(InputStream body) { + LOG.trace("enter EntityEnclosingMethod.setRequestBody(InputStream)"); + clearRequestBody(); + this.requestStream = body; + } + + /** + * Sets the request body to be the specified string. + * The string will be submitted, using the encoding + * specified in the Content-Type request header.setRequestHeader("Content-type", "text/xml; charset=UTF-8");
+ * This abstract class serves as a foundation for all HTTP methods + * that support 'Expect: 100-continue' handshake. + *
+ * + *+ * The purpose of the 100 (Continue) status (refer to section 10.1.1 + * of the RFC 2616 for more details) is to allow a client that is + * sending a request message with a request body to determine if the + * origin server is willing to accept the request (based on the request + * headers) before the client sends the request body. In some cases, + * it might either be inappropriate or highly inefficient for the + * client to send the body if the server will reject the message + * without looking at the body. + *
+ * + *+ * 'Expect: 100-continue' handshake should be used with caution, + * as it may cause problems with HTTP servers and proxies that + * do not support HTTP/1.1 protocol. + *
+ * + * @author Oleg Kalnichevski + * + * @since 2.0beta1 + */ + +public abstract class ExpectContinueMethod extends HttpMethodBase { + + /** LOG object for this class. */ + private static final Log LOG = LogFactory.getLog(ExpectContinueMethod.class); + + /** + * No-arg constructor. + * + * @since 2.0 + */ + public ExpectContinueMethod() { + super(); + } + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 2.0 + */ + public ExpectContinueMethod(String uri) { + super(uri); + } + + /** + *+ * Returns true if the 'Expect: 100-Continue' handshake + * is activated. The purpose of the 'Expect: 100-Continue' + * handshake to allow a client that is sending a request message + * with a request body to determine if the origin server is + * willing to accept the request (based on the request headers) + * before the client sends the request body. + *
+ * + * @return true if 'Expect: 100-Continue' handshake is to + * be used, false otherwise. + * + * @since 2.0beta1 + * + * @deprecated Use {@link HttpMethodParams} + * + * @see #getParams() + * @see HttpMethodParams + * @see HttpMethodParams#USE_EXPECT_CONTINUE + */ + public boolean getUseExpectHeader() { + return getParams().getBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false); + } + + /** + *+ * Activates 'Expect: 100-Continue' handshake. The purpose of + * the 'Expect: 100-Continue' handshake to allow a client that is + * sending a request message with a request body to determine if + * the origin server is willing to accept the request (based on + * the request headers) before the client sends the request body. + *
+ * + *+ * The use of the 'Expect: 100-continue' handshake can result in + * noticable peformance improvement for entity enclosing requests + * (such as POST and PUT) that require the target server's + * authentication. + *
+ * + *+ * 'Expect: 100-continue' handshake should be used with + * caution, as it may cause problems with HTTP servers and + * proxies that do not support HTTP/1.1 protocol. + *
+ * + * @param value boolean value + * + * @since 2.0beta1 + * + * @deprecated Use {@link HttpMethodParams} + * + * @see #getParams() + * @see HttpMethodParams + * @see HttpMethodParams#USE_EXPECT_CONTINUE + */ + public void setUseExpectHeader(boolean value) { + getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, value); + } + + /** + * Returns true if there is a request body to be sent. + * 'Expect: 100-continue' handshake may not be used if request + * body is not present + * + * @return boolean + * + * @since 2.0beta1 + */ + protected abstract boolean hasRequestContent(); + + /** + * Sets the Expect header if it has not already been set, + * in addition to the "standard" set of headers. + * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + protected void addRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter ExpectContinueMethod.addRequestHeaders(HttpState, HttpConnection)"); + + super.addRequestHeaders(state, conn); + // If the request is being retried, the header may already be present + boolean headerPresent = (getRequestHeader("Expect") != null); + // See if the expect header should be sent + // = HTTP/1.1 or higher + // = request body present + + if (getParams().isParameterTrue(HttpMethodParams.USE_EXPECT_CONTINUE) + && getEffectiveVersion().greaterEquals(HttpVersion.HTTP_1_1) + && hasRequestContent()) + { + if (!headerPresent) { + setRequestHeader("Expect", "100-continue"); + } + } else { + if (headerPresent) { + removeRequestHeader("Expect"); + } + } + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/GetMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/GetMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/GetMethod.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,128 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/GetMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * 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 + *+ * The HTTP GET method is defined in section 9.3 of + * RFC2616: + *
+ * The GET method means retrieve whatever information (in the form of an + * entity) is identified by the Request-URI. If the Request-URI refers + * to a data-producing process, it is the produced data which shall be + * returned as the entity in the response and not the source text of the + * process, unless that text happens to be the output of the process. + *+ * + *
+ * GetMethods will follow redirect requests from the http server by default. + * This behavour can be disabled by calling setFollowRedirects(false).
+ * + * @author Remy Maucherat + * @author Sung-Gu Park + * @author Sean C. Sullivan + * @author Mike Bowler + * @author Jeff Dever + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class GetMethod extends HttpMethodBase { + + // -------------------------------------------------------------- Constants + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(GetMethod.class); + + // ----------------------------------------------------------- Constructors + + /** + * No-arg constructor. + * + * @since 1.0 + */ + public GetMethod() { + setFollowRedirects(true); + } + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 1.0 + */ + public GetMethod(String uri) { + super(uri); + LOG.trace("enter GetMethod(String)"); + setFollowRedirects(true); + } + + // --------------------------------------------------------- Public Methods + + /** + * Returns "GET". + * + * @return "GET" + * + * @since 2.0 + */ + public String getName() { + return "GET"; + } + + // ------------------------------------------------------------- Properties + + /** + * Recycles the HTTP method so that it can be used again. + * Note that all of the instance variables will be reset + * once this method has been called. This method will also + * release the connection being used by this HTTP method. + * + * @see #releaseConnection() + * + * @since 1.0 + * + * @deprecated no longer supported and will be removed in the future + * version of HttpClient + */ + public void recycle() { + LOG.trace("enter GetMethod.recycle()"); + + super.recycle(); + setFollowRedirects(true); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/HeadMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/HeadMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/HeadMethod.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,218 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/HeadMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * 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 + *+ * The HTTP HEAD method is defined in section 9.4 of + * RFC2616: + *
+ * The HEAD method is identical to GET except that the server MUST NOT + * return a message-body in the response. The metainformation contained + * in the HTTP headers in response to a HEAD request SHOULD be identical + * to the information sent in response to a GET request. This method can + * be used for obtaining metainformation about the entity implied by the + * request without transferring the entity-body itself. This method is + * often used for testing hypertext links for validity, accessibility, + * and recent modification. + *+ * + * + * @author Remy Maucherat + * @author Mike Bowler + * @author Jeff Dever + * @author oleg Kalnichevski + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class HeadMethod extends HttpMethodBase { + //~ Static variables/initializers + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(HeadMethod.class); + + //~ Constructors + + /** + * No-arg constructor. + * + * @since 1.0 + */ + public HeadMethod() { + setFollowRedirects(true); + } + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 1.0 + */ + public HeadMethod(String uri) { + super(uri); + setFollowRedirects(true); + } + + //~ Methods + + /** + * Returns "HEAD". + * + * @return "HEAD" + * + * @since 2.0 + */ + public String getName() { + return "HEAD"; + } + + /** + * Recycles the HTTP method so that it can be used again. + * Note that all of the instance variables will be reset + * once this method has been called. This method will also + * release the connection being used by this HTTP method. + * + * @see #releaseConnection() + * + * @since 1.0 + * + * @deprecated no longer supported and will be removed in the future + * version of HttpClient + */ + public void recycle() { + super.recycle(); + setFollowRedirects(true); + } + + /** + * Overrides {@link HttpMethodBase} method to not read a response + * body, despite the presence of a Content-Length or + * Transfer-Encoding header. + * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #readResponse + * @see #processResponseBody + * + * @since 2.0 + */ + protected void readResponseBody(HttpState state, HttpConnection conn) + throws HttpException, IOException { + LOG.trace( + "enter HeadMethod.readResponseBody(HttpState, HttpConnection)"); + + int bodyCheckTimeout = + getParams().getIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, -1); + + if (bodyCheckTimeout < 0) { + responseBodyConsumed(); + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("Check for non-compliant response body. Timeout in " + + bodyCheckTimeout + " ms"); + } + boolean responseAvailable = false; + try { + responseAvailable = conn.isResponseAvailable(bodyCheckTimeout); + } catch (IOException e) { + LOG.debug("An IOException occurred while testing if a response was available," + + " we will assume one is not.", + e); + responseAvailable = false; + } + if (responseAvailable) { + if (getParams().isParameterTrue(HttpMethodParams.REJECT_HEAD_BODY)) { + throw new ProtocolException( + "Body content may not be sent in response to HTTP HEAD request"); + } else { + LOG.warn("Body content returned in response to HTTP HEAD"); + } + super.readResponseBody(state, conn); + } + } + + } + + /** + * Returns non-compliant response body check timeout. + * + * @return The period of time in milliseconds to wait for a response + * body from a non-compliant server. -1 returned when + * non-compliant response body check is disabled + * + * @deprecated Use {@link HttpMethodParams} + * + * @see #getParams() + * @see HttpMethodParams + * @see HttpMethodParams#HEAD_BODY_CHECK_TIMEOUT + */ + public int getBodyCheckTimeout() { + return getParams().getIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, -1); + } + + /** + * Sets non-compliant response body check timeout. + * + * @param timeout The period of time in milliseconds to wait for a response + * body from a non-compliant server. -1 can be used to + * disable non-compliant response body check + * + * @deprecated Use {@link HttpMethodParams} + * + * @see #getParams() + * @see HttpMethodParams + * @see HttpMethodParams#HEAD_BODY_CHECK_TIMEOUT + */ + public void setBodyCheckTimeout(int timeout) { + getParams().setIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, timeout); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,198 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * Copyright 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 + *
null
.
+ */
+ public InputStreamRequestEntity(InputStream content, String contentType) {
+ this(content, CONTENT_LENGTH_AUTO, contentType);
+ }
+
+ /**
+ * Creates a new InputStreamRequestEntity with the given content and content length.
+ * @param content The content to set.
+ * @param contentLength The content size in bytes or a negative number if not known.
+ * If {@link #CONTENT_LENGTH_AUTO} is given the content will be buffered in order to
+ * determine its size when {@link #getContentLength()} is called.
+ */
+ public InputStreamRequestEntity(InputStream content, long contentLength) {
+ this(content, contentLength, null);
+ }
+
+ /**
+ * Creates a new InputStreamRequestEntity with the given content, content length, and
+ * content type.
+ * @param content The content to set.
+ * @param contentLength The content size in bytes or a negative number if not known.
+ * If {@link #CONTENT_LENGTH_AUTO} is given the content will be buffered in order to
+ * determine its size when {@link #getContentLength()} is called.
+ * @param contentType The type of the content, or null
.
+ */
+ public InputStreamRequestEntity(InputStream content, long contentLength, String contentType) {
+ if (content == null) {
+ throw new IllegalArgumentException("The content cannot be null");
+ }
+ this.content = content;
+ this.contentLength = contentLength;
+ this.contentType = contentType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType()
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Buffers request body input stream.
+ */
+ private void bufferContent() {
+
+ if (this.buffer != null) {
+ // Already been buffered
+ return;
+ }
+ if (this.content != null) {
+ try {
+ ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+ byte[] data = new byte[4096];
+ int l = 0;
+ while ((l = this.content.read(data)) >= 0) {
+ tmp.write(data, 0, l);
+ }
+ this.buffer = tmp.toByteArray();
+ this.content = null;
+ this.contentLength = buffer.length;
+ } catch (IOException e) {
+ LOG.error(e.getMessage(), e);
+ this.buffer = null;
+ this.content = null;
+ this.contentLength = 0;
+ }
+ }
+ }
+
+ /**
+ * Tests if this method is repeatable. Only true
if the content has been
+ * buffered.
+ *
+ * @see #getContentLength()
+ */
+ public boolean isRepeatable() {
+ return buffer != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream)
+ */
+ public void writeRequest(OutputStream out) throws IOException {
+
+ if (content != null) {
+ byte[] tmp = new byte[4096];
+ int total = 0;
+ int i = 0;
+ while ((i = content.read(tmp)) >= 0) {
+ out.write(tmp, 0, i);
+ total += i;
+ }
+ } else if (buffer != null) {
+ out.write(buffer);
+ } else {
+ throw new IllegalStateException("Content must be set before entity is written");
+ }
+ }
+
+ /**
+ * Gets the content length. If the content length has not been set, the content will be
+ * buffered to determine the actual content length.
+ */
+ public long getContentLength() {
+ if (contentLength == CONTENT_LENGTH_AUTO && buffer == null) {
+ bufferContent();
+ }
+ return contentLength;
+ }
+
+ /**
+ * @return Returns the content.
+ */
+ public InputStream getContent() {
+ return content;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/MultipartPostMethod.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/MultipartPostMethod.java 22 Aug 2012 17:30:37 -0000 1.1
@@ -0,0 +1,332 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:37 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * + * The HTTP multipart POST method is defined in section 3.3 of + * RFC1867: + *
+ * The media-type multipart/form-data follows the rules of all multipart + * MIME data streams as outlined in RFC 1521. The multipart/form-data contains + * a series of parts. Each part is expected to contain a content-disposition + * header where the value is "form-data" and a name attribute specifies + * the field name within the form, e.g., 'content-disposition: form-data; + * name="xxxxx"', where xxxxx is the field name corresponding to that field. + * Field names originally in non-ASCII character sets may be encoded using + * the method outlined in RFC 1522. + *+ * + *
+ * + * @author Matthew Albright + * @author Jeff Dever + * @author Adrian Sutton + * @author Mark Diggory + * @author Mike Bowler + * @author Oleg Kalnichevski + * + * @since 2.0 + * + * @deprecated Use {@link org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity} + * in conjunction with {@link org.apache.commons.httpclient.methods.PostMethod} instead. + */ +public class MultipartPostMethod extends ExpectContinueMethod { + + /** The Content-Type for multipart/form-data. */ + public static final String MULTIPART_FORM_CONTENT_TYPE = + "multipart/form-data"; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(MultipartPostMethod.class); + + /** The parameters for this method */ + private final List parameters = new ArrayList(); + + /** + * No-arg constructor. + */ + public MultipartPostMethod() { + super(); + } + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + */ + public MultipartPostMethod(String uri) { + super(uri); + } + + /** + * Returns true + * + * @return true + * + * @since 2.0beta1 + */ + protected boolean hasRequestContent() { + return true; + } + + /** + * Returns "POST". + * @return "POST" + */ + public String getName() { + return "POST"; + } + + /** + * Adds a text field part + * + * @param parameterName The name of the parameter. + * @param parameterValue The value of the parameter. + */ + public void addParameter(String parameterName, String parameterValue) { + LOG.trace("enter addParameter(String parameterName, String parameterValue)"); + Part param = new StringPart(parameterName, parameterValue); + parameters.add(param); + } + + /** + * Adds a binary file part + * + * @param parameterName The name of the parameter + * @param parameterFile The name of the file. + * @throws FileNotFoundException If the file cannot be found. + */ + public void addParameter(String parameterName, File parameterFile) + throws FileNotFoundException { + LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " + + "File parameterFile)"); + Part param = new FilePart(parameterName, parameterFile); + parameters.add(param); + } + + /** + * Adds a binary file part with the given file name + * + * @param parameterName The name of the parameter + * @param fileName The file name + * @param parameterFile The file + * @throws FileNotFoundException If the file cannot be found. + */ + public void addParameter(String parameterName, String fileName, File parameterFile) + throws FileNotFoundException { + LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " + + "String fileName, File parameterFile)"); + Part param = new FilePart(parameterName, fileName, parameterFile); + parameters.add(param); + } + + /** + * Adds a part. + * + * @param part The part to add. + */ + public void addPart (final Part part) { + LOG.trace("enter addPart(Part part)"); + parameters.add(part); + } + + /** + * Returns all parts. + * + * @return an array of containing all parts + */ + public Part[] getParts() { + return (Part[]) parameters.toArray(new Part[parameters.size()]); + } + + /** + * Adds a Content-Length request header, as long as no + * Content-Length request header already exists. + * + * @param state current state of http requests + * @param conn the connection to use for I/O + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @since 3.0 + */ + protected void addContentLengthRequestHeader(HttpState state, + HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter EntityEnclosingMethod.addContentLengthRequestHeader(" + + "HttpState, HttpConnection)"); + + if (getRequestHeader("Content-Length") == null) { + long len = getRequestContentLength(); + addRequestHeader("Content-Length", String.valueOf(len)); + } + removeRequestHeader("Transfer-Encoding"); + } + + /** + * Adds a Content-Type request header. + * + * @param state current state of http requests + * @param conn the connection to use for I/O + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @since 3.0 + */ + protected void addContentTypeRequestHeader(HttpState state, + HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter EntityEnclosingMethod.addContentTypeRequestHeader(" + + "HttpState, HttpConnection)"); + + if (!parameters.isEmpty()) { + StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE); + if (Part.getBoundary() != null) { + buffer.append("; boundary="); + buffer.append(Part.getBoundary()); + } + setRequestHeader("Content-Type", buffer.toString()); + } + } + + /** + * Populates the request headers map to with additional + * {@link org.apache.commons.httpclient.Header headers} to be submitted to + * the given {@link HttpConnection}. + * + *
+ * This implementation adds tt>Content-Length and Content-Type + * headers, when appropriate. + *
+ * + *+ * Subclasses may want to override this method to to add additional + * headers, and may choose to invoke this implementation (via + * super) to add the "standard" headers. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + * + * @see #writeRequestHeaders + */ + protected void addRequestHeaders(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter MultipartPostMethod.addRequestHeaders(HttpState state, " + + "HttpConnection conn)"); + super.addRequestHeaders(state, conn); + addContentLengthRequestHeader(state, conn); + addContentTypeRequestHeader(state, conn); + } + + /** + * Writes the request body to the given {@link HttpConnection connection}. + * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @return true + * + * @throws IOException if an I/O (transport) error occurs. Some transport exceptions + * can be recovered from. + * @throws HttpException if a protocol exception occurs. Usually protocol exceptions + * cannot be recovered from. + */ + protected boolean writeRequestBody(HttpState state, HttpConnection conn) + throws IOException, HttpException { + LOG.trace("enter MultipartPostMethod.writeRequestBody(HttpState state, " + + "HttpConnection conn)"); + OutputStream out = conn.getRequestOutputStream(); + Part.sendParts(out, getParts()); + return true; + } + + /** + *Return the length of the request body.
+ * + *Once this method has been invoked, the request parameters cannot be + * altered until the method is {@link #recycle recycled}.
+ * + * @return The request content length. + */ + protected long getRequestContentLength() throws IOException { + LOG.trace("enter MultipartPostMethod.getRequestContentLength()"); + return Part.getLengthOfParts(getParts()); + } + + + /** + * Recycles the HTTP method so that it can be used again. + * Note that all of the instance variables will be reset + * once this method has been called. This method will also + * release the connection being used by this HTTP method. + * + * @see #releaseConnection() + * + * @deprecated no longer supported and will be removed in the future + * version of HttpClient + */ + public void recycle() { + LOG.trace("enter MultipartPostMethod.recycle()"); + super.recycle(); + parameters.clear(); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/OptionsMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/OptionsMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/OptionsMethod.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,191 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/OptionsMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * 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 + *+ * The HTTP OPTIONS method is defined in section 9.2 of + * RFC2616: + *
+ * The OPTIONS method represents a request for information about the + * communication options available on the request/response chain + * identified by the Request-URI. This method allows the client to + * determine the options and/or requirements associated with a resource, + * or the capabilities of a server, without implying a resource action + * or initiating a resource retrieval. + *+ * + * + * @author Remy Maucherat + * @author Mike Bowler + * @author Jeff Dever + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class OptionsMethod + extends HttpMethodBase { + + + // --------------------------------------------------------- Class Variables + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(OptionsMethod.class); + + // ----------------------------------------------------------- Constructors + + + /** + * Method constructor. + * + * @since 1.0 + */ + public OptionsMethod() { + } + + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 1.0 + */ + public OptionsMethod(String uri) { + super(uri); + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * Methods allowed. + */ + private Vector methodsAllowed = new Vector(); + + + // --------------------------------------------------------- Public Methods + + /** + * Get the name. + * @return "OPTIONS" + * @since 2.0 + */ + public String getName() { + return "OPTIONS"; + } + + + /** + * Is the specified method allowed ? + * + * @param method The method to check. + * @return true if the specified method is allowed. + * @since 1.0 + */ + public boolean isAllowed(String method) { + checkUsed(); + return methodsAllowed.contains(method); + } + + + /** + * Get a list of allowed methods. + * @return An enumeration of all the allowed methods. + * + * @since 1.0 + */ + public Enumeration getAllowedMethods() { + checkUsed(); + return methodsAllowed.elements(); + } + + + // ----------------------------------------------------- HttpMethod Methods + + /** + *
+ * This implementation will parse the Allow header to obtain + * the set of methods supported by the resource identified by the Request-URI. + *
+ * + * @param state the {@link HttpState state} information associated with this method + * @param conn the {@link HttpConnection connection} used to execute + * this HTTP method + * + * @see #readResponse + * @see #readResponseHeaders + * @since 2.0 + */ + protected void processResponseHeaders(HttpState state, HttpConnection conn) { + LOG.trace("enter OptionsMethod.processResponseHeaders(HttpState, HttpConnection)"); + + Header allowHeader = getResponseHeader("allow"); + if (allowHeader != null) { + String allowHeaderValue = allowHeader.getValue(); + StringTokenizer tokenizer = + new StringTokenizer(allowHeaderValue, ","); + while (tokenizer.hasMoreElements()) { + String methodAllowed = + tokenizer.nextToken().trim().toUpperCase(); + methodsAllowed.addElement(methodAllowed); + } + } + } + + /** + * Return true if the method needs a content-length header in the request. + * + * @return true if a content-length header will be expected by the server + * + * @since 1.0 + * + * @deprecated only entity enclosing methods set content length header + */ + public boolean needContentLength() { + return false; + } + + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PostMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PostMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PostMethod.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,410 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PostMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * 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 + *+ * The HTTP POST method is defined in section 9.5 of + * RFC2616: + *
+ * The POST method is used to request that the origin server accept the entity + * enclosed in the request as a new subordinate of the resource identified by + * the Request-URI in the Request-Line. POST is designed to allow a uniform + * method to cover the following functions: + *+ * + * + * @author Remy Maucherat + * @author Doug Sale + * @author Jeff Dever + * @author Ortwin Gl???ck + * @author Mike Bowler + * @author Oleg Kalnichevski + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class PostMethod extends EntityEnclosingMethod { + // -------------------------------------------------------------- Constants + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(PostMethod.class); + + /** The Content-Type for www-form-urlencoded. */ + public static final String FORM_URL_ENCODED_CONTENT_TYPE = + "application/x-www-form-urlencoded"; + + /** + * The buffered request body consisting of+ *
+ *- Annotation of existing resources
+ *- Posting a message to a bulletin board, newsgroup, mailing list, or + * similar group of articles
+ *- Providing a block of data, such as the result of submitting a form, + * to a data-handling process
+ *- Extending a database through an append operation
+ *
NameValuePair
s.
+ */
+ private Vector params = new Vector();
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * No-arg constructor.
+ *
+ * @since 1.0
+ */
+ public PostMethod() {
+ super();
+ }
+
+ /**
+ * Constructor specifying a URI.
+ *
+ * @param uri either an absolute or relative URI
+ *
+ * @since 1.0
+ */
+ public PostMethod(String uri) {
+ super(uri);
+ }
+
+ // ----------------------------------------------------- Instance Methods
+
+ /**
+ * Returns "POST".
+ *
+ * @return "POST"
+ *
+ * @since 2.0
+ */
+ public String getName() {
+ return "POST";
+ }
+
+
+ /**
+ * Returns true if there is a request body to be sent.
+ *
+ * This method must be overwritten by sub-classes that implement + * alternative request content input methods + *
+ * + * @return boolean + * + * @since 2.0beta1 + */ + protected boolean hasRequestContent() { + LOG.trace("enter PostMethod.hasRequestContent()"); + if (!this.params.isEmpty()) { + return true; + } else { + return super.hasRequestContent(); + } + } + + /** + * Clears request body. + * + *This method must be overwritten by sub-classes that implement + * alternative request content input methods
+ * + * @since 2.0beta1 + */ + protected void clearRequestBody() { + LOG.trace("enter PostMethod.clearRequestBody()"); + this.params.clear(); + super.clearRequestBody(); + } + + /** + * Generates a request entity from the post parameters, if present. Calls + * {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set. + * + * @since 3.0 + */ + protected RequestEntity generateRequestEntity() { + if (!this.params.isEmpty()) { + // Use a ByteArrayRequestEntity instead of a StringRequestEntity. + // This is to avoid potential encoding issues. Form url encoded strings + // are ASCII by definition but the content type may not be. Treating the content + // as bytes allows us to keep the current charset without worrying about how + // this charset will effect the encoding of the form url encoded string. + String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet()); + ByteArrayRequestEntity entity = new ByteArrayRequestEntity( + EncodingUtil.getAsciiBytes(content), + FORM_URL_ENCODED_CONTENT_TYPE + ); + return entity; + } else { + return super.generateRequestEntity(); + } + } + + /** + * Sets the value of parameter with parameterName to parameterValue. This method + * does not preserve the initial insertion order. + * + * @param parameterName name of the parameter + * @param parameterValue value of the parameter + * + * @since 2.0 + */ + public void setParameter(String parameterName, String parameterValue) { + LOG.trace("enter PostMethod.setParameter(String, String)"); + + removeParameter(parameterName); + addParameter(parameterName, parameterValue); + } + + /** + * Gets the parameter of the specified name. If there exists more than one + * parameter with the name paramName, then only the first one is returned. + * + * @param paramName name of the parameter + * + * @return If a parameter exists with the name argument, the coresponding + * NameValuePair is returned. Otherwise null. + * + * @since 2.0 + * + */ + public NameValuePair getParameter(String paramName) { + LOG.trace("enter PostMethod.getParameter(String)"); + + if (paramName == null) { + return null; + } + + Iterator iter = this.params.iterator(); + + while (iter.hasNext()) { + NameValuePair parameter = (NameValuePair) iter.next(); + + if (paramName.equals(parameter.getName())) { + return parameter; + } + } + return null; + } + + /** + * Gets the parameters currently added to the PostMethod. If there are no + * parameters, a valid array is returned with zero elements. The returned + * array object contains an array of pointers to the internal data + * members. + * + * @return An array of the current parameters + * + * @since 2.0 + * + */ + public NameValuePair[] getParameters() { + LOG.trace("enter PostMethod.getParameters()"); + + int numPairs = this.params.size(); + Object[] objectArr = this.params.toArray(); + NameValuePair[] nvPairArr = new NameValuePair[numPairs]; + + for (int i = 0; i < numPairs; i++) { + nvPairArr[i] = (NameValuePair) objectArr[i]; + } + + return nvPairArr; + } + + /** + * Adds a new parameter to be used in the POST request body. + * + * @param paramName The parameter name to add. + * @param paramValue The parameter value to add. + * + * @throws IllegalArgumentException if either argument is null + * + * @since 1.0 + */ + public void addParameter(String paramName, String paramValue) + throws IllegalArgumentException { + LOG.trace("enter PostMethod.addParameter(String, String)"); + + if ((paramName == null) || (paramValue == null)) { + throw new IllegalArgumentException( + "Arguments to addParameter(String, String) cannot be null"); + } + super.clearRequestBody(); + this.params.add(new NameValuePair(paramName, paramValue)); + } + + /** + * Adds a new parameter to be used in the POST request body. + * + * @param param The parameter to add. + * + * @throws IllegalArgumentException if the argument is null or contains + * null values + * + * @since 2.0 + */ + public void addParameter(NameValuePair param) + throws IllegalArgumentException { + LOG.trace("enter PostMethod.addParameter(NameValuePair)"); + + if (param == null) { + throw new IllegalArgumentException("NameValuePair may not be null"); + } + addParameter(param.getName(), param.getValue()); + } + + /** + * Adds an array of parameters to be used in the POST request body. Logs a + * warning if the parameters argument is null. + * + * @param parameters The array of parameters to add. + * + * @since 2.0 + */ + public void addParameters(NameValuePair[] parameters) { + LOG.trace("enter PostMethod.addParameters(NameValuePair[])"); + + if (parameters == null) { + LOG.warn("Attempt to addParameters(null) ignored"); + } else { + super.clearRequestBody(); + for (int i = 0; i < parameters.length; i++) { + this.params.add(parameters[i]); + } + } + } + + /** + * Removes all parameters with the given paramName. If there is more than + * one parameter with the given paramName, all of them are removed. If + * there is just one, it is removed. If there are none, then the request + * is ignored. + * + * @param paramName The parameter name to remove. + * + * @return true if at least one parameter was removed + * + * @throws IllegalArgumentException When the parameter name passed is null + * + * @since 2.0 + */ + public boolean removeParameter(String paramName) + throws IllegalArgumentException { + LOG.trace("enter PostMethod.removeParameter(String)"); + + if (paramName == null) { + throw new IllegalArgumentException( + "Argument passed to removeParameter(String) cannot be null"); + } + boolean removed = false; + Iterator iter = this.params.iterator(); + + while (iter.hasNext()) { + NameValuePair pair = (NameValuePair) iter.next(); + + if (paramName.equals(pair.getName())) { + iter.remove(); + removed = true; + } + } + return removed; + } + + /** + * Removes all parameter with the given paramName and paramValue. If there + * is more than one parameter with the given paramName, only one is + * removed. If there are none, then the request is ignored. + * + * @param paramName The parameter name to remove. + * @param paramValue The parameter value to remove. + * + * @return true if a parameter was removed. + * + * @throws IllegalArgumentException when param name or value are null + * + * @since 2.0 + */ + public boolean removeParameter(String paramName, String paramValue) + throws IllegalArgumentException { + LOG.trace("enter PostMethod.removeParameter(String, String)"); + + if (paramName == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + if (paramValue == null) { + throw new IllegalArgumentException("Parameter value may not be null"); + } + + Iterator iter = this.params.iterator(); + + while (iter.hasNext()) { + NameValuePair pair = (NameValuePair) iter.next(); + + if (paramName.equals(pair.getName()) + && paramValue.equals(pair.getValue())) { + iter.remove(); + return true; + } + } + + return false; + } + + /** + * Sets an array of parameters to be used in the POST request body + * + * @param parametersBody The array of parameters to add. + * + * @throws IllegalArgumentException when param parameters are null + * + * @since 2.0beta1 + */ + public void setRequestBody(NameValuePair[] parametersBody) + throws IllegalArgumentException { + LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])"); + + if (parametersBody == null) { + throw new IllegalArgumentException("Array of parameters may not be null"); + } + clearRequestBody(); + addParameters(parametersBody); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PutMethod.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PutMethod.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PutMethod.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,89 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PutMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * 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 + *+ * The HTTP PUT method is defined in section 9.6 of + * RFC2616: + *
+ * The PUT method requests that the enclosed entity be stored under the + * supplied Request-URI. If the Request-URI refers to an already + * existing resource, the enclosed entity SHOULD be considered as a + * modified version of the one residing on the origin server. + *+ * + * + * @author Remy Maucherat + * @author Mike Bowler + * @author Oleg Kalnichevski + * @author Jeff Dever + * + * @version $Revision: 1.1 $ + * @since 1.0 + */ +public class PutMethod extends EntityEnclosingMethod { + + // ----------------------------------------------------------- Constructors + + /** + * No-arg constructor. + * + * @since 1.0 + */ + public PutMethod() { + super(); + } + + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 1.0 + */ + public PutMethod(String uri) { + super(uri); + } + + // --------------------------------------------------------- Public Methods + + /** + * Return "PUT". + * @return "PUT" + * + * @since 2.0 + */ + public String getName() { + return "PUT"; + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/RequestEntity.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/RequestEntity.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/RequestEntity.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,74 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/RequestEntity.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * Copyright 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 + *
Creates a new entity with the given content. This constructor + * will use the default platform charset to convert the content string + * and will provide no content type.
+ * + *This constructor may be deprecated or changed to use the + * default HTTP content charset (ISO-8859-1) in the release 3.1
+ * + *It is strongly recommended to use + * {@link #StringRequestEntity(String, String, String)} constructor + * instead.
+ * + * @see #StringRequestEntity(String, String, String) + * + * @param content The content to set. + */ + public StringRequestEntity(String content) { + super(); + if (content == null) { + throw new IllegalArgumentException("The content cannot be null"); + } + this.contentType = null; + this.charset = null; + this.content = content.getBytes(); + } + + /** + * Creates a new entity with the given content, content type, and charset. + * + * @param content The content to set. + * @param contentType The type of the content, ornull
. The value retured
+ * by {@link #getContentType()}. If this content type contains a charset and the charset
+ * parameter is null, the content's type charset will be used.
+ * @param charset The charset of the content, or null
. Used to convert the
+ * content to bytes. If the content type does not contain a charset and charset is not null,
+ * then the charset will be appended to the content type.
+ */
+ public StringRequestEntity(String content, String contentType, String charset)
+ throws UnsupportedEncodingException {
+ super();
+ if (content == null) {
+ throw new IllegalArgumentException("The content cannot be null");
+ }
+
+ this.contentType = contentType;
+ this.charset = charset;
+
+ // resolve the content type and the charset
+ if (contentType != null) {
+ HeaderElement[] values = HeaderElement.parseElements(contentType);
+ NameValuePair charsetPair = null;
+ for (int i = 0; i < values.length; i++) {
+ if ((charsetPair = values[i].getParameterByName("charset")) != null) {
+ // charset found
+ break;
+ }
+ }
+ if (charset == null && charsetPair != null) {
+ // use the charset from the content type
+ this.charset = charsetPair.getValue();
+ } else if (charset != null && charsetPair == null) {
+ // append the charset to the content type
+ this.contentType = contentType + "; charset=" + charset;
+ }
+ }
+ if (this.charset != null) {
+ this.content = content.getBytes(this.charset);
+ } else {
+ this.content = content.getBytes();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType()
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * @return true
+ */
+ public boolean isRepeatable() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream)
+ */
+ public void writeRequest(OutputStream out) throws IOException {
+ if (out == null) {
+ throw new IllegalArgumentException("Output stream may not be null");
+ }
+ out.write(this.content);
+ out.flush();
+ }
+
+ /**
+ * @return The length of the content.
+ */
+ public long getContentLength() {
+ return this.content.length;
+ }
+
+ /**
+ * @return Returns the content.
+ */
+ public String getContent() {
+ if (this.charset != null) {
+ try {
+ return new String(this.content, this.charset);
+ } catch (UnsupportedEncodingException e) {
+ return new String(this.content);
+ }
+ } else {
+ return new String(this.content);
+ }
+ }
+
+ /**
+ * @return Returns the charset used to convert the content to bytes. null
if
+ * no charset as been specified.
+ */
+ public String getCharset() {
+ return charset;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/TraceMethod.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/TraceMethod.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/TraceMethod.java 22 Aug 2012 17:30:37 -0000 1.1
@@ -0,0 +1,107 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/TraceMethod.java,v 1.1 2012/08/22 17:30:37 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:37 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * The HTTP TRACE method is defined in section 9.6 of + * RFC2616: + *
+ * The TRACE method is used to invoke a remote, application-layer loop- + * back of the request message. The final recipient of the request + * SHOULD reflect the message received back to the client as the + * entity-body of a 200 (OK) response. The final recipient is either the + * origin server or the first proxy or gateway to receive a Max-Forwards + * value of zero (0) in the request (see section 14.31). A TRACE request + * MUST NOT include an entity. + *+ * + * + * @author Sean C. Sullivan + * @author Mike Bowler + * @author Jeff Dever + * + * @version $Revision: 1.1 $ + * @since 2.0 + * + */ +public class TraceMethod extends HttpMethodBase { + + //~ Constructors + + /** + * Constructor specifying a URI. + * + * @param uri either an absolute or relative URI + * + * @since 2.0 + * + */ + public TraceMethod(String uri) { + super(uri); + setFollowRedirects(false); + } + + //~ Methods + + /** + * Returns "TRACE". + * + * @return "TRACE" + * + * @since 2.0 + * + */ + public String getName() { + return "TRACE"; + } + + /** + * Recycles the HTTP method so that it can be used again. + * Note that all of the instance variables will be reset + * once this method has been called. This method will also + * release the connection being used by this HTTP method. + * + * @see #releaseConnection() + * + * @since 2.0 + * + * @deprecated no longer supported and will be removed in the future + * version of HttpClient + */ + public void recycle() { + super.recycle(); + setFollowRedirects(false); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/package.html 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,11 @@ + + + +
null
the
+ * {@link #DEFAULT_CONTENT_TYPE default} is used
+ * @param charset the charset encoding for this part, if null
the
+ * {@link #DEFAULT_CHARSET default} is used
+ */
+ public FilePart(String name, PartSource partSource, String contentType, String charset) {
+
+ super(
+ name,
+ contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
+ charset == null ? "ISO-8859-1" : charset,
+ DEFAULT_TRANSFER_ENCODING
+ );
+
+ if (partSource == null) {
+ throw new IllegalArgumentException("Source may not be null");
+ }
+ this.source = partSource;
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name for this part
+ * @param partSource the source for this part
+ */
+ public FilePart(String name, PartSource partSource) {
+ this(name, partSource, null, null);
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name of the file part
+ * @param file the file to post
+ *
+ * @throws FileNotFoundException if the file is not a normal
+ * file or if it is not readable.
+ */
+ public FilePart(String name, File file)
+ throws FileNotFoundException {
+ this(name, new FilePartSource(file), null, null);
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name of the file part
+ * @param file the file to post
+ * @param contentType the content type for this part, if null
the
+ * {@link #DEFAULT_CONTENT_TYPE default} is used
+ * @param charset the charset encoding for this part, if null
the
+ * {@link #DEFAULT_CHARSET default} is used
+ *
+ * @throws FileNotFoundException if the file is not a normal
+ * file or if it is not readable.
+ */
+ public FilePart(String name, File file, String contentType, String charset)
+ throws FileNotFoundException {
+ this(name, new FilePartSource(file), contentType, charset);
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name of the file part
+ * @param fileName the file name
+ * @param file the file to post
+ *
+ * @throws FileNotFoundException if the file is not a normal
+ * file or if it is not readable.
+ */
+ public FilePart(String name, String fileName, File file)
+ throws FileNotFoundException {
+ this(name, new FilePartSource(fileName, file), null, null);
+ }
+
+ /**
+ * FilePart Constructor.
+ *
+ * @param name the name of the file part
+ * @param fileName the file name
+ * @param file the file to post
+ * @param contentType the content type for this part, if null
the
+ * {@link #DEFAULT_CONTENT_TYPE default} is used
+ * @param charset the charset encoding for this part, if null
the
+ * {@link #DEFAULT_CHARSET default} is used
+ *
+ * @throws FileNotFoundException if the file is not a normal
+ * file or if it is not readable.
+ */
+ public FilePart(String name, String fileName, File file, String contentType, String charset)
+ throws FileNotFoundException {
+ this(name, new FilePartSource(fileName, file), contentType, charset);
+ }
+
+ /**
+ * Write the disposition header to the output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs
+ * @see Part#sendDispositionHeader(OutputStream)
+ */
+ protected void sendDispositionHeader(OutputStream out)
+ throws IOException {
+ LOG.trace("enter sendDispositionHeader(OutputStream out)");
+ super.sendDispositionHeader(out);
+ String filename = this.source.getFileName();
+ if (filename != null) {
+ out.write(FILE_NAME_BYTES);
+ out.write(QUOTE_BYTES);
+ out.write(EncodingUtil.getAsciiBytes(filename));
+ out.write(QUOTE_BYTES);
+ }
+ }
+
+ /**
+ * Write the data in "source" to the specified stream.
+ * @param out The output stream.
+ * @throws IOException if an IO problem occurs.
+ * @see org.apache.commons.httpclient.methods.multipart.Part#sendData(OutputStream)
+ */
+ protected void sendData(OutputStream out) throws IOException {
+ LOG.trace("enter sendData(OutputStream out)");
+ if (lengthOfData() == 0) {
+
+ // this file contains no data, so there is nothing to send.
+ // we don't want to create a zero length buffer as this will
+ // cause an infinite loop when reading.
+ LOG.debug("No data to send.");
+ return;
+ }
+
+ byte[] tmp = new byte[4096];
+ InputStream instream = source.createInputStream();
+ try {
+ int len;
+ while ((len = instream.read(tmp)) >= 0) {
+ out.write(tmp, 0, len);
+ }
+ } finally {
+ // we're done with the stream, close it
+ instream.close();
+ }
+ }
+
+ /**
+ * Returns the source of the file part.
+ *
+ * @return The source.
+ */
+ protected PartSource getSource() {
+ LOG.trace("enter getSource()");
+ return this.source;
+ }
+
+ /**
+ * Return the length of the data.
+ * @return The length.
+ * @throws IOException if an IO problem occurs
+ * @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
+ */
+ protected long lengthOfData() throws IOException {
+ LOG.trace("enter lengthOfData()");
+ return source.getLength();
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePartSource.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePartSource.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePartSource.java 22 Aug 2012 17:30:39 -0000 1.1
@@ -0,0 +1,130 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePartSource.java,v 1.1 2012/08/22 17:30:39 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:39 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * The HTTP multipart POST method is defined in section 3.3 of + * RFC1867: + *
+ * The media-type multipart/form-data follows the rules of all multipart + * MIME data streams as outlined in RFC 1521. The multipart/form-data contains + * a series of parts. Each part is expected to contain a content-disposition + * header where the value is "form-data" and a name attribute specifies + * the field name within the form, e.g., 'content-disposition: form-data; + * name="xxxxx"', where xxxxx is the field name corresponding to that field. + * Field names originally in non-ASCII character sets may be encoded using + * the method outlined in RFC 1522. + *+ * + *
This entity is designed to be used in conjunction with the + * {@link org.apache.commons.httpclient.methods.PostMethod post method} to provide + * multipart posts. Example usage:
+ *
+ * File f = new File("/path/fileToUpload.txt");
+ * PostMethod filePost = new PostMethod("http://host/some_path");
+ * Part[] parts = {
+ * new StringPart("param_name", "value"),
+ * new FilePart(f.getName(), f)
+ * };
+ * filePost.setRequestEntity(
+ * new MultipartRequestEntity(parts, filePost.getParams())
+ * );
+ * HttpClient client = new HttpClient();
+ * int status = client.executeMethod(filePost);
+ *
+ *
+ * @since 3.0
+ */
+public class MultipartRequestEntity implements RequestEntity {
+
+ private static final Log log = LogFactory.getLog(MultipartRequestEntity.class);
+
+ /** The Content-Type for multipart/form-data. */
+ private static final String MULTIPART_FORM_CONTENT_TYPE = "multipart/form-data";
+
+ /**
+ * The pool of ASCII chars to be used for generating a multipart boundary.
+ */
+ private static byte[] MULTIPART_CHARS = EncodingUtil.getAsciiBytes(
+ "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+ /**
+ * Generates a random multipart boundary string.
+ * @return
+ */
+ private static byte[] generateMultipartBoundary() {
+ Random rand = new Random();
+ byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size from 30 to 40
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)];
+ }
+ return bytes;
+ }
+
+ /** The MIME parts as set by the constructor */
+ protected Part[] parts;
+
+ private byte[] multipartBoundary;
+
+ private HttpMethodParams params;
+
+ /**
+ * Creates a new multipart entity containing the given parts.
+ * @param parts The parts to include.
+ * @param params The params of the HttpMethod using this entity.
+ */
+ public MultipartRequestEntity(Part[] parts, HttpMethodParams params) {
+ if (parts == null) {
+ throw new IllegalArgumentException("parts cannot be null");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException("params cannot be null");
+ }
+ this.parts = parts;
+ this.params = params;
+ }
+
+ /**
+ * Returns the MIME boundary string that is used to demarcate boundaries of
+ * this part. The first call to this method will implicitly create a new
+ * boundary string. To create a boundary string first the
+ * HttpMethodParams.MULTIPART_BOUNDARY parameter is considered. Otherwise
+ * a random one is generated.
+ *
+ * @return The boundary string of this entity in ASCII encoding.
+ */
+ protected byte[] getMultipartBoundary() {
+ if (multipartBoundary == null) {
+ String temp = (String) params.getParameter(HttpMethodParams.MULTIPART_BOUNDARY);
+ if (temp != null) {
+ multipartBoundary = EncodingUtil.getAsciiBytes(temp);
+ } else {
+ multipartBoundary = generateMultipartBoundary();
+ }
+ }
+ return multipartBoundary;
+ }
+
+ /**
+ * Returns true
if all parts are repeatable, false
otherwise.
+ * @see org.apache.commons.httpclient.methods.RequestEntity#isRepeatable()
+ */
+ public boolean isRepeatable() {
+ for (int i = 0; i < parts.length; i++) {
+ if (!parts[i].isRepeatable()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#writeRequest(java.io.OutputStream)
+ */
+ public void writeRequest(OutputStream out) throws IOException {
+ Part.sendParts(out, parts, getMultipartBoundary());
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#getContentLength()
+ */
+ public long getContentLength() {
+ try {
+ return Part.getLengthOfParts(parts, getMultipartBoundary());
+ } catch (Exception e) {
+ log.error("An exception occurred while getting the length of the parts", e);
+ return 0;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType()
+ */
+ public String getContentType() {
+ StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
+ buffer.append("; boundary=");
+ buffer.append(EncodingUtil.getAsciiString(getMultipartBoundary()));
+ return buffer.toString();
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/Part.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/Part.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/Part.java 22 Aug 2012 17:30:39 -0000 1.1
@@ -0,0 +1,437 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.1 2012/08/22 17:30:39 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:39 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * null
to exclude the content type header
+ */
+ public abstract String getContentType();
+
+ /**
+ * Return the character encoding of this part.
+ * @return the character encoding, or null
to exclude the character
+ * encoding header
+ */
+ public abstract String getCharSet();
+
+ /**
+ * Return the transfer encoding of this part.
+ * @return the transfer encoding, or null
to exclude the transfer encoding header
+ */
+ public abstract String getTransferEncoding();
+
+ /**
+ * Gets the part boundary to be used.
+ * @return the part boundary as an array of bytes.
+ *
+ * @since 3.0
+ */
+ protected byte[] getPartBoundary() {
+ if (boundaryBytes == null) {
+ // custom boundary bytes have not been set, use the default.
+ return DEFAULT_BOUNDARY_BYTES;
+ } else {
+ return boundaryBytes;
+ }
+ }
+
+ /**
+ * Sets the part boundary. Only meant to be used by
+ * {@link Part#sendParts(OutputStream, Part[], byte[])}
+ * and {@link Part#getLengthOfParts(Part[], byte[])}
+ * @param boundaryBytes An array of ASCII bytes.
+ * @since 3.0
+ */
+ void setPartBoundary(byte[] boundaryBytes) {
+ this.boundaryBytes = boundaryBytes;
+ }
+
+ /**
+ * Tests if this part can be sent more than once.
+ * @return true
if {@link #sendData(OutputStream)} can be successfully called
+ * more than once.
+ * @since 3.0
+ */
+ public boolean isRepeatable() {
+ return true;
+ }
+
+ /**
+ * Write the start to the specified output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendStart(OutputStream out) throws IOException {
+ LOG.trace("enter sendStart(OutputStream out)");
+ out.write(EXTRA_BYTES);
+ out.write(getPartBoundary());
+ out.write(CRLF_BYTES);
+ }
+
+ /**
+ * Write the content disposition header to the specified output stream
+ *
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendDispositionHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendDispositionHeader(OutputStream out)");
+ out.write(CONTENT_DISPOSITION_BYTES);
+ out.write(QUOTE_BYTES);
+ out.write(EncodingUtil.getAsciiBytes(getName()));
+ out.write(QUOTE_BYTES);
+ }
+
+ /**
+ * Write the content type header to the specified output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendContentTypeHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendContentTypeHeader(OutputStream out)");
+ String contentType = getContentType();
+ if (contentType != null) {
+ out.write(CRLF_BYTES);
+ out.write(CONTENT_TYPE_BYTES);
+ out.write(EncodingUtil.getAsciiBytes(contentType));
+ String charSet = getCharSet();
+ if (charSet != null) {
+ out.write(CHARSET_BYTES);
+ out.write(EncodingUtil.getAsciiBytes(charSet));
+ }
+ }
+ }
+
+ /**
+ * Write the content transfer encoding header to the specified
+ * output stream
+ *
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendTransferEncodingHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendTransferEncodingHeader(OutputStream out)");
+ String transferEncoding = getTransferEncoding();
+ if (transferEncoding != null) {
+ out.write(CRLF_BYTES);
+ out.write(CONTENT_TRANSFER_ENCODING_BYTES);
+ out.write(EncodingUtil.getAsciiBytes(transferEncoding));
+ }
+ }
+
+ /**
+ * Write the end of the header to the output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendEndOfHeader(OutputStream out) throws IOException {
+ LOG.trace("enter sendEndOfHeader(OutputStream out)");
+ out.write(CRLF_BYTES);
+ out.write(CRLF_BYTES);
+ }
+
+ /**
+ * Write the data to the specified output stream
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected abstract void sendData(OutputStream out) throws IOException;
+
+ /**
+ * Return the length of the main content
+ *
+ * @return long The length.
+ * @throws IOException If an IO problem occurs
+ */
+ protected abstract long lengthOfData() throws IOException;
+
+ /**
+ * Write the end data to the output stream.
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ protected void sendEnd(OutputStream out) throws IOException {
+ LOG.trace("enter sendEnd(OutputStream out)");
+ out.write(CRLF_BYTES);
+ }
+
+ /**
+ * Write all the data to the output stream.
+ * If you override this method make sure to override
+ * #length() as well
+ *
+ * @param out The output stream
+ * @throws IOException If an IO problem occurs.
+ */
+ public void send(OutputStream out) throws IOException {
+ LOG.trace("enter send(OutputStream out)");
+ sendStart(out);
+ sendDispositionHeader(out);
+ sendContentTypeHeader(out);
+ sendTransferEncodingHeader(out);
+ sendEndOfHeader(out);
+ sendData(out);
+ sendEnd(out);
+ }
+
+
+ /**
+ * Return the full length of all the data.
+ * If you override this method make sure to override
+ * #send(OutputStream) as well
+ *
+ * @return long The length.
+ * @throws IOException If an IO problem occurs
+ */
+ public long length() throws IOException {
+ LOG.trace("enter length()");
+ if (lengthOfData() < 0) {
+ return -1;
+ }
+ ByteArrayOutputStream overhead = new ByteArrayOutputStream();
+ sendStart(overhead);
+ sendDispositionHeader(overhead);
+ sendContentTypeHeader(overhead);
+ sendTransferEncodingHeader(overhead);
+ sendEndOfHeader(overhead);
+ sendEnd(overhead);
+ return overhead.size() + lengthOfData();
+ }
+
+ /**
+ * Return a string representation of this object.
+ * @return A string representation of this object.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return this.getName();
+ }
+
+ /**
+ * Write all parts and the last boundary to the specified output stream.
+ *
+ * @param out The stream to write to.
+ * @param parts The parts to write.
+ *
+ * @throws IOException If an I/O error occurs while writing the parts.
+ */
+ public static void sendParts(OutputStream out, final Part[] parts)
+ throws IOException {
+ sendParts(out, parts, DEFAULT_BOUNDARY_BYTES);
+ }
+
+ /**
+ * Write all parts and the last boundary to the specified output stream.
+ *
+ * @param out The stream to write to.
+ * @param parts The parts to write.
+ * @param partBoundary The ASCII bytes to use as the part boundary.
+ *
+ * @throws IOException If an I/O error occurs while writing the parts.
+ *
+ * @since 3.0
+ */
+ public static void sendParts(OutputStream out, Part[] parts, byte[] partBoundary)
+ throws IOException {
+
+ if (parts == null) {
+ throw new IllegalArgumentException("Parts may not be null");
+ }
+ if (partBoundary == null || partBoundary.length == 0) {
+ throw new IllegalArgumentException("partBoundary may not be empty");
+ }
+ for (int i = 0; i < parts.length; i++) {
+ // set the part boundary before the part is sent
+ parts[i].setPartBoundary(partBoundary);
+ parts[i].send(out);
+ }
+ out.write(EXTRA_BYTES);
+ out.write(partBoundary);
+ out.write(EXTRA_BYTES);
+ out.write(CRLF_BYTES);
+ }
+
+ /**
+ * Return the total sum of all parts and that of the last boundary
+ *
+ * @param parts The parts.
+ * @return The total length
+ *
+ * @throws IOException If an I/O error occurs while writing the parts.
+ */
+ public static long getLengthOfParts(Part[] parts)
+ throws IOException {
+ return getLengthOfParts(parts, DEFAULT_BOUNDARY_BYTES);
+ }
+
+ /**
+ * Gets the length of the multipart message including the given parts.
+ *
+ * @param parts The parts.
+ * @param partBoundary The ASCII bytes to use as the part boundary.
+ * @return The total length
+ *
+ * @throws IOException If an I/O error occurs while writing the parts.
+ *
+ * @since 3.0
+ */
+ public static long getLengthOfParts(Part[] parts, byte[] partBoundary) throws IOException {
+ LOG.trace("getLengthOfParts(Parts[])");
+ if (parts == null) {
+ throw new IllegalArgumentException("Parts may not be null");
+ }
+ long total = 0;
+ for (int i = 0; i < parts.length; i++) {
+ // set the part boundary before we calculate the part's length
+ parts[i].setPartBoundary(partBoundary);
+ long l = parts[i].length();
+ if (l < 0) {
+ return -1;
+ }
+ total += l;
+ }
+ total += EXTRA_BYTES.length;
+ total += partBoundary.length;
+ total += EXTRA_BYTES.length;
+ total += CRLF_BYTES.length;
+ return total;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartBase.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartBase.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartBase.java 22 Aug 2012 17:30:39 -0000 1.1
@@ -0,0 +1,145 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartBase.java,v 1.1 2012/08/22 17:30:39 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:39 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * null
+ * @param charSet The character encoding, or null
+ * @param transferEncoding The transfer encoding, or null
+ */
+ public PartBase(String name, String contentType, String charSet, String transferEncoding) {
+
+ if (name == null) {
+ throw new IllegalArgumentException("Name must not be null");
+ }
+ this.name = name;
+ this.contentType = contentType;
+ this.charSet = charSet;
+ this.transferEncoding = transferEncoding;
+ }
+
+ /**
+ * Returns the name.
+ * @return The name.
+ * @see org.apache.commons.httpclient.methods.multipart.Part#getName()
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Returns the content type of this part.
+ * @return String The name.
+ */
+ public String getContentType() {
+ return this.contentType;
+ }
+
+ /**
+ * Return the character encoding of this part.
+ * @return String The name.
+ */
+ public String getCharSet() {
+ return this.charSet;
+ }
+
+ /**
+ * Returns the transfer encoding of this part.
+ * @return String The name.
+ */
+ public String getTransferEncoding() {
+ return transferEncoding;
+ }
+
+ /**
+ * Sets the character encoding.
+ *
+ * @param charSet the character encoding, or null
to exclude the character
+ * encoding header
+ */
+ public void setCharSet(String charSet) {
+ this.charSet = charSet;
+ }
+
+ /**
+ * Sets the content type.
+ *
+ * @param contentType the content type, or null
to exclude the content type header
+ */
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ /**
+ * Sets the part name.
+ *
+ * @param name
+ */
+ public void setName(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Name must not be null");
+ }
+ this.name = name;
+ }
+
+ /**
+ * Sets the transfer encoding.
+ *
+ * @param transferEncoding the transfer encoding, or null
to exclude the
+ * transfer encoding header
+ */
+ public void setTransferEncoding(String transferEncoding) {
+ this.transferEncoding = transferEncoding;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartSource.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartSource.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartSource.java 22 Aug 2012 17:30:39 -0000 1.1
@@ -0,0 +1,71 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartSource.java,v 1.1 2012/08/22 17:30:39 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:39 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * null
+ * the {@link #DEFAULT_CHARSET default} is used
+ */
+ public StringPart(String name, String value, String charset) {
+
+ super(
+ name,
+ DEFAULT_CONTENT_TYPE,
+ charset == null ? DEFAULT_CHARSET : charset,
+ DEFAULT_TRANSFER_ENCODING
+ );
+ if (value == null) {
+ throw new IllegalArgumentException("Value may not be null");
+ }
+ if (value.indexOf(0) != -1) {
+ // See RFC 2048, 2.8. "8bit Data"
+ throw new IllegalArgumentException("NULs may not be present in string parts");
+ }
+ this.value = value;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the part
+ * @param value the string to post
+ */
+ public StringPart(String name, String value) {
+ this(name, value, null);
+ }
+
+ /**
+ * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
+ * after the part is created.
+ *
+ * @return the content in bytes
+ */
+ private byte[] getContent() {
+ if (content == null) {
+ content = EncodingUtil.getBytes(value, getCharSet());
+ }
+ return content;
+ }
+
+ /**
+ * Writes the data to the given OutputStream.
+ * @param out the OutputStream to write to
+ * @throws IOException if there is a write error
+ */
+ protected void sendData(OutputStream out) throws IOException {
+ LOG.trace("enter sendData(OutputStream)");
+ out.write(getContent());
+ }
+
+ /**
+ * Return the length of the data.
+ * @return The length of the data.
+ * @throws IOException If an IO problem occurs
+ * @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
+ */
+ protected long lengthOfData() throws IOException {
+ LOG.trace("enter lengthOfData()");
+ return getContent().length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.methods.multipart.BasePart#setCharSet(java.lang.String)
+ */
+ public void setCharSet(String charSet) {
+ super.setCharSet(charSet);
+ this.content = null;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/package.html
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/package.html,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/package.html 22 Aug 2012 17:30:39 -0000 1.1
@@ -0,0 +1,11 @@
+
+
+
+ HttpParamsFactory#getDefaultParams()
+ *
+ * @see HttpParamsFactory#getDefaultParams()
+ */
+ public static HttpParams getDefaultParams() {
+ return httpParamsFactory.getDefaultParams();
+ }
+
+ /**
+ * Sets the factory that will provide the default HttpParams.
+ *
+ * @param httpParamsFactory an instance of HttpParamsFactory
+ *
+ * @see #getDefaultParams()
+ */
+ public static void setHttpParamsFactory(HttpParamsFactory httpParamsFactory) {
+ if (httpParamsFactory == null) {
+ throw new IllegalArgumentException("httpParamsFactory may not be null");
+ }
+ DefaultHttpParams.httpParamsFactory = httpParamsFactory;
+ }
+
+ /** The set of default values to defer to */
+ private HttpParams defaults = null;
+
+ /** Hash map of HTTP parameters that this collection contains */
+ private HashMap parameters = null;
+
+ /**
+ * Creates a new collection of parameters with the given parent.
+ * The collection will defer to its parent for a default value
+ * if a particular parameter is not explicitly set in the collection
+ * itself.
+ *
+ * @param defaults the parent collection to defer to, if a parameter
+ * is not explictly set in the collection itself.
+ */
+ public DefaultHttpParams(final HttpParams defaults) {
+ super();
+ this.defaults = defaults;
+ }
+
+ /**
+ * Creates a new collection of parameters with the collection returned
+ * by {@link #getDefaultParams()} as a parent. The collection will defer
+ * to its parent for a default value if a particular parameter is not
+ * explicitly set in the collection itself.
+ *
+ * @see #getDefaultParams()
+ */
+ public DefaultHttpParams() {
+ this(getDefaultParams());
+ }
+
+ public synchronized HttpParams getDefaults() {
+ return this.defaults;
+ }
+
+ public synchronized void setDefaults(final HttpParams params) {
+ this.defaults = params;
+ }
+
+ public synchronized Object getParameter(final String name) {
+ // See if the parameter has been explicitly defined
+ Object param = null;
+ if (this.parameters != null) {
+ param = this.parameters.get(name);
+ }
+ if (param != null) {
+ // If so, return
+ return param;
+ } else {
+ // If not, see if defaults are available
+ if (this.defaults != null) {
+ // Return default parameter value
+ return this.defaults.getParameter(name);
+ } else {
+ // Otherwise, return null
+ return null;
+ }
+ }
+ }
+
+ public synchronized void setParameter(final String name, final Object value) {
+ if (this.parameters == null) {
+ this.parameters = new HashMap();
+ }
+ this.parameters.put(name, value);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Set parameter " + name + " = " + value);
+ }
+ }
+
+ /**
+ * Assigns the value to all the parameter with the given names
+ *
+ * @param names array of parameter name
+ * @param value parameter value
+ */
+ public synchronized void setParameters(final String[] names, final Object value) {
+ for (int i = 0; i < names.length; i++) {
+ setParameter(names[i], value);
+ }
+ }
+
+ public long getLongParameter(final String name, long defaultValue) {
+ Object param = getParameter(name);
+ if (param == null) {
+ return defaultValue;
+ }
+ return ((Long)param).longValue();
+ }
+
+ public void setLongParameter(final String name, long value) {
+ setParameter(name, new Long(value));
+ }
+
+ public int getIntParameter(final String name, int defaultValue) {
+ Object param = getParameter(name);
+ if (param == null) {
+ return defaultValue;
+ }
+ return ((Integer)param).intValue();
+ }
+
+ public void setIntParameter(final String name, int value) {
+ setParameter(name, new Integer(value));
+ }
+
+ public double getDoubleParameter(final String name, double defaultValue) {
+ Object param = getParameter(name);
+ if (param == null) {
+ return defaultValue;
+ }
+ return ((Double)param).doubleValue();
+ }
+
+ public void setDoubleParameter(final String name, double value) {
+ setParameter(name, new Double(value));
+ }
+
+ public boolean getBooleanParameter(final String name, boolean defaultValue) {
+ Object param = getParameter(name);
+ if (param == null) {
+ return defaultValue;
+ }
+ return ((Boolean)param).booleanValue();
+ }
+
+ public void setBooleanParameter(final String name, boolean value) {
+ setParameter(name, new Boolean(value));
+ }
+
+ public boolean isParameterSet(final String name) {
+ return getParameter(name) != null;
+ }
+
+ public boolean isParameterSetLocally(final String name) {
+ return this.parameters != null && this.parameters.get(name) != null;
+ }
+
+ public boolean isParameterTrue(final String name) {
+ return getBooleanParameter(name, false);
+ }
+
+ public boolean isParameterFalse(final String name) {
+ return !getBooleanParameter(name, false);
+ }
+
+ /**
+ * Removes all parameters from this collection.
+ */
+ public void clear() {
+ this.parameters = null;
+ }
+
+ /**
+ * Clones this collection of parameters. Please note that paramter values
+ * themselves are not cloned.
+ *
+ * @see java.io.Serializable
+ * @see java.lang.Object#clone()
+ */
+ public Object clone() throws CloneNotSupportedException
+ {
+ DefaultHttpParams clone = (DefaultHttpParams)super.clone();
+ if (this.parameters != null) {
+ clone.parameters = (HashMap)this.parameters.clone();
+ }
+ clone.setDefaults(this.defaults);
+ return clone;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,144 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * This parameter expects a value of type {@link java.util.Collection}. The + * collection is expected to contain {@link org.apache.commons.httpclient.Header}s. + *
+ */ + public static final String DEFAULT_HEADERS = "http.default-headers"; + + /** + * Creates a new collection of parameters with the collection returned + * by {@link #getDefaultParams()} as a parent. The collection will defer + * to its parent for a default value if a particular parameter is not + * explicitly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HostParams() { + super(); + } + + /** + * Creates a new collection of parameters with the given parent. + * The collection will defer to its parent for a default value + * if a particular parameter is not explicitly set in the collection + * itself. + * + * @param defaults the parent collection to defer to, if a parameter + * is not explictly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HostParams(HttpParams defaults) { + super(defaults); + } + + /** + * Sets the virtual host name. + * + * @param hostname The host name + */ + public void setVirtualHost(final String hostname) { + setParameter(HttpMethodParams.VIRTUAL_HOST, hostname); + } + + /** + * Returns the virtual host name. + * + * @return The virtual host name + */ + public String getVirtualHost() { + return (String) getParameter(HttpMethodParams.VIRTUAL_HOST); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpClientParams.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpClientParams.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpClientParams.java 22 Aug 2012 17:30:39 -0000 1.1 @@ -0,0 +1,210 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpClientParams.java,v 1.1 2012/08/22 17:30:39 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:39 $ + * + * ==================================================================== + * + * 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 + *+ * This parameter expects a value of type {@link Long}. + *
+ */ + public static final String CONNECTION_MANAGER_TIMEOUT = "http.connection-manager.timeout"; + + /** + * Defines the default + * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager} + * class. + *+ * This parameter expects a value of type {@link Class}. + *
+ */ + public static final String CONNECTION_MANAGER_CLASS = "http.connection-manager.class"; + + /** + * Defines whether authentication should be attempted preemptively. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String PREEMPTIVE_AUTHENTICATION = "http.authentication.preemptive"; + + /** + * Defines whether relative redirects should be rejected. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String REJECT_RELATIVE_REDIRECT = "http.protocol.reject-relative-redirect"; + + /** + * Defines the maximum number of redirects to be followed. + * The limit on number of redirects is intended to prevent infinite loops. + *+ * This parameter expects a value of type {@link Integer}. + *
+ */ + public static final String MAX_REDIRECTS = "http.protocol.max-redirects"; + + /** + * Defines whether circular redirects (redirects to the same location) should be allowed. + * The HTTP spec is not sufficiently clear whether circular redirects are permitted, + * therefore optionally they can be enabled + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String ALLOW_CIRCULAR_REDIRECTS = "http.protocol.allow-circular-redirects"; + + /** + * Creates a new collection of parameters with the collection returned + * by {@link #getDefaultParams()} as a parent. The collection will defer + * to its parent for a default value if a particular parameter is not + * explicitly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HttpClientParams() { + super(); + } + + /** + * Creates a new collection of parameters with the given parent. + * The collection will defer to its parent for a default value + * if a particular parameter is not explicitly set in the collection + * itself. + * + * @param defaults the parent collection to defer to, if a parameter + * is not explictly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HttpClientParams(HttpParams defaults) { + super(defaults); + } + + /** + * Returns the timeout in milliseconds used when retrieving an + * {@link org.apache.commons.httpclient.HttpConnection HTTP connection} from the + * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager}. + * + * @return timeout in milliseconds. + */ + public long getConnectionManagerTimeout() { + return getLongParameter(CONNECTION_MANAGER_TIMEOUT, 0); + } + + /** + * Sets the timeout in milliseconds used when retrieving an + * {@link org.apache.commons.httpclient.HttpConnection HTTP connection} from the + * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager}. + * + * @param timeout the timeout in milliseconds + */ + public void setConnectionManagerTimeout(long timeout) { + setLongParameter(CONNECTION_MANAGER_TIMEOUT, timeout); + } + + /** + * Returns the default + * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager} + * class. + * @return {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager} + * factory class. + */ + public Class getConnectionManagerClass() { + return (Class) getParameter(CONNECTION_MANAGER_CLASS); + } + + /** + * Sets {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager} + * class to be used der default. + * @param clazz + * {@link org.apache.commons.httpclient.HttpConnectionManager HTTP connection manager} + * factory class. + */ + public void setConnectionManagerClass(Class clazz) { + setParameter(CONNECTION_MANAGER_CLASS, clazz); + } + + /** + * Returns true if authentication should be attempted preemptively, + * false otherwise. + * + * @return true if authentication should be attempted preemptively, + * false otherwise. + */ + public boolean isAuthenticationPreemptive() { + return getBooleanParameter(PREEMPTIVE_AUTHENTICATION, false); + } + + /** + * Sets whether authentication should be attempted preemptively. + * + * @param value true if authentication should be attempted preemptively, + * false otherwise. + */ + public void setAuthenticationPreemptive(boolean value) { + setBooleanParameter(PREEMPTIVE_AUTHENTICATION, value); + } + + private static final String[] PROTOCOL_STRICTNESS_PARAMETERS = { + REJECT_RELATIVE_REDIRECT, + ALLOW_CIRCULAR_REDIRECTS + }; + + + public void makeStrict() { + super.makeStrict(); + setParameters(PROTOCOL_STRICTNESS_PARAMETERS, Boolean.TRUE); + } + + + public void makeLenient() { + super.makeLenient(); + setParameters(PROTOCOL_STRICTNESS_PARAMETERS, Boolean.FALSE); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,189 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * 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 + *+ * This parameter expects a value of type {@link java.util.Map}. The value + * should map instances of {@link org.apache.commons.httpclient.HostConfiguration} + * to {@link Integer integers}. The default value can be specified using + * {@link org.apache.commons.httpclient.HostConfiguration#ANY_HOST_CONFIGURATION}. + *
+ */ + public static final String MAX_HOST_CONNECTIONS = "http.connection-manager.max-per-host"; + + /** + * Defines the maximum number of connections allowed overall. This value only applies + * to the number of connections from a particular instance of HttpConnectionManager. + *+ * This parameter expects a value of type {@link Integer}. + *
+ */ + public static final String MAX_TOTAL_CONNECTIONS = "http.connection-manager.max-total"; + + /** + * Sets the default maximum number of connections allowed for a given + * host config. + * + * @param maxHostConnections The default maximum. + * + * @see #MAX_HOST_CONNECTIONS + */ + public void setDefaultMaxConnectionsPerHost(int maxHostConnections) { + setMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION, maxHostConnections); + } + + /** + * Sets the maximum number of connections to be used for the given host config. + * + * @param hostConfiguration The host config to set the maximum for. Use + * {@link HostConfiguration#ANY_HOST_CONFIGURATION} to configure the default value + * per host. + * @param maxHostConnections The maximum number of connections,> 0
+ *
+ * @see #MAX_HOST_CONNECTIONS
+ */
+ public void setMaxConnectionsPerHost(
+ HostConfiguration hostConfiguration,
+ int maxHostConnections) {
+
+ if (maxHostConnections <= 0) {
+ throw new IllegalArgumentException("maxHostConnections must be greater than 0");
+ }
+
+ Map currentValues = (Map) getParameter(MAX_HOST_CONNECTIONS);
+ // param values are meant to be immutable so we'll make a copy
+ // to modify
+ Map newValues = null;
+ if (currentValues == null) {
+ newValues = new HashMap();
+ } else {
+ newValues = new HashMap(currentValues);
+ }
+ newValues.put(hostConfiguration, new Integer(maxHostConnections));
+ setParameter(MAX_HOST_CONNECTIONS, newValues);
+ }
+
+ /**
+ * Gets the default maximum number of connections allowed for a given
+ * host config.
+ *
+ * @return The default maximum.
+ *
+ * @see #MAX_HOST_CONNECTIONS
+ */
+ public int getDefaultMaxConnectionsPerHost() {
+ return getMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION);
+ }
+
+ /**
+ * Gets the maximum number of connections to be used for a particular host config. If
+ * the value has not been specified for the given host the default value will be
+ * returned.
+ *
+ * @param hostConfiguration The host config.
+ * @return The maximum number of connections to be used for the given host config.
+ *
+ * @see #MAX_HOST_CONNECTIONS
+ */
+ public int getMaxConnectionsPerHost(HostConfiguration hostConfiguration) {
+
+ Map m = (Map) getParameter(MAX_HOST_CONNECTIONS);
+ if (m == null) {
+ // MAX_HOST_CONNECTIONS have not been configured, using the default value
+ return MultiThreadedHttpConnectionManager.DEFAULT_MAX_HOST_CONNECTIONS;
+ } else {
+ Integer max = (Integer) m.get(hostConfiguration);
+ if (max == null && hostConfiguration != HostConfiguration.ANY_HOST_CONFIGURATION) {
+ // the value has not been configured specifically for this host config,
+ // use the default value
+ return getMaxConnectionsPerHost(HostConfiguration.ANY_HOST_CONFIGURATION);
+ } else {
+ return (
+ max == null
+ ? MultiThreadedHttpConnectionManager.DEFAULT_MAX_HOST_CONNECTIONS
+ : max.intValue()
+ );
+ }
+ }
+ }
+
+ /**
+ * Sets the maximum number of connections allowed.
+ *
+ * @param maxTotalConnections The maximum number of connections allowed.
+ *
+ * @see #MAX_TOTAL_CONNECTIONS
+ */
+ public void setMaxTotalConnections(int maxTotalConnections) {
+ setIntParameter(
+ HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS,
+ maxTotalConnections);
+ }
+
+ /**
+ * Gets the maximum number of connections allowed.
+ *
+ * @return The maximum number of connections allowed.
+ *
+ * @see #MAX_TOTAL_CONNECTIONS
+ */
+ public int getMaxTotalConnections() {
+ return getIntParameter(
+ HttpConnectionManagerParams.MAX_TOTAL_CONNECTIONS,
+ MultiThreadedHttpConnectionManager.DEFAULT_MAX_TOTAL_CONNECTIONS);
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionParams.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionParams.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionParams.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,305 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionParams.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * This parameter expects a value of type {@link Integer}. + *
+ * @see java.net.SocketOptions#SO_TIMEOUT + */ + public static final String SO_TIMEOUT = "http.socket.timeout"; + + /** + * Determines whether Nagle's algorithm is to be used. The Nagle's algorithm + * tries to conserve bandwidth by minimizing the number of segments that are + * sent. When applications wish to decrease network latency and increase + * performance, they can disable Nagle's algorithm (that is enable TCP_NODELAY). + * Data will be sent earlier, at the cost of an increase in bandwidth consumption. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ * @see java.net.SocketOptions#TCP_NODELAY + */ + public static final String TCP_NODELAY = "http.tcp.nodelay"; + + /** + * Determines a hint the size of the underlying buffers used by the platform + * for outgoing network I/O. This value is a suggestion to the kernel from + * the application about the size of buffers to use for the data to be sent + * over the socket. + *+ * This parameter expects a value of type {@link Integer}. + *
+ * @see java.net.SocketOptions#SO_SNDBUF + */ + public static final String SO_SNDBUF = "http.socket.sendbuffer"; + + /** + * Determines a hint the size of the underlying buffers used by the platform + * for incoming network I/O. This value is a suggestion to the kernel from + * the application about the size of buffers to use for the data to be received + * over the socket. + *+ * This parameter expects a value of type {@link Integer}. + *
+ * @see java.net.SocketOptions#SO_RCVBUF + */ + public static final String SO_RCVBUF = "http.socket.receivebuffer"; + + /** + * Sets SO_LINGER with the specified linger time in seconds. The maximum timeout + * value is platform specific. Value 0 implies that the option is disabled. + * Value -1 implies that the JRE default is used. The setting only affects + * socket close. + *+ * This parameter expects a value of type {@link Integer}. + *
+ * @see java.net.SocketOptions#SO_LINGER + */ + public static final String SO_LINGER = "http.socket.linger"; + + /** + * Determines the timeout until a connection is etablished. A value of zero + * means the timeout is not used. The default value is zero. + *+ * This parameter expects a value of type {@link Integer}. + *
+ */ + public static final String CONNECTION_TIMEOUT = "http.connection.timeout"; + + /** + * Determines whether stale connection check is to be used. Disabling + * stale connection check may result in slight performance improvement + * at the risk of getting an I/O error when executing a request over a + * connection that has been closed at the server side. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String STALE_CONNECTION_CHECK = "http.connection.stalecheck"; + + /** + * Creates a new collection of parameters with the collection returned + * by {@link #getDefaultParams()} as a parent. The collection will defer + * to its parent for a default value if a particular parameter is not + * explicitly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HttpConnectionParams() { + super(); + } + + /** + * Returns the default socket timeout (SO_TIMEOUT) in milliseconds which is the + * timeout for waiting for data. A timeout value of zero is interpreted as an infinite + * timeout. This value is used when no socket timeout is set in the + * {@link HttpMethodParams HTTP method parameters}. + * + * @return timeout in milliseconds + */ + public int getSoTimeout() { + return getIntParameter(SO_TIMEOUT, 0); + } + + /** + * Sets the default socket timeout (SO_TIMEOUT) in milliseconds which is the + * timeout for waiting for data. A timeout value of zero is interpreted as an infinite + * timeout. This value is used when no socket timeout is set in the + * {@link HttpMethodParams HTTP method parameters}. + * + * @param timeout Timeout in milliseconds + */ + public void setSoTimeout(int timeout) { + setIntParameter(SO_TIMEOUT, timeout); + } + + /** + * Determines whether Nagle's algorithm is to be used. The Nagle's algorithm + * tries to conserve bandwidth by minimizing the number of segments that are + * sent. When applications wish to decrease network latency and increase + * performance, they can disable Nagle's algorithm (that is enable TCP_NODELAY). + * Data will be sent earlier, at the cost of an increase in bandwidth consumption. + * + * @param value true if the Nagle's algorithm is to NOT be used + * (that is enable TCP_NODELAY), false otherwise. + */ + public void setTcpNoDelay(boolean value) { + setBooleanParameter(TCP_NODELAY, value); + } + + /** + * Tests if Nagle's algorithm is to be used. + * + * @return true if the Nagle's algorithm is to NOT be used + * (that is enable TCP_NODELAY), false otherwise. + */ + public boolean getTcpNoDelay() { + return getBooleanParameter(TCP_NODELAY, true); + } + + /** + * Returns a hint the size of the underlying buffers used by the platform for + * outgoing network I/O. This value is a suggestion to the kernel from the + * application about the size of buffers to use for the data to be sent over + * the socket. + * + * @return the hint size of the send buffer + */ + public int getSendBufferSize() { + return getIntParameter(SO_SNDBUF, -1); + } + + /** + * Sets a hint the size of the underlying buffers used by the platform for + * outgoing network I/O. This value is a suggestion to the kernel from the + * application about the size of buffers to use for the data to be sent over + * the socket. + * + * @param size the hint size of the send buffer + */ + public void setSendBufferSize(int size) { + setIntParameter(SO_SNDBUF, size); + } + + /** + * Returns a hint the size of the underlying buffers used by the platform + * for incoming network I/O. This value is a suggestion to the kernel from + * the application about the size of buffers to use for the data to be received + * over the socket. + * + * @return the hint size of the send buffer + */ + public int getReceiveBufferSize() { + return getIntParameter(SO_RCVBUF, -1); + } + + /** + * Sets a hint the size of the underlying buffers used by the platform + * for incoming network I/O. This value is a suggestion to the kernel from + * the application about the size of buffers to use for the data to be received + * over the socket. + * + * @param size the hint size of the send buffer + */ + public void setReceiveBufferSize(int size) { + setIntParameter(SO_RCVBUF, size); + } + + /** + * Returns linger-on-close timeout. Value 0 implies that the option is + * disabled. Value -1 implies that the JRE default is used. + * + * @return the linger-on-close timeout + */ + public int getLinger() { + return getIntParameter(SO_LINGER, -1); + } + + /** + * Returns linger-on-close timeout. This option disables/enables immediate return + * from a close() of a TCP Socket. Enabling this option with a non-zero Integer + * timeout means that a close() will block pending the transmission and + * acknowledgement of all data written to the peer, at which point the socket is + * closed gracefully. Value 0 implies that the option is + * disabled. Value -1 implies that the JRE default is used. + * + * @param value the linger-on-close timeout + */ + public void setLinger(int value) { + setIntParameter(SO_LINGER, value); + } + + /** + * Returns the timeout until a connection is etablished. A value of zero + * means the timeout is not used. The default value is zero. + * + * @return timeout in milliseconds. + */ + public int getConnectionTimeout() { + return getIntParameter(CONNECTION_TIMEOUT, 0); + } + + /** + * Sets the timeout until a connection is etablished. A value of zero + * means the timeout is not used. The default value is zero. + * + * @param timeout Timeout in milliseconds. + */ + public void setConnectionTimeout(int timeout) { + setIntParameter(CONNECTION_TIMEOUT, timeout); + } + + /** + * Tests whether stale connection check is to be used. Disabling + * stale connection check may result in slight performance improvement + * at the risk of getting an I/O error when executing a request over a + * connection that has been closed at the server side. + * + * @return true if stale connection check is to be used, + * false otherwise. + */ + public boolean isStaleCheckingEnabled() { + return getBooleanParameter(STALE_CONNECTION_CHECK, true); + } + + /** + * Defines whether stale connection check is to be used. Disabling + * stale connection check may result in slight performance improvement + * at the risk of getting an I/O error when executing a request over a + * connection that has been closed at the server side. + * + * @param value true if stale connection check is to be used, + * false otherwise. + */ + public void setStaleCheckingEnabled(boolean value) { + setBooleanParameter(STALE_CONNECTION_CHECK, value); + } +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpMethodParams.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpMethodParams.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpMethodParams.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,493 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpMethodParams.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * 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 + *+ * This parameter expects a value of type {@link String}. + *
+ */ + public static final String USER_AGENT = "http.useragent"; + + /** + * Defines the {@link HttpVersion HTTP protocol version} used by + * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} per + * default. + *+ * This parameter expects a value of type {@link HttpVersion}. + *
+ */ + public static final String PROTOCOL_VERSION = "http.protocol.version"; + + /** + * Defines whether {@link org.apache.commons.httpclient.HttpMethod HTTP methods} should + * reject ambiguous {@link org.apache.commons.httpclient.StatusLine HTTP status line}. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String UNAMBIGUOUS_STATUS_LINE = "http.protocol.unambiguous-statusline"; + + /** + * Defines whether {@link org.apache.commons.httpclient.Cookie cookies} should be put on + * a single {@link org.apache.commons.httpclient.Header response header}. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; + + /** + * Defines whether responses with an invalid Transfer-Encoding header should be + * rejected. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String STRICT_TRANSFER_ENCODING = "http.protocol.strict-transfer-encoding"; + + /** + * Defines whether the content body sent in response to + * {@link org.apache.commons.httpclient.methods.HeadMethod} should be rejected. + *+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String REJECT_HEAD_BODY = "http.protocol.reject-head-body"; + + /** + * Sets period of time in milliseconds to wait for a content body sent in response to + * {@link org.apache.commons.httpclient.methods.HeadMethod HEAD method} from a + * non-compliant server. If the parameter is not set or set to -1 non-compliant + * response body check is disabled. + *+ * This parameter expects a value of type {@link Integer}. + *
+ */ + public static final String HEAD_BODY_CHECK_TIMEOUT = "http.protocol.head-body-timeout"; + + /** + *+ * Activates 'Expect: 100-Continue' handshake for the + * {@link org.apache.commons.httpclient.methods.ExpectContinueMethod + * entity enclosing methods}. The purpose of the 'Expect: 100-Continue' + * handshake to allow a client that is sending a request message with + * a request body to determine if the origin server is willing to + * accept the request (based on the request headers) before the client + * sends the request body. + *
+ * + *+ * The use of the 'Expect: 100-continue' handshake can result in + * noticable peformance improvement for entity enclosing requests + * (such as POST and PUT) that require the target server's + * authentication. + *
+ * + *+ * 'Expect: 100-continue' handshake should be used with + * caution, as it may cause problems with HTTP servers and + * proxies that do not support HTTP/1.1 protocol. + *
+ * + * This parameter expects a value of type {@link Boolean}. + */ + public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue"; + + /** + * Defines the charset to be used when encoding + * {@link org.apache.commons.httpclient.Credentials}. If not defined then the + * {@link #HTTP_ELEMENT_CHARSET} should be used. + *+ * This parameter expects a value of type {@link String}. + *
+ */ + public static final String CREDENTIAL_CHARSET = "http.protocol.credential-charset"; + + /** + * Defines the charset to be used for encoding HTTP protocol elements. + *+ * This parameter expects a value of type {@link String}. + *
+ */ + public static final String HTTP_ELEMENT_CHARSET = "http.protocol.element-charset"; + + /** + * Defines the charset to be used for encoding content body. + *+ * This parameter expects a value of type {@link String}. + *
+ */ + public static final String HTTP_CONTENT_CHARSET = "http.protocol.content-charset"; + + /** + * Defines {@link CookiePolicy cookie policy} to be used for cookie management. + *+ * This parameter expects a value of type {@link String}. + *
+ */ + public static final String COOKIE_POLICY = "http.protocol.cookie-policy"; + + /** + * Defines HttpClient's behavior when a response provides more bytes than + * expected (specified with Content-Length, for example). + *+ * Such surplus data makes the HTTP connection unreliable for keep-alive + * requests, as malicious response data (faked headers etc.) can lead to undesired + * results on the next request using that connection. + *
+ *
+ * If this parameter is set to true
, any detection of extra
+ * input data will generate a warning in the log.
+ *
+ * This parameter expects a value of type {@link Boolean}. + *
+ */ + public static final String WARN_EXTRA_INPUT = "http.protocol.warn-extra-input"; + + /** + * Defines the maximum number of ignorable lines before we expect + * a HTTP response's status code. + *
+ * With HTTP/1.1 persistent connections, the problem arises that
+ * broken scripts could return a wrong Content-Length
+ * (there are more bytes sent than specified).
+ * Unfortunately, in some cases, this is not possible after the bad response,
+ * but only before the next one.
+ * So, HttpClient must be able to skip those surplus lines this way.
+ *
+ * Set this to 0 to disallow any garbage/empty lines before the status line.
+ * To specify no limit, use {@link java.lang.Integer#MAX_VALUE} (default in lenient mode).
+ *
+ * This parameter expects a value of type {@link Integer}. + *
+ * @see java.net.SocketOptions#SO_TIMEOUT + */ + public static final String SO_TIMEOUT = "http.socket.timeout"; + + /** + * The key used to look up the date patterns used for parsing. The String patterns are stored + * in a {@link java.util.Collection} and must be compatible with + * {@link java.text.SimpleDateFormat}. + *+ * This parameter expects a value of type {@link java.util.Collection}. + *
+ */ + public static final String DATE_PATTERNS = "http.dateparser.patterns"; + + /** + * Sets the method retry handler parameter. + *+ * This parameter expects a value of type {@link org.apache.commons.httpclient.HttpMethodRetryHandler}. + *
+ */ + public static final String RETRY_HANDLER = "http.method.retry-handler"; + + /** + * Sets the maximum buffered response size (in bytes) that triggers no warning. Buffered + * responses exceeding this size will trigger a warning in the log. + *+ * This parameter expects a value if type {@link Integer}. + *
+ */ + public static final String BUFFER_WARN_TRIGGER_LIMIT = "http.method.response.buffer.warnlimit"; + + /** + * Defines the virtual host name. + *+ * This parameter expects a value of type {@link java.lang.String}. + *
+ */ + public static final String VIRTUAL_HOST = "http.virtual-host"; + + /** + * Sets the value to use as the multipart boundary. + *+ * This parameter expects a value if type {@link String}. + *
+ * @see org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity + */ + public static final String MULTIPART_BOUNDARY = "http.method.multipart.boundary"; + + /** + * Creates a new collection of parameters with the collection returned + * by {@link #getDefaultParams()} as a parent. The collection will defer + * to its parent for a default value if a particular parameter is not + * explicitly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HttpMethodParams() { + super(getDefaultParams()); + } + + /** + * Creates a new collection of parameters with the given parent. + * The collection will defer to its parent for a default value + * if a particular parameter is not explicitly set in the collection + * itself. + * + * @param defaults the parent collection to defer to, if a parameter + * is not explictly set in the collection itself. + * + * @see #getDefaultParams() + */ + public HttpMethodParams(HttpParams defaults) { + super(defaults); + } + + /** + * Returns the charset to be used for writing HTTP headers. + * @return The charset + */ + public String getHttpElementCharset() { + String charset = (String) getParameter(HTTP_ELEMENT_CHARSET); + if (charset == null) { + LOG.warn("HTTP element charset not configured, using US-ASCII"); + charset = "US-ASCII"; + } + return charset; + } + + /** + * Sets the charset to be used for writing HTTP headers. + * @param charset The charset + */ + public void setHttpElementCharset(String charset) { + setParameter(HTTP_ELEMENT_CHARSET, charset); + } + + /** + * Returns the default charset to be used for writing content body, + * when no charset explicitly specified. + * @return The charset + */ + public String getContentCharset() { + String charset = (String) getParameter(HTTP_CONTENT_CHARSET); + if (charset == null) { + LOG.warn("Default content charset not configured, using ISO-8859-1"); + charset = "ISO-8859-1"; + } + return charset; + } + + /** + * Sets the default charset to be used for writing content body, + * when no charset explicitly specified. + * @param charset The charset + */ + public void setContentCharset(String charset) { + setParameter(HTTP_CONTENT_CHARSET, charset); + } + + /** + * Returns the charset to be used for {@link org.apache.commons.httpclient.Credentials}. If + * not configured the {@link #HTTP_ELEMENT_CHARSET HTTP element charset} is used. + * @return The charset + */ + public String getCredentialCharset() { + String charset = (String) getParameter(CREDENTIAL_CHARSET); + if (charset == null) { + LOG.debug("Credential charset not configured, using HTTP element charset"); + charset = getHttpElementCharset(); + } + return charset; + } + + /** + * Sets the charset to be used for writing HTTP headers. + * @param charset The charset + */ + public void setCredentialCharset(String charset) { + setParameter(CREDENTIAL_CHARSET, charset); + } + + /** + * Returns {@link HttpVersion HTTP protocol version} to be used by the + * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} that + * this collection of parameters applies to. + * + * @return {@link HttpVersion HTTP protocol version} + */ + public HttpVersion getVersion() { + Object param = getParameter(PROTOCOL_VERSION); + if (param == null) { + return HttpVersion.HTTP_1_1; + } + return (HttpVersion)param; + } + + /** + * Assigns the {@link HttpVersion HTTP protocol version} to be used by the + * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} that + * this collection of parameters applies to. + * + * @param version the {@link HttpVersion HTTP protocol version} + */ + public void setVersion(HttpVersion version) { + setParameter(PROTOCOL_VERSION, version); + } + + + /** + * Returns {@link CookiePolicy cookie policy} to be used by the + * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} + * this collection of parameters applies to. + * + * @return {@link CookiePolicy cookie policy} + */ + public String getCookiePolicy() { + Object param = getParameter(COOKIE_POLICY); + if (param == null) { + return CookiePolicy.DEFAULT; + } + return (String)param; + } + + /** + * Assigns the {@link CookiePolicy cookie policy} to be used by the + * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} + * this collection of parameters applies to. + * + * @param policy the {@link CookiePolicy cookie policy} + */ + public void setCookiePolicy(String policy) { + setParameter(COOKIE_POLICY, policy); + } + + /** + * Returns the default socket timeout (SO_TIMEOUT) in milliseconds which is the + * timeout for waiting for data. A timeout value of zero is interpreted as an infinite + * timeout. + * + * @return timeout in milliseconds + */ + public int getSoTimeout() { + return getIntParameter(SO_TIMEOUT, 0); + } + + /** + * Sets the default socket timeout (SO_TIMEOUT) in milliseconds which is the + * timeout for waiting for data. A timeout value of zero is interpreted as an infinite + * timeout. + * + * @param timeout Timeout in milliseconds + */ + public void setSoTimeout(int timeout) { + setIntParameter(SO_TIMEOUT, timeout); + } + + /** + * Sets the virtual host name. + * + * @param hostname The host name + */ + public void setVirtualHost(final String hostname) { + setParameter(VIRTUAL_HOST, hostname); + } + + /** + * Returns the virtual host name. + * + * @return The virtual host name + */ + public String getVirtualHost() { + return (String) getParameter(VIRTUAL_HOST); + } + + private static final String[] PROTOCOL_STRICTNESS_PARAMETERS = { + UNAMBIGUOUS_STATUS_LINE, + SINGLE_COOKIE_HEADER, + STRICT_TRANSFER_ENCODING, + REJECT_HEAD_BODY, + WARN_EXTRA_INPUT + }; + + /** + * Makes the {@link org.apache.commons.httpclient.HttpMethod HTTP methods} + * strictly follow the HTTP protocol specification (RFC 2616 and other relevant RFCs). + * It must be noted that popular HTTP agents have different degree of HTTP protocol + * compliance and some HTTP serves are programmed to expect the behaviour that does not + * strictly adhere to the HTTP specification. + */ + public void makeStrict() { + setParameters(PROTOCOL_STRICTNESS_PARAMETERS, Boolean.TRUE); + setIntParameter(STATUS_LINE_GARBAGE_LIMIT, 0); + } + + /** + * Makes the {@link org.apache.commons.httpclient.HttpMethod HTTP methods} + * attempt to mimic the exact behaviour of commonly used HTTP agents, + * which many HTTP servers expect, even though such behaviour may violate + * the HTTP protocol specification (RFC 2616 and other relevant RFCs). + */ + public void makeLenient() { + setParameters(PROTOCOL_STRICTNESS_PARAMETERS, Boolean.FALSE); + setIntParameter(STATUS_LINE_GARBAGE_LIMIT, Integer.MAX_VALUE); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParams.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParams.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParams.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,231 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParams.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * 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 + *HttpParams
.
+ *
+ * @see org.apache.commons.httpclient.params.DefaultHttpParams#setHttpParamsFactory(HttpParamsFactory)
+ *
+ * @since 3.0
+ */
+public interface HttpParamsFactory {
+
+ /**
+ * Gets the default parameters. This method may be called more than once and is not required
+ * to always return the same value.
+ *
+ * @return an instance of HttpParams
+ */
+ HttpParams getDefaultParams();
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/package.html
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/package.html,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/package.html 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,11 @@
+
+
+
+ + * This method employs several techniques to circumvent the limitations of older JREs that + * do not support connect timeout. When running in JRE 1.4 or above reflection is used to + * call Socket#connect(SocketAddress endpoint, int timeout) method. When executing in older + * JREs a controller thread is executed. The controller thread attempts to create a new socket + * within the given limit of time. If socket constructor does not return until the timeout + * expires, the controller terminates and throws an {@link ConnectTimeoutException} + *
+ * + * @param host the host name/IP + * @param port the port on the host + * @param localAddress the local host name/IP to bind the socket to + * @param localPort the port on the local machine + * @param params {@link HttpConnectionParams Http connection parameters} + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + * @throws ConnectTimeoutException if socket cannot be connected within the + * given time limit + * + * @since 3.0 + */ + public Socket createSocket( + final String host, + final int port, + final InetAddress localAddress, + final int localPort, + final HttpConnectionParams params + ) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + if (timeout == 0) { + return createSocket(host, port, localAddress, localPort); + } else { + // To be eventually deprecated when migrated to Java 1.4 or above + Socket socket = ReflectionSocketFactory.createSocket( + "javax.net.SocketFactory", host, port, localAddress, localPort, timeout); + if (socket == null) { + socket = ControllerThreadSocketFactory.createSocket( + this, host, port, localAddress, localPort, timeout); + } + return socket; + } + } + + /** + * @see ProtocolSocketFactory#createSocket(java.lang.String,int) + */ + public Socket createSocket(String host, int port) + throws IOException, UnknownHostException { + return new Socket(host, port); + } + + /** + * All instances of DefaultProtocolSocketFactory are the same. + */ + public boolean equals(Object obj) { + return ((obj != null) && obj.getClass().equals(DefaultProtocolSocketFactory.class)); + } + + /** + * All instances of DefaultProtocolSocketFactory have the same hash code. + */ + public int hashCode() { + return DefaultProtocolSocketFactory.class.hashCode(); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/Protocol.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/Protocol.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/Protocol.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,295 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/Protocol.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *One use case for modifying the default set of protocols would be to set a + * custom SSL socket factory. This would look something like the following: + *
+ * Protocol myHTTPS = new Protocol( "https", new MySSLSocketFactory(), 443 ); + * + * Protocol.registerProtocol( "https", myHTTPS ); + *+ * + * @author Michael Becke + * @author Jeff Dever + * @author Mike Bowler + * + * @since 2.0 + */ +public class Protocol { + + /** The available protocols */ + private static final Map PROTOCOLS = Collections.synchronizedMap(new HashMap()); + + /** + * Registers a new protocol with the given identifier. If a protocol with + * the given ID already exists it will be overridden. This ID is the same + * one used to retrieve the protocol from getProtocol(String). + * + * @param id the identifier for this protocol + * @param protocol the protocol to register + * + * @see #getProtocol(String) + */ + public static void registerProtocol(String id, Protocol protocol) { + + if (id == null) { + throw new IllegalArgumentException("id is null"); + } + if (protocol == null) { + throw new IllegalArgumentException("protocol is null"); + } + + PROTOCOLS.put(id, protocol); + } + + /** + * Unregisters the protocol with the given ID. + * + * @param id the ID of the protocol to remove + */ + public static void unregisterProtocol(String id) { + + if (id == null) { + throw new IllegalArgumentException("id is null"); + } + + PROTOCOLS.remove(id); + } + + /** + * Gets the protocol with the given ID. + * + * @param id the protocol ID + * + * @return Protocol a protocol + * + * @throws IllegalStateException if a protocol with the ID cannot be found + */ + public static Protocol getProtocol(String id) + throws IllegalStateException { + + if (id == null) { + throw new IllegalArgumentException("id is null"); + } + + Protocol protocol = (Protocol) PROTOCOLS.get(id); + + if (protocol == null) { + protocol = lazyRegisterProtocol(id); + } + + return protocol; + } + + /** + * Lazily registers the protocol with the given id. + * + * @param id the protocol ID + * + * @return the lazily registered protocol + * + * @throws IllegalStateException if the protocol with id is not recognized + */ + private static Protocol lazyRegisterProtocol(String id) + throws IllegalStateException { + + if ("http".equals(id)) { + final Protocol http + = new Protocol("http", DefaultProtocolSocketFactory.getSocketFactory(), 80); + Protocol.registerProtocol("http", http); + return http; + } + + if ("https".equals(id)) { + final Protocol https + = new Protocol("https", SSLProtocolSocketFactory.getSocketFactory(), 443); + Protocol.registerProtocol("https", https); + return https; + } + + throw new IllegalStateException("unsupported protocol: '" + id + "'"); + } + + + /** the scheme of this protocol (e.g. http, https) */ + private String scheme; + + /** The socket factory for this protocol */ + private ProtocolSocketFactory socketFactory; + + /** The default port for this protocol */ + private int defaultPort; + + /** True if this protocol is secure */ + private boolean secure; + + /** + * Constructs a new Protocol. Whether the created protocol is secure depends on + * the class of
factory
.
+ *
+ * @param scheme the scheme (e.g. http, https)
+ * @param factory the factory for creating sockets for communication using
+ * this protocol
+ * @param defaultPort the port this protocol defaults to
+ */
+ public Protocol(String scheme, ProtocolSocketFactory factory, int defaultPort) {
+
+ if (scheme == null) {
+ throw new IllegalArgumentException("scheme is null");
+ }
+ if (factory == null) {
+ throw new IllegalArgumentException("socketFactory is null");
+ }
+ if (defaultPort <= 0) {
+ throw new IllegalArgumentException("port is invalid: " + defaultPort);
+ }
+
+ this.scheme = scheme;
+ this.socketFactory = factory;
+ this.defaultPort = defaultPort;
+ this.secure = (factory instanceof SecureProtocolSocketFactory);
+ }
+
+ /**
+ * Constructs a new Protocol. Whether the created protocol is secure depends on
+ * the class of factory
.
+ *
+ * @param scheme the scheme (e.g. http, https)
+ * @param factory the factory for creating sockets for communication using
+ * this protocol
+ * @param defaultPort the port this protocol defaults to
+ * @deprecated Use the constructor that uses ProtocolSocketFactory, this version of
+ * the constructor is only kept for backwards API compatibility.
+ */
+ public Protocol(String scheme,
+ SecureProtocolSocketFactory factory, int defaultPort) {
+ this(scheme, (ProtocolSocketFactory) factory, defaultPort);
+ }
+
+ /**
+ * Returns the defaultPort.
+ * @return int
+ */
+ public int getDefaultPort() {
+ return defaultPort;
+ }
+
+ /**
+ * Returns the socketFactory. If secure the factory is a
+ * SecureProtocolSocketFactory.
+ * @return SocketFactory
+ */
+ public ProtocolSocketFactory getSocketFactory() {
+ return socketFactory;
+ }
+
+ /**
+ * Returns the scheme.
+ * @return The scheme
+ */
+ public String getScheme() {
+ return scheme;
+ }
+
+ /**
+ * Returns true if this protocol is secure
+ * @return true if this protocol is secure
+ */
+ public boolean isSecure() {
+ return secure;
+ }
+
+ /**
+ * Resolves the correct port for this protocol. Returns the given port if
+ * valid or the default port otherwise.
+ *
+ * @param port the port to be resolved
+ *
+ * @return the given port or the defaultPort
+ */
+ public int resolvePort(int port) {
+ return port <= 0 ? getDefaultPort() : port;
+ }
+
+ /**
+ * Return a string representation of this object.
+ * @return a string representation of this object.
+ */
+ public String toString() {
+ return scheme + ":" + defaultPort;
+ }
+
+ /**
+ * Return true if the specified object equals this object.
+ * @param obj The object to compare against.
+ * @return true if the objects are equal.
+ */
+ public boolean equals(Object obj) {
+
+ if (obj instanceof Protocol) {
+
+ Protocol p = (Protocol) obj;
+
+ return (
+ defaultPort == p.getDefaultPort()
+ && scheme.equalsIgnoreCase(p.getScheme())
+ && secure == p.isSecure()
+ && socketFactory.equals(p.getSocketFactory()));
+
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * Return a hash code for this object
+ * @return The hash code.
+ */
+ public int hashCode() {
+ int hash = LangUtils.HASH_SEED;
+ hash = LangUtils.hashCode(hash, this.defaultPort);
+ hash = LangUtils.hashCode(hash, this.scheme.toLowerCase());
+ hash = LangUtils.hashCode(hash, this.secure);
+ hash = LangUtils.hashCode(hash, this.socketFactory);
+ return hash;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ProtocolSocketFactory.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ProtocolSocketFactory.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ProtocolSocketFactory.java 22 Aug 2012 17:30:37 -0000 1.1
@@ -0,0 +1,123 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ProtocolSocketFactory.java,v 1.1 2012/08/22 17:30:37 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:37 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * Both {@link java.lang.Object#equals(java.lang.Object) Object.equals()} and
+ * {@link java.lang.Object#hashCode() Object.hashCode()} should be overridden appropriately.
+ * Protocol socket factories are used to uniquely identify Protocol
s and
+ * HostConfiguration
s, and equals()
and hashCode()
are
+ * required for the correct operation of some connection managers.
+ * This method employs several techniques to circumvent the limitations of older JREs that + * do not support connect timeout. When running in JRE 1.4 or above reflection is used to + * call Socket#connect(SocketAddress endpoint, int timeout) method. When executing in older + * JREs a controller thread is executed. The controller thread attempts to create a new socket + * within the given limit of time. If socket constructor does not return until the timeout + * expires, the controller terminates and throws an {@link ConnectTimeoutException} + *
+ * + * @param host the host name/IP + * @param port the port on the host + * @param localAddress the local host name/IP to bind the socket to + * @param localPort the port on the local machine + * @param params {@link HttpConnectionParams Http connection parameters} + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + * + * @since 3.0 + */ + public Socket createSocket( + final String host, + final int port, + final InetAddress localAddress, + final int localPort, + final HttpConnectionParams params + ) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + if (timeout == 0) { + return createSocket(host, port, localAddress, localPort); + } else { + // To be eventually deprecated when migrated to Java 1.4 or above + Socket socket = ReflectionSocketFactory.createSocket( + "javax.net.ssl.SSLSocketFactory", host, port, localAddress, localPort, timeout); + if (socket == null) { + socket = ControllerThreadSocketFactory.createSocket( + this, host, port, localAddress, localPort, timeout); + } + return socket; + } + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) + */ + public Socket createSocket(String host, int port) + throws IOException, UnknownHostException { + return SSLSocketFactory.getDefault().createSocket( + host, + port + ); + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) + */ + public Socket createSocket( + Socket socket, + String host, + int port, + boolean autoClose) + throws IOException, UnknownHostException { + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket( + socket, + host, + port, + autoClose + ); + } + + /** + * All instances of SSLProtocolSocketFactory are the same. + */ + public boolean equals(Object obj) { + return ((obj != null) && obj.getClass().equals(SSLProtocolSocketFactory.class)); + } + + /** + * All instances of SSLProtocolSocketFactory have the same hash code. + */ + public int hashCode() { + return SSLProtocolSocketFactory.class.hashCode(); + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.java 22 Aug 2012 17:30:37 -0000 1.1 @@ -0,0 +1,71 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.java,v 1.1 2012/08/22 17:30:37 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:37 $ + * + * ==================================================================== + * + * Copyright 2002-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 + *asctime()
format.
+ */
+ public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
+
+ private static final Collection DEFAULT_PATTERNS = Arrays.asList(
+ new String[] { PATTERN_ASCTIME, PATTERN_RFC1036, PATTERN_RFC1123 } );
+ /**
+ * Parses a date value. The formats used for parsing the date value are retrieved from
+ * the default http params.
+ *
+ * @param dateValue the date value to parse
+ *
+ * @return the parsed date
+ *
+ * @throws DateParseException if the value could not be parsed using any of the
+ * supported date formats
+ */
+ public static Date parseDate(String dateValue) throws DateParseException {
+ return parseDate(dateValue, null);
+ }
+
+ /**
+ * Parses the date value using the given date formats.
+ *
+ * @param dateValue the date value to parse
+ * @param dateFormats the date formats to use
+ *
+ * @return the parsed date
+ *
+ * @throws DateParseException if none of the dataFormats could parse the dateValue
+ */
+ public static Date parseDate(
+ String dateValue,
+ Collection dateFormats
+ ) throws DateParseException {
+
+ if (dateValue == null) {
+ throw new IllegalArgumentException("dateValue is null");
+ }
+ if (dateFormats == null) {
+ dateFormats = DEFAULT_PATTERNS;
+ }
+ // trim single quotes around date if present
+ // see issue #5279
+ if (dateValue.length() > 1
+ && dateValue.startsWith("'")
+ && dateValue.endsWith("'")
+ ) {
+ dateValue = dateValue.substring (1, dateValue.length() - 1);
+ }
+
+ SimpleDateFormat dateParser = null;
+ Iterator formatIter = dateFormats.iterator();
+
+ while (formatIter.hasNext()) {
+ String format = (String) formatIter.next();
+ if (dateParser == null) {
+ dateParser = new SimpleDateFormat(format, Locale.US);
+ dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));
+ } else {
+ dateParser.applyPattern(format);
+ }
+ try {
+ return dateParser.parse(dateValue);
+ } catch (ParseException pe) {
+ // ignore this exception, we will try the next format
+ }
+ }
+
+ // we were unable to parse the date
+ throw new DateParseException("Unable to parse the date " + dateValue);
+ }
+
+ /** This class should not be instantiated. */
+ private DateParser() { }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateUtil.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateUtil.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateUtil.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,209 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateUtil.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * asctime()
format.
+ */
+ public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
+
+ private static final Collection DEFAULT_PATTERNS = Arrays.asList(
+ new String[] { PATTERN_ASCTIME, PATTERN_RFC1036, PATTERN_RFC1123 } );
+
+ private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
+
+ static {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(2000, Calendar.JANUARY, 1, 0, 0);
+ DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
+ }
+
+ private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+ /**
+ * Parses a date value. The formats used for parsing the date value are retrieved from
+ * the default http params.
+ *
+ * @param dateValue the date value to parse
+ *
+ * @return the parsed date
+ *
+ * @throws DateParseException if the value could not be parsed using any of the
+ * supported date formats
+ */
+ public static Date parseDate(String dateValue) throws DateParseException {
+ return parseDate(dateValue, null, null);
+ }
+
+ /**
+ * Parses the date value using the given date formats.
+ *
+ * @param dateValue the date value to parse
+ * @param dateFormats the date formats to use
+ *
+ * @return the parsed date
+ *
+ * @throws DateParseException if none of the dataFormats could parse the dateValue
+ */
+ public static Date parseDate(String dateValue, Collection dateFormats)
+ throws DateParseException {
+ return parseDate(dateValue, dateFormats, null);
+ }
+
+ /**
+ * Parses the date value using the given date formats.
+ *
+ * @param dateValue the date value to parse
+ * @param dateFormats the date formats to use
+ * @param startDate During parsing, two digit years will be placed in the range
+ * startDate
to startDate + 100 years
. This value may
+ * be null
. When null
is given as a parameter, year
+ * 2000
will be used.
+ *
+ * @return the parsed date
+ *
+ * @throws DateParseException if none of the dataFormats could parse the dateValue
+ */
+ public static Date parseDate(
+ String dateValue,
+ Collection dateFormats,
+ Date startDate
+ ) throws DateParseException {
+
+ if (dateValue == null) {
+ throw new IllegalArgumentException("dateValue is null");
+ }
+ if (dateFormats == null) {
+ dateFormats = DEFAULT_PATTERNS;
+ }
+ if (startDate == null) {
+ startDate = DEFAULT_TWO_DIGIT_YEAR_START;
+ }
+ // trim single quotes around date if present
+ // see issue #5279
+ if (dateValue.length() > 1
+ && dateValue.startsWith("'")
+ && dateValue.endsWith("'")
+ ) {
+ dateValue = dateValue.substring (1, dateValue.length() - 1);
+ }
+
+ SimpleDateFormat dateParser = null;
+ Iterator formatIter = dateFormats.iterator();
+
+ while (formatIter.hasNext()) {
+ String format = (String) formatIter.next();
+ if (dateParser == null) {
+ dateParser = new SimpleDateFormat(format, Locale.US);
+ dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));
+ dateParser.set2DigitYearStart(startDate);
+ } else {
+ dateParser.applyPattern(format);
+ }
+ try {
+ return dateParser.parse(dateValue);
+ } catch (ParseException pe) {
+ // ignore this exception, we will try the next format
+ }
+ }
+
+ // we were unable to parse the date
+ throw new DateParseException("Unable to parse the date " + dateValue);
+ }
+
+ /**
+ * Formats the given date according to the RFC 1123 pattern.
+ *
+ * @param date The date to format.
+ * @return An RFC 1123 formatted date string.
+ *
+ * @see #PATTERN_RFC1123
+ */
+ public static String formatDate(Date date) {
+ return formatDate(date, PATTERN_RFC1123);
+ }
+
+ /**
+ * Formats the given date according to the specified pattern. The pattern
+ * must conform to that used by the {@link SimpleDateFormat simple date
+ * format} class.
+ *
+ * @param date The date to format.
+ * @param pattern The pattern to use for formatting the date.
+ * @return A formatted date string.
+ *
+ * @throws IllegalArgumentException If the given date pattern is invalid.
+ *
+ * @see SimpleDateFormat
+ */
+ public static String formatDate(Date date, String pattern) {
+ if (date == null) throw new IllegalArgumentException("date is null");
+ if (pattern == null) throw new IllegalArgumentException("pattern is null");
+
+ SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.US);
+ formatter.setTimeZone(GMT);
+ return formatter.format(date);
+ }
+
+ /** This class should not be instantiated. */
+ private DateUtil() { }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/EncodingUtil.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/EncodingUtil.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/EncodingUtil.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,287 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/EncodingUtil.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * + * if the given charset is not supported, ISO-8859-1 is used instead. + *
+ * + * @param pairs the values to be encoded + * @param charset the character set of pairs to be encoded + * + * @return the urlencoded pairs + * + * @since 2.0 final + */ + public static String formUrlEncode(NameValuePair[] pairs, String charset) { + try { + return doFormUrlEncode(pairs, charset); + } catch (UnsupportedEncodingException e) { + LOG.error("Encoding not supported: " + charset); + try { + return doFormUrlEncode(pairs, DEFAULT_CHARSET); + } catch (UnsupportedEncodingException fatal) { + // Should never happen. ISO-8859-1 must be supported on all JVMs + throw new HttpClientError("Encoding not supported: " + + DEFAULT_CHARSET); + } + } + } + + /** + * Form-urlencoding routine. + * + * The default encoding for all forms is `application/x-www-form-urlencoded'. + * A form data set is represented in this media type as follows: + * + * The form field names and values are escaped: space characters are replaced + * by `+', and then reserved characters are escaped as per [URL]; that is, + * non-alphanumeric characters are replaced by `%HH', a percent sign and two + * hexadecimal digits representing the ASCII code of the character. Line breaks, + * as in multi-line text field values, are represented as CR LF pairs, i.e. `%0D%0A'. + * + * @param pairs the values to be encoded + * @param charset the character set of pairs to be encoded + * + * @return the urlencoded pairs + * @throws UnsupportedEncodingException if charset is not supported + * + * @since 2.0 final + */ + private static String doFormUrlEncode(NameValuePair[] pairs, String charset) + throws UnsupportedEncodingException + { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < pairs.length; i++) { + URLCodec codec = new URLCodec(); + NameValuePair pair = pairs[i]; + if (pair.getName() != null) { + if (i > 0) { + buf.append("&"); + } + buf.append(codec.encode(pair.getName(), charset)); + buf.append("="); + if (pair.getValue() != null) { + buf.append(codec.encode(pair.getValue(), charset)); + } + } + } + return buf.toString(); + } + + /** + * Converts the byte array of HTTP content characters to a string. If + * the specified charset is not supported, default system encoding + * is used. + * + * @param data the byte array to be encoded + * @param offset the index of the first byte to encode + * @param length the number of bytes to encode + * @param charset the desired character encoding + * @return The result of the conversion. + * + * @since 3.0 + */ + public static String getString( + final byte[] data, + int offset, + int length, + String charset + ) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + if (charset == null || charset.length() == 0) { + throw new IllegalArgumentException("charset may not be null or empty"); + } + + try { + return new String(data, offset, length, charset); + } catch (UnsupportedEncodingException e) { + + if (LOG.isWarnEnabled()) { + LOG.warn("Unsupported encoding: " + charset + ". System encoding used"); + } + return new String(data, offset, length); + } + } + + + /** + * Converts the byte array of HTTP content characters to a string. If + * the specified charset is not supported, default system encoding + * is used. + * + * @param data the byte array to be encoded + * @param charset the desired character encoding + * @return The result of the conversion. + * + * @since 3.0 + */ + public static String getString(final byte[] data, String charset) { + return getString(data, 0, data.length, charset); + } + + /** + * Converts the specified string to a byte array. If the charset is not supported the + * default system charset is used. + * + * @param data the string to be encoded + * @param charset the desired character encoding + * @return The resulting byte array. + * + * @since 3.0 + */ + public static byte[] getBytes(final String data, String charset) { + + if (data == null) { + throw new IllegalArgumentException("data may not be null"); + } + + if (charset == null || charset.length() == 0) { + throw new IllegalArgumentException("charset may not be null or empty"); + } + + try { + return data.getBytes(charset); + } catch (UnsupportedEncodingException e) { + + if (LOG.isWarnEnabled()) { + LOG.warn("Unsupported encoding: " + charset + ". System encoding used."); + } + + return data.getBytes(); + } + } + + /** + * Converts the specified string to byte array of ASCII characters. + * + * @param data the string to be encoded + * @return The string as a byte array. + * + * @since 3.0 + */ + public static byte[] getAsciiBytes(final String data) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + try { + return data.getBytes("US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new HttpClientError("HttpClient requires ASCII support"); + } + } + + /** + * Converts the byte array of ASCII characters to a string. This method is + * to be used when decoding content of HTTP elements (such as response + * headers) + * + * @param data the byte array to be encoded + * @param offset the index of the first byte to encode + * @param length the number of bytes to encode + * @return The string representation of the byte array + * + * @since 3.0 + */ + public static String getAsciiString(final byte[] data, int offset, int length) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + try { + return new String(data, offset, length, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new HttpClientError("HttpClient requires ASCII support"); + } + } + + /** + * Converts the byte array of ASCII characters to a string. This method is + * to be used when decoding content of HTTP elements (such as response + * headers) + * + * @param data the byte array to be encoded + * @return The string representation of the byte array + * + * @since 3.0 + */ + public static String getAsciiString(final byte[] data) { + return getAsciiString(data, 0, data.length); + } + + /** + * This class should not be instantiated. + */ + private EncodingUtil() { + } + +} Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ExceptionUtil.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ExceptionUtil.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ExceptionUtil.java 22 Aug 2012 17:30:38 -0000 1.1 @@ -0,0 +1,121 @@ +/* + * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ExceptionUtil.java,v 1.1 2012/08/22 17:30:38 marcin Exp $ + * $Revision: 1.1 $ + * $Date: 2012/08/22 17:30:38 $ + * + * ==================================================================== + * + * 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 + *Method allowing access to
+ * {@link Throwable.initCause(Throwable) initCause} method of {@link Throwable},
+ * or null
if the method
+ * does not exist.
+ *
+ * @return A Method for Throwable.initCause
, or
+ * null
if unavailable.
+ */
+ static private Method getInitCauseMethod() {
+ try {
+ Class[] paramsClasses = new Class[] { Throwable.class };
+ return Throwable.class.getMethod("initCause", paramsClasses);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns SocketTimeoutExceptionClass or null
if the class
+ * does not exist.
+ *
+ * @return SocketTimeoutExceptionClass, or null
if unavailable.
+ */
+ static private Class SocketTimeoutExceptionClass() {
+ try {
+ return Class.forName("java.net.SocketTimeoutException");
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * If we're running on JDK 1.4 or later, initialize the cause for the given throwable.
+ *
+ * @param throwable The throwable.
+ * @param cause The cause of the throwable.
+ */
+ public static void initCause(Throwable throwable, Throwable cause) {
+ if (INIT_CAUSE_METHOD != null) {
+ try {
+ INIT_CAUSE_METHOD.invoke(throwable, new Object[] { cause });
+ } catch (Exception e) {
+ LOG.warn("Exception invoking Throwable.initCause", e);
+ }
+ }
+ }
+
+ /**
+ * If SocketTimeoutExceptionClass is defined, returns true only if the
+ * exception is an instance of SocketTimeoutExceptionClass. If
+ * SocketTimeoutExceptionClass is undefined, always returns true.
+ *
+ * @param e an instance of InterruptedIOException class.
+ *
+ * @return true if the exception signals socket timeout, false
+ * otherwise.
+ */
+ public static boolean isSocketTimeoutException(final InterruptedIOException e) {
+ if (SOCKET_TIMEOUT_CLASS != null) {
+ return SOCKET_TIMEOUT_CLASS.isInstance(e);
+ } else {
+ return true;
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/HttpURLConnection.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/HttpURLConnection.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/HttpURLConnection.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,503 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/HttpURLConnection.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.Header;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.ProtocolException;
+import java.security.Permission;
+
+/**
+ * Provides a HttpURLConnection
wrapper around HttpClient's
+ * HttpMethod
. This allows existing code to easily switch to
+ * HttpClieht without breaking existing interfaces using the JDK
+ * HttpURLConnection
.
+ *
+ * Note 1: The current implementations wraps only a connected
+ * HttpMethod
, ie a method that has alreayd been used to connect
+ * to an HTTP server.
+ *
+ * Note 2: It is a best try effort as different version of the JDK have
+ * different behaviours for HttpURLConnection
(And I'm not even
+ * including the numerous HttpURLConnection
bugs!).
+ *
+ * @author Vincent Massol
+ * @author Jeff Dever
+ * @author Mike Bowler
+ *
+ * @since 2.0
+ *
+ * @version $Id: HttpURLConnection.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ */
+public class HttpURLConnection extends java.net.HttpURLConnection {
+
+ // -------------------------------------------------------- Class Variables
+
+ /** Log object for this class. */
+ private static final Log LOG = LogFactory.getLog(HttpURLConnection.class);
+
+
+ // ----------------------------------------------------- Instance Variables
+
+ /**
+ * The HttpMethod
object that was used to connect to the
+ * HTTP server. It contains all the returned data.
+ */
+ private HttpMethod method;
+
+ /**
+ * The URL to which we are connected
+ */
+ private URL url;
+
+
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Creates an HttpURLConnection
from a HttpMethod
.
+ *
+ * @param method the theMethod that was used to connect to the HTTP
+ * server and which contains the returned data.
+ * @param url the URL to which we are connected (includes query string)
+ */
+ public HttpURLConnection(HttpMethod method, URL url) {
+ super(url);
+ this.method = method;
+ this.url = url;
+ }
+
+ /**
+ * Create an instance.
+ * @param url The URL.
+ * @see java.net.HttpURLConnection#HttpURLConnection(URL)
+ */
+ protected HttpURLConnection(URL url) {
+ super(url);
+ throw new RuntimeException("An HTTP URL connection can only be "
+ + "constructed from a HttpMethod class");
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Gets an input stream for the HttpMethod response body.
+ * @throws IOException If an IO problem occurs.
+ * @return The input stream.
+ * @see java.net.HttpURLConnection#getInputStream()
+ * @see org.apache.commons.httpclient.HttpMethod#getResponseBodyAsStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ LOG.trace("enter HttpURLConnection.getInputStream()");
+ return this.method.getResponseBodyAsStream();
+ }
+
+ /**
+ * Not yet implemented.
+ * Return the error stream.
+ * @see java.net.HttpURLConnection#getErrorStream()
+ */
+ public InputStream getErrorStream() {
+ LOG.trace("enter HttpURLConnection.getErrorStream()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#disconnect()
+ */
+ public void disconnect() {
+ LOG.trace("enter HttpURLConnection.disconnect()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @throws IOException If an IO problem occurs.
+ * @see java.net.HttpURLConnection#connect()
+ */
+ public void connect() throws IOException {
+ LOG.trace("enter HttpURLConnection.connect()");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @return true if we are using a proxy.
+ * @see java.net.HttpURLConnection#usingProxy()
+ */
+ public boolean usingProxy() {
+ LOG.trace("enter HttpURLConnection.usingProxy()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Return the request method.
+ * @return The request method.
+ * @see java.net.HttpURLConnection#getRequestMethod()
+ * @see org.apache.commons.httpclient.HttpMethod#getName()
+ */
+ public String getRequestMethod() {
+ LOG.trace("enter HttpURLConnection.getRequestMethod()");
+ return this.method.getName();
+ }
+
+ /**
+ * Return the response code.
+ * @return The response code.
+ * @throws IOException If an IO problem occurs.
+ * @see java.net.HttpURLConnection#getResponseCode()
+ * @see org.apache.commons.httpclient.HttpMethod#getStatusCode()
+ */
+ public int getResponseCode() throws IOException {
+ LOG.trace("enter HttpURLConnection.getResponseCode()");
+ return this.method.getStatusCode();
+ }
+
+ /**
+ * Return the response message
+ * @return The response message
+ * @throws IOException If an IO problem occurs.
+ * @see java.net.HttpURLConnection#getResponseMessage()
+ * @see org.apache.commons.httpclient.HttpMethod#getStatusText()
+ */
+ public String getResponseMessage() throws IOException {
+ LOG.trace("enter HttpURLConnection.getResponseMessage()");
+ return this.method.getStatusText();
+ }
+
+ /**
+ * Return the header field
+ * @param name the name of the header
+ * @return the header field.
+ * @see java.net.HttpURLConnection#getHeaderField(String)
+ * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
+ */
+ public String getHeaderField(String name) {
+ LOG.trace("enter HttpURLConnection.getHeaderField(String)");
+ // Note: Return the last matching header in the Header[] array, as in
+ // the JDK implementation.
+ Header[] headers = this.method.getResponseHeaders();
+ for (int i = headers.length - 1; i >= 0; i--) {
+ if (headers[i].getName().equalsIgnoreCase(name)) {
+ return headers[i].getValue();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the header field key
+ * @param keyPosition The key position
+ * @return The header field key.
+ * @see java.net.HttpURLConnection#getHeaderFieldKey(int)
+ * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
+ */
+ public String getHeaderFieldKey(int keyPosition) {
+ LOG.trace("enter HttpURLConnection.getHeaderFieldKey(int)");
+
+ // Note: HttpClient does not consider the returned Status Line as
+ // a response header. However, getHeaderFieldKey(0) is supposed to
+ // return null. Hence the special case below ...
+
+ if (keyPosition == 0) {
+ return null;
+ }
+
+ // Note: HttpClient does not currently keep headers in the same order
+ // that they are read from the HTTP server.
+
+ Header[] headers = this.method.getResponseHeaders();
+ if (keyPosition < 0 || keyPosition > headers.length) {
+ return null;
+ }
+
+ return headers[keyPosition - 1].getName();
+ }
+
+ /**
+ * Return the header field at the specified position
+ * @param position The position
+ * @return The header field.
+ * @see java.net.HttpURLConnection#getHeaderField(int)
+ * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
+ */
+ public String getHeaderField(int position) {
+ LOG.trace("enter HttpURLConnection.getHeaderField(int)");
+
+ // Note: HttpClient does not consider the returned Status Line as
+ // a response header. However, getHeaderField(0) is supposed to
+ // return the status line. Hence the special case below ...
+
+ if (position == 0) {
+ return this.method.getStatusLine().toString();
+ }
+
+ // Note: HttpClient does not currently keep headers in the same order
+ // that they are read from the HTTP server.
+
+ Header[] headers = this.method.getResponseHeaders();
+ if (position < 0 || position > headers.length) {
+ return null;
+ }
+
+ return headers[position - 1].getValue();
+ }
+
+ /**
+ * Return the URL
+ * @return The URL.
+ * @see java.net.HttpURLConnection#getURL()
+ */
+ public URL getURL() {
+ LOG.trace("enter HttpURLConnection.getURL()");
+ return this.url;
+ }
+
+ // Note: We don't implement the following methods so that they default to
+ // the JDK implementation. They will all call
+ // getHeaderField(String)
which we have overridden.
+
+ // java.net.HttpURLConnection#getHeaderFieldDate(String, long)
+ // java.net.HttpURLConnection#getContentLength()
+ // java.net.HttpURLConnection#getContentType()
+ // java.net.HttpURLConnection#getContentEncoding()
+ // java.net.HttpURLConnection#getDate()
+ // java.net.HttpURLConnection#getHeaderFieldInt(String, int)
+ // java.net.HttpURLConnection#getExpiration()
+ // java.net.HttpURLConnection#getLastModified()
+
+ /**
+ * Not available: the data must have already been retrieved.
+ */
+ public void setInstanceFollowRedirects(boolean isFollowingRedirects) {
+ LOG.trace("enter HttpURLConnection.setInstanceFollowRedirects(boolean)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ */
+ public boolean getInstanceFollowRedirects() {
+ LOG.trace("enter HttpURLConnection.getInstanceFollowRedirects()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setRequestMethod(String)
+ */
+ public void setRequestMethod(String method) throws ProtocolException {
+ LOG.trace("enter HttpURLConnection.setRequestMethod(String)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getPermission()
+ */
+ public Permission getPermission() throws IOException {
+ LOG.trace("enter HttpURLConnection.getPermission()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getContent()
+ */
+ public Object getContent() throws IOException {
+ LOG.trace("enter HttpURLConnection.getContent()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not yet implemented.
+ */
+ public Object getContent(Class[] classes) throws IOException {
+ LOG.trace("enter HttpURLConnection.getContent(Class[])");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * @see java.net.HttpURLConnection#getOutputStream()
+ */
+ public OutputStream getOutputStream() throws IOException {
+ LOG.trace("enter HttpURLConnection.getOutputStream()");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setDoInput(boolean)
+ */
+ public void setDoInput(boolean isInput) {
+ LOG.trace("enter HttpURLConnection.setDoInput()");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getDoInput()
+ */
+ public boolean getDoInput() {
+ LOG.trace("enter HttpURLConnection.getDoInput()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setDoOutput(boolean)
+ */
+ public void setDoOutput(boolean isOutput) {
+ LOG.trace("enter HttpURLConnection.setDoOutput()");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getDoOutput()
+ */
+ public boolean getDoOutput() {
+ LOG.trace("enter HttpURLConnection.getDoOutput()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setAllowUserInteraction(boolean)
+ */
+ public void setAllowUserInteraction(boolean isAllowInteraction) {
+ LOG.trace("enter HttpURLConnection.setAllowUserInteraction(boolean)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getAllowUserInteraction()
+ */
+ public boolean getAllowUserInteraction() {
+ LOG.trace("enter HttpURLConnection.getAllowUserInteraction()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setUseCaches(boolean)
+ */
+ public void setUseCaches(boolean isUsingCaches) {
+ LOG.trace("enter HttpURLConnection.setUseCaches(boolean)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getUseCaches()
+ */
+ public boolean getUseCaches() {
+ LOG.trace("enter HttpURLConnection.getUseCaches()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setIfModifiedSince(long)
+ */
+ public void setIfModifiedSince(long modificationDate) {
+ LOG.trace("enter HttpURLConnection.setIfModifiedSince(long)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getIfModifiedSince()
+ */
+ public long getIfModifiedSince() {
+ LOG.trace("enter HttpURLConnection.getIfmodifiedSince()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#getDefaultUseCaches()
+ */
+ public boolean getDefaultUseCaches() {
+ LOG.trace("enter HttpURLConnection.getDefaultUseCaches()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setDefaultUseCaches(boolean)
+ */
+ public void setDefaultUseCaches(boolean isUsingCaches) {
+ LOG.trace("enter HttpURLConnection.setDefaultUseCaches(boolean)");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not available: the data must have already been retrieved.
+ * @see java.net.HttpURLConnection#setRequestProperty(String,String)
+ */
+ public void setRequestProperty(String key, String value) {
+ LOG.trace("enter HttpURLConnection.setRequestProperty()");
+ throw new RuntimeException("This class can only be used with already"
+ + "retrieved data");
+ }
+
+ /**
+ * Not yet implemented.
+ * @see java.net.HttpURLConnection#getRequestProperty(String)
+ */
+ public String getRequestProperty(String key) {
+ LOG.trace("enter HttpURLConnection.getRequestProperty()");
+ throw new RuntimeException("Not implemented yet");
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionHandler.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionHandler.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionHandler.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,124 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionHandler.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * Copyright 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
+ * .
+ *
+ */
+package org.apache.commons.httpclient.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.httpclient.HttpConnection;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A helper class for connection managers to track idle connections.
+ *
+ * This class is not synchronized.
+ *
+ * @see org.apache.commons.httpclient.HttpConnectionManager#closeIdleConnections(long)
+ *
+ * @since 3.0
+ */
+public class IdleConnectionHandler {
+
+ private static final Log LOG = LogFactory.getLog(IdleConnectionHandler.class);
+
+ /** Holds connections and the time they were added. */
+ private Map connectionToAdded = new HashMap();
+
+ /**
+ *
+ */
+ public IdleConnectionHandler() {
+ super();
+ }
+
+ /**
+ * Registers the given connection with this handler. The connection will be held until
+ * {@link #remove(HttpConnection)} or {@link #closeIdleConnections(long)} is called.
+ *
+ * @param connection the connection to add
+ *
+ * @see #remove(HttpConnection)
+ */
+ public void add(HttpConnection connection) {
+
+ Long timeAdded = new Long(System.currentTimeMillis());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding connection at: " + timeAdded);
+ }
+
+ connectionToAdded.put(connection, timeAdded);
+ }
+
+ /**
+ * Removes the given connection from the list of connections to be closed when idle.
+ * @param connection
+ */
+ public void remove(HttpConnection connection) {
+ connectionToAdded.remove(connection);
+ }
+
+ /**
+ * Removes all connections referenced by this handler.
+ */
+ public void removeAll() {
+ this.connectionToAdded.clear();
+ }
+
+ /**
+ * Closes connections that have been idle for at least the given amount of time.
+ *
+ * @param idleTime the minimum idle time, in milliseconds, for connections to be closed
+ */
+ public void closeIdleConnections(long idleTime) {
+
+ // the latest time for which connections will be closed
+ long idleTimeout = System.currentTimeMillis() - idleTime;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking for connections, idleTimeout: " + idleTimeout);
+ }
+
+ Iterator connectionIter = connectionToAdded.keySet().iterator();
+
+ while (connectionIter.hasNext()) {
+ HttpConnection conn = (HttpConnection) connectionIter.next();
+ Long connectionTime = (Long) connectionToAdded.get(conn);
+ if (connectionTime.longValue() <= idleTimeout) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Closing connection, connection time: " + connectionTime);
+ }
+ connectionIter.remove();
+ conn.close();
+ }
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionTimeoutThread.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionTimeoutThread.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionTimeoutThread.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,140 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionTimeoutThread.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * Copyright 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
+ * .
+ *
+ */
+package org.apache.commons.httpclient.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpConnectionManager;
+
+/**
+ * A utility class for periodically closing idle connections.
+ *
+ * @see org.apache.commons.httpclient.HttpConnectionManager#closeIdleConnections(long)
+ *
+ * @since 3.0
+ */
+public class IdleConnectionTimeoutThread extends Thread {
+
+ private List connectionManagers = new ArrayList();
+
+ private boolean shutdown = false;
+
+ private long timeoutInterval = 1000;
+
+ private long connectionTimeout = 3000;
+
+ public IdleConnectionTimeoutThread() {
+ setDaemon(true);
+ }
+
+ /**
+ * Adds a connection manager to be handled by this class.
+ * {@link HttpConnectionManager#closeIdleConnections(long)} will be called on the connection
+ * manager every {@link #setTimeoutInterval(long) timeoutInterval} milliseconds.
+ *
+ * @param connectionManager The connection manager to add
+ */
+ public synchronized void addConnectionManager(HttpConnectionManager connectionManager) {
+ if (shutdown) {
+ throw new IllegalStateException("IdleConnectionTimeoutThread has been shutdown");
+ }
+ this.connectionManagers.add(connectionManager);
+ }
+
+ /**
+ * Removes the connection manager from this class. The idle connections from the connection
+ * manager will no longer be automatically closed by this class.
+ *
+ * @param connectionManager The connection manager to remove
+ */
+ public synchronized void removeConnectionManager(HttpConnectionManager connectionManager) {
+ if (shutdown) {
+ throw new IllegalStateException("IdleConnectionTimeoutThread has been shutdown");
+ }
+ this.connectionManagers.remove(connectionManager);
+ }
+
+ /**
+ * Closes idle connections.
+ */
+ public synchronized void run() {
+ while (!shutdown) {
+ Iterator iter = connectionManagers.iterator();
+
+ while (iter.hasNext()) {
+ HttpConnectionManager connectionManager = (HttpConnectionManager) iter.next();
+ connectionManager.closeIdleConnections(connectionTimeout);
+ }
+
+ try {
+ this.wait(timeoutInterval);
+ } catch (InterruptedException e) {
+ }
+ }
+ // clear out the connection managers now that we're shutdown
+ this.connectionManagers.clear();
+ }
+
+ /**
+ * Stops the thread used to close idle connections. This class cannot be used once shutdown.
+ */
+ public synchronized void shutdown() {
+ this.shutdown = true;
+ this.notifyAll();
+ }
+
+ /**
+ * Sets the timeout value to use when testing for idle connections.
+ *
+ * @param connectionTimeout The connection timeout in milliseconds
+ *
+ * @see HttpConnectionManager#closeIdleConnections(long)
+ */
+ public synchronized void setConnectionTimeout(long connectionTimeout) {
+ if (shutdown) {
+ throw new IllegalStateException("IdleConnectionTimeoutThread has been shutdown");
+ }
+ this.connectionTimeout = connectionTimeout;
+ }
+ /**
+ * Sets the interval used by this class between closing idle connections. Idle
+ * connections will be closed every timeoutInterval
milliseconds.
+ *
+ * @param timeoutInterval The timeout interval in milliseconds
+ */
+ public synchronized void setTimeoutInterval(long timeoutInterval) {
+ if (shutdown) {
+ throw new IllegalStateException("IdleConnectionTimeoutThread has been shutdown");
+ }
+ this.timeoutInterval = timeoutInterval;
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/LangUtils.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/LangUtils.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/LangUtils.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,65 @@
+/*
+ * $HeadURL: http://svn.apache.org/repos/asf/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/LangUtils.java $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+/**
+ * A set of utility methods to help produce consistent Object#equals(Object) and
+ * Object#hashCode methods.
+ *
+ * @author Oleg Kalnichevski
+ *
+ * @since 3.0
+ */
+public class LangUtils {
+
+ public static final int HASH_SEED = 17;
+ public static final int HASH_OFFSET = 37;
+
+ private LangUtils() {
+ super();
+ }
+
+ public static int hashCode(final int seed, final int hashcode) {
+ return seed * HASH_OFFSET + hashcode;
+ }
+
+ public static int hashCode(final int seed, final Object obj) {
+ return hashCode(seed, obj != null ? obj.hashCode() : 0);
+ }
+
+ public static int hashCode(final int seed, final boolean b) {
+ return hashCode(seed, b ? 1 : 0);
+ }
+
+ public static boolean equals(final Object obj1, final Object obj2) {
+ return obj1 == null ? obj2 == null : obj1.equals(obj2);
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterFormatter.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterFormatter.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterFormatter.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,241 @@
+/*
+ * $HeadURL: http://svn.apache.org/repos/asf/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/util/ParameterFormatter.java $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+import org.apache.commons.httpclient.NameValuePair;
+
+/**
+ *
+ * This formatter produces a textual representation of attribute/value pairs. It
+ * comforms to the generic grammar and formatting rules outlined in the
+ * Section 2.1
+ * and
+ * Section 3.6
+ * of RFC 2616
+ *
+ * 2.1 Augmented BNF
+ *
+ * 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).
+ *
+ *
+ * token = 1*
+ * separators = "(" | ")" | "<" | ">" | "@"
+ * | "," | ";" | ":" | "\" | <">
+ * | "/" | "[" | "]" | "?" | "="
+ * | "{" | "}" | SP | HT
+ *
+ *
+ * A string of text is parsed as a single word if it is quoted using double-quote marks.
+ *
+ *
+ * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
+ * qdtext = >
+ *
+ *
+ * The backslash character ("\") MAY be used as a single-character quoting mechanism only
+ * within quoted-string and comment constructs.
+ *
+ *
+ * quoted-pair = "\" CHAR
+ *
+ * 3.6 Transfer Codings
+ *
+ * Parameters are in the form of attribute/value pairs.
+ *
+ *
+ * parameter = attribute "=" value
+ * attribute = token
+ * value = token | quoted-string
+ *
+ *
+ * @author Oleg Kalnichevski
+ *
+ * @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 true if all parameter values must be enclosed in
+ * quotation marks, false 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 true if the parameter value must
+ * be enclosed in quotation marks, even if it does not contain any special
+ * characters, false 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();
+ }
+
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterParser.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterParser.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterParser.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,234 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterParser.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ */
+
+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
+ *
+ * @since 3.0
+ */
+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;
+ boolean charEscaped = false;
+ while (hasChar()) {
+ ch = chars[pos];
+ if (!quoted && isOneOf(ch, terminators)) {
+ break;
+ }
+ if (!charEscaped && ch == '"') {
+ quoted = !quoted;
+ }
+ charEscaped = (!charEscaped && ch == '\\');
+ 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 new ArrayList();
+ }
+ 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 new ArrayList();
+ }
+ 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 new ArrayList();
+ }
+ List params = new ArrayList();
+ this.chars = chars;
+ this.pos = offset;
+ this.len = length;
+
+ String paramName = null;
+ String paramValue = null;
+ 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.equals("") && paramValue == null)) {
+ params.add(new NameValuePair(paramName, paramValue));
+ }
+ }
+ return params;
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/TimeoutController.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/TimeoutController.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/TimeoutController.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,92 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/TimeoutController.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * 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
+ * .
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+/**
+ *
+ * Executes a task with a specified timeout.
+ *
+ * @author Ortwin Glueck
+ * @author Mike Bowler
+ * @version $Revision: 1.1 $
+ * @since 2.0
+ */
+public final class TimeoutController {
+
+ /**
+ * Do not instantiate objects of this class. Methods are static.
+ */
+ private TimeoutController() {
+ }
+
+ /**
+ * Executes task
. Waits for timeout
+ * milliseconds for the task to end and returns. If the task does not return
+ * in time, the thread is interrupted and an Exception is thrown.
+ * The caller should override the Thread.interrupt() method to something that
+ * quickly makes the thread die or use Thread.isInterrupted().
+ * @param task The thread to execute
+ * @param timeout The timeout in milliseconds. 0 means to wait forever.
+ * @throws TimeoutException if the timeout passes and the thread does not return.
+ */
+ public static void execute(Thread task, long timeout) throws TimeoutException {
+ task.start();
+ try {
+ task.join(timeout);
+ } catch (InterruptedException e) {
+ /* if somebody interrupts us he knows what he is doing */
+ }
+ if (task.isAlive()) {
+ task.interrupt();
+ throw new TimeoutException();
+ }
+ }
+
+ /**
+ * Executes task
in a new deamon Thread and waits for the timeout.
+ * @param task The task to execute
+ * @param timeout The timeout in milliseconds. 0 means to wait forever.
+ * @throws TimeoutException if the timeout passes and the thread does not return.
+ */
+ public static void execute(Runnable task, long timeout) throws TimeoutException {
+ Thread t = new Thread(task, "Timeout guard");
+ t.setDaemon(true);
+ execute(t, timeout);
+ }
+
+ /**
+ * Signals that the task timed out.
+ */
+ public static class TimeoutException extends Exception {
+ /** Create an instance */
+ public TimeoutException() {
+ }
+ }
+}
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/URIUtil.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/URIUtil.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/URIUtil.java 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,657 @@
+/*
+ * $Header: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/URIUtil.java,v 1.1 2012/08/22 17:30:38 marcin Exp $
+ * $Revision: 1.1 $
+ * $Date: 2012/08/22 17:30:38 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-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
+ * .
+ *
+ */
+
+package org.apache.commons.httpclient.util;
+
+import java.util.BitSet;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.net.URLCodec;
+import org.apache.commons.httpclient.URI;
+import org.apache.commons.httpclient.URIException;
+
+/**
+ * The URI escape and character encoding and decoding utility.
+ * It's compatible with {@link org.apache.commons.httpclient.HttpURL} rather
+ * than {@link org.apache.commons.httpclient.URI}.
+ *
+ * @author Sung-Gu
+ * @version $Revision: 1.1 $ $Date: 2002/03/14 15:14:01
+ */
+public class URIUtil {
+
+ // ----------------------------------------------------- Instance variables
+
+ protected static final BitSet empty = new BitSet(1);
+
+ // ---------------------------------------------------------- URI utilities
+
+ /**
+ * Get the basename of an URI. It's possibly an empty string.
+ *
+ * @param uri a string regarded an URI
+ * @return the basename string; an empty string if the path ends with slash
+ */
+ public static String getName(String uri) {
+ if (uri == null || uri.length() == 0) { return uri; }
+ String path = URIUtil.getPath(uri);
+ int at = path.lastIndexOf("/");
+ int to = path.length();
+ return (at >= 0) ? path.substring(at + 1, to) : path;
+ }
+
+
+ /**
+ * Get the query of an URI.
+ *
+ * @param uri a string regarded an URI
+ * @return the query string; null
if empty or undefined
+ */
+ public static String getQuery(String uri) {
+ if (uri == null || uri.length() == 0) { return null; }
+ // consider of net_path
+ int at = uri.indexOf("//");
+ int from = uri.indexOf(
+ "/",
+ at >= 0 ? (uri.lastIndexOf("/", at - 1) >= 0 ? 0 : at + 2) : 0
+ );
+ // the authority part of URI ignored
+ int to = uri.length();
+ // reuse the at and from variables to consider the query
+ at = uri.indexOf("?", from);
+ if (at >= 0) {
+ from = at + 1;
+ } else {
+ return null;
+ }
+ // check the fragment
+ if (uri.lastIndexOf("#") > from) {
+ to = uri.lastIndexOf("#");
+ }
+ // get the path and query.
+ return (from < 0 || from == to) ? null : uri.substring(from, to);
+ }
+
+
+ /**
+ * Get the path of an URI.
+ *
+ * @param uri a string regarded an URI
+ * @return the path string
+ */
+ public static String getPath(String uri) {
+ if (uri == null) {
+ return null;
+ }
+ // consider of net_path
+ int at = uri.indexOf("//");
+ int from = uri.indexOf(
+ "/",
+ at >= 0 ? (uri.lastIndexOf("/", at - 1) >= 0 ? 0 : at + 2) : 0
+ );
+ // the authority part of URI ignored
+ int to = uri.length();
+ // check the query
+ if (uri.indexOf('?', from) != -1) {
+ to = uri.indexOf('?', from);
+ }
+ // check the fragment
+ if (uri.lastIndexOf("#") > from && uri.lastIndexOf("#") < to) {
+ to = uri.lastIndexOf("#");
+ }
+ // get only the path.
+ return (from < 0) ? (at >= 0 ? "/" : uri) : uri.substring(from, to);
+ }
+
+
+ /**
+ * Get the path and query of an URI.
+ *
+ * @param uri a string regarded an URI
+ * @return the path and query string
+ */
+ public static String getPathQuery(String uri) {
+ if (uri == null) {
+ return null;
+ }
+ // consider of net_path
+ int at = uri.indexOf("//");
+ int from = uri.indexOf(
+ "/",
+ at >= 0 ? (uri.lastIndexOf("/", at - 1) >= 0 ? 0 : at + 2) : 0
+ );
+ // the authority part of URI ignored
+ int to = uri.length();
+ // Ignore the '?' mark so to ignore the query.
+ // check the fragment
+ if (uri.lastIndexOf("#") > from) {
+ to = uri.lastIndexOf("#");
+ }
+ // get the path and query.
+ return (from < 0) ? (at >= 0 ? "/" : uri) : uri.substring(from, to);
+ }
+
+
+ /**
+ * Get the path of an URI and its rest part.
+ *
+ * @param uri a string regarded an URI
+ * @return the string from the path part
+ */
+ public static String getFromPath(String uri) {
+ if (uri == null) {
+ return null;
+ }
+ // consider of net_path
+ int at = uri.indexOf("//");
+ int from = uri.indexOf(
+ "/",
+ at >= 0 ? (uri.lastIndexOf("/", at - 1) >= 0 ? 0 : at + 2) : 0
+ );
+ // get the path and its rest.
+ return (from < 0) ? (at >= 0 ? "/" : uri) : uri.substring(from);
+ }
+
+ // ----------------------------------------------------- Encoding utilities
+
+ /**
+ * Get the all escaped and encoded string with the default protocl charset.
+ * It's the same function to use encode(String unescaped, Bitset
+ * empty, URI.getDefaultProtocolCharset())
.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodeAll(String unescaped) throws URIException {
+ return encodeAll(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Get the all escaped and encoded string with a given charset.
+ * It's the same function to use encode(String unescaped, Bitset
+ * empty, String charset)
.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodeAll(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, empty, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the authority component of
+ * an URI with the default protocol charset.
+ * Within the authority component, the characters ";", ":", "@", "?", and
+ * "/" are reserved.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodeWithinAuthority(String unescaped)
+ throws URIException {
+
+ return encodeWithinAuthority(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the authority component of
+ * an URI with a given charset.
+ * Within the authority component, the characters ";", ":", "@", "?", and
+ * "/" are reserved.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodeWithinAuthority(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, URI.allowed_within_authority, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the path and query components of
+ * an URI with the default protocol charset.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodePathQuery(String unescaped) throws URIException {
+ return encodePathQuery(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the path and query components of
+ * an URI with a given charset.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodePathQuery(String unescaped, String charset)
+ throws URIException {
+
+ int at = unescaped.indexOf('?');
+ if (at < 0) {
+ return encode(unescaped, URI.allowed_abs_path, charset);
+ }
+ // else
+ return encode(unescaped.substring(0, at), URI.allowed_abs_path, charset)
+ + '?' + encode(unescaped.substring(at + 1), URI.allowed_query, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the path component of an
+ * URI with the default protocol charset.
+ * The path may consist of a sequence of path segments separated by a
+ * single slash "/" character. Within a path segment, the characters
+ * "/", ";", "=", and "?" are reserved.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodeWithinPath(String unescaped)
+ throws URIException {
+
+ return encodeWithinPath(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the path component of an
+ * URI with a given charset.
+ * The path may consist of a sequence of path segments separated by a
+ * single slash "/" character. Within a path segment, the characters
+ * "/", ";", "=", and "?" are reserved.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodeWithinPath(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, URI.allowed_within_path, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the path component of an URI with
+ * the default protocol charset.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodePath(String unescaped) throws URIException {
+ return encodePath(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the path component of an URI with
+ * a given charset.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodePath(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, URI.allowed_abs_path, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the query component of an
+ * URI with the default protocol charset.
+ * When a query comprise the name and value pairs, it is used in order
+ * to encode each name and value string. The reserved special characters
+ * within a query component are being included in encoding the query.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodeWithinQuery(String unescaped)
+ throws URIException {
+
+ return encodeWithinQuery(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as within the query component of an
+ * URI with a given charset.
+ * When a query comprise the name and value pairs, it is used in order
+ * to encode each name and value string. The reserved special characters
+ * within a query component are being included in encoding the query.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodeWithinQuery(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, URI.allowed_within_query, charset);
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the query component of an URI with
+ * the default protocol charset.
+ * When a query string is not misunderstood the reserved special characters
+ * ("&", "=", "+", ",", and "$") within a query component, this method
+ * is recommended to use in encoding the whole query.
+ *
+ * @param unescaped an unescaped string
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ * @see #encode
+ */
+ public static String encodeQuery(String unescaped) throws URIException {
+ return encodeQuery(unescaped, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a string regarded as the query component of an URI with
+ * a given charset.
+ * When a query string is not misunderstood the reserved special characters
+ * ("&", "=", "+", ",", and "$") within a query component, this method
+ * is recommended to use in encoding the whole query.
+ *
+ * @param unescaped an unescaped string
+ * @param charset the charset
+ * @return the escaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see #encode
+ */
+ public static String encodeQuery(String unescaped, String charset)
+ throws URIException {
+
+ return encode(unescaped, URI.allowed_query, charset);
+ }
+
+
+ /**
+ * Escape and encode a given string with allowed characters not to be
+ * escaped and the default protocol charset.
+ *
+ * @param unescaped a string
+ * @param allowed allowed characters not to be escaped
+ * @return the escaped string
+ *
+ * @throws URIException if the default protocol charset is not supported
+ *
+ * @see URI#getDefaultProtocolCharset
+ */
+ public static String encode(String unescaped, BitSet allowed)
+ throws URIException {
+
+ return encode(unescaped, allowed, URI.getDefaultProtocolCharset());
+ }
+
+
+ /**
+ * Escape and encode a given string with allowed characters not to be
+ * escaped and a given charset.
+ *
+ * @param unescaped a string
+ * @param allowed allowed characters not to be escaped
+ * @param charset the charset
+ * @return the escaped string
+ */
+ public static String encode(String unescaped, BitSet allowed,
+ String charset) throws URIException {
+ byte[] rawdata = URLCodec.encodeUrl(allowed,
+ EncodingUtil.getBytes(unescaped, charset));
+ return EncodingUtil.getAsciiString(rawdata);
+ }
+
+
+ /**
+ * Unescape and decode a given string regarded as an escaped string with the
+ * default protocol charset.
+ *
+ * @param escaped a string
+ * @return the unescaped string
+ *
+ * @throws URIException if the string cannot be decoded (invalid)
+ *
+ * @see URI#getDefaultProtocolCharset
+ */
+ public static String decode(String escaped) throws URIException {
+ try {
+ byte[] rawdata = URLCodec.decodeUrl(EncodingUtil.getAsciiBytes(escaped));
+ return EncodingUtil.getString(rawdata, URI.getDefaultProtocolCharset());
+ } catch (DecoderException e) {
+ throw new URIException(e.getMessage());
+ }
+ }
+
+ /**
+ * Unescape and decode a given string regarded as an escaped string.
+ *
+ * @param escaped a string
+ * @param charset the charset
+ * @return the unescaped string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @see Coder#decode
+ */
+ public static String decode(String escaped, String charset)
+ throws URIException {
+
+ return Coder.decode(escaped.toCharArray(), charset);
+ }
+
+ // ---------------------------------------------------------- Inner classes
+
+ /**
+ * The basic and internal utility for URI escape and character encoding and
+ * decoding.
+ *
+ * @deprecated use org.apache.commons.codec.net.URLCodec
+ */
+ protected static class Coder extends URI {
+
+ /**
+ * Escape and encode a given string with allowed characters not to be
+ * escaped.
+ *
+ * @param unescapedComponent an unescaped component
+ * @param allowed allowed characters not to be escaped
+ * @param charset the charset to encode
+ * @return the escaped and encoded string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @deprecated use org.apache.commons.codec.net.URLCodec
+ */
+ public static char[] encode(String unescapedComponent, BitSet allowed, String charset)
+ throws URIException {
+
+ return URI.encode(unescapedComponent, allowed, charset);
+ }
+
+
+ /**
+ * Unescape and decode a given string.
+ *
+ * @param escapedComponent an being-unescaped component
+ * @param charset the charset to decode
+ * @return the escaped and encoded string
+ *
+ * @throws URIException if the charset is not supported
+ *
+ * @deprecated use org.apache.commons.codec.net.URLCodec
+ */
+ public static String decode(char[] escapedComponent, String charset)
+ throws URIException {
+
+ return URI.decode(escapedComponent, charset);
+ }
+
+
+ /**
+ * Verify whether a given string is escaped or not
+ *
+ * @param original given characters
+ * @return true if the given character array is 7 bit ASCII-compatible.
+ */
+ public static boolean verifyEscaped(char[] original) {
+ for (int i = 0; i < original.length; i++) {
+ int c = original[i];
+ if (c > 128) {
+ return false;
+ } else if (c == '%') {
+ if (Character.digit(original[++i], 16) == -1
+ || Character.digit(original[++i], 16) == -1) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Replace from a given character to given character in an array order
+ * for a given string.
+ *
+ * @param original a given string
+ * @param from a replacing character array
+ * @param to a replaced character array
+ * @return the replaced string
+ */
+ public static String replace(String original, char[] from, char[] to) {
+ for (int i = from.length; i > 0; --i) {
+ original = replace(original, from[i], to[i]);
+ }
+ return original.toString();
+ }
+
+
+ /**
+ * Replace from a given character to given character for a given string.
+ *
+ * @param original a given string
+ * @param from a replacing character array
+ * @param to a replaced character array
+ * @return the replaced string
+ */
+ public static String replace(String original, char from, char to) {
+ StringBuffer result = new StringBuffer(original.length());
+ int at, saved = 0;
+ do {
+ at = original.indexOf(from);
+ if (at >= 0) {
+ result.append(original.substring(0, at));
+ result.append(to);
+ } else {
+ result.append(original.substring(saved));
+ }
+ saved = at;
+ } while (at >= 0);
+ return result.toString();
+ }
+ }
+
+}
+
Index: 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/package.html
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/package.html,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/package.html 22 Aug 2012 17:30:38 -0000 1.1
@@ -0,0 +1,11 @@
+
+
+
+ Package Documentation for org.apache.commons.httpclient.util
+
+
+ Provides some utility classes for use by HttpClient.
+
+ @since 2.0
+
+
Index: lams_build/3rdParty.userlibraries
===================================================================
RCS file: /usr/local/cvsroot/lams_build/3rdParty.userlibraries,v
diff -u -r1.55 -r1.56
--- lams_build/3rdParty.userlibraries 17 Aug 2012 14:13:06 -0000 1.55
+++ lams_build/3rdParty.userlibraries 22 Aug 2012 17:28:46 -0000 1.56
@@ -116,6 +116,6 @@
-
+