Mercurial > hg4j
comparison src/org/tmatesoft/hg/internal/remote/HttpConnector.java @ 698:822f3a83ff57
in, out and clone tests pass for ssh repositories. Infrastructure to decouple HgRemoteRepository from specific Connector implementation
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Tue, 06 Aug 2013 21:18:33 +0200 | 
| parents | 24f4efedc9d5 | 
| children | a483b2b68a2e | 
   comparison
  equal
  deleted
  inserted
  replaced
| 697:24f4efedc9d5 | 698:822f3a83ff57 | 
|---|---|
| 26 import java.io.InputStreamReader; | 26 import java.io.InputStreamReader; | 
| 27 import java.io.OutputStream; | 27 import java.io.OutputStream; | 
| 28 import java.io.SequenceInputStream; | 28 import java.io.SequenceInputStream; | 
| 29 import java.net.HttpURLConnection; | 29 import java.net.HttpURLConnection; | 
| 30 import java.net.MalformedURLException; | 30 import java.net.MalformedURLException; | 
| 31 import java.net.URI; | |
| 31 import java.net.URL; | 32 import java.net.URL; | 
| 32 import java.net.URLConnection; | 33 import java.net.URLConnection; | 
| 33 import java.security.cert.CertificateException; | 34 import java.security.cert.CertificateException; | 
| 34 import java.security.cert.X509Certificate; | 35 import java.security.cert.X509Certificate; | 
| 35 import java.util.Collection; | 36 import java.util.Collection; | 
| 54 * | 55 * | 
| 55 * @author Artem Tikhomirov | 56 * @author Artem Tikhomirov | 
| 56 * @author TMate Software Ltd. | 57 * @author TMate Software Ltd. | 
| 57 */ | 58 */ | 
| 58 public class HttpConnector implements Connector { | 59 public class HttpConnector implements Connector { | 
| 60 private URI uri; | |
| 59 private URL url; | 61 private URL url; | 
| 60 private SSLContext sslContext; | 62 private SSLContext sslContext; | 
| 61 private String authInfo; | 63 private String authInfo; | 
| 62 private boolean debug; | 64 private boolean debug; | 
| 63 private SessionContext sessionCtx; | 65 private SessionContext sessionCtx; | 
| 64 // | 66 // | 
| 65 private HttpURLConnection conn; | 67 private HttpURLConnection conn; | 
| 66 | 68 | 
| 67 public void init(URL url, SessionContext sessionContext, Object globalConfig) throws HgRuntimeException { | 69 public void init(URI uri, SessionContext sessionContext, Object globalConfig) throws HgRuntimeException { | 
| 68 this.url = url; | 70 this.uri = uri; | 
| 69 sessionCtx = sessionContext; | 71 sessionCtx = sessionContext; | 
| 70 debug = new PropertyMarshal(sessionCtx).getBoolean("hg4j.remote.debug", false); | 72 debug = new PropertyMarshal(sessionCtx).getBoolean("hg4j.remote.debug", false); | 
| 71 if (url.getUserInfo() != null) { | 73 if (uri.getUserInfo() != null) { | 
| 72 String ai = null; | 74 String ai = null; | 
| 73 try { | 75 try { | 
| 74 // Hack to get Base64-encoded credentials | 76 // Hack to get Base64-encoded credentials | 
| 75 Preferences tempNode = Preferences.userRoot().node("xxx"); | 77 Preferences tempNode = Preferences.userRoot().node("xxx"); | 
| 76 tempNode.putByteArray("xxx", url.getUserInfo().getBytes()); | 78 tempNode.putByteArray("xxx", uri.getUserInfo().getBytes()); | 
| 77 ai = tempNode.get("xxx", null); | 79 ai = tempNode.get("xxx", null); | 
| 78 tempNode.removeNode(); | 80 tempNode.removeNode(); | 
| 79 } catch (BackingStoreException ex) { | 81 } catch (BackingStoreException ex) { | 
| 80 sessionContext.getLog().dump(getClass(), Info, ex, null); | 82 sessionContext.getLog().dump(getClass(), Info, ex, null); | 
| 81 // IGNORE | 83 // IGNORE | 
| 85 authInfo = null; | 87 authInfo = null; | 
| 86 } | 88 } | 
| 87 } | 89 } | 
| 88 | 90 | 
| 89 public void connect() throws HgRemoteConnectionException, HgRuntimeException { | 91 public void connect() throws HgRemoteConnectionException, HgRuntimeException { | 
| 92 try { | |
| 93 url = uri.toURL(); | |
| 94 } catch (MalformedURLException ex) { | |
| 95 throw new HgRemoteConnectionException("Bad URL", ex); | |
| 96 } | |
| 90 if ("https".equals(url.getProtocol())) { | 97 if ("https".equals(url.getProtocol())) { | 
| 91 try { | 98 try { | 
| 92 sslContext = SSLContext.getInstance("SSL"); | 99 sslContext = SSLContext.getInstance("SSL"); | 
| 93 class TrustEveryone implements X509TrustManager { | 100 class TrustEveryone implements X509TrustManager { | 
| 94 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { | 101 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { | 
| 130 conn = null; | 137 conn = null; | 
| 131 } | 138 } | 
| 132 } | 139 } | 
| 133 | 140 | 
| 134 public String getServerLocation() { | 141 public String getServerLocation() { | 
| 135 if (url.getUserInfo() == null) { | 142 if (uri.getUserInfo() == null) { | 
| 136 return url.toExternalForm(); | 143 return uri.toString(); | 
| 137 } | 144 } | 
| 138 if (url.getPort() != -1) { | 145 if (uri.getPort() != -1) { | 
| 139 return String.format("%s://%s:%d%s", url.getProtocol(), url.getHost(), url.getPort(), url.getPath()); | 146 return String.format("%s://%s:%d%s", uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath()); | 
| 140 } else { | 147 } else { | 
| 141 return String.format("%s://%s%s", url.getProtocol(), url.getHost(), url.getPath()); | 148 return String.format("%s://%s%s", uri.getScheme(), uri.getHost(), uri.getPath()); | 
| 142 } | 149 } | 
| 143 } | 150 } | 
| 144 | 151 | 
| 145 public String getCapabilities() throws HgRemoteConnectionException { | 152 public String getCapabilities() throws HgRemoteConnectionException { | 
| 146 // say hello to server, check response | 153 // say hello to server, check response | 
| 292 return new FilterOutputStream(conn.getOutputStream()) { | 299 return new FilterOutputStream(conn.getOutputStream()) { | 
| 293 public void close() throws IOException { | 300 public void close() throws IOException { | 
| 294 super.close(); | 301 super.close(); | 
| 295 if (debug) { | 302 if (debug) { | 
| 296 dumpResponseHeader(u); | 303 dumpResponseHeader(u); | 
| 297 dumpResponse(); | |
| 298 } | 304 } | 
| 299 try { | 305 try { | 
| 300 checkResponseOk("Push", CMD_UNBUNDLE); | 306 checkResponseOk("Push", CMD_UNBUNDLE); | 
| 301 } catch (HgRemoteConnectionException ex) { | 307 } catch (HgRemoteConnectionException ex) { | 
| 302 IOException e = new IOException(ex.getMessage()); | 308 IOException e = new IOException(ex.getMessage()); | 
| 393 final Map<String, List<String>> headerFields = conn.getHeaderFields(); | 399 final Map<String, List<String>> headerFields = conn.getHeaderFields(); | 
| 394 for (String s : headerFields.keySet()) { | 400 for (String s : headerFields.keySet()) { | 
| 395 System.out.printf("%s: %s\n", s, conn.getHeaderField(s)); | 401 System.out.printf("%s: %s\n", s, conn.getHeaderField(s)); | 
| 396 } | 402 } | 
| 397 } | 403 } | 
| 398 | |
| 399 private void dumpResponse() throws IOException { | |
| 400 if (conn.getContentLength() > 0) { | |
| 401 final Object content = conn.getContent(); | |
| 402 System.out.println(content); | |
| 403 } | |
| 404 } | |
| 405 } | 404 } | 
