/*
 * Copyright (C) 2010, 2017 Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.http.test;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_LENGTH;
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jgit.errors.RemoteRepositoryException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.http.server.GitServlet;
import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRng;
import org.eclipse.jgit.junit.http.AccessEvent;
import org.eclipse.jgit.junit.http.AppServer;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook;
import org.eclipse.jgit.transport.AdvertiseRefsHook;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchConnection;
import org.eclipse.jgit.transport.HttpTransport;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.TransportHttp;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UploadPack;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.transport.http.HttpConnectionFactory;
import org.eclipse.jgit.util.HttpSupport;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Before;
import org.junit.Test;

public class SmartClientSmartServerTest extends AllFactoriesHttpTestCase {
	private static final String HDR_TRANSFER_ENCODING = "Transfer-Encoding";

	private AdvertiseRefsHook advertiseRefsHook;

	private Repository remoteRepository;

	private CredentialsProvider testCredentials = new UsernamePasswordCredentialsProvider(
			AppServer.username, AppServer.password);

	private URIish remoteURI;

	private URIish brokenURI;

	private URIish redirectURI;

	private URIish authURI;

	private URIish authOnPostURI;

	private RevBlob A_txt;

	private RevCommit A, B, unreachableCommit;

	public SmartClientSmartServerTest(HttpConnectionFactory cf) {
		super(cf);
	}

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();

		final TestRepository<Repository> src = createTestRepository();
		final String srcName = src.getRepository().getDirectory().getName();
		src.getRepository()
				.getConfig()
				.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true);

		GitServlet gs = new GitServlet();
		gs.setUploadPackFactory((HttpServletRequest req, Repository db) -> {
			DefaultUploadPackFactory f = new DefaultUploadPackFactory();
			UploadPack up = f.create(req, db);
			if (advertiseRefsHook != null) {
				up.setAdvertiseRefsHook(advertiseRefsHook);
			}
			return up;
		});

		ServletContextHandler app = addNormalContext(gs, src, srcName);

		ServletContextHandler broken = addBrokenContext(gs, srcName);

		ServletContextHandler redirect = addRedirectContext(gs);

		ServletContextHandler auth = addAuthContext(gs, "auth");

		ServletContextHandler authOnPost = addAuthContext(gs, "pauth", "POST");

		server.setUp();

		remoteRepository = src.getRepository();
		remoteURI = toURIish(app, srcName);
		brokenURI = toURIish(broken, srcName);
		redirectURI = toURIish(redirect, srcName);
		authURI = toURIish(auth, srcName);
		authOnPostURI = toURIish(authOnPost, srcName);

		A_txt = src.blob("A");
		A = src.commit().add("A_txt", A_txt).create();
		B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create();
		src.update(master, B);

		unreachableCommit = src.commit().add("A_txt", A_txt).create();

		src.update("refs/garbage/a/very/long/ref/name/to/compress", B);
	}

	private ServletContextHandler addNormalContext(GitServlet gs, TestRepository<Repository> src, String srcName) {
		ServletContextHandler app = server.addContext("/git");
		app.addFilter(new FilterHolder(new Filter() {

			@Override
			public void init(FilterConfig filterConfig)
					throws ServletException {
				// empty
			}

			// Does an internal forward for GET requests containing "/post/",
			// and issues a 301 redirect on POST requests for such URLs. Used
			// in the POST redirect tests.
			@Override
			public void doFilter(ServletRequest request,
					ServletResponse response, FilterChain chain)
					throws IOException, ServletException {
				final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
				final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
				final StringBuffer fullUrl = httpServletRequest.getRequestURL();
				if (httpServletRequest.getQueryString() != null) {
					fullUrl.append("?")
							.append(httpServletRequest.getQueryString());
				}
				String urlString = fullUrl.toString();
				if ("POST".equalsIgnoreCase(httpServletRequest.getMethod())) {
					httpServletResponse.setStatus(
							HttpServletResponse.SC_MOVED_PERMANENTLY);
					httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
							urlString.replace("/post/", "/"));
				} else {
					String path = httpServletRequest.getPathInfo();
					path = path.replace("/post/", "/");
					if (httpServletRequest.getQueryString() != null) {
						path += '?' + httpServletRequest.getQueryString();
					}
					RequestDispatcher dispatcher = httpServletRequest
							.getRequestDispatcher(path);
					dispatcher.forward(httpServletRequest, httpServletResponse);
				}
			}

			@Override
			public void destroy() {
				// empty
			}
		}), "/post/*", EnumSet.of(DispatcherType.REQUEST));
		gs.setRepositoryResolver(new TestRepositoryResolver(src, srcName));
		app.addServlet(new ServletHolder(gs), "/*");
		return app;
	}

	private ServletContextHandler addBrokenContext(GitServlet gs,
			String srcName) {
		ServletContextHandler broken = server.addContext("/bad");
		broken.addFilter(new FilterHolder(new Filter() {

			@Override
			public void doFilter(ServletRequest request,
					ServletResponse response, FilterChain chain)
					throws IOException, ServletException {
				final HttpServletResponse r = (HttpServletResponse) response;
				r.setContentType("text/plain");
				r.setCharacterEncoding(UTF_8.name());
				try (PrintWriter w = r.getWriter()) {
					w.print("OK");
				}
			}

			@Override
			public void init(FilterConfig filterConfig)
					throws ServletException {
				// empty
			}

			@Override
			public void destroy() {
				// empty
			}
		}), "/" + srcName + "/git-upload-pack",
				EnumSet.of(DispatcherType.REQUEST));
		broken.addServlet(new ServletHolder(gs), "/*");
		return broken;
	}

	private ServletContextHandler addAuthContext(GitServlet gs,
			String contextPath, String... methods) {
		ServletContextHandler auth = server.addContext('/' + contextPath);
		auth.addServlet(new ServletHolder(gs), "/*");
		return server.authBasic(auth, methods);
	}

	private ServletContextHandler addRedirectContext(GitServlet gs) {
		ServletContextHandler redirect = server.addContext("/redirect");
		redirect.addFilter(new FilterHolder(new Filter() {

			// Enables tests for different codes, and for multiple redirects.
			// First parameter is the number of redirects, second one is the
			// redirect status code that should be used
			private Pattern responsePattern = Pattern
					.compile("/response/(\\d+)/(30[1237])/");

			// Enables tests to specify the context that the request should be
			// redirected to in the end. If not present, redirects got to the
			// normal /git context.
			private Pattern targetPattern = Pattern.compile("/target(/\\w+)/");

			@Override
			public void init(FilterConfig filterConfig)
					throws ServletException {
				// empty
			}

			private String local(String url, boolean toLocal) {
				if (!toLocal) {
					return url;
				}
				try {
					URI u = new URI(url);
					String fragment = u.getRawFragment();
					if (fragment != null) {
						return u.getRawPath() + '#' + fragment;
					}
					return u.getRawPath();
				} catch (URISyntaxException e) {
					return url;
				}
			}

			@Override
			public void doFilter(ServletRequest request,
					ServletResponse response, FilterChain chain)
					throws IOException, ServletException {
				final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
				final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
				final StringBuffer fullUrl = httpServletRequest.getRequestURL();
				if (httpServletRequest.getQueryString() != null) {
					fullUrl.append("?")
							.append(httpServletRequest.getQueryString());
				}
				String urlString = fullUrl.toString();
				boolean localRedirect = false;
				if (urlString.contains("/local")) {
					urlString = urlString.replace("/local", "");
					localRedirect = true;
				}
				if (urlString.contains("/loop/")) {
					urlString = urlString.replace("/loop/", "/loop/x/");
					if (urlString.contains("/loop/x/x/x/x/x/x/x/x/")) {
						// Go back to initial.
						urlString = urlString.replace("/loop/x/x/x/x/x/x/x/x/",
								"/loop/");
					}
					httpServletResponse.setStatus(
							HttpServletResponse.SC_MOVED_TEMPORARILY);
					httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
							local(urlString, localRedirect));
					return;
				}
				int responseCode = HttpServletResponse.SC_MOVED_PERMANENTLY;
				int nofRedirects = 0;
				Matcher matcher = responsePattern.matcher(urlString);
				if (matcher.find()) {
					nofRedirects = Integer
							.parseUnsignedInt(matcher.group(1));
					responseCode = Integer.parseUnsignedInt(matcher.group(2));
					if (--nofRedirects <= 0) {
						urlString = urlString.substring(0, matcher.start())
								+ '/' + urlString.substring(matcher.end());
					} else {
						urlString = urlString.substring(0, matcher.start())
								+ "/response/" + nofRedirects + "/"
								+ responseCode + '/'
								+ urlString.substring(matcher.end());
					}
				}
				httpServletResponse.setStatus(responseCode);
				if (nofRedirects <= 0) {
					String targetContext = "/git";
					matcher = targetPattern.matcher(urlString);
					if (matcher.find()) {
						urlString = urlString.substring(0, matcher.start())
								+ '/' + urlString.substring(matcher.end());
						targetContext = matcher.group(1);
					}
					urlString = urlString.replace("/redirect", targetContext);

				}
				httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
						local(urlString, localRedirect));
			}

			@Override
			public void destroy() {
				// empty
			}
		}), "/*", EnumSet.of(DispatcherType.REQUEST));
		redirect.addServlet(new ServletHolder(gs), "/*");
		return redirect;
	}

	@Test
	public void testListRemote() throws IOException {
		assertEquals("http", remoteURI.getScheme());

		Map<String, Ref> map;
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI)) {
			// I didn't make up these public interface names, I just
			// approved them for inclusion into the code base. Sorry.
			// --spearce
			//
			assertTrue("isa TransportHttp", t instanceof TransportHttp);
			assertTrue("isa HttpTransport", t instanceof HttpTransport);

			try (FetchConnection c = t.openFetch()) {
				map = c.getRefsMap();
			}
		}

		assertNotNull("have map of refs", map);
		assertEquals(3, map.size());

		assertNotNull("has " + master, map.get(master));
		assertEquals(B, map.get(master).getObjectId());

		assertNotNull("has " + Constants.HEAD, map.get(Constants.HEAD));
		assertEquals(B, map.get(Constants.HEAD).getObjectId());

		List<AccessEvent> requests = getRequests();
		assertEquals(1, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
	}

	@Test
	public void testListRemote_BadName() throws IOException, URISyntaxException {
		URIish uri = new URIish(this.remoteURI.toString() + ".invalid");
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, uri)) {
			try {
				t.openFetch();
				fail("fetch connection opened");
			} catch (RemoteRepositoryException notFound) {
				assertEquals(uri + ": Git repository not found",
						notFound.getMessage());
			}
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(1, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(uri, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testFetchBySHA1() throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE,
					Collections.singletonList(new RefSpec(B.name())));
			assertTrue(dst.getObjectDatabase().has(A_txt));
		}
	}

	@Test
	public void testFetchBySHA1Unreachable() throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			Exception e = assertThrows(TransportException.class,
					() -> t.fetch(NullProgressMonitor.INSTANCE,
							Collections.singletonList(
									new RefSpec(unreachableCommit.name()))));
			assertTrue(e.getMessage().contains(
					"want " + unreachableCommit.name() + " not valid"));
		}
	}

	@Test
	public void testFetchBySHA1UnreachableByAdvertiseRefsHook()
			throws Exception {
		advertiseRefsHook = new AbstractAdvertiseRefsHook() {
			@Override
			protected Map<String, Ref> getAdvertisedRefs(Repository repository,
					RevWalk revWalk) {
				return Collections.emptyMap();
			}
		};

		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			Exception e = assertThrows(TransportException.class,
					() -> t.fetch(NullProgressMonitor.INSTANCE,
							Collections.singletonList(new RefSpec(A.name()))));
			assertTrue(
					e.getMessage().contains("want " + A.name() + " not valid"));
		}
	}

	@Test
	public void testInitialClone_Small() throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(2, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length", service
				.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked", service
				.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result", service
				.getResponseHeader(HDR_CONTENT_TYPE));
	}

	private void initialClone_Redirect(int nofRedirects, int code)
			throws Exception {
		initialClone_Redirect(nofRedirects, code, false);
	}

	private void initialClone_Redirect(int nofRedirects, int code,
			boolean localRedirect) throws Exception {
		URIish cloneFrom = redirectURI;
		if (localRedirect) {
			cloneFrom = extendPath(cloneFrom, "/local");
		}
		if (code != 301 || nofRedirects > 1) {
			cloneFrom = extendPath(cloneFrom,
					"/response/" + nofRedirects + "/" + code);
		}

		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(2 + nofRedirects, requests.size());

		int n = 0;
		while (n < nofRedirects) {
			AccessEvent redirect = requests.get(n++);
			assertEquals(code, redirect.getStatus());
		}

		AccessEvent info = requests.get(n++);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent service = requests.get(n++);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInitialClone_Redirect301Small() throws Exception {
		initialClone_Redirect(1, 301);
	}

	@Test
	public void testInitialClone_Redirect301Local() throws Exception {
		initialClone_Redirect(1, 301, true);
	}

	@Test
	public void testInitialClone_Redirect302Small() throws Exception {
		initialClone_Redirect(1, 302);
	}

	@Test
	public void testInitialClone_Redirect303Small() throws Exception {
		initialClone_Redirect(1, 303);
	}

	@Test
	public void testInitialClone_Redirect307Small() throws Exception {
		initialClone_Redirect(1, 307);
	}

	@Test
	public void testInitialClone_RedirectMultiple() throws Exception {
		initialClone_Redirect(4, 302);
	}

	@Test
	public void testInitialClone_RedirectMax() throws Exception {
		StoredConfig userConfig = SystemReader.getInstance()
				.getUserConfig();
		userConfig.setInt("http", null, "maxRedirects", 4);
		userConfig.save();
		initialClone_Redirect(4, 302);
	}

	@Test
	public void testInitialClone_RedirectTooOften() throws Exception {
		StoredConfig userConfig = SystemReader.getInstance()
				.getUserConfig();
		userConfig.setInt("http", null, "maxRedirects", 3);
		userConfig.save();

		URIish cloneFrom = extendPath(redirectURI, "/response/4/302");
		String remoteUri = cloneFrom.toString();
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should have failed (too many redirects)");
		} catch (TransportException e) {
			String expectedMessageBegin = remoteUri.toString() + ": "
					+ MessageFormat.format(JGitText.get().redirectLimitExceeded,
							"3", remoteUri.replace("/4/", "/1/") + '/', "");
			String message = e.getMessage();
			if (message.length() > expectedMessageBegin.length()) {
				message = message.substring(0, expectedMessageBegin.length());
			}
			assertEquals(expectedMessageBegin, message);
		}
	}

	@Test
	public void testInitialClone_RedirectLoop() throws Exception {
		URIish cloneFrom = extendPath(redirectURI, "/loop");
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should have failed (redirect loop)");
		} catch (TransportException e) {
			assertTrue(e.getMessage().contains("Redirected more than"));
		}
	}

	@Test
	public void testInitialClone_RedirectOnPostAllowed() throws Exception {
		StoredConfig userConfig = SystemReader.getInstance()
				.getUserConfig();
		userConfig.setString("http", null, "followRedirects", "true");
		userConfig.save();

		URIish cloneFrom = extendPath(remoteURI, "/post");
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(3, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(cloneFrom, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent redirect = requests.get(1);
		assertEquals("POST", redirect.getMethod());
		assertEquals(301, redirect.getStatus());

		AccessEvent service = requests.get(2);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInitialClone_RedirectOnPostForbidden() throws Exception {
		URIish cloneFrom = extendPath(remoteURI, "/post");
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should have failed (redirect on POST)");
		} catch (TransportException e) {
			assertTrue(e.getMessage().contains("301"));
		}
	}

	@Test
	public void testInitialClone_RedirectForbidden() throws Exception {
		StoredConfig userConfig = SystemReader.getInstance()
				.getUserConfig();
		userConfig.setString("http", null, "followRedirects", "false");
		userConfig.save();

		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, redirectURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should have failed (redirects forbidden)");
		} catch (TransportException e) {
			assertTrue(
					e.getMessage().contains("http.followRedirects is false"));
		}
	}

	@Test
	public void testInitialClone_WithAuthentication() throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, authURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.setCredentialsProvider(testCredentials);
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(3, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(401, info.getStatus());

		info = requests.get(1);
		assertEquals("GET", info.getMethod());
		assertEquals(join(authURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent service = requests.get(2);
		assertEquals("POST", service.getMethod());
		assertEquals(join(authURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInitialClone_WithAuthenticationNoCredentials()
			throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, authURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should not have succeeded -- no authentication");
		} catch (TransportException e) {
			String msg = e.getMessage();
			assertTrue("Unexpected exception message: " + msg,
					msg.contains("no CredentialsProvider"));
		}
		List<AccessEvent> requests = getRequests();
		assertEquals(1, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(401, info.getStatus());
	}

	@Test
	public void testInitialClone_WithAuthenticationWrongCredentials()
			throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, authURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
					AppServer.username, "wrongpassword"));
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			fail("Should not have succeeded -- wrong password");
		} catch (TransportException e) {
			String msg = e.getMessage();
			assertTrue("Unexpected exception message: " + msg,
					msg.contains("auth"));
		}
		List<AccessEvent> requests = getRequests();
		// Once without authentication plus three re-tries with authentication
		assertEquals(4, requests.size());

		for (AccessEvent event : requests) {
			assertEquals("GET", event.getMethod());
			assertEquals(401, event.getStatus());
		}
	}

	@Test
	public void testInitialClone_WithAuthenticationAfterRedirect()
			throws Exception {
		URIish cloneFrom = extendPath(redirectURI, "/target/auth");
		CredentialsProvider uriSpecificCredentialsProvider = new UsernamePasswordCredentialsProvider(
				"unknown", "none") {
			@Override
			public boolean get(URIish uri, CredentialItem... items)
					throws UnsupportedCredentialItem {
				// Only return the true credentials if the uri path starts with
				// /auth. This ensures that we do provide the correct
				// credentials only for the URi after the redirect, making the
				// test fail if we should be asked for the credentials for the
				// original URI.
				if (uri.getPath().startsWith("/auth")) {
					return testCredentials.get(uri, items);
				}
				return super.get(uri, items);
			}
		};
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, cloneFrom)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.setCredentialsProvider(uriSpecificCredentialsProvider);
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(4, requests.size());

		AccessEvent redirect = requests.get(0);
		assertEquals("GET", redirect.getMethod());
		assertEquals(join(cloneFrom, "info/refs"), redirect.getPath());
		assertEquals(301, redirect.getStatus());

		AccessEvent info = requests.get(1);
		assertEquals("GET", info.getMethod());
		assertEquals(join(authURI, "info/refs"), info.getPath());
		assertEquals(401, info.getStatus());

		info = requests.get(2);
		assertEquals("GET", info.getMethod());
		assertEquals(join(authURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent service = requests.get(3);
		assertEquals("POST", service.getMethod());
		assertEquals(join(authURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInitialClone_WithAuthenticationOnPostOnly()
			throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, authOnPostURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			t.setCredentialsProvider(testCredentials);
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
			assertTrue(dst.getObjectDatabase().has(A_txt));
			assertEquals(B, dst.exactRef(master).getObjectId());
			fsck(dst, B);
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(3, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(authOnPostURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));
		assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));

		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(authOnPostURI, "git-upload-pack"), service.getPath());
		assertEquals(401, service.getStatus());

		service = requests.get(2);
		assertEquals("POST", service.getMethod());
		assertEquals(join(authOnPostURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testFetch_FewLocalCommits() throws Exception {
		// Bootstrap by doing the clone.
		//
		TestRepository dst = createTestRepository();
		try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
		}
		assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
		List<AccessEvent> cloneRequests = getRequests();

		// Only create a few new commits.
		TestRepository.BranchBuilder b = dst.branch(master);
		for (int i = 0; i < 4; i++)
			b.commit().tick(3600 /* 1 hour */).message("c" + i).create();

		// Create a new commit on the remote.
		//
		RevCommit Z;
		try (TestRepository<Repository> tr = new TestRepository<>(
				remoteRepository)) {
			b = tr.branch(master);
			Z = b.commit().message("Z").create();
		}

		// Now incrementally update.
		//
		try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
		}
		assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());

		List<AccessEvent> requests = getRequests();
		requests.removeAll(cloneRequests);
		assertEquals(2, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement",
				info.getResponseHeader(HDR_CONTENT_TYPE));

		// We should have needed one request to perform the fetch.
		//
		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length",
				service.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked",
				service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testFetch_TooManyLocalCommits() throws Exception {
		// Bootstrap by doing the clone.
		//
		TestRepository dst = createTestRepository();
		try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
		}
		assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
		List<AccessEvent> cloneRequests = getRequests();

		// Force enough into the local client that enumeration will
		// need multiple packets, but not too many to overflow and
		// not pick up the ACK_COMMON message.
		//
		TestRepository.BranchBuilder b = dst.branch(master);
		for (int i = 0; i < 32 - 1; i++)
			b.commit().tick(3600 /* 1 hour */).message("c" + i).create();

		// Create a new commit on the remote.
		//
		RevCommit Z;
		try (TestRepository<Repository> tr = new TestRepository<>(
				remoteRepository)) {
			b = tr.branch(master);
			Z = b.commit().message("Z").create();
		}

		// Now incrementally update.
		//
		try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
			t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
		}
		assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());

		List<AccessEvent> requests = getRequests();
		requests.removeAll(cloneRequests);
		assertEquals(3, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));

		// We should have needed two requests to perform the fetch
		// due to the high number of local unknown commits.
		//
		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length", service
				.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked", service
				.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result", service
				.getResponseHeader(HDR_CONTENT_TYPE));

		service = requests.get(2);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length", service
				.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked", service
				.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-upload-pack-result", service
				.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInitialClone_BrokenServer() throws Exception {
		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, brokenURI)) {
			assertFalse(dst.getObjectDatabase().has(A_txt));
			try {
				t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
				fail("fetch completed despite upload-pack being broken");
			} catch (TransportException err) {
				String exp = brokenURI + ": expected"
						+ " Content-Type application/x-git-upload-pack-result;"
						+ " received Content-Type text/plain;charset=utf-8";
				assertEquals(exp, err.getMessage());
			}
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(2, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(brokenURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-upload-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-upload-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));

		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(brokenURI, "git-upload-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertEquals(200, service.getStatus());
		assertEquals("text/plain;charset=utf-8",
				service.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testInvalidWant() throws Exception {
		ObjectId id;
		try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
			id = formatter.idFor(Constants.OBJ_BLOB,
					"testInvalidWant".getBytes(UTF_8));
		}

		try (Repository dst = createBareRepository();
				Transport t = Transport.open(dst, remoteURI);
				FetchConnection c = t.openFetch()) {
			Ref want = new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, id.name(),
					id);
			c.fetch(NullProgressMonitor.INSTANCE, Collections.singleton(want),
					Collections.<ObjectId> emptySet());
			fail("Server accepted want " + id.name());
		} catch (TransportException err) {
			assertEquals("want " + id.name() + " not valid", err.getMessage());
		}
	}

	@Test
	public void testFetch_RefsUnreadableOnUpload() throws Exception {
		AppServer noRefServer = new AppServer();
		try {
			final String repoName = "refs-unreadable";
			RefsUnreadableInMemoryRepository badRefsRepo = new RefsUnreadableInMemoryRepository(
					new DfsRepositoryDescription(repoName));
			final TestRepository<Repository> repo = new TestRepository<>(
					badRefsRepo);

			ServletContextHandler app = noRefServer.addContext("/git");
			GitServlet gs = new GitServlet();
			gs.setRepositoryResolver(new TestRepositoryResolver(repo, repoName));
			app.addServlet(new ServletHolder(gs), "/*");
			noRefServer.setUp();

			RevBlob A2_txt = repo.blob("A2");
			RevCommit A2 = repo.commit().add("A2_txt", A2_txt).create();
			RevCommit B2 = repo.commit().parent(A2).add("A2_txt", "C2")
					.add("B2", "B2").create();
			repo.update(master, B2);

			URIish badRefsURI = new URIish(noRefServer.getURI()
					.resolve(app.getContextPath() + "/" + repoName).toString());

			try (Repository dst = createBareRepository();
					Transport t = Transport.open(dst, badRefsURI);
					FetchConnection c = t.openFetch()) {
				// We start failing here to exercise the post-advertisement
				// upload pack handler.
				badRefsRepo.startFailing();
				// Need to flush caches because ref advertisement populated them.
				badRefsRepo.getRefDatabase().refresh();
				c.fetch(NullProgressMonitor.INSTANCE,
						Collections.singleton(c.getRef(master)),
						Collections.<ObjectId> emptySet());
				fail("Successfully served ref with value " + c.getRef(master));
			} catch (TransportException err) {
				assertEquals("Internal server error", err.getMessage());
			}
		} finally {
			noRefServer.tearDown();
		}
	}

	@Test
	public void testPush_NotAuthorized() throws Exception {
		final TestRepository src = createTestRepository();
		final RevBlob Q_txt = src.blob("new text");
		final RevCommit Q = src.commit().add("Q", Q_txt).create();
		final Repository db = src.getRepository();
		final String dstName = Constants.R_HEADS + "new.branch";

		// push anonymous shouldn't be allowed.
		//
		try (Transport t = Transport.open(db, remoteURI)) {
			final String srcExpr = Q.name();
			final boolean forceUpdate = false;
			final String localName = null;
			final ObjectId oldId = null;

			RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
					srcExpr, dstName, forceUpdate, localName, oldId);
			try {
				t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
				fail("anonymous push incorrectly accepted without error");
			} catch (TransportException e) {
				final String exp = remoteURI + ": "
						+ JGitText.get().authenticationNotSupported;
				assertEquals(exp, e.getMessage());
			}
		}

		List<AccessEvent> requests = getRequests();
		assertEquals(1, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-receive-pack", info.getParameter("service"));
		assertEquals(401, info.getStatus());
	}

	@Test
	public void testPush_CreateBranch() throws Exception {
		final TestRepository src = createTestRepository();
		final RevBlob Q_txt = src.blob("new text");
		final RevCommit Q = src.commit().add("Q", Q_txt).create();
		final Repository db = src.getRepository();
		final String dstName = Constants.R_HEADS + "new.branch";

		enableReceivePack();

		try (Transport t = Transport.open(db, remoteURI)) {
			final String srcExpr = Q.name();
			final boolean forceUpdate = false;
			final String localName = null;
			final ObjectId oldId = null;

			RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
					srcExpr, dstName, forceUpdate, localName, oldId);
			t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
		}

		assertTrue(remoteRepository.getObjectDatabase().has(Q_txt));
		assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
		assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
		fsck(remoteRepository, Q);

		final ReflogReader log = remoteRepository.getReflogReader(dstName);
		assertNotNull("has log for " + dstName, log);

		final ReflogEntry last = log.getLastEntry();
		assertNotNull("has last entry", last);
		assertEquals(ObjectId.zeroId(), last.getOldId());
		assertEquals(Q, last.getNewId());
		assertEquals("anonymous", last.getWho().getName());

		// Assumption: The host name we use to contact the server should
		// be the server's own host name, because it should be the loopback
		// network interface.
		//
		final String clientHost = remoteURI.getHost();
		assertEquals("anonymous@" + clientHost, last.getWho().getEmailAddress());
		assertEquals("push: created", last.getComment());

		List<AccessEvent> requests = getRequests();
		assertEquals(2, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-receive-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-receive-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));

		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-receive-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNotNull("has content-length", service
				.getRequestHeader(HDR_CONTENT_LENGTH));
		assertNull("not chunked", service
				.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-receive-pack-result", service
				.getResponseHeader(HDR_CONTENT_TYPE));
	}

	@Test
	public void testPush_ChunkedEncoding() throws Exception {
		final TestRepository<Repository> src = createTestRepository();
		final RevBlob Q_bin = src.blob(new TestRng("Q").nextBytes(128 * 1024));
		final RevCommit Q = src.commit().add("Q", Q_bin).create();
		final Repository db = src.getRepository();
		final String dstName = Constants.R_HEADS + "new.branch";

		enableReceivePack();

		final StoredConfig cfg = db.getConfig();
		cfg.setInt("core", null, "compression", 0);
		cfg.setInt("http", null, "postbuffer", 8 * 1024);
		cfg.save();

		try (Transport t = Transport.open(db, remoteURI)) {
			final String srcExpr = Q.name();
			final boolean forceUpdate = false;
			final String localName = null;
			final ObjectId oldId = null;

			RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
					srcExpr, dstName, forceUpdate, localName, oldId);
			t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
		}

		assertTrue(remoteRepository.getObjectDatabase().has(Q_bin));
		assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
		assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
		fsck(remoteRepository, Q);

		List<AccessEvent> requests = getRequests();
		assertEquals(2, requests.size());

		AccessEvent info = requests.get(0);
		assertEquals("GET", info.getMethod());
		assertEquals(join(remoteURI, "info/refs"), info.getPath());
		assertEquals(1, info.getParameters().size());
		assertEquals("git-receive-pack", info.getParameter("service"));
		assertEquals(200, info.getStatus());
		assertEquals("application/x-git-receive-pack-advertisement", info
				.getResponseHeader(HDR_CONTENT_TYPE));

		AccessEvent service = requests.get(1);
		assertEquals("POST", service.getMethod());
		assertEquals(join(remoteURI, "git-receive-pack"), service.getPath());
		assertEquals(0, service.getParameters().size());
		assertNull("no content-length", service
				.getRequestHeader(HDR_CONTENT_LENGTH));
		assertEquals("chunked", service.getRequestHeader(HDR_TRANSFER_ENCODING));

		assertEquals(200, service.getStatus());
		assertEquals("application/x-git-receive-pack-result", service
				.getResponseHeader(HDR_CONTENT_TYPE));
	}

	private void enableReceivePack() throws IOException {
		final StoredConfig cfg = remoteRepository.getConfig();
		cfg.setBoolean("http", null, "receivepack", true);
		cfg.save();
	}

}
