001: /*
002: * ========================================================================
003: *
004: * Copyright 2001-2004 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.internal.client.connector.http;
021:
022: import java.io.IOException;
023:
024: import java.net.HttpURLConnection;
025: import java.net.URL;
026:
027: import java.util.ArrayList;
028: import java.util.Enumeration;
029: import java.util.List;
030:
031: import org.apache.cactus.WebRequest;
032: import org.apache.cactus.client.authentication.Authentication;
033: import org.apache.cactus.internal.configuration.Configuration;
034: import org.apache.cactus.internal.util.CookieUtil;
035: import org.apache.cactus.internal.util.UrlUtil;
036: import org.apache.commons.httpclient.HostConfiguration;
037: import org.apache.commons.httpclient.HttpClient;
038: import org.apache.commons.httpclient.HttpState;
039: import org.apache.commons.httpclient.HttpMethod;
040: import org.apache.commons.httpclient.NameValuePair;
041: import org.apache.commons.httpclient.methods.GetMethod;
042: import org.apache.commons.httpclient.methods.PostMethod;
043: import org.apache.commons.httpclient.protocol.Protocol;
044:
045: /**
046: * Implementation of <code>ConnectionHelper</code> using Jakarta Commons
047: * HttpClient.
048: *
049: * @version $Id: HttpClientConnectionHelper.java 238991 2004-05-22 11:34:50Z vmassol $
050: */
051: public class HttpClientConnectionHelper implements ConnectionHelper {
052: /**
053: * The <code>HttpMethod</code> used to connect to the HTTP server. It is
054: * either a <code>GetMethod</code> or a <code>PostMethod</code>.
055: */
056: private HttpMethod method;
057:
058: /**
059: * The URL that will be used for the HTTP connection.
060: */
061: private String url;
062:
063: /**
064: * @param theURL the URL that will be used for the HTTP connection.
065: */
066: public HttpClientConnectionHelper(String theURL) {
067: this .url = theURL;
068: }
069:
070: /**
071: * @see ConnectionHelper#connect(WebRequest, Configuration)
072: */
073: public HttpURLConnection connect(WebRequest theRequest,
074: Configuration theConfiguration) throws Throwable {
075: URL url = new URL(this .url);
076:
077: HttpState state = new HttpState();
078:
079: // Choose the method that we will use to post data :
080: // - If at least one parameter is to be sent in the request body, then
081: // we are doing a POST.
082: // - If user data has been specified, then we are doing a POST
083: if (theRequest.getParameterNamesPost().hasMoreElements()
084: || (theRequest.getUserData() != null)) {
085: this .method = new PostMethod();
086: } else {
087: this .method = new GetMethod();
088: }
089:
090: // Add Authentication headers, if necessary. This is the first
091: // step to allow authentication to add extra headers, HTTP parameters,
092: // etc.
093: Authentication authentication = theRequest.getAuthentication();
094:
095: if (authentication != null) {
096: authentication.configure(state, this .method, theRequest,
097: theConfiguration);
098: }
099:
100: // Add the parameters that need to be passed as part of the URL
101: url = HttpUtil.addHttpGetParameters(theRequest, url);
102:
103: this .method.setFollowRedirects(false);
104: this .method.setPath(UrlUtil.getPath(url));
105: this .method.setQueryString(UrlUtil.getQuery(url));
106:
107: // Sets the content type
108: this .method.setRequestHeader("Content-type", theRequest
109: .getContentType());
110:
111: // Add the other header fields
112: addHeaders(theRequest);
113:
114: // Add the POST parameters if no user data has been specified (user data
115: // overried post parameters)
116: if (theRequest.getUserData() != null) {
117: addUserData(theRequest);
118: } else {
119: addHttpPostParameters(theRequest);
120: }
121:
122: // Add the cookies to the state
123: state.addCookies(CookieUtil.createHttpClientCookies(theRequest,
124: url));
125:
126: // Open the connection and get the result
127: HttpClient client = new HttpClient();
128: HostConfiguration hostConfiguration = new HostConfiguration();
129: hostConfiguration.setHost(url.getHost(), url.getPort(),
130: Protocol.getProtocol(url.getProtocol()));
131: client.setState(state);
132: client.executeMethod(hostConfiguration, this .method);
133:
134: // Wrap the HttpClient method in a java.net.HttpURLConnection object
135: return new org.apache.commons.httpclient.util.HttpURLConnection(
136: this .method, url);
137: }
138:
139: /**
140: * Add the HTTP parameters that need to be passed in the request body.
141: *
142: * @param theRequest the request containing all data to pass to the server
143: * redirector.
144: */
145: private void addHttpPostParameters(WebRequest theRequest) {
146: // If no parameters, then exit
147: if (!theRequest.getParameterNamesPost().hasMoreElements()) {
148: return;
149: }
150:
151: Enumeration keys = theRequest.getParameterNamesPost();
152: List parameters = new ArrayList();
153: while (keys.hasMoreElements()) {
154: String key = (String) keys.nextElement();
155: String[] values = theRequest.getParameterValuesPost(key);
156: for (int i = 0; i < values.length; i++) {
157: parameters.add(new NameValuePair(key, values[i]));
158: }
159: }
160: ((PostMethod) this .method)
161: .setRequestBody((NameValuePair[]) parameters
162: .toArray(new NameValuePair[parameters.size()]));
163: }
164:
165: /**
166: * Add the Headers to the request.
167: *
168: * @param theRequest the request containing all data to pass to the server
169: * redirector.
170: */
171: private void addHeaders(WebRequest theRequest) {
172: Enumeration keys = theRequest.getHeaderNames();
173:
174: while (keys.hasMoreElements()) {
175: String key = (String) keys.nextElement();
176: String[] values = theRequest.getHeaderValues(key);
177:
178: StringBuffer fullHeaderValue = new StringBuffer(values[0]);
179:
180: for (int i = 1; i < values.length; i++) {
181: fullHeaderValue.append("," + values[i]);
182: }
183:
184: this .method.addRequestHeader(key, fullHeaderValue
185: .toString());
186: }
187: }
188:
189: /**
190: * Add user data in the request body.
191: *
192: * @param theRequest the request containing all data to pass to the server
193: * redirector.
194: * @exception IOException if we fail to read the user data
195: */
196: private void addUserData(WebRequest theRequest) throws IOException {
197: // If no user data, then exit
198: if (theRequest.getUserData() == null) {
199: return;
200: }
201:
202: ((PostMethod) this.method).setRequestBody(theRequest
203: .getUserData());
204: }
205: }
|