Transport* - general support for push() and implementations
[egit/graphgui.git] / org.spearce.jgit / src / org / spearce / jgit / transport / TransportGitAnon.java
blob6e49083978ce1b67876a6b80bd77779ff687d7d7
1 /*
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or
9 * without modification, are permitted provided that the following
10 * conditions are met:
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
20 * - Neither the name of the Git Development Community nor the
21 * names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior
23 * written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 package org.spearce.jgit.transport;
42 import java.io.IOException;
43 import java.net.ConnectException;
44 import java.net.InetAddress;
45 import java.net.Socket;
46 import java.net.UnknownHostException;
48 import org.spearce.jgit.errors.TransportException;
49 import org.spearce.jgit.lib.Repository;
51 /**
52 * Transport through a git-daemon waiting for anonymous TCP connections.
53 * <p>
54 * This transport supports the <code>git://</code> protocol, usually run on
55 * the IANA registered port 9418. It is a popular means for distributing open
56 * source projects, as there are no authentication or authorization overheads.
58 class TransportGitAnon extends PackTransport {
59 /** IANA assigned port number for Git. */
60 static final int GIT_PORT = 9418;
62 static boolean canHandle(final URIish uri) {
63 return "git".equals(uri.getScheme());
66 TransportGitAnon(final Repository local, final URIish uri) {
67 super(local, uri);
70 @Override
71 public FetchConnection openFetch() throws TransportException {
72 return new TcpFetchConnection();
75 @Override
76 public PushConnection openPush() throws TransportException {
77 return new TcpPushConnection();
80 Socket openConnection() throws TransportException {
81 final int port = uri.getPort() > 0 ? uri.getPort() : GIT_PORT;
82 try {
83 return new Socket(InetAddress.getByName(uri.getHost()), port);
84 } catch (IOException c) {
85 final String us = uri.toString();
86 if (c instanceof UnknownHostException)
87 throw new TransportException(us + ": Unknown host");
88 if (c instanceof ConnectException)
89 throw new TransportException(us + ": " + c.getMessage());
90 throw new TransportException(us + ": " + c.getMessage(), c);
94 void service(final String name, final PacketLineOut pckOut)
95 throws IOException {
96 final StringBuilder cmd = new StringBuilder();
97 cmd.append(name);
98 cmd.append(' ');
99 cmd.append(uri.getPath());
100 cmd.append('\0');
101 cmd.append("host=");
102 cmd.append(uri.getHost());
103 cmd.append('\0');
104 pckOut.writeString(cmd.toString());
105 pckOut.flush();
108 class TcpFetchConnection extends BasePackFetchConnection {
109 private Socket sock;
111 TcpFetchConnection() throws TransportException {
112 super(TransportGitAnon.this);
113 sock = openConnection();
114 try {
115 init(sock.getInputStream(), sock.getOutputStream());
116 service("git-upload-pack", pckOut);
117 } catch (IOException err) {
118 close();
119 throw new TransportException(uri.toString()
120 + ": remote hung up unexpectedly", err);
122 readAdvertisedRefs();
125 @Override
126 public void close() {
127 super.close();
129 if (sock != null) {
130 try {
131 sock.close();
132 } catch (IOException err) {
133 // Ignore errors during close.
134 } finally {
135 sock = null;
141 class TcpPushConnection extends BasePackPushConnection {
142 private Socket sock;
144 TcpPushConnection() throws TransportException {
145 super(TransportGitAnon.this);
146 sock = openConnection();
147 try {
148 init(sock.getInputStream(), sock.getOutputStream());
149 service("git-receive-pack", pckOut);
150 } catch (IOException err) {
151 close();
152 throw new TransportException(uri.toString()
153 + ": remote hung up unexpectedly", err);
155 readAdvertisedRefs();
158 @Override
159 public void close() {
160 super.close();
162 if (sock != null) {
163 try {
164 sock.close();
165 } catch (IOException err) {
166 // Ignore errors during close.
167 } finally {
168 sock = null;