|
From: <cy...@us...> - 2003-06-12 02:37:25
|
Update of /cvsroot/ebxmlms/ebxmlms/src/hk/hku/cecid/phoenix/message/transport
In directory sc8-pr-cvs1:/tmp/cvs-serv13359
Added Files:
Http.java
Log Message:
First commit of Http.java.
- It does the same thing as HttpServlet.java (but HttpServlet is actually
not a servlet any more, so rename).
- It does not call JAXM SOAPConnection.call() as it cannot handle the
case when the HTTP response code is 200 with no content.
--- NEW FILE: Http.java ---
/*
* Copyright(c) 2002 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the Academic Free License Version 1.0
*
* Academic Free License
* Version 1.0
*
* This Academic Free License applies to any software and associated
* documentation (the "Software") whose owner (the "Licensor") has placed the
* statement "Licensed under the Academic Free License Version 1.0" immediately
* after the copyright notice that applies to the Software.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of the Software (1) to use, copy, modify, merge, publish, perform,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, and (2) under patent
* claims owned or controlled by the Licensor that are embodied in the Software
* as furnished by the Licensor, to make, use, sell and offer for sale the
* Software and derivative works thereof, subject to the following conditions:
*
* - Redistributions of the Software in source code form must retain all
* copyright notices in the Software as furnished by the Licensor, this list
* of conditions, and the following disclaimers.
* - Redistributions of the Software in executable form must reproduce all
* copyright notices in the Software as furnished by the Licensor, this list
* of conditions, and the following disclaimers in the documentation and/or
* other materials provided with the distribution.
* - Neither the names of Licensor, nor the names of any contributors to the
* Software, nor any of their trademarks or service marks, may be used to
* endorse or promote products derived from this Software without express
* prior written permission of the Licensor.
*
* DISCLAIMERS: LICENSOR WARRANTS THAT THE COPYRIGHT IN AND TO THE SOFTWARE IS
* OWNED BY THE LICENSOR OR THAT THE SOFTWARE IS DISTRIBUTED BY LICENSOR UNDER
* A VALID CURRENT LICENSE. EXCEPT AS EXPRESSLY STATED IN THE IMMEDIATELY
* PRECEDING SENTENCE, THE SOFTWARE IS PROVIDED BY THE LICENSOR, CONTRIBUTORS
* AND COPYRIGHT OWNERS "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* LICENSOR, CONTRIBUTORS OR COPYRIGHT OWNERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE.
*
* This license is Copyright (C) 2002 Lawrence E. Rosen. All rights reserved.
* Permission is hereby granted to copy and distribute this license without
* modification. This license may not be modified without the express written
* permission of its copyright owner.
*/
/* =====
*
* $Header: /cvsroot/ebxmlms/ebxmlms/src/hk/hku/cecid/phoenix/message/transport/Http.java,v 1.1 2003/06/12 02:37:22 cyng Exp $
*
* Code authored by:
*
* cyng [2003-06-09]
*
* Code reviewed by:
*
* username [YYYY-MM-DD]
*
* Remarks:
*
* =====
*/
package hk.hku.cecid.phoenix.message.transport;
import hk.hku.cecid.phoenix.common.util.Property;
import hk.hku.cecid.phoenix.message.handler.Constants;
import hk.hku.cecid.phoenix.message.handler.ErrorMessages;
import hk.hku.cecid.phoenix.message.handler.InitializationException;
import hk.hku.cecid.phoenix.message.handler.Utility;
import hk.hku.cecid.phoenix.message.packaging.EbxmlMessage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.Provider;
import java.security.Security;
import java.util.Iterator;
// import java.util.Map;
// import java.util.Map.Entry;
import java.util.StringTokenizer;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import org.apache.log4j.Logger;
/**
* Transport layer to send and receive <code>SOAPMessage</code> via HTTP
* synchronously.
*
* @author cyng
* @version $Revision: 1.1 $
*/
public final class Http {
private static final String HTTP_METHOD = "POST";
private static final String AUTHORIZATION = "Authorization";
private static final String PROTOCOL_HANDLER_PKGS =
"java.protocol.handler.pkgs";
private static final String SSL_WWW_PROTOCOL =
"com.sun.net.ssl.internal.www.protocol";
private static String SSL_SSL_PROVIDER =
"com.sun.net.ssl.internal.ssl.Provider";
static Logger logger = Logger.getLogger(Http.class);
private static String encoding =
Constants.DEFAULT_CONTENT_TRANSFER_ENCODING;
public static void configure(Property prop) throws InitializationException {
String s = prop.get(Constants.PROPERTY_CONTENT_TRANSFER_ENCODING);
if (s != null && !s.equals("")) {
encoding = s;
}
}
/**
* Send an <code>EbxmlMessage</code> synchronously to the given URL and
* block the thread until a response is received.
*
* @param message <code>EbxmlMessage</code> to be sent.
* @param toUrl Destination URL for the message to be sent to.
*
* @return the <code>SOAPMessage</code> which is the response of the
* message that was sent.
* @throws TransportException
*/
public static SOAPMessage send(EbxmlMessage message, String toUrl)
throws TransportException {
logger.debug("=> Http.send");
logger.info("Sending message to " + toUrl);
/*
boolean hasAttachments = message.getPayloadContainers().hasNext();
try {
// set content-transfer-encoding
if (hasAttachments) {
Utility.addContentTransferEncoding(message,
Constants.DEFAULT_CONTENT_TRANSFER_ENCODING, encoding);
message.saveChanges();
}
}
catch (SOAPException e) {
logger.error(ErrorMessages.getMessage(
ErrorMessages.ERR_SOAP_CANNOT_SAVE_OBJECT, e));
throw new TransportException(ErrorMessages.getMessage(
ErrorMessages.ERR_SOAP_CANNOT_SAVE_OBJECT));
}
catch (Exception e) {
String err = ErrorMessages.getMessage(
ErrorMessages.ERR_HERMES_UNKNOWN_ERROR, e);
logger.error(err);
throw new TransportException(err);
}
// modify content type to a single line
String type = message.getMimeHeaders().getHeader
(Constants.CONTENT_TYPE)[0];
int index = type.indexOf("\n");
if (index != -1) {
type = type.substring(0, index).trim() + " " +
type.substring(index+1, type.length()).trim();
}
index = type.indexOf("\r");
if (index != -1) {
type = type.substring(0, index).trim() + " " +
type.substring(index+1, type.length()).trim();
}
if (type.toLowerCase().indexOf(Constants.CHARACTER_SET) == -1) {
type += "; " + Constants.CHARACTER_SET + "=\"" +
Constants.CHARACTER_ENCODING + "\"";
}
if (type.toLowerCase().indexOf(Constants.MULTIPART_RELATED) != -1
&& type.toLowerCase().indexOf(Constants.START) == -1) {
type += "; " + Constants.START + "=\"<" +
EbxmlMessage.SOAP_PART_CONTENT_ID + ">\"";
}
message.getMimeHeaders().setHeader(Constants.CONTENT_TYPE, type);
*/
SOAPMessage responseMessage = null;
try {
URL url = new URL(toUrl);
if (url.getProtocol().equalsIgnoreCase
(Constants.TRANSPORT_TYPE_HTTPS)) {
String pkgs = System.getProperty(PROTOCOL_HANDLER_PKGS);
if (pkgs == null || pkgs.indexOf(SSL_WWW_PROTOCOL) < 0 ) {
pkgs = (pkgs == null ? SSL_WWW_PROTOCOL :
SSL_WWW_PROTOCOL + "|" + pkgs);
System.setProperty(PROTOCOL_HANDLER_PKGS, pkgs);
Security.addProvider((Provider) Class.forName
(SSL_SSL_PROVIDER).newInstance());
}
}
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.setRequestMethod(HTTP_METHOD);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
HttpURLConnection.setFollowRedirects(true);
boolean hasAuthorization = false;
// Map headers = message.getMimeHeaders();
MimeHeaders headers = message.getSOAPMessage().getMimeHeaders();
for (Iterator i=headers.getAllHeaders() ; i.hasNext() ; ) {
MimeHeader header = (MimeHeader) i.next();
String[] values = headers.getHeader(header.getName());
String value = header.getValue();
if (values.length > 1) {
for (int j=1 ; j<values.length ; j++) {
value += "," + values[j];
}
}
/*
Map.Entry entry = (Map.Entry) i.next();
connection.setRequestProperty((String) entry.getKey(),
(String) entry.getValue());
*/
connection.setRequestProperty(header.getName(), value);
hasAuthorization = header.getName().equals(AUTHORIZATION);
}
if (!hasAuthorization) {
throw new Error("HTTP Authorization not yet implemented!");
}
OutputStream os = connection.getOutputStream();
message.writeTo(os);
os.flush();
os.close();
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
headers = new MimeHeaders();
String key = connection.getHeaderFieldKey(1);
String value = connection.getHeaderFieldKey(1);
for (int i=2 ; key != null ; i++) {
StringTokenizer values = new StringTokenizer(value, ",");
while (values.hasMoreTokens()) {
headers.addHeader(key, values.nextToken().trim());
}
key = connection.getHeaderFieldKey(i);
value = connection.getHeaderFieldKey(i);
}
InputStream is = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[65536];
for (int c=is.read(buffer) ; c != -1 ; c=is.read(buffer)) {
baos.write(buffer, 0, c);
}
byte[] bytes = baos.toByteArray();
baos = null;
is.close();
int contentLength = connection.getContentLength();
if (contentLength != -1 && contentLength != bytes.length) {
String err = ErrorMessages.getMessage(ErrorMessages.
ERR_HERMES_HTTP_POST_FAILED, Constants.CONTENT_LENGTH +
" = " + contentLength + " but only " + bytes.length +
" bytes are successfully read from response stream");
logger.error(err);
throw new TransportException(err);
}
if (bytes.length > 0) {
responseMessage = MessageFactory.newInstance().
createMessage(headers, new ByteArrayInputStream(bytes));
}
}
else if ((responseCode/100) != (HttpURLConnection.HTTP_OK/100)) {
String err = ErrorMessages.getMessage(ErrorMessages.
ERR_HERMES_HTTP_POST_FAILED, "Bad response: code = " +
responseCode + " and message = " + connection.
getResponseMessage());
logger.error(err);
throw new TransportException(err);
}
connection.disconnect();
}
catch (TransportException e) {
throw e;
}
catch (Exception e) {
String err =
((e instanceof SOAPException || e instanceof IOException) ?
ErrorMessages.getMessage
(ErrorMessages.ERR_SOAP_CANNOT_SEND_MESSAGE, e) :
ErrorMessages.getMessage
(ErrorMessages.ERR_HERMES_UNKNOWN_ERROR, e));
logger.error(err);
throw new TransportException(err);
}
/*
try {
// unset content-transfer-encoding
if (hasAttachments) {
Utility.removeContentTransferEncoding(message);
message.saveChanges();
}
}
catch (SOAPException e) {
logger.error(ErrorMessages.getMessage(
ErrorMessages.ERR_SOAP_CANNOT_SAVE_OBJECT, e));
throw new TransportException(ErrorMessages.getMessage(
ErrorMessages.ERR_SOAP_CANNOT_SAVE_OBJECT));
}
catch (Exception e) {
String err = ErrorMessages.getMessage(
ErrorMessages.ERR_HERMES_UNKNOWN_ERROR, e);
logger.error(err);
throw new TransportException(err);
}
*/
logger.debug("<= Http.send");
return responseMessage;
}
}
|