annotate src/org/tmatesoft/hg/internal/remote/SshConnector.java @ 694:7efabe0cddcf

Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 05 Aug 2013 17:42:10 +0200
parents 9859fcea475d
children 5b5d199e2eb3
rev   line source
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2013 TMate Software Ltd
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal.remote;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import java.io.BufferedReader;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20 import java.io.Closeable;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
21 import java.io.EOFException;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
22 import java.io.File;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
23 import java.io.FilterInputStream;
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
24 import java.io.FilterOutputStream;
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25 import java.io.IOException;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
26 import java.io.InputStream;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import java.io.InputStreamReader;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
28 import java.io.OutputStream;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
29 import java.net.URL;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
30 import java.util.ArrayList;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
31 import java.util.Collection;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
32 import java.util.Collections;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33 import java.util.List;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
34
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
35 import org.tmatesoft.hg.core.HgRemoteConnectionException;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
36 import org.tmatesoft.hg.core.Nodeid;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
37 import org.tmatesoft.hg.core.SessionContext;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 import org.tmatesoft.hg.repo.HgRemoteRepository.Range;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
39 import org.tmatesoft.hg.repo.HgRuntimeException;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40 import org.tmatesoft.hg.util.LogFacility.Severity;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 import ch.ethz.ssh2.Connection;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 import ch.ethz.ssh2.ConnectionInfo;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 import ch.ethz.ssh2.Session;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 import ch.ethz.ssh2.StreamGobbler;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47 /**
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 * Remote repository via SSH
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 *
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
50 * @author Artem Tikhomirov
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
51 * @author TMate Software Ltd.
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52 */
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
53 public class SshConnector implements Connector {
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
54 private SessionContext sessionCtx;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
55 private URL url;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 private Connection conn;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 private Session session;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58 private int sessionUse;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 private StreamGobbler remoteErr, remoteOut;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 private OutputStream remoteIn;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
63 public void init(URL url, SessionContext sessionContext, Object globalConfig) throws HgRuntimeException {
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 sessionCtx = sessionContext;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
65 this.url = url;
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
66 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
67
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
68 public void connect() throws HgRemoteConnectionException, HgRuntimeException {
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
69 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
70 conn = new Connection(url.getHost(), url.getPort() == -1 ? 22 : url.getPort());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
71 conn.connect();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
72 } catch (IOException ex) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
73 throw new HgRemoteConnectionException("Failed to establish connection");
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
74 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
75 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
76 conn.authenticateWithPublicKey(System.getProperty("user.name"), new File(System.getProperty("user.home"), ".ssh/id_rsa"), null);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
77 ConnectionInfo ci = conn.getConnectionInfo();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
78 System.out.printf("%s %s %s %d %s %s %s\n", ci.clientToServerCryptoAlgorithm, ci.clientToServerMACAlgorithm, ci.keyExchangeAlgorithm, ci.keyExchangeCounter, ci.serverHostKeyAlgorithm, ci.serverToClientCryptoAlgorithm, ci.serverToClientMACAlgorithm);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 } catch (IOException ex) {
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
80 throw new HgRemoteConnectionException("Failed to authenticate", ex).setServerInfo(getServerLocation());
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
81 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
82 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 public void disconnect() throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85 if (session != null) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
86 forceSessionClose();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
87 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
88 if (conn != null) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
89 conn.close();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
90 conn = null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
91 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
92 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
93
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
94 public void sessionBegin() throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
95 if (sessionUse > 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
96 assert session != null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
97 sessionUse++;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
98 return;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
100 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
101 session = conn.openSession();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
102 session.execCommand(String.format("hg -R %s serve --stdio", url.getPath()));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
103 remoteErr = new StreamGobbler(session.getStderr());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
104 remoteOut = new StreamGobbler(session.getStdout());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
105 sessionUse = 1;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
106 } catch (IOException ex) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
107 throw new HgRemoteConnectionException("Failed to create ssh session", ex);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
108 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
109 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
110
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
111 public void sessionEnd() throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
112 assert sessionUse > 0;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
113 assert session != null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
114 if (sessionUse > 1) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
115 sessionUse--;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
116 return;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
117 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
118 forceSessionClose();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
119 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
120
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
121 public String getServerLocation() {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
122 return ""; // FIXME
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
123 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
124
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
125 public String getCapabilities() throws HgRemoteConnectionException {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
126 try {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
127 consume(remoteOut);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
128 consume(remoteErr);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
129 remoteIn.write(CMD_HELLO.getBytes());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
130 remoteIn.write('\n');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
131 remoteIn.write(CMD_CAPABILITIES.getBytes()); // see http connector for details
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
132 remoteIn.write('\n');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
133 remoteIn.write(CMD_HEADS.getBytes());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
134 remoteIn.write('\n');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
135 checkError();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
136 int responseLen = readResponseLength();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
137 checkError();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
138 FilterStream s = new FilterStream(remoteOut, responseLen);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
139 BufferedReader r = new BufferedReader(new InputStreamReader(s));
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
140 String line;
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
141 while ((line = r.readLine()) != null) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
142 if (line.startsWith(CMD_CAPABILITIES) && line.length() > (CMD_CAPABILITIES.length()+1)) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
143 line = line.substring(CMD_CAPABILITIES.length());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
144 if (line.charAt(0) == ':') {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
145 return line.substring(CMD_CAPABILITIES.length() + 1);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
146 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
147 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
148 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
149 r.close();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
150 consume(remoteOut);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
151 checkError();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
152 return new String();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
153 } catch (IOException ex) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
154 throw new HgRemoteConnectionException("Failed to initiate dialog with server", ex).setRemoteCommand(CMD_HELLO).setServerInfo(getServerLocation());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
155 }
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
156 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
157
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
158 public InputStream heads() throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
159 return executeCommand("heads", Collections.<Parameter>emptyList());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
160 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
161
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
162 public InputStream between(Collection<Range> ranges) throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
163 StringBuilder sb = new StringBuilder(ranges.size() * 82);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
164 for (Range r : ranges) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
165 r.append(sb).append(' ');
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
166 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
167 if (!ranges.isEmpty()) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
168 sb.setLength(sb.length() - 1);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
169 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
170 return executeCommand("between", Collections.singletonList(new Parameter("pairs", sb.toString())));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
171 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
172
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
173 public InputStream branches(List<Nodeid> nodes) throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
174 String l = join(nodes, ' ');
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
175 return executeCommand("branches", Collections.singletonList(new Parameter("nodes", l)));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
176 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
177
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
178 public InputStream changegroup(List<Nodeid> roots) throws HgRemoteConnectionException, HgRuntimeException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
179 String l = join(roots, ' ');
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
180 return executeCommand("changegroup", Collections.singletonList(new Parameter("roots", l)));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
181 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
182
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
183 public OutputStream unbundle(long outputLen, List<Nodeid> remoteHeads) throws HgRemoteConnectionException, HgRuntimeException {
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
184 String l = join(remoteHeads, ' ');
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
185 try {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
186 consume(remoteOut);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
187 consume(remoteErr);
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
188 remoteIn.write(CMD_UNBUNDLE.getBytes());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
189 remoteIn.write('\n');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
190 writeParameters(Collections.singletonList(new Parameter("heads", l)));
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
191 checkError();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
192 return new FilterOutputStream(remoteIn) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
193 @Override
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
194 public void close() throws IOException {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
195 out.flush();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
196 @SuppressWarnings("unused")
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
197 int responseLen = readResponseLength();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
198 checkError();
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
199 // XXX perhaps, need to return responseLen to caller?
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
200 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
201 };
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
202 } catch (IOException ex) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
203 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand(CMD_UNBUNDLE).setServerInfo(getServerLocation());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
204 }
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
205 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
206
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
207 public InputStream pushkey(String opName, String namespace, String key, String oldValue, String newValue) throws HgRemoteConnectionException, HgRuntimeException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
208 ArrayList<Parameter> p = new ArrayList<Parameter>();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
209 p.add(new Parameter("namespace", namespace));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
210 p.add(new Parameter("key", key));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
211 p.add(new Parameter("old", oldValue));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
212 p.add(new Parameter("new", newValue));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
213 return executeCommand("pushkey", p);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
214 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
215
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
216 public InputStream listkeys(String namespace, String actionName) throws HgRemoteConnectionException, HgRuntimeException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
217 return executeCommand("listkeys", Collections.singletonList(new Parameter("namespace", namespace)));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
218 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
219
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
220 private InputStream executeCommand(String cmd, List<Parameter> parameters) throws HgRemoteConnectionException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
221 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
222 consume(remoteOut);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
223 consume(remoteErr);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
224 remoteIn.write(cmd.getBytes());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
225 remoteIn.write('\n');
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
226 writeParameters(parameters);
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
227 checkError();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
228 int responseLen = readResponseLength();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
229 checkError();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
230 return new FilterStream(remoteOut, responseLen);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
231 } catch (IOException ex) {
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
232 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand(cmd).setServerInfo(getServerLocation());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
233 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
234 }
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
235
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
236 private void writeParameters(List<Parameter> parameters) throws IOException {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
237 for (Parameter p : parameters) {
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
238 remoteIn.write(p.name().getBytes());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
239 remoteIn.write(' ');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
240 remoteIn.write(String.valueOf(p.size()).getBytes());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
241 remoteIn.write('\n');
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
242 remoteIn.write(p.data());
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
243 remoteIn.write('\n');
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
244 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
245 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
246
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
247 private void consume(InputStream is) throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
248 while (is.available() > 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
249 is.read();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
250 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
251 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
252
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
253 private void checkError() throws IOException {
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
254 if (remoteErr.available() > 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
255 StringBuilder sb = new StringBuilder();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
256 int c;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
257 while ((c = remoteErr.read()) != -1) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
258 sb.append((char)c);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
259 }
687
9859fcea475d Towards ssh remote repositories: refactor HgRemoteRepository - move http related code to HttpConnector
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 685
diff changeset
260 throw new IOException(sb.toString());
685
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
261 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
262 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
263
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
264 private int readResponseLength() throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
265 int c;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
266 StringBuilder sb = new StringBuilder();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
267 while ((c = remoteOut.read()) != -1) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
268 if (c == '\n') {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
269 break;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
270 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
271 sb.append((char) c);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
272 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
273 if (c == -1) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
274 throw new EOFException();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
275 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
276 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
277 return Integer.parseInt(sb.toString());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
278 } catch (NumberFormatException ex) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
279 throw new IOException(String.format("Expected response length instead of %s", sb));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
280 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
281 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
282
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
283
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
284 private void forceSessionClose() {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
285 if (session != null) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
286 closeQuietly(remoteErr);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
287 closeQuietly(remoteOut);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
288 remoteErr = remoteOut = null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
289 closeQuietly(remoteIn);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
290 remoteIn = null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
291 session.close();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
292 session = null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
293 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
294 sessionUse = 0;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
295 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
296
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
297 private void closeQuietly(Closeable c) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
298 try {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
299 if (c != null) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
300 c.close();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
301 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
302 } catch (IOException ex) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
303 sessionCtx.getLog().dump(getClass(), Severity.Warn, ex, null);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
304 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
305 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
306
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
307 private static String join(List<Nodeid> values, char sep) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
308 StringBuilder sb = new StringBuilder(values.size() * 41);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
309 for (Nodeid n : values) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
310 sb.append(n.toString());
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
311 sb.append(sep);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
312 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
313 if (!values.isEmpty()) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
314 // strip last space
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
315 sb.setLength(sb.length() - 1);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
316 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
317 return sb.toString();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
318 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
319
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
320 private static final class Parameter {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
321 private final String name;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
322 private final byte[] data;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
323
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
324 public Parameter(String paramName, String paramValue) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
325 assert paramName != null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
326 assert paramValue != null;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
327 name = paramName;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
328 data = paramValue.getBytes();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
329 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
330
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
331 public String name() {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
332 return name;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
333 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
334 public int size() {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
335 return data.length;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
336 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
337 public byte[] data() {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
338 return data;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
339 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
340 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
341
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
342 private static final class FilterStream extends FilterInputStream {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
343 private int length;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
344
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
345 public FilterStream(InputStream is, int initialLength) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
346 super(is);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
347 length = initialLength;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
348 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
349
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
350 @Override
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
351 public int available() throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
352 return Math.min(super.available(), length);
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
353 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
354 @Override
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
355 public int read() throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
356 if (length == 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
357 return -1;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
358 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
359 int r = super.read();
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
360 if (r >= 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
361 length--;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
362 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
363 return r;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
364 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
365 @Override
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
366 public int read(byte[] b, int off, int len) throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
367 if (length == 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
368 return -1;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
369 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
370 int r = super.read(b, off, Math.min(len, length));
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
371 if (r >= 0) {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
372 assert r <= length;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
373 length -= r;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
374 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
375 return r;
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
376 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
377 @Override
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
378 public void close() throws IOException {
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
379 // INTENTIONALLY DOES NOT CLOSE THE STREAM
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
380 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
381 }
9897cbfd2790 Towards ssh remote repositories: use ganymed library for ssh transport
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
382 }