blob: 74ee745a1588b468b6f4047a44beaf35a80d3449 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.transport.http;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.description.OutInAxisOperation;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.transport.MessageFormatter;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.net.URL;
public class HTTPSender extends AbstractHTTPSender {
private static final Log log = LogFactory.getLog(HTTPSender.class);
public void send(MessageContext msgContext, URL url, String soapActionString)
throws IOException {
// execute the HtttpMethodBase - a connection manager can be given for
// handle multiple
String httpMethod =
(String) msgContext.getProperty(Constants.Configuration.HTTP_METHOD);
if ((httpMethod != null)) {
if (Constants.Configuration.HTTP_METHOD_GET.equalsIgnoreCase(httpMethod)) {
this.sendViaGet(msgContext, url, soapActionString);
return;
} else if (Constants.Configuration.HTTP_METHOD_DELETE.equalsIgnoreCase(httpMethod)) {
this.sendViaDelete(msgContext, url, soapActionString);
return;
} else if (Constants.Configuration.HTTP_METHOD_PUT.equalsIgnoreCase(httpMethod)) {
this.sendViaPut(msgContext, url, soapActionString);
return;
}
}
this.sendViaPost(msgContext, url, soapActionString);
}
/**
* Used to send a request via HTTP Get method
*
* @param msgContext - The MessageContext of the message
* @param url - The target URL
* @param soapActiionString - The soapAction string of the request
* @throws AxisFault - Thrown in case an exception occurs
*/
private void sendViaGet(MessageContext msgContext, URL url, String soapActiionString)
throws AxisFault {
GetMethod getMethod = new GetMethod();
HttpClient httpClient = getHttpClient(msgContext);
MessageFormatter messageFormatter =
populateCommonProperties(msgContext, url, getMethod, httpClient, soapActiionString);
// Need to have this here because we can have soap action when using the soap response MEP
String soapAction =
messageFormatter.formatSOAPAction(msgContext, format, soapActiionString);
if (soapAction != null) {
getMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
}
try {
executeMethod(httpClient, msgContext, url, getMethod);
handleResponse(msgContext, getMethod);
} catch (IOException e) {
log.info("Unable to sendViaGet to url[" + url + "]", e);
throw AxisFault.makeFault(e);
} finally {
cleanup(msgContext, getMethod);
}
}
private void cleanup(MessageContext msgContext, HttpMethod method) {
if (msgContext.isPropertyTrue(HTTPConstants.AUTO_RELEASE_CONNECTION)) {
// Protect against synchronously waiting for a response, in which case
// this would result in trying to read a closed stream...!
if (!(msgContext.getAxisOperation() instanceof OutInAxisOperation) ||
msgContext.getOptions().isUseSeparateListener()) {
log.trace("AutoReleasing " + method);
method.releaseConnection();
}
}
}
/**
* Used to send a request via HTTP Delete Method
*
* @param msgContext - The MessageContext of the message
* @param url - The target URL
* @param soapActiionString - The soapAction string of the request
* @throws AxisFault - Thrown in case an exception occurs
*/
private void sendViaDelete(MessageContext msgContext, URL url, String soapActiionString)
throws AxisFault {
DeleteMethod deleteMethod = new DeleteMethod();
HttpClient httpClient = getHttpClient(msgContext);
populateCommonProperties(msgContext, url, deleteMethod, httpClient, soapActiionString);
try {
executeMethod(httpClient, msgContext, url, deleteMethod);
handleResponse(msgContext, deleteMethod);
} catch (IOException e) {
log.info("Unable to sendViaDelete to url[" + url + "]", e);
throw AxisFault.makeFault(e);
} finally {
cleanup(msgContext, deleteMethod);
}
}
/**
* Used to send a request via HTTP Post Method
*
* @param msgContext - The MessageContext of the message
* @param url - The target URL
* @param soapActionString - The soapAction string of the request
* @throws AxisFault - Thrown in case an exception occurs
*/
private void sendViaPost(MessageContext msgContext, URL url,
String soapActionString) throws AxisFault {
HttpClient httpClient = getHttpClient(msgContext);
/* What's up with this, it never gets used anywhere?? --Glen
String charEncoding =
(String) msgContext.getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
if (charEncoding == null) {
charEncoding = MessageContext.DEFAULT_CHAR_SET_ENCODING;
}
*/
PostMethod postMethod = new PostMethod();
if (log.isTraceEnabled()) {
log.trace(Thread.currentThread() + " PostMethod " + postMethod + " / " + httpClient);
}
MessageFormatter messageFormatter =
populateCommonProperties(msgContext, url, postMethod, httpClient, soapActionString);
postMethod.setRequestEntity(new AxisRequestEntity(messageFormatter,
msgContext, format, soapActionString,
chunked, isAllowedRetry));
if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
postMethod.setContentChunked(true);
}
String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
if (soapAction != null) {
postMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
}
/*
* main excecution takes place..
*/
try {
executeMethod(httpClient, msgContext, url, postMethod);
handleResponse(msgContext, postMethod);
} catch (IOException e) {
log.info("Unable to sendViaPost to url[" + url + "]", e);
throw AxisFault.makeFault(e);
} finally {
// If we're a dual-channel request, just auto-release the connection so it gets
// cleaned up and avoids starvation problems.
// TODO: Confirm this is OK with WS-RM, fix if not!
if (msgContext.getOptions().isUseSeparateListener())
msgContext.setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION, true);
cleanup(msgContext, postMethod);
}
}
/**
* Used to send a request via HTTP Put Method
*
* @param msgContext - The MessageContext of the message
* @param url - The target URL
* @param soapActionString - The soapAction string of the request
* @throws AxisFault - Thrown in case an exception occurs
*/
private void sendViaPut(MessageContext msgContext, URL url,
String soapActionString) throws AxisFault {
HttpClient httpClient = getHttpClient(msgContext);
/* Same deal - this value never gets used, why is it here? --Glen
String charEncoding =
(String) msgContext.getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
if (charEncoding == null) {
charEncoding = MessageContext.DEFAULT_CHAR_SET_ENCODING;
}
*/
PutMethod putMethod = new PutMethod();
MessageFormatter messageFormatter =
populateCommonProperties(msgContext, url, putMethod, httpClient, soapActionString);
putMethod.setRequestEntity(new AxisRequestEntity(messageFormatter,
msgContext, format, soapActionString,
chunked, isAllowedRetry));
if (!httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_10) && chunked) {
putMethod.setContentChunked(true);
}
String soapAction = messageFormatter.formatSOAPAction(msgContext, format, soapActionString);
if (soapAction != null) {
putMethod.setRequestHeader(HTTPConstants.HEADER_SOAP_ACTION, soapAction);
}
/*
* main excecution takes place..
*/
try {
executeMethod(httpClient, msgContext, url, putMethod);
handleResponse(msgContext, putMethod);
} catch (IOException e) {
log.info("Unable to sendViaPut to url[" + url + "]", e);
throw AxisFault.makeFault(e);
} finally {
cleanup(msgContext, putMethod);
}
}
/**
* Used to handle the HTTP Response
*
* @param msgContext - The MessageContext of the message
* @param method - The HTTP method used
* @throws IOException - Thrown in case an exception occurs
*/
private void handleResponse(MessageContext msgContext,
HttpMethodBase method) throws IOException {
int statusCode = method.getStatusCode();
log.trace("Handling response - " + statusCode);
if (statusCode == HttpStatus.SC_OK) {
processResponse(method, msgContext);
} else if (statusCode == HttpStatus.SC_ACCEPTED) {
} else if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR ||
statusCode == HttpStatus.SC_BAD_REQUEST) {
Header contenttypeHeader =
method.getResponseHeader(HTTPConstants.HEADER_CONTENT_TYPE);
String value = null;
if (contenttypeHeader != null) {
value = contenttypeHeader.getValue();
}
OperationContext opContext = msgContext.getOperationContext();
if(opContext!=null){
MessageContext inMessageContext =
opContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
if(inMessageContext!=null){
inMessageContext.setProcessingFault(true);
}
}
if (value != null) {
processResponse(method, msgContext);
}
Object isTransportNonBlocking = msgContext.getProperty(
MessageContext.TRANSPORT_NON_BLOCKING);
if (isTransportNonBlocking != null && (Boolean)isTransportNonBlocking) {
throw new AxisFault(Messages.getMessage("transportError",
String.valueOf(statusCode),
method.getStatusText()));
}
} else {
throw new AxisFault(Messages.getMessage("transportError",
String.valueOf(statusCode),
method.getStatusText()));
}
}
}