1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.axis2.transport.http;
21
22
23 import org.apache.axis2.AxisFault;
24 import org.apache.axis2.Constants;
25 import org.apache.axis2.context.MessageContext;
26 import org.apache.axis2.context.OperationContext;
27 import org.apache.axis2.i18n.Messages;
28 import org.apache.axis2.transport.MessageFormatter;
29 import org.apache.axis2.wsdl.WSDLConstants;
30 import org.apache.commons.httpclient.Header;
31 import org.apache.commons.httpclient.HttpClient;
32 import org.apache.commons.httpclient.HttpMethod;
33 import org.apache.commons.httpclient.HttpMethodBase;
34 import org.apache.commons.httpclient.HttpStatus;
35 import org.apache.commons.httpclient.methods.DeleteMethod;
36 import org.apache.commons.httpclient.methods.GetMethod;
37 import org.apache.commons.httpclient.methods.PostMethod;
38 import org.apache.commons.httpclient.methods.PutMethod;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 import java.io.IOException;
43 import java.net.URL;
44
45 public class HTTPSender extends AbstractHTTPSender {
46
47 private static final Log log = LogFactory.getLog(HTTPSender.class);
48
49 public void send(MessageContext msgContext, URL url, String soapActionString)
50 throws IOException {
51
52 // execute the HtttpMethodBase - a connection manager can be given for
53 // handle multiple
54
55 String httpMethod =
56 (String) msgContext.getProperty(Constants.Configuration.HTTP_METHOD);
57
58 if ((httpMethod != null)) {
59
60 if (Constants.Configuration.HTTP_METHOD_GET.equalsIgnoreCase(httpMethod)) {
61 this.sendViaGet(msgContext, url, soapActionString);
62
63 return;
64 } else if (Constants.Configuration.HTTP_METHOD_DELETE.equalsIgnoreCase(httpMethod)) {
65 this.sendViaDelete(msgContext, url, soapActionString);
66
67 return;
68 } else if (Constants.Configuration.HTTP_METHOD_PUT.equalsIgnoreCase(httpMethod)) {
69 this.sendViaPut(msgContext, url, soapActionString);
70
71 return;
72 }
73 }
74
75 this.sendViaPost(msgContext, url, soapActionString);
76 }
77
78 /**
79 * Used to send a request via HTTP Get method
80 *
81 * @param msgContext - The MessageContext of the message
82 * @param url - The target URL
83 * @param soapActiionString - The soapAction string of the request
84 * @throws AxisFault - Thrown in case an exception occurs
85 */
86 private void sendViaGet(MessageContext msgContext, URL url, String soapActiionString)
87 throws AxisFault {
88
89 GetMethod getMethod = new GetMethod();
90 HttpClient httpClient = getHttpClient(msgContext);
91 MessageFormatter messageFormatter =
92 populateCommonProperties(msgContext, url, getMethod, httpClient, soapActiionString);
93
94 // Need to have this here because we can have soap action when using the soap response MEP
95 String soapAction =
96 messageFormatter.formatSOAPAction(msgContext, format, soapActiionString);
97
98 if (soapAction != null) {
99 getMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
100 }
101 try {
102 executeMethod(httpClient, msgContext, url, getMethod);
103 handleResponse(msgContext, getMethod);
104 } catch (IOException e) {
105 log.info("Unable to sendViaGet to url[" + url + "]", e);
106 throw AxisFault.makeFault(e);
107 } finally {
108 cleanup(msgContext, getMethod);
109 }
110 }
111
112 private void cleanup(MessageContext msgContext, HttpMethod method) {
113 if (msgContext.isPropertyTrue(HTTPConstants.AUTO_RELEASE_CONNECTION)) {
114 method.releaseConnection();
115 }
116 }
117
118 /**
119 * Used to send a request via HTTP Delete Method
120 *
121 * @param msgContext - The MessageContext of the message
122 * @param url - The target URL
123 * @param soapActiionString - The soapAction string of the request
124 * @throws AxisFault - Thrown in case an exception occurs
125 */
126 private void sendViaDelete(MessageContext msgContext, URL url, String soapActiionString)
127 throws AxisFault {
128
129 DeleteMethod deleteMethod = new DeleteMethod();
130 HttpClient httpClient = getHttpClient(msgContext);
131 populateCommonProperties(msgContext, url, deleteMethod, httpClient, soapActiionString);
132
133 try {
134 executeMethod(httpClient, msgContext, url, deleteMethod);
135 handleResponse(msgContext, deleteMethod);
136 } catch (IOException e) {
137 log.info("Unable to sendViaDelete to url[" + url + "]", e);
138 throw AxisFault.makeFault(e);
139 } finally {
140 cleanup(msgContext, deleteMethod);
141 }
142 }
143
144 /**
145 * Used to send a request via HTTP Post Method
146 *
147 * @param msgContext - The MessageContext of the message
148 * @param url - The target URL
149 * @param soapActionString - The soapAction string of the request
150 * @throws AxisFault - Thrown in case an exception occurs
151 */
152 private void sendViaPost(MessageContext msgContext, URL url,
153 String soapActionString) throws AxisFault {
154
155
156 HttpClient httpClient = getHttpClient(msgContext);
157
158 /* What's up with this, it never gets used anywhere?? --Glen
159 String charEncoding =
160 (String) msgContext.getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
161
162 if (charEncoding == null) {
163 charEncoding = MessageContext.DEFAULT_CHAR_SET_ENCODING;
164 }
165 */
166
167 PostMethod postMethod = new PostMethod();
168 MessageFormatter messageFormatter =
169 populateCommonProperties(msgContext, url, postMethod, httpClient, soapActionString);
170
171 postMethod.setRequestEntity(new AxisRequestEntity(messageFormatter,
172 msgContext, format, soapActionString,
173 chunked, isAllowedRetry));
174
175 if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
176 postMethod.setContentChunked(true);
177 }
178
179 String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
180
181 if (soapAction != null) {
182 postMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
183 }
184
185 /*
186 * main excecution takes place..
187 */
188 try {
189 executeMethod(httpClient, msgContext, url, postMethod);
190 handleResponse(msgContext, postMethod);
191 } catch (IOException e) {
192 log.info("Unable to sendViaPost to url[" + url + "]", e);
193 throw AxisFault.makeFault(e);
194 } finally {
195 cleanup(msgContext, postMethod);
196 }
197 }
198
199 /**
200 * Used to send a request via HTTP Put Method
201 *
202 * @param msgContext - The MessageContext of the message
203 * @param url - The target URL
204 * @param soapActionString - The soapAction string of the request
205 * @throws AxisFault - Thrown in case an exception occurs
206 */
207 private void sendViaPut(MessageContext msgContext, URL url,
208 String soapActionString) throws AxisFault {
209
210
211 HttpClient httpClient = getHttpClient(msgContext);
212
213 /* Same deal - this value never gets used, why is it here? --Glen
214 String charEncoding =
215 (String) msgContext.getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
216
217 if (charEncoding == null) {
218 charEncoding = MessageContext.DEFAULT_CHAR_SET_ENCODING;
219 }
220 */
221
222 PutMethod putMethod = new PutMethod();
223 MessageFormatter messageFormatter =
224 populateCommonProperties(msgContext, url, putMethod, httpClient, soapActionString);
225
226 putMethod.setRequestEntity(new AxisRequestEntity(messageFormatter,
227 msgContext, format, soapActionString,
228 chunked, isAllowedRetry));
229
230 if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
231 putMethod.setContentChunked(true);
232 }
233
234 String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
235 if (soapAction != null) {
236 putMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
237 }
238
239 /*
240 * main excecution takes place..
241 */
242 try {
243 executeMethod(httpClient, msgContext, url, putMethod);
244 handleResponse(msgContext, putMethod);
245 } catch (IOException e) {
246 log.info("Unable to sendViaPut to url[" + url + "]", e);
247 throw AxisFault.makeFault(e);
248 } finally {
249 cleanup(msgContext, putMethod);
250 }
251 }
252
253 /**
254 * Used to handle the HTTP Response
255 *
256 * @param msgContext - The MessageContext of the message
257 * @param method - The HTTP method used
258 * @throws IOException - Thrown in case an exception occurs
259 */
260 private void handleResponse(MessageContext msgContext,
261 HttpMethodBase method) throws IOException {
262
263 int statusCode = method.getStatusCode();
264 if (statusCode == HttpStatus.SC_OK) {
265 processResponse(method, msgContext);
266 } else if (statusCode == HttpStatus.SC_ACCEPTED) {
267 } else if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR ||
268 statusCode == HttpStatus.SC_BAD_REQUEST) {
269 Header contenttypeHeader =
270 method.getResponseHeader(HTTPConstants.HEADER_CONTENT_TYPE);
271 String value = null;
272 if (contenttypeHeader != null) {
273 value = contenttypeHeader.getValue();
274 }
275 OperationContext opContext = msgContext.getOperationContext();
276 if(opContext!=null){
277 MessageContext inMessageContext =
278 opContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
279 if(inMessageContext!=null){
280 inMessageContext.setProcessingFault(true);
281 }
282 }
283 if (value != null) {
284
285 processResponse(method, msgContext);
286 }
287 Object isTransportNonBlocking = msgContext.getProperty(
288 MessageContext.TRANSPORT_NON_BLOCKING);
289 if (isTransportNonBlocking != null && (Boolean)isTransportNonBlocking) {
290 throw new AxisFault(Messages.getMessage("transportError",
291 String.valueOf(statusCode),
292 method.getStatusText()));
293 }
294 } else {
295 throw new AxisFault(Messages.getMessage("transportError",
296 String.valueOf(statusCode),
297 method.getStatusText()));
298 }
299 }
300 }