2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.internal.client.connector.http;
22  
23  import java.io.IOException;
24  
25  import java.net.HttpURLConnection;
26  import java.net.URL;
27  
28  import java.util.ArrayList;
29  import java.util.Enumeration;
30  import java.util.List;
31  
32  import org.apache.cactus.WebRequest;
33  import org.apache.cactus.client.authentication.Authentication;
34  import org.apache.cactus.internal.configuration.Configuration;
35  import org.apache.cactus.internal.util.CookieUtil;
36  import org.apache.cactus.internal.util.UrlUtil;
37  import org.apache.commons.httpclient.HostConfiguration;
38  import org.apache.commons.httpclient.HttpClient;
39  import org.apache.commons.httpclient.HttpState;
40  import org.apache.commons.httpclient.HttpMethod;
41  import org.apache.commons.httpclient.NameValuePair;
42  import org.apache.commons.httpclient.methods.GetMethod;
43  import org.apache.commons.httpclient.methods.PostMethod;
44  import org.apache.commons.httpclient.protocol.Protocol;
45  
46  /**
47   * Implementation of <code>ConnectionHelper</code> using Jakarta Commons
48   * HttpClient.
49   *
50   * @version $Id: HttpClientConnectionHelper.java 238991 2004-05-22 11:34:50Z vmassol $
51   */
52  public class HttpClientConnectionHelper implements ConnectionHelper
53  {
54      /**
55       * The <code>HttpMethod</code> used to connect to the HTTP server. It is
56       * either a <code>GetMethod</code> or a <code>PostMethod</code>.
57       */
58      private HttpMethod method;
59  
60      /**
61       * The URL that will be used for the HTTP connection.
62       */
63      private String url;
64  
65      /**
66       * @param theURL the URL that will be used for the HTTP connection.
67       */
68      public HttpClientConnectionHelper(String theURL)
69      {
70          this.url = theURL;
71      }
72  
73      /**
74       * {@inheritDoc}
75       * @see ConnectionHelper#connect(WebRequest, Configuration)
76       */
77      public HttpURLConnection connect(WebRequest theRequest, 
78          Configuration theConfiguration) throws Throwable
79      {
80          URL url = new URL(this.url);
81  
82          HttpState state = new HttpState();
83  
84          // Choose the method that we will use to post data :
85          // - If at least one parameter is to be sent in the request body, then
86          //   we are doing a POST.
87          // - If user data has been specified, then we are doing a POST
88          if (theRequest.getParameterNamesPost().hasMoreElements()
89              || (theRequest.getUserData() != null))
90          {
91              this.method = new PostMethod();
92          }
93          else
94          {
95              this.method = new GetMethod();
96          }
97  
98          // Add Authentication headers, if necessary. This is the first
99          // step to allow authentication to add extra headers, HTTP parameters,
100         // etc.
101         Authentication authentication = theRequest.getAuthentication();
102 
103         if (authentication != null)
104         {
105             authentication.configure(state, this.method, theRequest, 
106                 theConfiguration);
107         }
108 
109         // Add the parameters that need to be passed as part of the URL
110         url = HttpUtil.addHttpGetParameters(theRequest, url);
111 
112         this.method.setFollowRedirects(false);
113         this.method.setPath(UrlUtil.getPath(url));
114         this.method.setQueryString(UrlUtil.getQuery(url));
115 
116         // Sets the content type
117         this.method.setRequestHeader("Content-type", 
118             theRequest.getContentType());
119 
120         // Add the other header fields
121         addHeaders(theRequest);
122 
123         // Add the POST parameters if no user data has been specified (user data
124         // overried post parameters)
125         if (theRequest.getUserData() != null)
126         {
127             addUserData(theRequest);
128         }
129         else
130         {
131             addHttpPostParameters(theRequest);
132         }
133 
134         // Add the cookies to the state
135         state.addCookies(CookieUtil.createHttpClientCookies(theRequest, 
136             url));
137 
138         // Open the connection and get the result
139         HttpClient client = new HttpClient();
140         HostConfiguration hostConfiguration = new HostConfiguration();
141         hostConfiguration.setHost(url.getHost(), url.getPort(),
142             Protocol.getProtocol(url.getProtocol()));
143         client.setState(state);
144         client.executeMethod(hostConfiguration, this.method);
145 
146         // Wrap the HttpClient method in a java.net.HttpURLConnection object
147         return new org.apache.commons.httpclient.util.HttpURLConnection(
148             this.method, url);
149     }
150     
151     /**
152      * Add the HTTP parameters that need to be passed in the request body.
153      *
154      * @param theRequest the request containing all data to pass to the server
155      *        redirector.
156      */
157     private void addHttpPostParameters(WebRequest theRequest)
158     {
159         // If no parameters, then exit
160         if (!theRequest.getParameterNamesPost().hasMoreElements())
161         {
162             return;
163         }
164 
165         Enumeration keys = theRequest.getParameterNamesPost();
166         List parameters = new ArrayList();
167         while (keys.hasMoreElements())
168         {
169             String key = (String) keys.nextElement();
170             String[] values = theRequest.getParameterValuesPost(key);
171             for (int i = 0; i < values.length; i++)
172             {
173                 parameters.add(new NameValuePair(key, values[i]));
174             }
175         }
176         ((PostMethod) this.method).setRequestBody(
177             (NameValuePair[]) parameters.toArray(
178                 new NameValuePair[parameters.size()]));
179     }
180 
181     /**
182      * Add the Headers to the request.
183      *
184      * @param theRequest the request containing all data to pass to the server
185      *        redirector.
186      */
187     private void addHeaders(WebRequest theRequest)
188     {
189         Enumeration keys = theRequest.getHeaderNames();
190 
191         while (keys.hasMoreElements())
192         {
193             String key = (String) keys.nextElement();
194             String[] values = theRequest.getHeaderValues(key);
195 
196             StringBuffer fullHeaderValue = new StringBuffer(values[0]);
197 
198             for (int i = 1; i < values.length; i++)
199             {
200                 fullHeaderValue.append("," + values[i]);
201             }
202 
203             this.method.addRequestHeader(key, fullHeaderValue.toString());
204         }
205     }
206 
207     /**
208      * Add user data in the request body.
209      *
210      * @param theRequest the request containing all data to pass to the server
211      *        redirector.
212      * @exception IOException if we fail to read the user data
213      */
214     private void addUserData(WebRequest theRequest) throws IOException
215     {
216         // If no user data, then exit
217         if (theRequest.getUserData() == null)
218         {
219             return;
220         }
221 
222         ((PostMethod) this.method).setRequestBody(theRequest.getUserData());
223     }
224 }