View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java,v 1.15 2003/05/22 18:26:33 olegk Exp $ 3 * $Revision: 1.15 $ 4 * $Date: 2003/05/22 18:26:33 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>;. 59 * 60 * [Additional notices, if required by prior licensing conditions] 61 * 62 */ 63 64 package org.apache.commons.httpclient; 65 66 import java.io.IOException; 67 68 import org.apache.commons.logging.Log; 69 import org.apache.commons.logging.LogFactory; 70 71 /*** 72 * <p>Wraps another method to tunnel through a proxy.</p> 73 * 74 * @author Ortwin Glueck 75 * @author dIon Gillard 76 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 77 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 78 * @since 2.0 79 * @version $Revision: 1.15 $ $Date: 2003/05/22 18:26:33 $ 80 */ 81 public class ConnectMethod extends HttpMethodBase { 82 /*** the name of this method */ 83 public static final String NAME = "CONNECT"; 84 85 /*** 86 * Create a connect method wrapping the existing method 87 * 88 * @param method the {@link HttpMethod method} to execute after connecting 89 * to the server 90 */ 91 public ConnectMethod(HttpMethod method) { 92 LOG.trace("enter ConnectMethod(HttpMethod)"); 93 this.method = method; 94 } 95 96 /*** 97 * Provide the {@link #NAME name} of this method. 98 * 99 * @return the String "CONNECT" 100 */ 101 public String getName() { 102 return NAME; 103 } 104 105 106 /*** 107 * This method does nothing. <tt>CONNECT</tt> request is not supposed 108 * to contain <tt>Authorization</tt> request header. 109 * 110 * @param state current state of http requests 111 * @param conn the connection to use for I/O 112 * 113 * @throws IOException when errors occur reading or writing to/from the 114 * connection 115 * @throws HttpException when a recoverable error occurs 116 * 117 * @see HttpMethodBase#addAuthorizationRequestHeader(HttpState, HttpConnection) 118 */ 119 protected void addAuthorizationRequestHeader(HttpState state, HttpConnection conn) 120 throws IOException, HttpException { 121 // Do nothing. Not applicable to CONNECT method 122 } 123 124 /*** 125 * This method does nothing. <tt>CONNECT</tt> request is not supposed 126 * to contain <tt>Content-Length</tt> request header. 127 * 128 * @param state current state of http requests 129 * @param conn the connection to use for I/O 130 * 131 * @throws IOException when errors occur reading or writing to/from the 132 * connection 133 * @throws HttpException when a recoverable error occurs 134 * 135 * @see HttpMethodBase#addContentLengthRequestHeader(HttpState, HttpConnection) 136 */ 137 protected void addContentLengthRequestHeader(HttpState state, HttpConnection conn) 138 throws IOException, HttpException { 139 // Do nothing. Not applicable to CONNECT method 140 } 141 142 /*** 143 * This method does nothing. <tt>CONNECT</tt> request is not supposed 144 * to contain <tt>Cookie</tt> request header. 145 * 146 * @param state current state of http requests 147 * @param conn the connection to use for I/O 148 * 149 * @throws IOException when errors occur reading or writing to/from the 150 * connection 151 * @throws HttpException when a recoverable error occurs 152 * 153 * @see HttpMethodBase#addCookieRequestHeader(HttpState, HttpConnection) 154 */ 155 protected void addCookieRequestHeader(HttpState state, HttpConnection conn) 156 throws IOException, HttpException { 157 // Do nothing. Not applicable to CONNECT method 158 } 159 160 161 /*** 162 * Populates the request headers map to with additional {@link Header 163 * headers} to be submitted to the given {@link HttpConnection}. 164 * 165 * <p> 166 * This implementation adds <tt>User-Agent</tt>, <tt>Host</tt>, 167 * and <tt>Proxy-Authorization</tt> headers, when appropriate. 168 * </p> 169 * 170 * @param state the client state 171 * @param conn the {@link HttpConnection} the headers will eventually be 172 * written to 173 * @throws IOException when an error occurs writing the request 174 * @throws HttpException when a HTTP protocol error occurs 175 * 176 * @see #writeRequestHeaders 177 */ 178 protected void addRequestHeaders(HttpState state, HttpConnection conn) 179 throws IOException, HttpException { 180 LOG.trace("enter ConnectMethod.addRequestHeaders(HttpState, " 181 + "HttpConnection)"); 182 addUserAgentRequestHeader(state, conn); 183 addHostRequestHeader(state, conn); 184 addProxyAuthorizationRequestHeader(state, conn); 185 addProxyConnectionHeader(state, conn); 186 } 187 188 /*** 189 * Execute this method by tunnelling and then executing the wrapped method. 190 * 191 * @param state the current http state 192 * @param conn the connection to write to 193 * @return the http status code from execution 194 * @throws HttpException when an error occurs writing the headers 195 * @throws IOException when an error occurs writing the headers 196 */ 197 public int execute(HttpState state, HttpConnection conn) 198 throws IOException, HttpException { 199 200 LOG.trace("enter ConnectMethod.execute(HttpState, HttpConnection)"); 201 int code = super.execute(state, conn); 202 LOG.debug("CONNECT status code " + code); 203 if ((code >= 200) && (code < 300)) { 204 conn.tunnelCreated(); 205 code = method.execute(state, conn); 206 } else { 207 // What is to follow is an ugly hack. 208 // I REALLY hate having to resort to such 209 // an appalling trick 210 // TODO: Connect method must be redesigned. 211 // The only feasible solution is to split monolithic 212 // HttpMethod into HttpRequest/HttpResponse pair. 213 // That would allow to execute CONNECT method 214 // behind the scene and return CONNECT HttpResponse 215 // object in response to the original request that 216 // contains the correct status line, headers & 217 // response body. 218 219 LOG.debug("CONNECT failed, fake the response for the original method"); 220 if (method instanceof HttpMethodBase) { 221 // Pass the status, headers and response stream to the wrapped 222 // method. 223 // To ensure that the connection is not released more than once 224 // this method is still responsible for releasing the connection. 225 // This will happen when the response body is consumed, or when 226 // the wrapped method closes the response connection in 227 // releaseConnection(). 228 ((HttpMethodBase) method).fakeResponse( 229 getStatusLine(), 230 getResponseHeaderGroup(), 231 getResponseStream() 232 ); 233 } else { 234 releaseConnection(); 235 } 236 } 237 return code; 238 } 239 240 /*** 241 * Special Connect request. 242 * 243 * @param state the current http state 244 * @param conn the connection to write to 245 * @throws IOException when an error occurs writing the request 246 * @throws HttpException when an error occurs writing the request 247 */ 248 protected void writeRequestLine(HttpState state, HttpConnection conn) 249 throws IOException, HttpException { 250 int port = conn.getPort(); 251 if (port == -1) { 252 port = conn.getProtocol().getDefaultPort(); 253 } 254 StringBuffer buffer = new StringBuffer(); 255 buffer.append(getName()); 256 buffer.append(' '); 257 buffer.append(conn.getHost()); 258 if (port > -1) { 259 buffer.append(':'); 260 buffer.append(port); 261 } 262 buffer.append(" HTTP/1.1"); 263 String line = buffer.toString(); 264 conn.printLine(line); 265 if (Wire.enabled()) { 266 Wire.output(line); 267 } 268 } 269 270 /*** 271 * Returns <code>true</code> if the status code is anything other than 272 * SC_OK, <code>false</code> otherwise. 273 * 274 * @see HttpMethodBase#shouldCloseConnection(HttpConnection) 275 * @see HttpStatus#SC_OK 276 * 277 * @return <code>true</code> if the connection should be closed 278 */ 279 protected boolean shouldCloseConnection(HttpConnection conn) { 280 return (getStatusCode() != HttpStatus.SC_OK); 281 } 282 283 /*** Log object for this class. */ 284 private static final Log LOG = LogFactory.getLog(ConnectMethod.class); 285 286 /*** The wrapped method */ 287 private HttpMethod method; 288 289 }

This page was automatically generated by Maven