00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
00285
00286
00287
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 }