View Javadoc

1   /*
2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java,v 1.29 2004/06/24 21:39:52 mbecke Exp $
3    * $Revision: 155418 $
4    * $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   */
29  
30  package org.apache.commons.httpclient;
31  
32  import java.io.IOException;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /***
38   * Establishes a tunneled HTTP connection via the CONNECT method.
39   *
40   * @author Ortwin Gl???ck
41   * @author dIon Gillard
42   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
43   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
44   * @since 2.0
45   * @version $Revision: 155418 $ $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
46   */
47  public class ConnectMethod extends HttpMethodBase {
48      
49      /*** the name of this method */
50      public static final String NAME = "CONNECT";
51  
52      /***
53       * Create a connect method.
54       * 
55       * @since 3.0
56       */
57      public ConnectMethod() {
58          LOG.trace("enter ConnectMethod()");
59      }
60  
61      /***
62       * @deprecated the wrapped method is no longer used
63       * 
64       * Create a connect method wrapping the existing method
65       *
66       * @param method the {@link HttpMethod method} to execute after connecting
67       *      to the server
68       */
69      public ConnectMethod(HttpMethod method) {
70          LOG.trace("enter ConnectMethod(HttpMethod)");
71      }
72  
73      /***
74       * Provide the {@link #NAME name} of this method.
75       *
76       * @return the String "CONNECT"
77       */
78      public String getName() {
79          return NAME;
80      }
81  
82      /***
83       * This method does nothing. <tt>CONNECT</tt> request is not supposed 
84       * to contain <tt>Cookie</tt> request header.
85       *
86       * @param state current state of http requests
87       * @param conn the connection to use for I/O
88       *
89       * @throws IOException when errors occur reading or writing to/from the
90       *         connection
91       * @throws HttpException when a recoverable error occurs
92       *  
93       * @see HttpMethodBase#addCookieRequestHeader(HttpState, HttpConnection)
94       */
95      protected void addCookieRequestHeader(HttpState state, HttpConnection conn)
96          throws IOException, HttpException {
97          // Do nothing. Not applicable to CONNECT method
98      }
99  
100 
101     /***
102      * Populates the request headers map to with additional {@link Header
103      * headers} to be submitted to the given {@link HttpConnection}.
104      *
105      * <p>
106      * This implementation adds <tt>User-Agent</tt>, <tt>Host</tt>,
107      * and <tt>Proxy-Authorization</tt> headers, when appropriate.
108      * </p>
109      *
110      * @param state the client state
111      * @param conn the {@link HttpConnection} the headers will eventually be
112      *        written to
113      * @throws IOException when an error occurs writing the request
114      * @throws HttpException when a HTTP protocol error occurs
115      *
116      * @see #writeRequestHeaders
117      */
118     protected void addRequestHeaders(HttpState state, HttpConnection conn)
119         throws IOException, HttpException {
120         LOG.trace("enter ConnectMethod.addRequestHeaders(HttpState, "
121             + "HttpConnection)");
122         addUserAgentRequestHeader(state, conn);
123         addHostRequestHeader(state, conn);
124         addProxyConnectionHeader(state, conn);
125     }
126 
127     /***
128      * Execute this method and create a tunneled HttpConnection.  If the method
129      * is successful (i.e. the status is a 2xx) tunnelCreated() will be called
130      * on the connection.
131      *
132      * @param state the current http state
133      * @param conn the connection to write to
134      * @return the http status code from execution
135      * @throws HttpException when an error occurs writing the headers
136      * @throws IOException when an error occurs writing the headers
137      * 
138      * @see HttpConnection#tunnelCreated()
139      */
140     public int execute(HttpState state, HttpConnection conn) 
141     throws IOException, HttpException {
142 
143         LOG.trace("enter ConnectMethod.execute(HttpState, HttpConnection)");
144         int code = super.execute(state, conn);
145         if (LOG.isDebugEnabled()) {
146             LOG.debug("CONNECT status code " + code);
147         }
148         return code;
149     }
150 
151     /***
152      * Special Connect request.
153      *
154      * @param state the current http state
155      * @param conn the connection to write to
156      * @throws IOException when an error occurs writing the request
157      * @throws HttpException when an error occurs writing the request
158      */
159     protected void writeRequestLine(HttpState state, HttpConnection conn)
160     throws IOException, HttpException {
161         int port = conn.getPort();
162         if (port == -1) {
163             port = conn.getProtocol().getDefaultPort();  
164         }
165         StringBuffer buffer = new StringBuffer();
166         buffer.append(getName()); 
167         buffer.append(' '); 
168         buffer.append(conn.getHost()); 
169         if (port > -1) {
170             buffer.append(':'); 
171             buffer.append(port); 
172         }
173         buffer.append(" "); 
174         buffer.append(getEffectiveVersion()); 
175         String line = buffer.toString();
176         conn.printLine(line, getParams().getHttpElementCharset());
177         if (Wire.HEADER_WIRE.enabled()) {
178             Wire.HEADER_WIRE.output(line);
179         }
180     }
181 
182     /***
183      * Returns <code>true</code> if the status code is anything other than
184      * SC_OK, <code>false</code> otherwise.
185      * 
186      * @see HttpMethodBase#shouldCloseConnection(HttpConnection)
187      * @see HttpStatus#SC_OK
188      * 
189      * @return <code>true</code> if the connection should be closed
190      */
191     protected boolean shouldCloseConnection(HttpConnection conn) {
192         if (getStatusCode() == HttpStatus.SC_OK) {
193             Header connectionHeader = null;
194             if (!conn.isTransparent()) {
195                 connectionHeader = getResponseHeader("proxy-connection");
196             }
197             if (connectionHeader == null) {
198                 connectionHeader = getResponseHeader("connection");
199             }
200             if (connectionHeader != null) {
201                 if (connectionHeader.getValue().equalsIgnoreCase("close")) {
202                     if (LOG.isWarnEnabled()) {
203                         LOG.warn("Invalid header encountered '" + connectionHeader.toExternalForm() 
204                         + "' in response " + getStatusLine().toString());
205                     }
206                 }
207             }
208             return false;
209         } else {
210             return super.shouldCloseConnection(conn);
211         }
212     }
213     
214     /*** Log object for this class. */
215     private static final Log LOG = LogFactory.getLog(ConnectMethod.class);
216 
217 }