View Javadoc
1   /*
2    * Copyright (C) 2010, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.http.test;
12  
13  import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT;
14  import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA;
15  import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT;
16  import static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertFalse;
18  import static org.junit.Assert.assertNotNull;
19  import static org.junit.Assert.assertTrue;
20  import static org.junit.Assert.fail;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.net.URI;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.eclipse.jetty.servlet.DefaultServlet;
29  import org.eclipse.jetty.servlet.ServletContextHandler;
30  import org.eclipse.jetty.servlet.ServletHolder;
31  import org.eclipse.jgit.errors.NotSupportedException;
32  import org.eclipse.jgit.junit.TestRepository;
33  import org.eclipse.jgit.junit.http.AccessEvent;
34  import org.eclipse.jgit.lib.Constants;
35  import org.eclipse.jgit.lib.NullProgressMonitor;
36  import org.eclipse.jgit.lib.Ref;
37  import org.eclipse.jgit.lib.Repository;
38  import org.eclipse.jgit.lib.StoredConfig;
39  import org.eclipse.jgit.revwalk.RevBlob;
40  import org.eclipse.jgit.revwalk.RevCommit;
41  import org.eclipse.jgit.transport.FetchConnection;
42  import org.eclipse.jgit.transport.HttpTransport;
43  import org.eclipse.jgit.transport.Transport;
44  import org.eclipse.jgit.transport.TransportHttp;
45  import org.eclipse.jgit.transport.URIish;
46  import org.eclipse.jgit.transport.http.HttpConnectionFactory;
47  import org.junit.Before;
48  import org.junit.Test;
49  
50  public class DumbClientDumbServerTest extends AllFactoriesHttpTestCase {
51  	private Repository remoteRepository;
52  
53  	private URIish remoteURI;
54  
55  	private RevBlob A_txt;
56  
57  	private RevCommit A, B;
58  
59  	public DumbClientDumbServerTest(HttpConnectionFactory cf) {
60  		super(cf);
61  	}
62  
63  	@Override
64  	@Before
65  	public void setUp() throws Exception {
66  		super.setUp();
67  
68  		final TestRepository<Repository> src = createTestRepository();
69  		final File srcGit = src.getRepository().getDirectory();
70  		final URI base = srcGit.getParentFile().toURI();
71  
72  		ServletContextHandler app = server.addContext("/git");
73  		app.setResourceBase(base.toString());
74  		ServletHolder holder = app.addServlet(DefaultServlet.class, "/");
75  		// The tmp directory is symlinked on OS X
76  		holder.setInitParameter("aliases", "true");
77  		server.setUp();
78  
79  		remoteRepository = src.getRepository();
80  		remoteURI = toURIish(app, srcGit.getName());
81  		StoredConfig cfg = remoteRepository.getConfig();
82  		cfg.setInt("protocol", null, "version", 0);
83  		cfg.save();
84  
85  		A_txt = src.blob("A");
86  		A = src.commit().add("A_txt", A_txt).create();
87  		B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create();
88  		src.update(master, B);
89  	}
90  
91  	@Test
92  	public void testListRemote() throws IOException {
93  		Repository dst = createBareRepository();
94  
95  		assertEquals("http", remoteURI.getScheme());
96  
97  		Map<String, Ref> map;
98  		try (Transport t = Transport.open(dst, remoteURI)) {
99  			// I didn't make up these public interface names, I just
100 			// approved them for inclusion into the code base. Sorry.
101 			// --spearce
102 			//
103 			assertTrue("isa TransportHttp", t instanceof TransportHttp);
104 			assertTrue("isa HttpTransport", t instanceof HttpTransport);
105 
106 			try (FetchConnection c = t.openFetch()) {
107 				map = c.getRefsMap();
108 			}
109 		}
110 
111 		assertNotNull("have map of refs", map);
112 		assertEquals(2, map.size());
113 
114 		assertNotNull("has " + master, map.get(master));
115 		assertEquals(B, map.get(master).getObjectId());
116 
117 		assertNotNull("has " + Constants.HEAD, map.get(Constants.HEAD));
118 		assertEquals(B, map.get(Constants.HEAD).getObjectId());
119 
120 		List<AccessEvent> requests = getRequests();
121 		assertEquals(2, requests.size());
122 		assertEquals(0, getRequests(remoteURI, "git-upload-pack").size());
123 
124 		AccessEvent info = requests.get(0);
125 		assertEquals("GET", info.getMethod());
126 		assertEquals(join(remoteURI, "info/refs"), info.getPath());
127 		assertEquals(1, info.getParameters().size());
128 		assertEquals("git-upload-pack", info.getParameter("service"));
129 		assertEquals("no-cache", info.getRequestHeader(HDR_PRAGMA));
130 		assertNotNull("has user-agent", info.getRequestHeader(HDR_USER_AGENT));
131 		assertTrue("is jgit agent", info.getRequestHeader(HDR_USER_AGENT)
132 				.startsWith("JGit/"));
133 		assertEquals("application/x-git-upload-pack-advertisement, */*", info
134 				.getRequestHeader(HDR_ACCEPT));
135 		assertEquals(200, info.getStatus());
136 
137 		AccessEvent head = requests.get(1);
138 		assertEquals("GET", head.getMethod());
139 		assertEquals(join(remoteURI, "HEAD"), head.getPath());
140 		assertEquals(0, head.getParameters().size());
141 		assertEquals("no-cache", head.getRequestHeader(HDR_PRAGMA));
142 		assertNotNull("has user-agent", head.getRequestHeader(HDR_USER_AGENT));
143 		assertTrue("is jgit agent", head.getRequestHeader(HDR_USER_AGENT)
144 				.startsWith("JGit/"));
145 		assertEquals(200, head.getStatus());
146 	}
147 
148 	@Test
149 	public void testInitialClone_Loose() throws Exception {
150 		Repository dst = createBareRepository();
151 		assertFalse(dst.getObjectDatabase().has(A_txt));
152 
153 		try (Transport t = Transport.open(dst, remoteURI)) {
154 			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
155 		}
156 
157 		assertTrue(dst.getObjectDatabase().has(A_txt));
158 		assertEquals(B, dst.exactRef(master).getObjectId());
159 		fsck(dst, B);
160 
161 		List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt));
162 		assertEquals(1, loose.size());
163 		assertEquals("GET", loose.get(0).getMethod());
164 		assertEquals(0, loose.get(0).getParameters().size());
165 		assertEquals(200, loose.get(0).getStatus());
166 	}
167 
168 	@Test
169 	public void testInitialClone_Packed() throws Exception {
170 		try (TestRepository<Repository> tr = new TestRepository<>(
171 				remoteRepository)) {
172 			tr.packAndPrune();
173 		}
174 
175 		Repository dst = createBareRepository();
176 		assertFalse(dst.getObjectDatabase().has(A_txt));
177 
178 		try (Transport t = Transport.open(dst, remoteURI)) {
179 			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
180 		}
181 
182 		assertTrue(dst.getObjectDatabase().has(A_txt));
183 		assertEquals(B, dst.exactRef(master).getObjectId());
184 		fsck(dst, B);
185 
186 		List<AccessEvent> req;
187 		AccessEvent event;
188 
189 		req = getRequests(loose(remoteURI, B));
190 		assertEquals(1, req.size());
191 		event = req.get(0);
192 		assertEquals("GET", event.getMethod());
193 		assertEquals(0, event.getParameters().size());
194 		assertEquals(404, event.getStatus());
195 
196 		req = getRequests(join(remoteURI, "objects/info/packs"));
197 		assertEquals(1, req.size());
198 		event = req.get(0);
199 		assertEquals("GET", event.getMethod());
200 		assertEquals(0, event.getParameters().size());
201 		assertEquals("no-cache", event.getRequestHeader(HDR_PRAGMA));
202 		assertNotNull("has user-agent", event.getRequestHeader(HDR_USER_AGENT));
203 		assertTrue("is jgit agent", event.getRequestHeader(HDR_USER_AGENT)
204 				.startsWith("JGit/"));
205 		assertEquals(200, event.getStatus());
206 	}
207 
208 	@Test
209 	public void testPushNotSupported() throws Exception {
210 		final TestRepository src = createTestRepository();
211 		final RevCommit Q = src.commit().create();
212 		final Repository db = src.getRepository();
213 
214 		try (Transport t = Transport.open(db, remoteURI)) {
215 			try {
216 				t.push(NullProgressMonitor.INSTANCE, push(src, Q));
217 				fail("push incorrectly completed against a dumb server");
218 			} catch (NotSupportedException nse) {
219 				String exp = "remote does not support smart HTTP push";
220 				assertEquals(exp, nse.getMessage());
221 			}
222 		}
223 	}
224 }