package com.metlife.ibpp.net.http; /** * HttpSocketCall.java * * Call a web service using a TCP/IP socket. * * Calls vary depending on the use of non-secure/HTTP * or secure/HTTPS connections. * * SOAP calls provide an action that is written to the * header. The SOAP envelope should be pre-formed in * the request body. * * Provide the returned XML/string to the caller. * * @author Mike Pastor Summer 2004 */ import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Enumeration; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.PrintWriter; import java.net.ConnectException; import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; public class HttpSocketCall { public static final String HTTP_VERSION = "1.0"; public static final String HTTP_POST = "POST "; public static final String HEADER_HOST = "Host: "; public static final String HEADER_CONTENT_TYPE = "Content-Type: "; public static final String HEADER_CONTENT_LENGTH = "Content-Length: "; public static final String SOAP_ACTION = "SOAPAction: "; public static final String PRAGMA = "Pragma: "; public static final String COOKIE = "Cookie: "; public static final String COOKIE_VERSION = "$Version=\"1\";"; //public static final int DEFAULT_TIMEOUT_IO = 0; //public static final int DEFAULT_TIMEOUT_CONNECTION = 0; //public static final int MILLISEC_PER_SEC = 1000; public static final int HTTP_DEFAULT_PORT = 80; public static final int HTTPS_DEFAULT_PORT = 443; public static final int BUFF_SIZE = 100; //public static final String CONTENT_TYPE_FORM_URL_ENCODED = //"application/x-www-form-urlencoded"; public static final String CONTENT_TYPE_XML = "text/xml"; private String contentType = null; private String requestUrl = null; private String requestBody = null; private String soapAction = null; private Hashtable cookies = new Hashtable(); private Hashtable parameters = new Hashtable(); private Hashtable requestProperties = new Hashtable(); private boolean cache = false; // Constructors // public HttpSocketCall() { super(); } public HttpSocketCall( String contentType, String requestUrl, String requestBody, String soapAction) { super(); this.contentType = contentType; this.requestUrl = requestUrl; this.requestBody = requestBody; this.soapAction = soapAction; } // Set the request XML // public void setRequestBody(String requestBody) { this.requestBody = requestBody; } // Set the SOAP action that will be written // to the header. // public void setSoapAction(String soapActionStr) { this.soapAction = soapActionStr; } public void setUseCache(boolean cache) { this.cache = cache; } public void setContentType(String contentType) { this.contentType = contentType; } public void setServiceUrl(String requestURL) { this.requestUrl = requestURL; } public String getServiceUrl() { return this.requestUrl; } // A variety of overloaded sendRequest() methods // public String sendRequest(int socketTimeOut, int threadTimeOut) throws IOException, Exception { checkState(); return sendRequestWithTimeout(socketTimeOut, threadTimeOut); } public String sendRequest() throws IOException, Exception { checkState(); return sendRequestWithTimeout(10, 20); // default timeouts } public String sendRequest( String contentType, String requestUrl, String requestBody, String soapAction) throws Exception { this.contentType = contentType; this.requestUrl = requestUrl; this.requestBody = requestBody; this.soapAction = soapAction; checkState(); return sendRequest(); } public String sendRequestWithTimeout(int socketTimeout, int threadTimeout) throws IOException, Exception { URL url = new URL(requestUrl); return processRequest( getTcpSocket(url, socketTimeout, threadTimeout), url); } public String sendSSLRequestWithTimeout( int socketTimeout, int threadTimeout) throws IOException, Exception { // This call will setup the security provider // and the secure socket factory in the JVM. // SSLSetup.setURLConnection(); URL url = new URL(this.getServiceUrl()); return processRequest( getSSLTcpSocket(url, socketTimeout, threadTimeout), url); } public String sendSSLRequestWithTimeoutDebug( int socketTimeout, int threadTimeout) throws IOException, Exception { // Add the magic debug words to the JVM! // The JVM can also be called with // -Djavax.net.debug=true // for even more debug data. mlp // SSLSetup.setDebug(); SSLSetup.setURLConnection(); URL url = new URL(this.getServiceUrl()); return processRequest( getSSLTcpSocket(url, socketTimeout, threadTimeout), url); } // Get the TCP/IP socket // protected Socket getTcpSocket( URL url, int socketTimeOut, int threadTimeOut) throws ConnectException, IOException, UnknownHostException { int port = url.getPort(); if (port < 0) port = HTTP_DEFAULT_PORT; SocketFactory socketFactory = SocketFactory.getInstance(); return socketFactory.newSocket( url.getHost(), port, socketTimeOut * 1000, threadTimeOut * 1000, false); } public final Socket getSSLTcpSocket( URL url, int socketTimeOut, int threadTimeOut) throws ConnectException, IOException, UnknownHostException { int port = url.getPort(); if (port < 0) port = HTTPS_DEFAULT_PORT; return SocketFactory.getInstance().newSocket( url.getHost(), port, socketTimeOut * 1000, threadTimeOut * 1000, true); } // Check some basic setup parameters // private void checkState() throws IllegalArgumentException { if ((this.requestBody == null || this.requestBody.trim().equals("")) || (this.requestUrl == null || this.requestUrl.trim().equals("")) || (this.contentType == null || this.contentType.trim().equals(""))) { throw new IllegalArgumentException(); } } // Call the web service // protected String processRequest(Socket socket, URL url) throws IOException, ConnectException, Exception { System.out.println( "*** MLP: HttpSocketCall processRequest() for URL: " + requestUrl); PrintWriter socketWriter = null; BufferedReader bufferedreader = null; socketWriter = new PrintWriter(socket.getOutputStream()); bufferedreader = new BufferedReader(new InputStreamReader(socket.getInputStream())); socketWriter.print( HTTP_POST + url.getFile() + " HTTP/" + HTTP_VERSION + "\r\n"); writeRequestProperties(socketWriter); socketWriter.print( HEADER_HOST + url.getHost() + ':' + url.getPort() + "\r\n"); socketWriter.print(HEADER_CONTENT_TYPE + contentType + "\r\n"); socketWriter.print( HEADER_CONTENT_LENGTH + requestBody.length() + "\r\n"); socketWriter.print(PRAGMA + (cache ? "cache" : "no-cache") + "\r\n"); writeCookies(socketWriter); if (soapAction != null) socketWriter.print(SOAP_ACTION + soapAction + "\r\n"); socketWriter.print("\r\n"); socketWriter.print(requestBody); socketWriter.print("\r\n\r\n"); socketWriter.flush(); boolean flag = false; Object obj = null; StringBuffer stringbuffer = new StringBuffer(); System.out.println( "*** MLP: HttpSocketCall sent request: " + requestBody); try { StringTokenizer stringtokenizer = new StringTokenizer(bufferedreader.readLine()); stringtokenizer.nextToken(); int l = Integer.parseInt(stringtokenizer.nextToken()); while (stringtokenizer.hasMoreTokens()) { stringbuffer.append(stringtokenizer.nextToken()); if (stringtokenizer.hasMoreTokens()) stringbuffer.append(" "); } if (!stringbuffer.toString().equalsIgnoreCase("ok") && !stringbuffer.toString().equalsIgnoreCase("Accepted")) { System.out.println( "*** MLP: RESPONSE ERROR: " + stringbuffer.toString()); //return stringbuffer.toString(); throw new ConnectException( "HttpSocketCall.processRequest(): Received bad (not 'ok' or 'Accepted') response: " + stringbuffer.toString()); } } catch (InterruptedIOException e) { throw new ConnectException( "HttpSocketCall.processRequest() Interrupted Exception:" + e.getMessage()); } catch (IOException e) { throw new IOException( "HttpSocketCall.processRequest() IO Exception:" + e.getMessage()); } catch (Exception e) { //e.printStackTrace(); //if((exception instanceof ConnectException) || (exception instanceof IOException) || (exception instanceof UnknownHostException)) // throw exception; //else throw new Exception( "HttpSocketCall.processRequest() EXCEPTION: " + e.getMessage()); } System.out.println( "*** MLP: Got Good (ok or accepted) Response..." + stringbuffer.toString()); // Read the response header lines // try { for (String httpHeader = null; (httpHeader = bufferedreader.readLine()) != null; ) { if (httpHeader.length() == 0) break; int k1 = httpHeader.indexOf(58); String name = httpHeader.substring(0, k1); String value = httpHeader.substring(k1 + 1).trim(); int i1; String s4; if (name.equalsIgnoreCase("Content-Length")) i1 = Integer.parseInt(value); else if (name.equalsIgnoreCase("Content-Type")) s4 = value; else if (name.equalsIgnoreCase("set-cookie")) { int equal = value.indexOf("="); if (equal > 0) { String realName = value.substring(0, equal); processCookie(realName, value.substring(equal + 1)); } //hashtable.put(name, value); } } } catch (Exception exception1) { //if((exception1 instanceof ConnectException) || (exception1 instanceof IOException) || (exception1 instanceof UnknownHostException)) // throw exception1; //else throw new IllegalArgumentException( "error reading HTTP headers: " + exception1.getMessage()); } // Read the response body // StringBuffer responseBody = new StringBuffer(BUFF_SIZE); char chunk[] = new char[BUFF_SIZE]; int length; while ((length = bufferedreader.read(chunk, 0, BUFF_SIZE - 1)) > 0) responseBody.append(chunk, 0, length); return responseBody.toString(); } private void processCookie( String name, String value) { // TBD - add full support for cookies including version, expires etc addCookie(name, value); } public void addCookie(String name, String value) { if ((name != null && value != null) && (name.trim().length() > 0) && (value.trim().length() > 0)) { this.cookies.put(name.trim(), value.trim()); } } public void addParameter(String name, String value) { if ((name != null && value != null) && (name.trim().length() > 0) && (value.trim().length() > 0)) { this.parameters.put(name.trim(), value.trim()); } } public void addRequestProperty(String name, String value) { if ((name != null && value != null) && (name.trim().length() > 0) && (value.trim().length() > 0)) { this.requestProperties.put(name.trim(), value.trim()); } } private void writeCookies(PrintWriter socketWriter) { if (!this.cookies.isEmpty()) { String cookieString = COOKIE_VERSION; String name = null; for (Enumeration enum = cookies.keys(); enum.hasMoreElements();) { name = (String) enum.nextElement(); cookieString = cookieString + name + "=" + cookies.get(name) + ";" + " "; } socketWriter.print(COOKIE + cookieString + "\r\n"); } } private void writeRequestProperties(PrintWriter socketWriter) { Enumeration keys = this.requestProperties.keys(); String key = null; while (keys.hasMoreElements() == true) { key = (String) keys.nextElement(); socketWriter.print( key + ": " + (String) requestProperties.get(key) + "\r\n"); } } }