/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.apache.axis.transport.http; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.soap.MimeHeader; import javax.xml.soap.MimeHeaders; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.encoding.Base64; import org.apache.axis.handlers.BasicHandler; import org.openflexo.logging.FlexoLogger; /** * @author gunsnroz@hotmail.com */ public class HTTPUrlConnectionSender extends BasicHandler { private static final Logger logger = FlexoLogger.getLogger(HTTPUrlConnectionSender.class.getPackage().getName()); @Override public void invoke(MessageContext context) throws AxisFault { try { if (logger.isLoggable(Level.FINE)) { logger.fine("URLConnection sender invoked for " + context.getStrProp(MessageContext.TRANS_URL)); } URL targetURL = new URL(context.getStrProp(MessageContext.TRANS_URL)); HttpURLConnection connection = createHttpConnection(context, targetURL); prepareContext(context); send(context, connection); receive(context, connection); } catch (IOException e) { if (logger.isLoggable(Level.FINE)) { logger.fine("Message context is:"); Iterator<?> i = context.getAllPropertyNames(); while (i.hasNext()) { Object prop = i.next(); logger.fine(prop + "=" + context.getProperty(prop.toString())); } } throw AxisFault.makeFault(e); } catch (SOAPException e) { throw AxisFault.makeFault(e); } } private HttpURLConnection createHttpConnection(MessageContext context, URL targetURL) throws IOException { HttpURLConnection connection = (HttpURLConnection) targetURL.openConnection(); connection.setAllowUserInteraction(true); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("POST"); String contentType = context.getRequestMessage().getContentType(context.getSOAPConstants()); connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, contentType); return connection; } private void prepareContext(MessageContext context) throws SOAPException { SOAPMessage message = context.getRequestMessage(); // SOAPAction if (message.saveRequired()) { message.saveChanges(); } String soapAction = context.useSOAPAction() ? context.getSOAPActionURI() : ""; message.getMimeHeaders().setHeader("SOAPAction", "\"" + soapAction + "\""); // USERID, PASSWORD String username = context.getUsername(); String password = context.getPassword(); if (username != null) { if (logger.isLoggable(Level.FINE)) { logger.fine("Setting credentials for username " + username); } String credentials = username + ":" + password; credentials = Base64.encode(credentials.getBytes()); message.getMimeHeaders().setHeader(HTTPConstants.HEADER_AUTHORIZATION, "Basic " + credentials); } } private void send(MessageContext context, HttpURLConnection connection) throws IOException, SOAPException { writeMimeHeaders(context, connection); if (logger.isLoggable(Level.FINE)) { logger.fine("About to connect to: '" + connection.getURL() + "'."); } OutputStream os = connection.getOutputStream(); context.getRequestMessage().writeTo(os); os.flush(); os.close(); } private void writeMimeHeaders(MessageContext context, HttpURLConnection connection) throws IOException { SOAPMessage reqMessage = context.getRequestMessage(); MimeHeader header = null; for (Iterator it = reqMessage.getMimeHeaders().getAllHeaders(); it.hasNext();) { header = (MimeHeader) it.next(); connection.setRequestProperty(header.getName(), header.getValue()); } // don't forget the cookies if (context.getMaintainSession()) { String cookie = context.getStrProp(HTTPConstants.HEADER_COOKIE); String cookie2 = context.getStrProp(HTTPConstants.HEADER_COOKIE2); if (cookie != null) { connection.setRequestProperty(HTTPConstants.HEADER_COOKIE, cookie); } // GPO: not sure about cookie2 here under if (cookie2 != null) { connection.setRequestProperty(HTTPConstants.HEADER_COOKIE2, cookie2); } } } private void receive(MessageContext context, HttpURLConnection connection) throws IOException { connection.connect(); boolean isSuccess = checkResponseStatusCode(context, connection); MimeHeaders headers = getMimeHeaders(connection); InputStream is = null; if (isSuccess) { is = connection.getInputStream(); } else { is = connection.getErrorStream(); } Message message = new Message(is, false, headers); message.setMessageType(Message.RESPONSE); context.setResponseMessage(message); // is.close(); // DO NOT close input stream } private boolean checkResponseStatusCode(MessageContext context, HttpURLConnection connection) throws IOException { boolean isSuccess = true; int statusCode = connection.getResponseCode(); String statusMessage = connection.getResponseMessage(); if (statusCode > 199 && statusCode < 300) { // SOAP return OK. so fall through context.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, Integer.valueOf(statusCode)); context.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, statusMessage); } else { if (statusCode >= 500) { // SOAP Fault should be in here - so fall through isSuccess = false; } else if (statusCode > 299 && statusCode < 400) { throw new AxisFault("redirect (" + statusCode + "): " + statusMessage + " Location: " + connection.getHeaderField("Location")); } else if (statusCode == 401) { throw new AxisFault("request requires HTTP authentication: " + statusMessage); } else if (statusCode == 404) { throw new AxisFault("HTTP Status-Code 404 : NOT Found " + statusMessage); } else if (statusCode == 407) { throw new AxisFault("HTTP Status-Code 407 : Authentication required " + statusMessage); } else { throw new AxisFault("HTTP Status-Code " + "(" + statusCode + ")" + statusMessage); } } return isSuccess; } private MimeHeaders getMimeHeaders(HttpURLConnection connection) { MimeHeaders headers = new MimeHeaders(); int i = 1; String name = null; String value = null; while ((name = connection.getHeaderField(i)) != null) { value = connection.getHeaderField(i); headers.addHeader(name, value); i++; } return headers; } }