org/objectweb/proactive/core/ssh/httpssh/HttpSshUrlConnection.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.core.ssh.httpssh;
00032 
00033 import java.io.IOException;
00034 import java.io.InputStream;
00035 import java.io.OutputStream;
00036 import java.net.HttpURLConnection;
00037 import java.net.InetSocketAddress;
00038 import java.net.ProtocolException;
00039 import java.net.Socket;
00040 import java.util.ArrayList;
00041 import java.util.Hashtable;
00042 import java.util.List;
00043 import java.util.Map;
00044 
00045 import org.apache.log4j.Logger;
00046 import org.objectweb.proactive.core.ssh.SshParameters;
00047 import org.objectweb.proactive.core.ssh.SshTunnel;
00048 import org.objectweb.proactive.core.ssh.SshTunnelFactory;
00049 import org.objectweb.proactive.core.ssh.TryCache;
00050 import org.objectweb.proactive.core.util.log.Loggers;
00051 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00052 
00053 
00057 public class HttpSshUrlConnection extends java.net.HttpURLConnection {
00058     static Logger logger = ProActiveLogger.getLogger(Loggers.SSH);
00059     private SshTunnel _tunnel;
00060     private HttpURLConnection _httpConnection;
00061     private java.util.Hashtable<String,List<String>> _properties;
00062     static private TryCache _tryCache = null;
00063 
00064     static private TryCache getTryCache() {
00065         if (_tryCache == null) {
00066             _tryCache = new TryCache();
00067         }
00068         return _tryCache;
00069     }
00070 
00071     protected void finalize() throws Throwable {
00072         super.finalize();
00073         SshTunnelFactory.reportUnusedTunnel(_tunnel);
00074     }
00075 
00076     public HttpSshUrlConnection(java.net.URL u) throws IOException {
00077         super(u);
00078         _properties = new Hashtable<String,List<String>>();
00079     }
00080 
00081     private void checkNotConnected() throws IllegalStateException {
00082         if (connected) {
00083             throw new IllegalStateException("already connected");
00084         }
00085     }
00086 
00087     private void checkNullKey(String str) throws NullPointerException {
00088         if (str == null) {
00089             throw new NullPointerException("null key");
00090         }
00091     }
00092 
00093     public Map <String,List<String>> getRequestProperties() {
00094         checkNotConnected();
00095         return _properties;
00096     }
00097 
00098     public String getRequestProperty(String key) {
00099         checkNotConnected();
00100         if (key == null) {
00101             return null;
00102         }
00103         ArrayList list = (ArrayList) _properties.get(key);
00104         String retval = null;
00105         if (list != null) {
00106             retval = (String) list.get(0);
00107         }
00108         return retval;
00109     }
00110 
00111     public void setRequestProperty(String key, String value) {
00112         checkNotConnected();
00113         checkNullKey(key);
00114         ArrayList<String> list = new ArrayList<String>();
00115         list.add(value);
00116         _properties.put(key, list);
00117     }
00118 
00119     public void addRequestProperty(String key, String value) {
00120         checkNotConnected();
00121         checkNullKey(key);
00122         List<String> list = _properties.get(key);
00123         if (list == null) {
00124             list = new ArrayList<String>();
00125         } 
00126         list.add(value);
00127         _properties.put(key, list);
00128     }
00129 
00130     public void setInstanceFollowRedirects(boolean followRedirects) {
00131         super.setInstanceFollowRedirects(followRedirects);
00132         if (_httpConnection != null) {
00133             _httpConnection.setInstanceFollowRedirects(followRedirects);
00134         }
00135     }
00136 
00137     public void setRequestMethod(String method) throws ProtocolException {
00138         super.setRequestMethod(method);
00139         if (_httpConnection != null) {
00140             _httpConnection.setRequestMethod(method);
00141         }
00142     }
00143 
00144     public int getResponseCode() throws IOException {
00145         ensureTunnel();
00146         return _httpConnection.getResponseCode();
00147     }
00148 
00149     public void connect() throws IOException {
00150         ensureTunnel();
00151         _httpConnection.connect();
00152         connected = true;
00153     }
00154 
00155     public void disconnect() {
00156         connected = false;
00157     }
00158 
00159     public boolean usingProxy() {
00160         if (_httpConnection != null) {
00161             return _httpConnection.usingProxy();
00162         } else {
00163             return false;
00164         }
00165     }
00166 
00167     public InputStream getErrorStream() {
00168         if (!connected) {
00169             return null;
00170         } else {
00171             // if we are connected, _httpConnection is a valid field.
00172             return _httpConnection.getErrorStream();
00173         }
00174     }
00175 
00176     public String getHeaderField(String name) {
00177         try {
00178             ensureTunnel();
00179             return _httpConnection.getHeaderField(name);
00180         } catch (Exception e) {
00181             return null;
00182         }
00183     }
00184 
00185     public String getHeaderField(int n) {
00186         try {
00187             ensureTunnel();
00188             return _httpConnection.getHeaderField(n);
00189         } catch (Exception e) {
00190             return null;
00191         }
00192     }
00193 
00194     public String getHeaderFieldKey(int n) {
00195         try {
00196             ensureTunnel();
00197             return _httpConnection.getHeaderFieldKey(n);
00198         } catch (Exception e) {
00199             return null;
00200         }
00201     }
00202 
00203     public Map<String,List<String>> getHeaderFields() {
00204         try {
00205             ensureTunnel();
00206             return _httpConnection.getHeaderFields();
00207         } catch (Exception e) {
00208             return null;
00209         }
00210     }
00211 
00212     public InputStream getInputStream() throws IOException {
00213         ensureTunnel();
00214         return _httpConnection.getInputStream();
00215     }
00216 
00217     public OutputStream getOutputStream() throws IOException {
00218         ensureTunnel();
00219         return _httpConnection.getOutputStream();
00220     }
00221 
00222     public String toString() {
00223         return HttpSshUrlConnection.class.getName() + ":" + url.toString();
00224     }
00225 
00226     private void ensureSetup(HttpURLConnection connection) {
00227         connection.setDoInput(getDoInput());
00228         connection.setDoOutput(getDoOutput());
00229         connection.setAllowUserInteraction(getAllowUserInteraction());
00230         connection.setIfModifiedSince(getIfModifiedSince());
00231         connection.setUseCaches(getUseCaches());
00232 
00233         connection.setInstanceFollowRedirects(getInstanceFollowRedirects());
00234         try {
00235             connection.setRequestMethod(getRequestMethod());
00236         } catch (Exception e) {
00237             e.printStackTrace();
00238         }
00239 
00240         java.util.Set set = _properties.entrySet();
00241         for (java.util.Iterator i = set.iterator(); i.hasNext();) {
00242             Map.Entry entry = (Map.Entry) i.next();
00243             String key = (String) entry.getKey();
00244             ArrayList values = (ArrayList) entry.getValue();
00245             for (java.util.Iterator j = values.iterator(); j.hasNext();) {
00246                 String val = (String) j.next();
00247                 try {
00248                     connection.addRequestProperty(key, val);
00249                 } catch (Exception e) {
00250                     e.printStackTrace();
00251                 }
00252             }
00253         }
00254     }
00255 
00256     private void ensureTunnel() throws IOException {
00257         if (_httpConnection != null) {
00258             return;
00259         }
00260         java.net.URL u = getURL();
00261         logger.debug("create http " + url.toString());
00262         String host = u.getHost();
00263         int port = u.getPort();
00264         String path = u.getPath();
00265         if (SshParameters.getTryNormalFirst() &&
00266                 getTryCache().needToTry(host, port)) {
00267             if (!getTryCache().everTried(host, port)) {
00268                 try {
00269                     logger.debug("try http socket probing");
00270                     InetSocketAddress address = new InetSocketAddress(host, port);
00271                     Socket socket = new Socket();
00272                     socket.connect(address, SshParameters.getConnectTimeout());
00273                     socket.close();
00274                     logger.debug("success http socket probing");
00275                 } catch (Exception e) {
00276                     logger.debug("failure http socket probing");
00277                     getTryCache().recordTryFailure(host, port);
00278                 }
00279             }
00280             if (getTryCache().needToTry(host, port)) {
00281                 try {
00282                     java.net.URL httpURL = new java.net.URL("http://" + host +
00283                             ":" +
00284                             port // uncomment the following line and comment the one above to make sure
00285                             // you test that connections fallback to tunneling if the main
00286                         // connection fails.
00287                         //+ 1 
00288                              +path);
00289                     logger.debug("try http not tunneled");
00290                     _httpConnection = (HttpURLConnection) httpURL.openConnection();
00291                     ensureSetup(_httpConnection);
00292                     _httpConnection.connect();
00293                     logger.debug("success http not tunneled ");
00294                     connected = true;
00295                     getTryCache().recordTrySuccess(host, port);
00296                     return;
00297                 } catch (Exception e) {
00298                     getTryCache().recordTryFailure(host, port);
00299                     logger.debug("failure http not tunneled ");
00300                 }
00301             }
00302         }
00303         logger.debug("try http ssh tunneled");
00304         _tunnel = SshTunnelFactory.createTunnel(host, port);
00305         java.net.URL httpURL = new java.net.URL("http://127.0.0.1:" +
00306                 _tunnel.getPort() + path);
00307         _httpConnection = (HttpURLConnection) httpURL.openConnection();
00308         ensureSetup(_httpConnection);
00309         logger.debug("Opened http connection through tunnel 127.0.0.1:" +
00310             _tunnel.getPort() + " -> " + host + ":" + port + " ressource " +
00311             path + " -- " + _httpConnection.toString());
00312     }
00313 }

Generated on Mon Jan 22 15:16:09 2007 for ProActive by  doxygen 1.5.1