Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 12739 invoked from network); 7 Nov 2002 18:29:04 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 7 Nov 2002 18:29:04 -0000 Received: (qmail 23202 invoked by uid 97); 7 Nov 2002 18:29:05 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 23095 invoked by uid 97); 7 Nov 2002 18:29:03 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 24449 invoked by uid 98); 7 Nov 2002 17:26:23 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Message-ID: From: Noam Berg To: "'commons-dev@jakarta.apache.org'" Subject: [httpclient]-timeout-> i found a small but important bug. Date: Thu, 7 Nov 2002 19:28:35 +0200 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2653.19) Content-Type: multipart/mixed; boundary="----_=_NextPart_000_01C28683.1A3D7BF0" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N ------_=_NextPart_000_01C28683.1A3D7BF0 Content-Type: text/plain; charset="windows-1255" Hello, I need to use http connections with timeouts, since it is not part of the release i downloaded 7th Nov 2002 sources, but using HttpClient.setTimeout didnt help. i checked out the code and find out that when you create the sockets using host+port it immediately connects so setting the timeout after that does not change (at least in my case where i dont reuse them and its important in first connect for a timeout to be set). The changes: line 350: _socket = new Socket(); _socket.connect(new java.net.InetSocketAddress(host,port),_so_timeout); line 781: Socket s = sslSocketFactory.createSocket(); s.connect(new java.net.InetSocketAddress(host, port), _so_timeout); return s; and the whole file : <> i'm sorry but i dont have CVS ... 10x. P.S. Another small thing (suggestion) ... When i first started using this package i wanted to do a very simple httpconnection ... what would have help me _a lot_ would have been a few small source examples for usage (maybe a bit like your test classes). 10x Noam Berg R&D SofaWare Technologies Ltd. 3 Hahilazon St. Ramat-Gan Israel Tel: +972-3-6128989 ext 102 Fax: +972-3-5755442 E-mail: noam@sofaware.com Web: http://www.sofaware.com ------_=_NextPart_000_01C28683.1A3D7BF0 Content-Type: application/octet-stream; name="HttpConnection.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="HttpConnection.java" /*=0A= * $Header: = /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/h= ttpclient/HttpConnection.java,v 1.23 2002/10/31 07:45:34 jsdever Exp = $=0A= * $Revision: 1.23 $=0A= * $Date: 2002/10/31 07:45:34 $=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 1999-2002 The Apache Software Foundation. All = rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or = without=0A= * modification, are permitted provided that the following = conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above = copyright=0A= * notice, this list of conditions and the following disclaimer = in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution, = if=0A= * any, must include the following acknowlegement:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowlegement may appear in the software = itself,=0A= * if and wherever such third-party acknowlegements normally = appear.=0A= *=0A= * 4. The names "The Jakarta Project", "HttpClient", and "Apache = Software=0A= * Foundation" must not be used to endorse or promote products = derived=0A= * from this software without prior written permission. For = written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache"=0A= * nor may "Apache" appear in their names without prior written=0A= * permission of the Apache Group.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED = AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT = LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY = OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY = OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For = more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= *=0A= * [Additional notices, if required by prior licensing conditions]=0A= *=0A= */=0A= =0A= package org.apache.commons.httpclient;=0A= =0A= import org.apache.commons.logging.Log;=0A= import org.apache.commons.logging.LogFactory;=0A= =0A= import java.io.IOException;=0A= import java.io.InputStream;=0A= import java.io.OutputStream;=0A= import java.lang.reflect.Method;=0A= import java.net.Socket;=0A= import java.net.SocketException;=0A= import javax.net.ssl.SSLSocketFactory;=0A= =0A= =0A= =0A= /**=0A= *

=0A= * An abstraction of an HTTP {@link InputStream} and {@link = OutputStream}=0A= * pair, together with the relevant attributes.=0A= *

