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 @Override
98 @Before
99 public void setUp() throws Exception {
100 super.setUp();
101
102 remoteRepository = createTestRepository();
103 remoteRepository.update(master, remoteRepository.commit().create());
104
105 ServletContextHandler dNone = dumb("/dnone");
106 ServletContextHandler dBasic = server.authBasic(dumb("/dbasic"));
107
108 ServletContextHandler sNone = smart("/snone");
109 ServletContextHandler sBasic = server.authBasic(smart("/sbasic"));
110
111 server.setUp();
112
113 final String srcName = nameOf(remoteRepository.getRepository());
114 dumbAuthNoneURI = toURIish(dNone, srcName);
115 dumbAuthBasicURI = toURIish(dBasic, srcName);
116
117 smartAuthNoneURI = toURIish(sNone, srcName);
118 smartAuthBasicURI = toURIish(sBasic, srcName);
119 }
120
121 private ServletContextHandler dumb(final String path) {
122 final File srcGit = remoteRepository.getRepository().getDirectory();
123 final URI base = srcGit.getParentFile().toURI();
124
125 ServletContextHandler ctx = server.addContext(path);
126 ctx.setResourceBase(base.toString());
127 ServletHolder holder = ctx.addServlet(DefaultServlet.class, "/");
128
129 holder.setInitParameter("aliases", "true");
130 return ctx;
131 }
132
133 private ServletContextHandler smart(final String path) {
134 GitServlet gs = new GitServlet();
135 gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
136 @Override
137 public Repository open(HttpServletRequest req, String name)
138 throws RepositoryNotFoundException,
139 ServiceNotEnabledException {
140 final Repository db = remoteRepository.getRepository();
141 if (!name.equals(nameOf(db)))
142 throw new RepositoryNotFoundException(name);
143
144 db.incrementOpen();
145 return db;
146 }
147 });
148
149 ServletContextHandler ctx = server.addContext(path);
150 ctx.addServlet(new ServletHolder(gs), "/*");
151 return ctx;
152 }
153
154 private static String nameOf(final Repository db) {
155 return db.getDirectory().getName();
156 }
157
158 @Test
159 public void testRepositoryNotFound_Dumb() throws Exception {
160 URIish uri = toURIish("/dumb.none/not-found");
161 Repository dst = createBareRepository();
162 try (Transport t = Transport.open(dst, uri)) {
163 try {
164 t.openFetch();
165 fail("connection opened to not found repository");
166 } catch (NoRemoteRepositoryException err) {
167 String exp = uri + ": " + uri
168 + "/info/refs?service=git-upload-pack not found";
169 assertEquals(exp, err.getMessage());
170 }
171 }
172 }
173
174 @Test
175 public void testRepositoryNotFound_Smart() throws Exception {
176 URIish uri = toURIish("/smart.none/not-found");
177 Repository dst = createBareRepository();
178 try (Transport t = Transport.open(dst, uri)) {
179 try {
180 t.openFetch();
181 fail("connection opened to not found repository");
182 } catch (NoRemoteRepositoryException err) {
183 String exp = uri + ": " + uri
184 + "/info/refs?service=git-upload-pack not found";
185 assertEquals(exp, err.getMessage());
186 }
187 }
188 }
189
190 @Test
191 public void testListRemote_Dumb_DetachedHEAD() throws Exception {
192 Repository src = remoteRepository.getRepository();
193 RefUpdate u = src.updateRef(Constants.HEAD, true);
194 RevCommit Q = remoteRepository.commit().message("Q").create();
195 u.setNewObjectId(Q);
196 assertEquals(RefUpdate.Result.FORCED, u.forceUpdate());
197
198 Repository dst = createBareRepository();
199 Ref head;
200 try (Transport t = Transport.open(dst, dumbAuthNoneURI);
201 FetchConnection c = t.openFetch()) {
202 head = c.getRef(Constants.HEAD);
203 }
204 assertNotNull("has " + Constants.HEAD, head);
205 assertEquals(Q, head.getObjectId());
206 }
207
208 @Test
209 public void testListRemote_Dumb_NoHEAD() throws Exception {
210 Repository src = remoteRepository.getRepository();
211 File headref = new File(src.getDirectory(), Constants.HEAD);
212 assertTrue("HEAD used to be present", headref.delete());
213 assertFalse("HEAD is gone", headref.exists());
214
215 Repository dst = createBareRepository();
216 Ref head;
217 try (Transport t = Transport.open(dst, dumbAuthNoneURI);
218 FetchConnection c = t.openFetch()) {
219 head = c.getRef(Constants.HEAD);
220 }
221 assertNull("has no " + Constants.HEAD, head);
222 }
223
224 @Test
225 public void testListRemote_Smart_DetachedHEAD() throws Exception {
226 Repository src = remoteRepository.getRepository();
227 RefUpdate u = src.updateRef(Constants.HEAD, true);
228 RevCommit Q = remoteRepository.commit().message("Q").create();
229 u.setNewObjectId(Q);
230 assertEquals(RefUpdate.Result.FORCED, u.forceUpdate());
231
232 Repository dst = createBareRepository();
233 Ref head;
234 try (Transport t = Transport.open(dst, smartAuthNoneURI);
235 FetchConnection c = t.openFetch()) {
236 head = c.getRef(Constants.HEAD);
237 }
238 assertNotNull("has " + Constants.HEAD, head);
239 assertEquals(Q, head.getObjectId());
240 }
241
242 @Test
243 public void testListRemote_Smart_WithQueryParameters() throws Exception {
244 URIish myURI = toURIish("/snone/do?r=1&p=test.git");
245 Repository dst = createBareRepository();
246 try (Transport t = Transport.open(dst, myURI)) {
247 try {
248 t.openFetch();
249 fail("test did not fail to find repository as expected");
250 } catch (NoRemoteRepositoryException err) {
251
252 }
253 }
254
255 List<AccessEvent> requests = getRequests();
256 assertEquals(1, requests.size());
257
258 AccessEvent info = requests.get(0);
259 assertEquals("GET", info.getMethod());
260 assertEquals("/snone/do", info.getPath());
261 assertEquals(3, info.getParameters().size());
262 assertEquals("1", info.getParameter("r"));
263 assertEquals("test.git/info/refs", info.getParameter("p"));
264 assertEquals("git-upload-pack", info.getParameter("service"));
265 assertEquals(404, info.getStatus());
266 }
267
268 @Test
269 public void testListRemote_Dumb_NeedsAuth() throws Exception {
270 Repository dst = createBareRepository();
271 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
272 try {
273 t.openFetch();
274 fail("connection opened even info/refs needs auth basic");
275 } catch (TransportException err) {
276 String exp = dumbAuthBasicURI + ": "
277 + JGitText.get().noCredentialsProvider;
278 assertEquals(exp, err.getMessage());
279 }
280 }
281 }
282
283 @Test
284 public void testListRemote_Dumb_Auth() throws Exception {
285 Repository dst = createBareRepository();
286 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
287 t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
288 AppServer.username, AppServer.password));
289 t.openFetch().close();
290 }
291 try (Transport t = Transport.open(dst, dumbAuthBasicURI)) {
292 t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
293 AppServer.username, ""));
294 try {
295 t.openFetch();
296 fail("connection opened even info/refs needs auth basic and we provide wrong password");
297 } catch (TransportException err) {
298 String exp = dumbAuthBasicURI + ": "
299 + JGitText.get().notAuthorized;
300 assertEquals(exp, err.getMessage());
301 }
302 }
303 }
304
305 @Test
306 public void testListRemote_Smart_UploadPackNeedsAuth() throws Exception {
307 Repository dst = createBareRepository();
308 try (Transport t = Transport.open(dst, smartAuthBasicURI)) {
309 try {
310 t.openFetch();
311 fail("connection opened even though service disabled");
312 } catch (TransportException err) {
313 String exp = smartAuthBasicURI + ": "
314 + JGitText.get().noCredentialsProvider;
315 assertEquals(exp, err.getMessage());
316 }
317 }
318 }
319
320 @Test
321 public void testListRemote_Smart_UploadPackDisabled() throws Exception {
322 Repository src = remoteRepository.getRepository();
323 final StoredConfig cfg = src.getConfig();
324 cfg.setBoolean("http", null, "uploadpack", false);
325 cfg.save();
326
327 Repository dst = createBareRepository();
328 try (Transport t = Transport.open(dst, smartAuthNoneURI)) {
329 try {
330 t.openFetch();
331 fail("connection opened even though service disabled");
332 } catch (TransportException err) {
333 String exp = smartAuthNoneURI + ": "
334 + JGitText.get().serviceNotEnabledNoName;
335 assertEquals(exp, err.getMessage());
336 }
337 }
338 }
339
340 @Test
341 public void testListRemoteWithoutLocalRepository() throws Exception {
342 try (Transport t = Transport.open(smartAuthNoneURI);
343 FetchConnection c = t.openFetch()) {
344 Ref head = c.getRef(Constants.HEAD);
345 assertNotNull(head);
346 }
347 }
348 }