comparison src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 428:ead6c67f3319

Actual 'hello' check of the remote server/connection
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 29 Mar 2012 18:05:05 +0200
parents 48f993aa2f41
children 2a08466838d3
comparison
equal deleted inserted replaced
427:31a89587eb04 428:ead6c67f3319
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.repo; 17 package org.tmatesoft.hg.repo;
18 18
19 import java.io.BufferedReader;
19 import java.io.File; 20 import java.io.File;
20 import java.io.FileOutputStream; 21 import java.io.FileOutputStream;
21 import java.io.IOException; 22 import java.io.IOException;
22 import java.io.InputStream; 23 import java.io.InputStream;
23 import java.io.InputStreamReader; 24 import java.io.InputStreamReader;
28 import java.net.URL; 29 import java.net.URL;
29 import java.net.URLConnection; 30 import java.net.URLConnection;
30 import java.security.cert.CertificateException; 31 import java.security.cert.CertificateException;
31 import java.security.cert.X509Certificate; 32 import java.security.cert.X509Certificate;
32 import java.util.ArrayList; 33 import java.util.ArrayList;
34 import java.util.Arrays;
33 import java.util.Collection; 35 import java.util.Collection;
34 import java.util.Collections; 36 import java.util.Collections;
37 import java.util.HashSet;
35 import java.util.Iterator; 38 import java.util.Iterator;
36 import java.util.LinkedHashMap; 39 import java.util.LinkedHashMap;
37 import java.util.LinkedList; 40 import java.util.LinkedList;
38 import java.util.List; 41 import java.util.List;
39 import java.util.Map; 42 import java.util.Map;
43 import java.util.Set;
40 import java.util.prefs.BackingStoreException; 44 import java.util.prefs.BackingStoreException;
41 import java.util.prefs.Preferences; 45 import java.util.prefs.Preferences;
42 import java.util.zip.InflaterInputStream; 46 import java.util.zip.InflaterInputStream;
43 47
44 import javax.net.ssl.HttpsURLConnection; 48 import javax.net.ssl.HttpsURLConnection;
66 private final SSLContext sslContext; 70 private final SSLContext sslContext;
67 private final String authInfo; 71 private final String authInfo;
68 private final boolean debug; 72 private final boolean debug;
69 private HgLookup lookupHelper; 73 private HgLookup lookupHelper;
70 private final SessionContext sessionContext; 74 private final SessionContext sessionContext;
71 75 private Set<String> remoteCapabilities;
76
72 HgRemoteRepository(SessionContext ctx, URL url) throws HgBadArgumentException { 77 HgRemoteRepository(SessionContext ctx, URL url) throws HgBadArgumentException {
73 if (url == null || ctx == null) { 78 if (url == null || ctx == null) {
74 throw new IllegalArgumentException(); 79 throw new IllegalArgumentException();
75 } 80 }
76 this.url = url; 81 this.url = url;
119 authInfo = null; 124 authInfo = null;
120 } 125 }
121 } 126 }
122 127
123 public boolean isInvalid() throws HgRemoteConnectionException { 128 public boolean isInvalid() throws HgRemoteConnectionException {
124 // say hello to server, check response 129 if (remoteCapabilities == null) {
125 if (Boolean.FALSE.booleanValue()) { 130 remoteCapabilities = new HashSet<String>();
126 throw HgRepository.notImplemented(); 131 // say hello to server, check response
127 } 132 try {
128 return false; // FIXME implement remote repository hello/check 133 URL u = new URL(url, url.getPath() + "?cmd=hello");
134 HttpURLConnection c = setupConnection(u.openConnection());
135 c.connect();
136 if (debug) {
137 dumpResponseHeader(u, c);
138 }
139 BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream(), "US-ASCII"));
140 String line = r.readLine();
141 c.disconnect();
142 final String capsPrefix = "capabilities:";
143 if (line == null || !line.startsWith(capsPrefix)) {
144 // for whatever reason, some servers do not respond to hello command (e.g. svnkit)
145 // but respond to 'capabilities' instead. Try it.
146 // TODO [post-1.0] tests needed
147 u = new URL(url, url.getPath() + "?cmd=capabilities");
148 c = setupConnection(u.openConnection());
149 c.connect();
150 if (debug) {
151 dumpResponseHeader(u, c);
152 }
153 r = new BufferedReader(new InputStreamReader(c.getInputStream(), "US-ASCII"));
154 line = r.readLine();
155 c.disconnect();
156 if (line == null || line.trim().isEmpty()) {
157 return true;
158 }
159 } else {
160 line = line.substring(capsPrefix.length()).trim();
161 }
162 String[] caps = line.split("\\s");
163 remoteCapabilities.addAll(Arrays.asList(caps));
164 c.disconnect();
165 } catch (MalformedURLException ex) {
166 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("hello").setServerInfo(getLocation());
167 } catch (IOException ex) {
168 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("hello").setServerInfo(getLocation());
169 }
170 }
171 return remoteCapabilities.isEmpty();
129 } 172 }
130 173
131 /** 174 /**
132 * @return human-readable address of the server, without user credentials or any other security information 175 * @return human-readable address of the server, without user credentials or any other security information
133 */ 176 */
150 if (debug) { 193 if (debug) {
151 dumpResponseHeader(u, c); 194 dumpResponseHeader(u, c);
152 } 195 }
153 InputStreamReader is = new InputStreamReader(c.getInputStream(), "US-ASCII"); 196 InputStreamReader is = new InputStreamReader(c.getInputStream(), "US-ASCII");
154 StreamTokenizer st = new StreamTokenizer(is); 197 StreamTokenizer st = new StreamTokenizer(is);
155 st.ordinaryChars('0', '9'); 198 st.ordinaryChars('0', '9'); // wordChars performs |, hence need to 0 first
156 st.wordChars('0', '9'); 199 st.wordChars('0', '9');
157 st.eolIsSignificant(false); 200 st.eolIsSignificant(false);
158 LinkedList<Nodeid> parseResult = new LinkedList<Nodeid>(); 201 LinkedList<Nodeid> parseResult = new LinkedList<Nodeid>();
159 while (st.nextToken() != StreamTokenizer.TT_EOF) { 202 while (st.nextToken() != StreamTokenizer.TT_EOF) {
160 parseResult.add(Nodeid.fromAscii(st.sval)); 203 parseResult.add(Nodeid.fromAscii(st.sval));