=0A= * @author Rod Waldhoff=0A= * @author Sean C. Sullivan=0A= * @author Ortwin Gl=FCck=0A= * @version $Revision: 1.23 $ $Date: 2002/10/31 07:45:34 $=0A= */=0A= public class HttpConnection {=0A= // ----------------------------------------------------------- = Constructors=0A= =0A= /**=0A= * Constructor.=0A= *=0A= * @param host the host I should connect to=0A= * @param port the port I should connect to=0A= */=0A= public HttpConnection(String host, int port) {=0A= this(null, -1, host, port, false);=0A= }=0A= =0A= /**=0A= * Constructor.=0A= *=0A= * @param host the host I should connect to=0A= * @param port the port I should connect to=0A= * @param secure when true, connect via HTTPS (SSL)=0A= */=0A= public HttpConnection(String host, int port, boolean secure) {=0A= this(null, -1, host, port, secure);=0A= }=0A= =0A= /**=0A= * Constructor.=0A= *=0A= * @param proxyHost the host I should proxy via=0A= * @param proxyPort the port I should proxy via=0A= * @param host the host I should connect to=0A= * @param port the port I should connect to=0A= */=0A= public HttpConnection(String proxyHost, int proxyPort, String host, = int port) {=0A= this(proxyHost, proxyPort, host, port, false);=0A= }=0A= =0A= /**=0A= * Fully-specified constructor.=0A= *=0A= * @param proxyHost the host I should proxy via=0A= * @param proxyPort the port I should proxy via=0A= * @param host the host I should connect to. Parameter value must = be non-null.=0A= * @param port the port I should connect to=0A= * @param secure when true, connect via HTTPS (SSL)=0A= */=0A= public HttpConnection(String proxyHost, int proxyPort, String host, = =0A= int port, boolean secure) {=0A= if (log.isDebugEnabled()){=0A= log.debug("HttpConnectionManager.getConnection: creating = "=0A= + " connection for " + host + ":" + port + " via " + = proxyHost=0A= + ":" + proxyPort);=0A= }=0A= =0A= if (host =3D=3D null) {=0A= throw new NullPointerException("host parameter is = null");=0A= }=0A= _proxyHost =3D proxyHost;=0A= _proxyPort =3D proxyPort;=0A= _host =3D host;=0A= _port =3D port;=0A= _ssl =3D secure;=0A= }=0A= =0A= // ------------------------------------------ Attribute Setters and = Getters=0A= =0A= /**=0A= * Specifies an alternative factory for SSL sockets. If = factory=0A= * is null the default implementation is used.=0A= *=0A= * @param factory An instance of a SSLSocketFactory or = null.=0A= * @throws IllegalStateException If called after the connection was = opened=0A= */=0A= public void setSSLSocketFactory(SSLSocketFactory factory) {=0A= assertNotOpen();=0A= sslSocketFactory =3D factory;=0A= }=0A= =0A= /**=0A= * Return my host.=0A= *=0A= * @return my host.=0A= */=0A= public String getHost() {=0A= return _host;=0A= }=0A= =0A= /**=0A= * Set my host.=0A= *=0A= * @param host the host I should connect to. Parameter value must = be non-null.=0A= * @throws IllegalStateException if I am already connected=0A= */=0A= public void setHost(String host) throws IllegalStateException {=0A= if (host =3D=3D null) {=0A= throw new NullPointerException("host parameter is = null");=0A= }=0A= assertNotOpen();=0A= _host =3D host;=0A= }=0A= =0A= /**=0A= * Return my port.=0A= *=0A= * If the port is -1 (or less than 0) the default port for=0A= * the current protocol is returned.=0A= *=0A= * @return my port.=0A= */=0A= public int getPort() {=0A= if (_port < 0) {=0A= return isSecure() ? 443 : 80;=0A= } else {=0A= return _port;=0A= }=0A= }=0A= =0A= /**=0A= * Set my port.=0A= *=0A= * @param port the port I should connect to=0A= * @throws IllegalStateException if I am already connected=0A= */=0A= public void setPort(int port) throws IllegalStateException {=0A= assertNotOpen();=0A= _port =3D port;=0A= }=0A= =0A= /**=0A= * Return my proxy host.=0A= *=0A= * @return my proxy host.=0A= */=0A= public String getProxyHost() {=0A= return _proxyHost;=0A= }=0A= =0A= /**=0A= * Set the host I should proxy through.=0A= *=0A= * @param host the host I should proxy through.=0A= * @throws IllegalStateException if I am already connected=0A= */=0A= public void setProxyHost(String host) throws IllegalStateException = {=0A= assertNotOpen();=0A= _proxyHost =3D host;=0A= }=0A= =0A= /**=0A= * Return my proxy port.=0A= *=0A= * @return my proxy port.=0A= */=0A= public int getProxyPort() {=0A= return _proxyPort;=0A= }=0A= =0A= /**=0A= * Set the port I should proxy through.=0A= *=0A= * @param port the host I should proxy through.=0A= * @throws IllegalStateException if I am already connected=0A= */=0A= public void setProxyPort(int port) throws IllegalStateException = {=0A= assertNotOpen();=0A= _proxyPort =3D port;=0A= }=0A= =0A= /**=0A= * Return true if I will (or I am) connected over a=0A= * secure (HTTPS/SSL) protocol.=0A= *=0A= * @return true if I will (or I am) connected over a=0A= * secure (HTTPS/SSL) protocol.=0A= */=0A= public boolean isSecure() {=0A= return _ssl;=0A= }=0A= =0A= /**=0A= * Get the protocol.=0A= * @return HTTPS if secure, HTTP otherwise=0A= */=0A= public String getProtocol() {=0A= return (isSecure() ? "HTTPS" : "HTTP");=0A= }=0A= =0A= =0A= =0A= /**=0A= * Set whether or not I should connect over HTTPS (SSL).=0A= *=0A= * @param secure whether or not I should connect over HTTPS = (SSL).=0A= * @throws IllegalStateException if I am already connected=0A= */=0A= public void setSecure(boolean secure) throws IllegalStateException = {=0A= assertNotOpen();=0A= _ssl =3D secure;=0A= }=0A= =0A= /**=0A= * Return true if I am connected,=0A= * false otherwise.=0A= *=0A= * @return true if I am connected=0A= */=0A= public boolean isOpen() {=0A= return _open;=0A= }=0A= =0A= /**=0A= * Return true if I am (or I will be)=0A= * connected via a proxy, false otherwise.=0A= *=0A= * @return true if I am (or I will be)=0A= * connected via a proxy, false otherwise.=0A= */=0A= public boolean isProxied() {=0A= return (!(null =3D=3D _proxyHost || 0 >=3D _proxyPort));=0A= }=0A= =0A= // --------------------------------------------------- Other Public = Methods=0A= =0A= /**=0A= * Set my {@link Socket}'s timeout, via {@link = Socket#setSoTimeout}. If the=0A= * connection is already open, the SO_TIMEOUT is changed. If no = connection=0A= * is open, then subsequent connections will use the timeout = value.=0A= *=0A= * @param timeout the timeout value=0A= * @throws SocketException - if there is an error in the = underlying=0A= * protocol, such as a TCP error.=0A= * @throws IllegalStateException if I am not connected=0A= */=0A= public void setSoTimeout(int timeout) =0A= throws SocketException, IllegalStateException {=0A= log.debug("HttpConnection.setSoTimeout("+ timeout +")");=0A= _so_timeout =3D timeout;=0A= if(_socket !=3D null){=0A= _socket.setSoTimeout(timeout);=0A= }=0A= }=0A= =0A= /**=0A= * Open this connection to the current host and port=0A= * (via a proxy if so configured).=0A= *=0A= * @throws IOException when there are errors opening the = connection=0A= */=0A= public void open() throws IOException {=0A= log.trace("enter HttpConnection.open()");=0A= =0A= assertNotOpen(); // ??? is this worth doing?=0A= try {=0A= if (null =3D=3D _socket) {=0A= String host =3D (null =3D=3D _proxyHost) ? _host : = _proxyHost;=0A= int port =3D (null =3D=3D _proxyHost) ? _port : = _proxyPort;=0A= if (isSecure() && !isProxied()) {=0A= if (sslSocketFactory =3D=3D null) {=0A= sslSocketFactory =3D (SSLSocketFactory) = SSLSocketFactory.getDefault();=0A= }=0A= _socket =3D (new = SocketCreator()).createSocket(host,port);=0A= _usingSecureSocket =3D true;=0A= } else {=0A= _socket =3D new Socket();=0A= _socket.connect(new = java.net.InetSocketAddress(host,port),_so_timeout);=0A= _usingSecureSocket =3D false;=0A= }=0A= }=0A= _socket.setSoTimeout(_so_timeout);=0A= _input =3D _socket.getInputStream();=0A= _output =3D _socket.getOutputStream();=0A= _open =3D true;=0A= } catch (IOException e) {=0A= // Connection wasn't opened properly=0A= // so close everything out=0A= closeSocketAndStreams();=0A= throw e;=0A= }=0A= }=0A= =0A= /**=0A= * Calling this method indicates that the proxy has successfully = created=0A= * the tunnel to the host. The socket will be switched to the = secure socket.=0A= * Subsequent communication is done via the secure socket. The = method can only=0A= * be called once on a proxied secure connection.=0A= *=0A= * @throws IllegalStateException if connection is not secure and = proxied or=0A= * if the socket is already secure.=0A= * @throws IOException if an error occured creating the secure = socket=0A= */=0A= public void tunnelCreated()=0A= throws IllegalStateException, IOException {=0A= log.trace("enter HttpConnection.tunnelCreated()");=0A= =0A= if (!isSecure() || !isProxied()) {=0A= throw new IllegalStateException("Connection must be secure and = proxied to use this feature");=0A= }=0A= if (_usingSecureSocket) {=0A= throw new IllegalStateException("Already using a secure = socket");=0A= }=0A= =0A= if (sslSocketFactory =3D=3D null) {=0A= sslSocketFactory =3D (SSLSocketFactory) = SSLSocketFactory.getDefault();=0A= }=0A= _socket =3D (new SocketCreator()).createSocket(_socket, _host, = _port, true);=0A= _input =3D _socket.getInputStream();=0A= _output =3D _socket.getOutputStream();=0A= _usingSecureSocket =3D true;=0A= _tunnelEstablished =3D true;=0A= log.debug("Secure tunnel created");=0A= }=0A= =0A= =0A= /**=0A= * Indicates if the connection is completely transparent from end = to end.=0A= *=0A= * @return true if conncetion is not proxied or tunneled through a = transparent=0A= * proxy; false otherwise.=0A= */=0A= public boolean isTransparent() {=0A= return !isProxied() || _tunnelEstablished;=0A= }=0A= =0A= /**=0A= * Return a {@link RequestOutputStream} suitable for writing = (possibly =0A= * chunked) bytes to my {@link OutputStream}.=0A= *=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= * @return a stream to write the request to=0A= */=0A= public OutputStream getRequestOutputStream()=0A= throws IOException, IllegalStateException {=0A= log.trace("enter HttpConnection.getRequestOutputStream()");=0A= assertOpen();=0A= return _output;=0A= }=0A= =0A= /**=0A= * Return a {@link RequestOutputStream} suitable for writing = (possibly =0A= * chunked) bytes to my {@link OutputStream}.=0A= *=0A= * @param useChunking when true the chunked = transfer-encoding will=0A= * be used=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= * @return a stream to write the request to=0A= * @deprecated Use new = ChunkedOutputStream(httpConnecion.getRequestOutputStream());=0A= */=0A= public OutputStream getRequestOutputStream(boolean useChunking) =0A= throws IOException, IllegalStateException {=0A= log.trace("enter = HttpConnection.getRequestOutputStream(boolean)");=0A= =0A= assertOpen();=0A= if (useChunking) {=0A= return new ChunkedOutputStream(_output);=0A= } else {=0A= return _output;=0A= }=0A= }=0A= =0A= /**=0A= * Return a {@link ResponseInputStream} suitable for reading = (possibly =0A= * chunked) bytes from my {@link InputStream}.=0A= *

=0A= * If the given {@link HttpMethod} contains=0A= * a Transfer-Encoding: chunked header,=0A= * the returned stream will be configured=0A= * to read chunked bytes.=0A= *=0A= * @param method This argument is ignored.=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= * @return a stream to read the response from=0A= * @deprecated Use getResponseInputStream() instead. =0A= */=0A= public InputStream getResponseInputStream(HttpMethod method) =0A= throws IOException, IllegalStateException {=0A= log.trace("enter = HttpConnection.getResponseInputStream(HttpMethod)");=0A= return getResponseInputStream();=0A= }=0A= =0A= public InputStream getResponseInputStream() =0A= throws IOException, IllegalStateException {=0A= log.trace("enter HttpConnection.getResponseInputStream()");=0A= assertOpen();=0A= return _input;=0A= }=0A= =0A= /**=0A= * Write the specified bytes to my output stream.=0A= *=0A= * @param data the data to be written=0A= * @throws HttpRecoverableException if a SocketException occurs =0A= * @throws IllegalStateException if not connected=0A= * @throws IOException if an I/O problem occurs=0A= * @see #write(byte[],int,int) =0A= */=0A= public void write(byte[] data) =0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.write(byte[])");=0A= this.write(data, 0, data.length);=0A= }=0A= =0A= =0A= /**=0A= * Write length bytes in data starting at =0A= * offset to my output stream. =0A= *=0A= * The general contract for=0A= * write(b, off, len) is that some of the bytes in the array b are = written=0A= * to the output stream in order; element b[off] is the first byte = written=0A= * and b[off+len-1] is the last byte written by this operation.=0A= *=0A= * @param data array containing the data to be written.=0A= * @param offset the start offset in the data.=0A= * @param length the number of bytes to write.=0A= * @throws HttpRecoverableException if a SocketException occurs =0A= * @throws IllegalStateException if not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void write(byte[] data, int offset, int length) =0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.write(byte[], int, int)");=0A= =0A= if (offset+length > data.length){=0A= throw new HttpRecoverableException("Unable to write:" +=0A= " offset=3D" + offset +=0A= " length=3D" + length +=0A= " data.length=3D" + data.length);=0A= }else if (data.length <=3D 0){=0A= throw new HttpRecoverableException("Unable to write:" +=0A= " data.length=3D" + data.length);=0A= }=0A= =0A= assertOpen();=0A= =0A= if(wireLog.isDebugEnabled()) {=0A= String data_str =3D new String(data, offset, length, = "ISO-8859-1");=0A= wireLog.debug(">> \"" + data_str + "\" [\\r\\n]" );=0A= }=0A= try {=0A= _output.write(data, offset, length);=0A= } catch(SocketException se){=0A= log.debug("HttpConnection: Socket exception while writing = data", se);=0A= throw new HttpRecoverableException(se.toString());=0A= } catch(IOException ioe) {=0A= log.debug("HttpConnection: Exception while writing data", = ioe);=0A= throw ioe;=0A= }=0A= }=0A= =0A= =0A= =0A= /**=0A= * Write the specified bytes, followed by = "\r\n".getBytes() to my=0A= * output stream.=0A= *=0A= * @param data the bytes to be written=0A= * @throws HttpRecoverableException when socket exceptions occur = writing data=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void writeLine(byte[] data) =0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.writeLine(byte[])");=0A= =0A= assertOpen();=0A= if(wireLog.isDebugEnabled() && (data.length > 0)) {=0A= String data_str =3D new String(data);=0A= wireLog.debug(">> \"" + data_str.trim() + "\" [\\r\\n]" = );=0A= }=0A= try{=0A= _output.write(data);=0A= writeLine();=0A= } catch(SocketException se){=0A= log.info("SocketException while writing data to output", = se);=0A= throw new HttpRecoverableException(se.toString());=0A= } catch(IOException ioe){=0A= log.info("IOException while writing data to output", = ioe);=0A= throw ioe;=0A= }=0A= }=0A= =0A= /**=0A= * Write "\r\n".getBytes() to my output stream.=0A= *=0A= * @throws HttpRecoverableException when socket exceptions occur = writing=0A= * data=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void writeLine() =0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.writeLine()");=0A= =0A= wireLog.debug(">> [\\r\\n]");=0A= try{=0A= _output.write(CRLF);=0A= } catch(SocketException se){=0A= log.warn("HttpConnection: Socket exception while writing = data", se);=0A= throw new HttpRecoverableException(se.toString());=0A= } catch(IOException ioe){=0A= log.warn("HttpConnection: IO exception while writing data", = ioe);=0A= throw ioe;=0A= }=0A= }=0A= =0A= /**=0A= * Write the specified String (as bytes) to my output stream.=0A= *=0A= * @param data the string to be written=0A= * @throws HttpRecoverableException when socket exceptions occur = writing=0A= * data=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void print(String data) =0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.print(String)");=0A= write(data.getBytes());=0A= }=0A= =0A= /**=0A= * Write the specified String (as bytes), followed by =0A= * "\r\n".getBytes() to my output stream.=0A= *=0A= * @param data the data to be written=0A= * @throws HttpRecoverableException when socket exceptions occur = writing=0A= * data=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void printLine(String data)=0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.printLine(String)");=0A= writeLine(data.getBytes());=0A= }=0A= =0A= /**=0A= * Write "\r\n".getBytes() to my output stream.=0A= *=0A= * @throws HttpRecoverableException when socket exceptions occur = writing=0A= * data=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= */=0A= public void printLine()=0A= throws IOException, IllegalStateException, HttpRecoverableException = {=0A= log.trace("enter HttpConnection.printLine()");=0A= writeLine();=0A= }=0A= =0A= /**=0A= * Read up to "\r\n" from my (unchunked) input stream.=0A= *=0A= * @throws IllegalStateException if I am not connected=0A= * @throws IOException if an I/O problem occurs=0A= * @return a line from the response=0A= */=0A= public String readLine()=0A= throws IOException, IllegalStateException {=0A= log.trace("enter HttpConnection.readLine()");=0A= =0A= assertOpen();=0A= StringBuffer buf =3D new StringBuffer();=0A= for(;;) {=0A= int ch =3D _input.read();=0A= if(ch < 0) {=0A= if(buf.length() =3D=3D 0) {=0A= return null;=0A= } else {=0A= break;=0A= }=0A= } else if (ch =3D=3D '\r') {=0A= // log.debug("HttpConnection.readLine() found \\r, = continuing");=0A= continue;=0A= } else if (ch =3D=3D '\n') {=0A= // log.debug("HttpConnection.readLine() found \\n, = breaking");=0A= break;=0A= }=0A= buf.append((char)ch);=0A= }=0A= if(wireLog.isDebugEnabled() && buf.length() > 0) {=0A= wireLog.debug("<< \"" + buf.toString() + "\" [\\r\\n]");=0A= }=0A= return (buf.toString());=0A= }=0A= =0A= /**=0A= * Shutdown my {@link Socket}'s output, via {@link = Socket#shutdownOutput}.=0A= */=0A= public void shutdownOutput() { =0A= log.trace("enter HttpConnection.shutdownOutput()");=0A= =0A= try {=0A= // Socket.shutdownOutput is a JDK 1.3=0A= // method. We'll use reflection in case=0A= // we're running in an older VM=0A= Class[] paramsClasses =3D new Class[0];=0A= Method shutdownOutput =3D _socket.getClass().getMethod=0A= ("shutdownOutput", paramsClasses);=0A= Object[] params =3D new Object[0];=0A= shutdownOutput.invoke(_socket, params);=0A= } catch (Exception ex) {=0A= log.debug("Unexpected Exception caught", ex);=0A= // Ignore, and hope everything goes right=0A= }=0A= // close output stream?=0A= }=0A= =0A= /**=0A= * Close my socket and streams.=0A= */=0A= public void close() {=0A= log.trace("enter HttpConnection.close()");=0A= closeSocketAndStreams();=0A= }=0A= =0A= // ------------------------------------------------------ Protected = Methods=0A= =0A= =0A= /**=0A= * Close everything out.=0A= */=0A= protected void closeSocketAndStreams() {=0A= log.trace("enter HttpConnection.closeSockedAndStreams()");=0A= =0A= if (null !=3D _input) {=0A= try {=0A= _input.close();=0A= } catch(Exception ex) {=0A= log.debug("Exception caught when closing input", ex);=0A= // ignored=0A= }=0A= _input =3D null;=0A= }=0A= =0A= if (null !=3D _output) {=0A= try {=0A= _output.close();=0A= } catch(Exception ex) {=0A= log.debug("Exception caught when closing output", ex);=0A= // ignored=0A= }=0A= _output =3D null;=0A= }=0A= =0A= if (null !=3D _socket) {=0A= try {=0A= _socket.close();=0A= } catch(Exception ex) {=0A= log.debug("Exception caught when closing socket", ex);=0A= // ignored=0A= }=0A= _socket =3D null;=0A= }=0A= _open =3D false;=0A= _tunnelEstablished =3D false;=0A= _usingSecureSocket =3D false;=0A= }=0A= =0A= /** =0A= * Throw an {@link IllegalStateException} if I am connected.=0A= *=0A= * @throws IllegalStateException if connected=0A= */=0A= protected void assertNotOpen()=0A= throws IllegalStateException {=0A= if(_open) {=0A= throw new IllegalStateException("Connection is open");=0A= }=0A= }=0A= =0A= /**=0A= * Throw an {@link IllegalStateException} if I am not connected.=0A= *=0A= * @throws IllegalStateException if not connected=0A= */=0A= protected void assertOpen()=0A= throws IllegalStateException {=0A= if(!_open) {=0A= throw new IllegalStateException("Connection is not = open");=0A= }=0A= }=0A= =0A= // -- javax.net binary isolation=0A= =0A= private class SocketCreator {=0A= public Socket createSocket(Socket socket, String host, int = port, boolean auto) throws IOException {=0A= return sslSocketFactory.createSocket(socket, host, port, = auto);=0A= }=0A= =0A= public Socket createSocket(String host, int port) throws = IOException {=0A= Socket s =3D sslSocketFactory.createSocket();=0A= s.connect(new java.net.InetSocketAddress(host, port), = _so_timeout);=0A= return s;=0A= }=0A= }=0A= // ------------------------------------------------------------- = Attributes=0A= =0A= /** Log object for this class. */=0A= private static final Log log =3D = LogFactory.getLog(HttpConnection.class);=0A= /** Log for any wire messages. */=0A= private static final Log wireLog =3D = LogFactory.getLog("httpclient.wire");=0A= /** My host. */=0A= private String _host =3D null;=0A= /** My port. */=0A= private int _port =3D -1;=0A= /** My proxy host. */=0A= private String _proxyHost =3D null;=0A= /** My proxy port. */=0A= private int _proxyPort =3D -1;=0A= /** My client Socket. */=0A= private Socket _socket =3D null;=0A= /** My InputStream. */=0A= private InputStream _input =3D null;=0A= /** My OutputStream. */=0A= private OutputStream _output =3D null;=0A= /** Whether or not I am connected. */=0A= private boolean _open =3D false;=0A= /** Whether or not I am/should connect via SSL. */=0A= private boolean _ssl =3D false;=0A= /** "\r\n", as bytes. */=0A= private static final byte[] CRLF =3D "\r\n".getBytes();=0A= /** SO_TIMEOUT value */=0A= private int _so_timeout =3D 0;=0A= /** An alternative factory for SSL sockets to use */=0A= private SSLSocketFactory sslSocketFactory =3D null;=0A= /** Whether or not the _socket is a secure one. Note the difference = to _ssl */=0A= private boolean _usingSecureSocket =3D false;=0A= /** Whether I am tunneling a proxy or not */=0A= private boolean _tunnelEstablished =3D false;=0A= }=0A= ------_=_NextPart_000_01C28683.1A3D7BF0 Content-Type: text/plain; charset=us-ascii -- To unsubscribe, e-mail: For additional commands, e-mail: ------_=_NextPart_000_01C28683.1A3D7BF0--