1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.http.test;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertNull;
50 import static org.junit.Assert.assertTrue;
51 import static org.junit.Assert.fail;
52
53 import java.io.File;
54 import java.net.URI;
55 import java.util.List;
56
57 import javax.servlet.http.HttpServletRequest;
58
59 import org.eclipse.jetty.servlet.DefaultServlet;
60 import org.eclipse.jetty.servlet.ServletContextHandler;
61 import org.eclipse.jetty.servlet.ServletHolder;
62 import org.eclipse.jgit.errors.NoRemoteRepositoryException;
63 import org.eclipse.jgit.errors.RepositoryNotFoundException;
64 import org.eclipse.jgit.errors.TransportException;
65 import org.eclipse.jgit.http.server.GitServlet;
66 import org.eclipse.jgit.internal.JGitText;
67 import org.eclipse.jgit.junit.TestRepository;
68 import org.eclipse.jgit.junit.http.AccessEvent;
69 import org.eclipse.jgit.junit.http.AppServer;
70 import org.eclipse.jgit.junit.http.HttpTestCase;
71 import org.eclipse.jgit.lib.Constants;
72 import org.eclipse.jgit.lib.Ref;
73 import org.eclipse.jgit.lib.RefUpdate;
74 import org.eclipse.jgit.lib.Repository;
75 import org.eclipse.jgit.lib.StoredConfig;
76 import org.eclipse.jgit.revwalk.RevCommit;
77 import org.eclipse.jgit.transport.FetchConnection;
78 import org.eclipse.jgit.transport.Transport;
79 import org.eclipse.jgit.transport.URIish;
80 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
81 import org.eclipse.jgit.transport.resolver.RepositoryResolver;
82 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
83 import org.junit.Before;
84 import org.junit.Test;
85
86 public class HttpClientTests extends HttpTestCase {
87 private TestRepository<Repository> remoteRepository;
88
89 private URIish dumbAuthNoneURI;
90
91 private URIish dumbAuthBasicURI;
92
93 private URIish smartAuthNoneURI;
94
95 private URIish smartAuthBasicURI;
96
97 @Before
98 public void setUp() throws Exception {
99 super.setUp();
100
101 remoteRepository = createTestRepository();
102 remoteRepository.update(master, remoteRepository.commit().create());
103
104 ServletContextHandler dNone = dumb("/dnone");
105 ServletContextHandler dBasic = server.authBasic(dumb("/dbasic"));
106
107 ServletContextHandler sNone = smart("/snone");
108 ServletContextHandler sBasic = server.authBasic(smart("/sbasic"));
109
110 server.setUp();
111
112 final String srcName = nameOf(remoteRepository.getRepository());
113 dumbAuthNoneURI = toURIish(dNone, srcName);
114 dumbAuthBasicURI = toURIish(dBasic, srcName);
115
116 smartAuthNoneURI = toURIish(sNone, srcName);
117 smartAuthBasicURI = toURIish(sBasic, srcName);
118 }
119
120 private ServletContextHandler dumb(final String path) {
121 final File srcGit = remoteRepository.getRepository().getDirectory();
122 final URI base = srcGit.getParentFile().toURI();
123
124 ServletContextHandler ctx = server.addContext(path);
125 ctx.setResourceBase(base.toString());
126 ServletHolder holder = ctx.addServlet(DefaultServlet.class, "/");
127
128 holder.setInitParameter("aliases", "true");
129 return ctx;
130 }
131
132 private ServletContextHandler smart(final String path) {
133 GitServlet gs = new GitServlet();
134 gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
135 public Repository open(HttpServletRequest req, String name)
136 throws RepositoryNotFoundException,
137 ServiceNotEnabledException {
138 final Repository db = remoteRepository.getRepository();
139 if (!name.equals(nameOf(db)))
140 throw new RepositoryNotFoundException(name);
141
142 db.incrementOpen();
143 return db;
144 }
145 });
146
147 ServletContextHandler ctx = server.addContext(path);
148 ctx.addServlet(new ServletHolder(gs), "/*");
149 return ctx;
150 }
151
152 private static String nameOf(final Repository db) {
153 return db.getDirectory().getName();
154 }
155
156 @Test
157 public void testRepositoryNotFound_Dumb() throws Exception {
158 URIish uri = toURIish("/dumb.none/not-found");
159 Repository dst = createBareRepository();
160 try (Transport t = Transport.open(dst, uri)) {
161 try {
162 t.openFetch();
163 fail("connection opened to not found repository");
164 } catch (NoRemoteRepositoryException err) {
165 String exp = uri + ": " + uri
166 + "/info/refs?service=git-upload-pack not found";
167 assertEquals(exp, err.getMessage());
168 }
169 }
170 }
171
172 @Test
173 public void testRepositoryNotFound_Smart() throws Exception {
174 URIish uri = toURIish("/smart.none/not-found");
175 Repository dst = createBareRepository();
176 try (Transport t = Transport.open(dst, uri)) {
177 try {
178 t.openFetch();
179 fail("connection opened to not found repository");
180 } catch (NoRemoteRepositoryException err) {
181 String exp = uri + ": " + uri
182 + "/info/refs?service=git-upload-pack not found";
183 assertEquals(exp, err.getMessage());
184 }
185 }
186 }
187
188 @Test
189 public void testListRemote_Dumb_DetachedHEAD() throws Exception {
190 Repository src = remoteRepository.getRepository();
191 RefUpdate u = src.updateRef(Constants.HEAD, true);
192 RevCommit Q = remoteRepository.commit().message("Q").create();
193 u.setNewObjectId(Q);
194 assertEquals(RefUpdate.Result.FORCED, u.forceUpdate());
195
196 Repository dst = createBareRepository();
197 Ref head;
198 try (Transport t = Transport.open(dst, dumbAuthNoneURI);
199 FetchConnection c = t.openFetch()) {
200 head = c.getRef(Constants.HEAD);
201 }
202 assertNotNull("has " + Constants.HEAD, head);
203 assertEquals(Q, head.getObjectId());
204 }
205
206 @Test
207 public void testListRemote_Dumb_NoHEAD() throws Exception {
208 Repository src = remoteRepository.getRepository();
209 File headref = new File(src.getDirectory(), Constants.HEAD);
210 assertTrue("HEAD used to be present", headref.delete());
211 assertFalse("HEAD is gone", headref.exists());
212
213 Repository dst = createBareRepository();
214 Ref head;
215 try (Transport t = Transport.open(dst, dumbAuthNoneURI);
216 FetchConnection c = t.openFetch()) {
217 head = c.getRef(Constants.HEAD);
218 }
219 assertNull("has no " + Constants.HEAD, head);
220 }
221
222 @Test
223 public void testListRemote_Smart_DetachedHEAD() throws Exception {
224 Repository src = remoteRepository.getRepository();
225 RefUpdate u = src.updateRef(Constants.HEAD, true);
226 RevCommit Q = remoteRepository.commit().message("Q").create();
227 u.setNewObjectId(Q);
228 assertEquals(RefUpdate.Result.FORCED, u.forceUpdate());
229
230 Repository dst = createBareRepository();
231 Ref head;
232 try (Transport t = Transport.open(dst, smartAuthNoneURI);
233 FetchConnection c = t.openFetch()) {
234 head = c.getRef(Constants.HEAD);
235 }
236 assertNotNull("has " + Constants.HEAD, head);
237 assertEquals(Q, head.getObjectId());
238 }
239
240 @Test
241 public void testListRemote_Smart_WithQueryParameters() throws Exception {
242 URIish myURI = toURIish("/snone/do?r=1&p=test.git");
243 Repository dst = createBareRepository();
244 try (Transport t = Transport.open(dst, myURI)) {
245 try {
246 t.openFetch();
247 fail("test did not fail to find repository as expected");
248 } catch (NoRemoteRepositoryException err) {
249
250 }
251 }
252
253 List<AccessEvent> requests = getRequests();
254 assertEquals(1, requests.size());
255
256 AccessEvent info = requests.get(0);
257 assertEquals("GET", info.getMethod());
258 assertEquals("/snone/do", info.getPath());
259 assertEquals(3, info.getParameters().size());
260 assertEquals("1", info.getParameter("r"));
261 assertEquals("test.git/info/refs", info.getParameter("p"));
262 assertEquals("git-upload-pack", info.getParameter("service"));
263 assertEquals(404, info.getStatus());
264 }
265
266 @Test
267 public void testListRemote_Dumb_NeedsAuth() throws Exception {
268 Repository dst = createBareRepository();
269 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
270 try {
271 t.openFetch();
272 fail("connection opened even info/refs needs auth basic");
273 } catch (TransportException err) {
274 String exp = dumbAuthBasicURI + ": "
275 + JGitText.get().noCredentialsProvider;
276 assertEquals(exp, err.getMessage());
277 }
278 }
279 }
280
281 @Test
282 public void testListRemote_Dumb_Auth() throws Exception {
283 Repository dst = createBareRepository();
284 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
285 t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
286 AppServer.username, AppServer.password));
287 t.openFetch().close();
288 }
289 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
290 t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
291 AppServer.username, ""));
292 try {
293 t.openFetch();
294 fail("connection opened even info/refs needs auth basic and we provide wrong password");
295 } catch (TransportException err) {
296 String exp = dumbAuthBasicURI + ": "
297 + JGitText.get().notAuthorized;
298 assertEquals(exp, err.getMessage());
299 }
300 }
301 }
302
303 @Test
304 public void testListRemote_Smart_UploadPackNeedsAuth() throws Exception {
305 Repository dst = createBareRepository();
306 try (Transport t = Transport.open(dst, smartAuthBasicURI)) {
307 try {
308 t.openFetch();
309 fail("connection opened even though service disabled");
310 } catch (TransportException err) {
311 String exp = smartAuthBasicURI + ": "
312 + JGitText.get().noCredentialsProvider;
313 assertEquals(exp, err.getMessage());
314 }
315 }
316 }
317
318 @Test
319 public void testListRemote_Smart_UploadPackDisabled() throws Exception {
320 Repository src = remoteRepository.getRepository();
321 final StoredConfig cfg = src.getConfig();
322 cfg.setBoolean("http", null, "uploadpack", false);
323 cfg.save();
324
325 Repository dst = createBareRepository();
326 try (Transport t = Transport.open(dst, smartAuthNoneURI)) {
327 try {
328 t.openFetch();
329 fail("connection opened even though service disabled");
330 } catch (TransportException err) {
331 String exp = smartAuthNoneURI + ": "
332 + JGitText.get().serviceNotEnabledNoName;
333 assertEquals(exp, err.getMessage());
334 }
335 }
336 }
337
338 @Test
339 public void testListRemoteWithoutLocalRepository() throws Exception {
340 try (Transport t = Transport.open(smartAuthNoneURI);
341 FetchConnection c = t.openFetch()) {
342 Ref head = c.getRef(Constants.HEAD);
343 assertNotNull(head);
344 }
345 }
346 }