Remove System.out.println from RevWalkFilterTest
[egit/imyousuf.git] / org.spearce.jgit / src / org / spearce / jgit / transport / TransportHttp.java
blobda0dfd9c620149e1aa7f59886767f6dade383a7f
1 /*
2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org.spearce.jgit.transport;
40 import java.io.BufferedReader;
41 import java.io.FileNotFoundException;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.net.HttpURLConnection;
45 import java.net.MalformedURLException;
46 import java.net.Proxy;
47 import java.net.ProxySelector;
48 import java.net.URL;
49 import java.util.ArrayList;
50 import java.util.Collection;
51 import java.util.Map;
52 import java.util.TreeMap;
54 import org.spearce.jgit.errors.NotSupportedException;
55 import org.spearce.jgit.errors.PackProtocolException;
56 import org.spearce.jgit.errors.TransportException;
57 import org.spearce.jgit.lib.ObjectId;
58 import org.spearce.jgit.lib.Ref;
59 import org.spearce.jgit.lib.Repository;
60 import org.spearce.jgit.util.HttpSupport;
62 /**
63 * Transport over the non-Git aware HTTP and FTP protocol.
64 * <p>
65 * The HTTP transport does not require any specialized Git support on the remote
66 * (server side) repository. Object files are retrieved directly through
67 * standard HTTP GET requests, making it easy to serve a Git repository through
68 * a standard web host provider that does not offer specific support for Git.
70 * @see WalkFetchConnection
72 public class TransportHttp extends HttpTransport implements WalkTransport {
73 static boolean canHandle(final URIish uri) {
74 if (!uri.isRemote())
75 return false;
76 final String s = uri.getScheme();
77 return "http".equals(s) || "https".equals(s) || "ftp".equals(s);
80 private final URL baseUrl;
82 private final URL objectsUrl;
84 private final ProxySelector proxySelector;
86 TransportHttp(final Repository local, final URIish uri)
87 throws NotSupportedException {
88 super(local, uri);
89 try {
90 String uriString = uri.toString();
91 if (!uriString.endsWith("/"))
92 uriString += "/";
93 baseUrl = new URL(uriString);
94 objectsUrl = new URL(baseUrl, "objects/");
95 } catch (MalformedURLException e) {
96 throw new NotSupportedException("Invalid URL " + uri, e);
98 proxySelector = ProxySelector.getDefault();
101 @Override
102 public FetchConnection openFetch() throws TransportException {
103 final HttpObjectDB c = new HttpObjectDB(objectsUrl);
104 final WalkFetchConnection r = new WalkFetchConnection(this, c);
105 r.available(c.readAdvertisedRefs());
106 return r;
109 @Override
110 public PushConnection openPush() throws NotSupportedException,
111 TransportException {
112 final String s = getURI().getScheme();
113 throw new NotSupportedException("Push not supported over " + s + ".");
116 @Override
117 public void close() {
118 // No explicit connections are maintained.
121 class HttpObjectDB extends WalkRemoteObjectDatabase {
122 private final URL objectsUrl;
124 HttpObjectDB(final URL b) {
125 objectsUrl = b;
128 @Override
129 URIish getURI() {
130 return new URIish(objectsUrl);
133 @Override
134 Collection<WalkRemoteObjectDatabase> getAlternates() throws IOException {
135 try {
136 return readAlternates(INFO_HTTP_ALTERNATES);
137 } catch (FileNotFoundException err) {
138 // Fall through.
141 try {
142 return readAlternates(INFO_ALTERNATES);
143 } catch (FileNotFoundException err) {
144 // Fall through.
147 return null;
150 @Override
151 WalkRemoteObjectDatabase openAlternate(final String location)
152 throws IOException {
153 return new HttpObjectDB(new URL(objectsUrl, location));
156 @Override
157 Collection<String> getPackNames() throws IOException {
158 final Collection<String> packs = new ArrayList<String>();
159 try {
160 final BufferedReader br = openReader(INFO_PACKS);
161 try {
162 for (;;) {
163 final String s = br.readLine();
164 if (s == null || s.length() == 0)
165 break;
166 if (!s.startsWith("P pack-") || !s.endsWith(".pack"))
167 throw invalidAdvertisement(s);
168 packs.add(s.substring(2));
170 return packs;
171 } finally {
172 br.close();
174 } catch (FileNotFoundException err) {
175 return packs;
179 @Override
180 FileStream open(final String path) throws IOException {
181 final URL base = objectsUrl;
182 final URL u = new URL(base, path);
183 final Proxy proxy = HttpSupport.proxyFor(proxySelector, u);
184 final HttpURLConnection c;
186 c = (HttpURLConnection) u.openConnection(proxy);
187 switch (HttpSupport.response(c)) {
188 case HttpURLConnection.HTTP_OK:
189 final InputStream in = c.getInputStream();
190 final int len = c.getContentLength();
191 return new FileStream(in, len);
192 case HttpURLConnection.HTTP_NOT_FOUND:
193 throw new FileNotFoundException(u.toString());
194 default:
195 throw new IOException(u.toString() + ": "
196 + HttpSupport.response(c) + " "
197 + c.getResponseMessage());
201 Map<String, Ref> readAdvertisedRefs() throws TransportException {
202 try {
203 final BufferedReader br = openReader(INFO_REFS);
204 try {
205 return readAdvertisedImpl(br);
206 } finally {
207 br.close();
209 } catch (IOException err) {
210 try {
211 throw new TransportException(new URL(objectsUrl, INFO_REFS)
212 + ": cannot read available refs", err);
213 } catch (MalformedURLException mue) {
214 throw new TransportException(objectsUrl + INFO_REFS
215 + ": cannot read available refs", err);
220 private Map<String, Ref> readAdvertisedImpl(final BufferedReader br)
221 throws IOException, PackProtocolException {
222 final TreeMap<String, Ref> avail = new TreeMap<String, Ref>();
223 for (;;) {
224 String line = br.readLine();
225 if (line == null)
226 break;
228 final int tab = line.indexOf('\t');
229 if (tab < 0)
230 throw invalidAdvertisement(line);
232 String name;
233 final ObjectId id;
235 name = line.substring(tab + 1);
236 id = ObjectId.fromString(line.substring(0, tab));
237 if (name.endsWith("^{}")) {
238 name = name.substring(0, name.length() - 3);
239 final Ref prior = avail.get(name);
240 if (prior == null)
241 throw outOfOrderAdvertisement(name);
243 if (prior.getPeeledObjectId() != null)
244 throw duplicateAdvertisement(name + "^{}");
246 avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior
247 .getObjectId(), id, true));
248 } else {
249 final Ref prior = avail.put(name, new Ref(
250 Ref.Storage.NETWORK, name, id));
251 if (prior != null)
252 throw duplicateAdvertisement(name);
255 return avail;
258 private PackProtocolException outOfOrderAdvertisement(final String n) {
259 return new PackProtocolException("advertisement of " + n
260 + "^{} came before " + n);
263 private PackProtocolException invalidAdvertisement(final String n) {
264 return new PackProtocolException("invalid advertisement of " + n);
267 private PackProtocolException duplicateAdvertisement(final String n) {
268 return new PackProtocolException("duplicate advertisements of " + n);
271 @Override
272 void close() {
273 // We do not maintain persistent connections.