1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jgit.transport;
14
15 import java.io.BufferedInputStream;
16 import java.io.BufferedOutputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.net.ConnectException;
21 import java.net.InetAddress;
22 import java.net.InetSocketAddress;
23 import java.net.Socket;
24 import java.net.UnknownHostException;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.EnumSet;
28 import java.util.Set;
29
30 import org.eclipse.jgit.errors.NotSupportedException;
31 import org.eclipse.jgit.errors.TransportException;
32 import org.eclipse.jgit.internal.JGitText;
33 import org.eclipse.jgit.lib.Repository;
34
35
36
37
38
39
40
41
42 class TransportGitAnon extends TcpTransport implements PackTransport {
43 static final int GIT_PORT = Daemon.DEFAULT_PORT;
44
45 static final TransportProtocol PROTO_GIT = new TransportProtocol() {
46 @Override
47 public String getName() {
48 return JGitText.get().transportProtoGitAnon;
49 }
50
51 @Override
52 public Set<String> getSchemes() {
53 return Collections.singleton("git");
54 }
55
56 @Override
57 public Set<URIishField> getRequiredFields() {
58 return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
59 URIishField.PATH));
60 }
61
62 @Override
63 public Set<URIishField> getOptionalFields() {
64 return Collections.unmodifiableSet(EnumSet.of(URIishField.PORT));
65 }
66
67 @Override
68 public int getDefaultPort() {
69 return GIT_PORT;
70 }
71
72 @Override
73 public Transport open(URIish uri, Repository local, String remoteName)
74 throws NotSupportedException {
75 return new TransportGitAnon(local, uri);
76 }
77
78 @Override
79 public Transport open(URIish uri) throws NotSupportedException, TransportException {
80 return new TransportGitAnon(uri);
81 }
82 };
83
84 TransportGitAnon(Repository local, URIish uri) {
85 super(local, uri);
86 }
87
88 TransportGitAnon(URIish uri) {
89 super(uri);
90 }
91
92
93 @Override
94 public FetchConnection openFetch() throws TransportException {
95 return new TcpFetchConnection();
96 }
97
98 @Override
99 public FetchConnection openFetch(Collection<RefSpec> refSpecs,
100 String... additionalPatterns)
101 throws NotSupportedException, TransportException {
102 return new TcpFetchConnection(refSpecs, additionalPatterns);
103 }
104
105
106 @Override
107 public PushConnection openPush() throws TransportException {
108 return new TcpPushConnection();
109 }
110
111
112 @Override
113 public void close() {
114
115 }
116
117 Socket openConnection() throws TransportException {
118 final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
119 final int port = uri.getPort() > 0 ? uri.getPort() : GIT_PORT;
120 @SuppressWarnings("resource")
121 final Socket s = new Socket();
122 try {
123 final InetAddress host = InetAddress.getByName(uri.getHost());
124 s.connect(new InetSocketAddress(host, port), tms);
125 } catch (IOException c) {
126 try {
127 s.close();
128 } catch (IOException closeErr) {
129
130 }
131 if (c instanceof UnknownHostException)
132 throw new TransportException(uri, JGitText.get().unknownHost);
133 if (c instanceof ConnectException)
134 throw new TransportException(uri, c.getMessage());
135 throw new TransportException(uri, c.getMessage(), c);
136 }
137 return s;
138 }
139
140 void service(String name, PacketLineOut pckOut,
141 TransferConfig.ProtocolVersion gitProtocol)
142 throws IOException {
143 final StringBuilder cmd = new StringBuilder();
144 cmd.append(name);
145 cmd.append(' ');
146 cmd.append(uri.getPath());
147 cmd.append('\0');
148 cmd.append("host=");
149 cmd.append(uri.getHost());
150 if (uri.getPort() > 0 && uri.getPort() != GIT_PORT) {
151 cmd.append(":");
152 cmd.append(uri.getPort());
153 }
154 cmd.append('\0');
155 if (TransferConfig.ProtocolVersion.V2.equals(gitProtocol)) {
156 cmd.append('\0');
157 cmd.append(GitProtocolConstants.VERSION_2_REQUEST);
158 cmd.append('\0');
159 }
160 pckOut.writeString(cmd.toString());
161 pckOut.flush();
162 }
163
164 class TcpFetchConnection extends BasePackFetchConnection {
165 private Socket sock;
166
167 TcpFetchConnection() throws TransportException {
168 this(Collections.emptyList());
169 }
170
171 TcpFetchConnection(Collection<RefSpec> refSpecs,
172 String... additionalPatterns) throws TransportException {
173 super(TransportGitAnon.this);
174 sock = openConnection();
175 try {
176 InputStream sIn = sock.getInputStream();
177 OutputStream sOut = sock.getOutputStream();
178
179 sIn = new BufferedInputStream(sIn);
180 sOut = new BufferedOutputStream(sOut);
181
182 init(sIn, sOut);
183 TransferConfig.ProtocolVersion gitProtocol = protocol;
184 if (gitProtocol == null) {
185 gitProtocol = TransferConfig.ProtocolVersion.V2;
186 }
187 service("git-upload-pack", pckOut, gitProtocol);
188 } catch (IOException err) {
189 close();
190 throw new TransportException(uri,
191 JGitText.get().remoteHungUpUnexpectedly, err);
192 }
193 if (!readAdvertisedRefs()) {
194 lsRefs(refSpecs, additionalPatterns);
195 }
196 }
197
198 @Override
199 public void close() {
200 super.close();
201
202 if (sock != null) {
203 try {
204 sock.close();
205 } catch (IOException err) {
206
207 } finally {
208 sock = null;
209 }
210 }
211 }
212 }
213
214 class TcpPushConnection extends BasePackPushConnection {
215 private Socket sock;
216
217 TcpPushConnection() throws TransportException {
218 super(TransportGitAnon.this);
219 sock = openConnection();
220 try {
221 InputStream sIn = sock.getInputStream();
222 OutputStream sOut = sock.getOutputStream();
223
224 sIn = new BufferedInputStream(sIn);
225 sOut = new BufferedOutputStream(sOut);
226
227 init(sIn, sOut);
228 service("git-receive-pack", pckOut, null);
229 } catch (IOException err) {
230 close();
231 throw new TransportException(uri,
232 JGitText.get().remoteHungUpUnexpectedly, err);
233 }
234 readAdvertisedRefs();
235 }
236
237 @Override
238 public void close() {
239 super.close();
240
241 if (sock != null) {
242 try {
243 sock.close();
244 } catch (IOException err) {
245
246 } finally {
247 sock = null;
248 }
249 }
250 }
251 }
252 }