No Eclipse support for this project is provided, because the Jetty project does not publish a complete P2 repository. Change-Id: Ic5fe2e79bb216e36920fd4a70ec15dd6ccfd1468 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>tags/v0.7.0
@@ -0,0 +1 @@ | |||
/target |
@@ -0,0 +1,108 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Copyright (C) 2009-2010, Google Inc. | |||
Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com> | |||
and other copyright owners as documented in the project's IP log. | |||
This program and the accompanying materials are made available | |||
under the terms of the Eclipse Distribution License v1.0 which | |||
accompanies this distribution, is reproduced below, and is | |||
available at http://www.eclipse.org/org/documents/edl-v10.php | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or | |||
without modification, are permitted provided that the following | |||
conditions are met: | |||
- Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | |||
- Redistributions in binary form must reproduce the above | |||
copyright notice, this list of conditions and the following | |||
disclaimer in the documentation and/or other materials provided | |||
with the distribution. | |||
- Neither the name of the Eclipse Foundation, Inc. nor the | |||
names of its contributors may be used to endorse or promote | |||
products derived from this software without specific prior | |||
written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
--> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.eclipse.jgit</groupId> | |||
<artifactId>org.eclipse.jgit-parent</artifactId> | |||
<version>0.6.0-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>org.eclipse.jgit.http.test</artifactId> | |||
<name>JGit - HTTP Tests</name> | |||
<description> | |||
Tests for the HTTP transport. | |||
</description> | |||
<dependencies> | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.jgit</groupId> | |||
<artifactId>org.eclipse.jgit</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.jgit</groupId> | |||
<artifactId>org.eclipse.jgit.junit</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.jgit</groupId> | |||
<artifactId>org.eclipse.jgit.http.server</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.jetty</groupId> | |||
<artifactId>jetty-servlet</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<testSourceDirectory>tst/</testSourceDirectory> | |||
<testResources> | |||
<testResource> | |||
<directory>tst-rsrc/</directory> | |||
</testResource> | |||
</testResources> | |||
</build> | |||
</project> |
@@ -0,0 +1,136 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import javax.servlet.http.HttpServletRequestWrapper; | |||
import org.eclipse.jetty.server.Request; | |||
import org.eclipse.jgit.http.server.resolver.AsIsFileService; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.lib.Repository; | |||
public class AsIsServiceTest extends LocalDiskRepositoryTestCase { | |||
private Repository db; | |||
private AsIsFileService service; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
db = createBareRepository(); | |||
service = new AsIsFileService(); | |||
} | |||
public void testDisabledSingleton() throws ServiceNotAuthorizedException { | |||
service = AsIsFileService.DISABLED; | |||
try { | |||
service.access(new R(null, "1.2.3.4"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
service.access(new R("bob", "1.2.3.4"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_Default() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
service.access(new R(null, "1.2.3.4"), db); | |||
service.access(new R("bob", "1.2.3.4"), db); | |||
} | |||
public void testCreate_Disabled() throws ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "getanyfile", false); | |||
try { | |||
service.access(new R(null, "1.2.3.4"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
service.access(new R("bob", "1.2.3.4"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_Enabled() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "getanyfile", true); | |||
service.access(new R(null, "1.2.3.4"), db); | |||
service.access(new R("bob", "1.2.3.4"), db); | |||
} | |||
private final class R extends HttpServletRequestWrapper { | |||
private final String user; | |||
private final String host; | |||
R(final String user, final String host) { | |||
super(new Request() /* can't pass null, sigh */); | |||
this.user = user; | |||
this.host = host; | |||
} | |||
@Override | |||
public String getRemoteHost() { | |||
return host; | |||
} | |||
@Override | |||
public String getRemoteUser() { | |||
return user; | |||
} | |||
} | |||
} |
@@ -0,0 +1,198 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import javax.servlet.http.HttpServletRequestWrapper; | |||
import org.eclipse.jetty.server.Request; | |||
import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; | |||
import org.eclipse.jgit.http.server.resolver.ReceivePackFactory; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.transport.ReceivePack; | |||
public class DefaultReceivePackFactoryTest extends LocalDiskRepositoryTestCase { | |||
private Repository db; | |||
private ReceivePackFactory factory; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
db = createBareRepository(); | |||
factory = new DefaultReceivePackFactory(); | |||
} | |||
public void testDisabledSingleton() throws ServiceNotAuthorizedException { | |||
factory = ReceivePackFactory.DISABLED; | |||
try { | |||
factory.create(new R(null, "localhost"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("", "localhost"), db); | |||
fail("Created session for anonymous user: \"\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("bob", "localhost"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_NullUser() throws ServiceNotEnabledException { | |||
try { | |||
factory.create(new R(null, "localhost"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotAuthorizedException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_EmptyStringUser() throws ServiceNotEnabledException { | |||
try { | |||
factory.create(new R("", "localhost"), db); | |||
fail("Created session for anonymous user: \"\""); | |||
} catch (ServiceNotAuthorizedException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_AuthUser() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
ReceivePack rp; | |||
rp = factory.create(new R("bob", "1.2.3.4"), db); | |||
assertNotNull("have ReceivePack", rp); | |||
assertSame(db, rp.getRepository()); | |||
PersonIdent id = rp.getRefLogIdent(); | |||
assertNotNull(id); | |||
assertEquals("bob", id.getName()); | |||
assertEquals("bob@1.2.3.4", id.getEmailAddress()); | |||
// Should have inherited off the current system, which is mocked | |||
assertEquals(author.getTimeZoneOffset(), id.getTimeZoneOffset()); | |||
assertEquals(author.getWhen(), id.getWhen()); | |||
} | |||
public void testCreate_Disabled() throws ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "receivepack", false); | |||
try { | |||
factory.create(new R(null, "localhost"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("", "localhost"), db); | |||
fail("Created session for anonymous user: \"\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("bob", "localhost"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_Enabled() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "receivepack", true); | |||
ReceivePack rp; | |||
rp = factory.create(new R(null, "1.2.3.4"), db); | |||
assertNotNull("have ReceivePack", rp); | |||
assertSame(db, rp.getRepository()); | |||
PersonIdent id = rp.getRefLogIdent(); | |||
assertNotNull(id); | |||
assertEquals("anonymous", id.getName()); | |||
assertEquals("anonymous@1.2.3.4", id.getEmailAddress()); | |||
// Should have inherited off the current system, which is mocked | |||
assertEquals(author.getTimeZoneOffset(), id.getTimeZoneOffset()); | |||
assertEquals(author.getWhen(), id.getWhen()); | |||
rp = factory.create(new R("bob", "1.2.3.4"), db); | |||
assertNotNull("have ReceivePack", rp); | |||
} | |||
private final class R extends HttpServletRequestWrapper { | |||
private final String user; | |||
private final String host; | |||
R(final String user, final String host) { | |||
super(new Request() /* can't pass null, sigh */); | |||
this.user = user; | |||
this.host = host; | |||
} | |||
@Override | |||
public String getRemoteHost() { | |||
return host; | |||
} | |||
@Override | |||
public String getRemoteUser() { | |||
return user; | |||
} | |||
} | |||
} |
@@ -0,0 +1,160 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import javax.servlet.http.HttpServletRequestWrapper; | |||
import org.eclipse.jetty.server.Request; | |||
import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.http.server.resolver.UploadPackFactory; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.transport.UploadPack; | |||
public class DefaultUploadPackFactoryTest extends LocalDiskRepositoryTestCase { | |||
private Repository db; | |||
private UploadPackFactory factory; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
db = createBareRepository(); | |||
factory = new DefaultUploadPackFactory(); | |||
} | |||
public void testDisabledSingleton() throws ServiceNotAuthorizedException { | |||
factory = UploadPackFactory.DISABLED; | |||
try { | |||
factory.create(new R(null, "localhost"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("", "localhost"), db); | |||
fail("Created session for anonymous user: \"\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("bob", "localhost"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_Default() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
UploadPack up; | |||
up = factory.create(new R(null, "1.2.3.4"), db); | |||
assertNotNull("have UploadPack", up); | |||
assertSame(db, up.getRepository()); | |||
up = factory.create(new R("bob", "1.2.3.4"), db); | |||
assertNotNull("have UploadPack", up); | |||
assertSame(db, up.getRepository()); | |||
} | |||
public void testCreate_Disabled() throws ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "uploadpack", false); | |||
try { | |||
factory.create(new R(null, "localhost"), db); | |||
fail("Created session for anonymous user: null"); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
try { | |||
factory.create(new R("bob", "localhost"), db); | |||
fail("Created session for user: \"bob\""); | |||
} catch (ServiceNotEnabledException e) { | |||
// expected not authorized | |||
} | |||
} | |||
public void testCreate_Enabled() throws ServiceNotEnabledException, | |||
ServiceNotAuthorizedException { | |||
db.getConfig().setBoolean("http", null, "uploadpack", true); | |||
UploadPack up; | |||
up = factory.create(new R(null, "1.2.3.4"), db); | |||
assertNotNull("have UploadPack", up); | |||
assertSame(db, up.getRepository()); | |||
up = factory.create(new R("bob", "1.2.3.4"), db); | |||
assertNotNull("have UploadPack", up); | |||
assertSame(db, up.getRepository()); | |||
} | |||
private final class R extends HttpServletRequestWrapper { | |||
private final String user; | |||
private final String host; | |||
R(final String user, final String host) { | |||
super(new Request() /* can't pass null, sigh */); | |||
this.user = user; | |||
this.host = host; | |||
} | |||
@Override | |||
public String getRemoteHost() { | |||
return host; | |||
} | |||
@Override | |||
public String getRemoteUser() { | |||
return user; | |||
} | |||
} | |||
} |
@@ -0,0 +1,246 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.net.URI; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.eclipse.jetty.servlet.DefaultServlet; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jgit.errors.NotSupportedException; | |||
import org.eclipse.jgit.http.test.util.AccessEvent; | |||
import org.eclipse.jgit.http.test.util.HttpTestCase; | |||
import org.eclipse.jgit.junit.TestRepository; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevBlob; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.FetchConnection; | |||
import org.eclipse.jgit.transport.HttpTransport; | |||
import org.eclipse.jgit.transport.Transport; | |||
import org.eclipse.jgit.transport.TransportHttp; | |||
import org.eclipse.jgit.transport.URIish; | |||
public class DumbClientDumbServerTest extends HttpTestCase { | |||
private Repository remoteRepository; | |||
private URIish remoteURI; | |||
private RevBlob A_txt; | |||
private RevCommit A, B; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
final TestRepository src = createTestRepository(); | |||
final File srcGit = src.getRepository().getDirectory(); | |||
final URI base = srcGit.getParentFile().toURI(); | |||
ServletContextHandler app = server.addContext("/git"); | |||
app.setResourceBase(base.toString()); | |||
app.addServlet(DefaultServlet.class, "/"); | |||
server.setUp(); | |||
remoteRepository = src.getRepository(); | |||
remoteURI = toURIish(app, srcGit.getName()); | |||
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); | |||
} | |||
public void testListRemote() throws IOException { | |||
Repository dst = createBareRepository(); | |||
assertEquals("http", remoteURI.getScheme()); | |||
Map<String, Ref> map; | |||
Transport t = Transport.open(dst, remoteURI); | |||
try { | |||
// 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); | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
map = c.getRefsMap(); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
assertNotNull("have map of refs", map); | |||
assertEquals(2, 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(2, requests.size()); | |||
assertEquals(0, getRequests(remoteURI, "git-upload-pack").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("no-cache", info.getRequestHeader(HDR_PRAGMA)); | |||
assertNotNull("has user-agent", info.getRequestHeader(HDR_USER_AGENT)); | |||
assertTrue("is jgit agent", info.getRequestHeader(HDR_USER_AGENT) | |||
.startsWith("JGit/")); | |||
assertEquals("application/x-git-upload-pack-advertisement, */*", info | |||
.getRequestHeader(HDR_ACCEPT)); | |||
assertEquals(200, info.getStatus()); | |||
AccessEvent head = requests.get(1); | |||
assertEquals("GET", head.getMethod()); | |||
assertEquals(join(remoteURI, "HEAD"), head.getPath()); | |||
assertEquals(0, head.getParameters().size()); | |||
assertEquals("no-cache", head.getRequestHeader(HDR_PRAGMA)); | |||
assertNotNull("has user-agent", head.getRequestHeader(HDR_USER_AGENT)); | |||
assertTrue("is jgit agent", head.getRequestHeader(HDR_USER_AGENT) | |||
.startsWith("JGit/")); | |||
assertEquals(200, head.getStatus()); | |||
} | |||
public void testInitialClone_Loose() throws Exception { | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, remoteURI); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(dst.hasObject(A_txt)); | |||
assertEquals(B, dst.getRef(master).getObjectId()); | |||
fsck(dst, B); | |||
List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt)); | |||
assertEquals(1, loose.size()); | |||
assertEquals("GET", loose.get(0).getMethod()); | |||
assertEquals(0, loose.get(0).getParameters().size()); | |||
assertEquals(200, loose.get(0).getStatus()); | |||
} | |||
public void testInitialClone_Packed() throws Exception { | |||
new TestRepository(remoteRepository).packAndPrune(); | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, remoteURI); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(dst.hasObject(A_txt)); | |||
assertEquals(B, dst.getRef(master).getObjectId()); | |||
fsck(dst, B); | |||
List<AccessEvent> req; | |||
AccessEvent event; | |||
req = getRequests(loose(remoteURI, B)); | |||
assertEquals(1, req.size()); | |||
event = req.get(0); | |||
assertEquals("GET", event.getMethod()); | |||
assertEquals(0, event.getParameters().size()); | |||
assertEquals(404, event.getStatus()); | |||
req = getRequests(join(remoteURI, "objects/info/packs")); | |||
assertEquals(1, req.size()); | |||
event = req.get(0); | |||
assertEquals("GET", event.getMethod()); | |||
assertEquals(0, event.getParameters().size()); | |||
assertEquals("no-cache", event.getRequestHeader(HDR_PRAGMA)); | |||
assertNotNull("has user-agent", event.getRequestHeader(HDR_USER_AGENT)); | |||
assertTrue("is jgit agent", event.getRequestHeader(HDR_USER_AGENT) | |||
.startsWith("JGit/")); | |||
assertEquals(200, event.getStatus()); | |||
} | |||
public void testPushNotSupported() throws Exception { | |||
final TestRepository src = createTestRepository(); | |||
final RevCommit Q = src.commit().create(); | |||
final Repository db = src.getRepository(); | |||
Transport t = Transport.open(db, remoteURI); | |||
try { | |||
try { | |||
t.push(NullProgressMonitor.INSTANCE, push(src, Q)); | |||
fail("push incorrectly completed against a dumb server"); | |||
} catch (NotSupportedException nse) { | |||
String exp = "remote does not support smart HTTP push"; | |||
assertEquals(exp, nse.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,261 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; | |||
import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import java.util.Map; | |||
import javax.servlet.http.HttpServletRequest; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import org.eclipse.jgit.errors.NotSupportedException; | |||
import org.eclipse.jgit.errors.RepositoryNotFoundException; | |||
import org.eclipse.jgit.http.server.GitServlet; | |||
import org.eclipse.jgit.http.server.resolver.RepositoryResolver; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.http.test.util.AccessEvent; | |||
import org.eclipse.jgit.http.test.util.HttpTestCase; | |||
import org.eclipse.jgit.junit.TestRepository; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevBlob; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.FetchConnection; | |||
import org.eclipse.jgit.transport.HttpTransport; | |||
import org.eclipse.jgit.transport.Transport; | |||
import org.eclipse.jgit.transport.TransportHttp; | |||
import org.eclipse.jgit.transport.URIish; | |||
public class DumbClientSmartServerTest extends HttpTestCase { | |||
private Repository remoteRepository; | |||
private URIish remoteURI; | |||
private RevBlob A_txt; | |||
private RevCommit A, B; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
final TestRepository src = createTestRepository(); | |||
final String srcName = src.getRepository().getDirectory().getName(); | |||
ServletContextHandler app = server.addContext("/git"); | |||
GitServlet gs = new GitServlet(); | |||
gs.setRepositoryResolver(new RepositoryResolver() { | |||
public Repository open(HttpServletRequest req, String name) | |||
throws RepositoryNotFoundException, | |||
ServiceNotEnabledException { | |||
if (!name.equals(srcName)) | |||
throw new RepositoryNotFoundException(name); | |||
final Repository db = src.getRepository(); | |||
db.incrementOpen(); | |||
return db; | |||
} | |||
}); | |||
app.addServlet(new ServletHolder(gs), "/*"); | |||
server.setUp(); | |||
remoteRepository = src.getRepository(); | |||
remoteURI = toURIish(app, 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); | |||
} | |||
public void testListRemote() throws IOException { | |||
Repository dst = createBareRepository(); | |||
assertEquals("http", remoteURI.getScheme()); | |||
Map<String, Ref> map; | |||
Transport t = Transport.open(dst, remoteURI); | |||
((TransportHttp) t).setUseSmartHttp(false); | |||
try { | |||
// 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); | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
map = c.getRefsMap(); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
assertNotNull("have map of refs", map); | |||
assertEquals(2, 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(2, requests.size()); | |||
assertEquals(0, getRequests(remoteURI, "git-upload-pack").size()); | |||
AccessEvent info = requests.get(0); | |||
assertEquals("GET", info.getMethod()); | |||
assertEquals(join(remoteURI, "info/refs"), info.getPath()); | |||
assertEquals(0, info.getParameters().size()); | |||
assertNull("no service parameter", info.getParameter("service")); | |||
assertEquals("no-cache", info.getRequestHeader(HDR_PRAGMA)); | |||
assertNotNull("has user-agent", info.getRequestHeader(HDR_USER_AGENT)); | |||
assertTrue("is jgit agent", info.getRequestHeader(HDR_USER_AGENT) | |||
.startsWith("JGit/")); | |||
assertEquals("*/*", info.getRequestHeader(HDR_ACCEPT)); | |||
assertEquals(200, info.getStatus()); | |||
assertEquals("text/plain;charset=UTF-8", info | |||
.getResponseHeader(HDR_CONTENT_TYPE)); | |||
AccessEvent head = requests.get(1); | |||
assertEquals("GET", head.getMethod()); | |||
assertEquals(join(remoteURI, "HEAD"), head.getPath()); | |||
assertEquals(0, head.getParameters().size()); | |||
assertEquals(200, head.getStatus()); | |||
assertEquals("text/plain", head.getResponseHeader(HDR_CONTENT_TYPE)); | |||
} | |||
public void testInitialClone_Small() throws Exception { | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, remoteURI); | |||
((TransportHttp) t).setUseSmartHttp(false); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(dst.hasObject(A_txt)); | |||
assertEquals(B, dst.getRef(master).getObjectId()); | |||
fsck(dst, B); | |||
List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt)); | |||
assertEquals(1, loose.size()); | |||
assertEquals("GET", loose.get(0).getMethod()); | |||
assertEquals(0, loose.get(0).getParameters().size()); | |||
assertEquals(200, loose.get(0).getStatus()); | |||
assertEquals("application/x-git-loose-object", loose.get(0) | |||
.getResponseHeader(HDR_CONTENT_TYPE)); | |||
} | |||
public void testInitialClone_Packed() throws Exception { | |||
new TestRepository(remoteRepository).packAndPrune(); | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, remoteURI); | |||
((TransportHttp) t).setUseSmartHttp(false); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(dst.hasObject(A_txt)); | |||
assertEquals(B, dst.getRef(master).getObjectId()); | |||
fsck(dst, B); | |||
List<AccessEvent> req; | |||
req = getRequests(loose(remoteURI, B)); | |||
assertEquals(1, req.size()); | |||
assertEquals("GET", req.get(0).getMethod()); | |||
assertEquals(0, req.get(0).getParameters().size()); | |||
assertEquals(404, req.get(0).getStatus()); | |||
req = getRequests(join(remoteURI, "objects/info/packs")); | |||
assertEquals(1, req.size()); | |||
assertEquals("GET", req.get(0).getMethod()); | |||
assertEquals(0, req.get(0).getParameters().size()); | |||
assertEquals(200, req.get(0).getStatus()); | |||
assertEquals("text/plain;charset=UTF-8", req.get(0).getResponseHeader( | |||
HDR_CONTENT_TYPE)); | |||
} | |||
public void testPushNotSupported() throws Exception { | |||
final TestRepository src = createTestRepository(); | |||
final RevCommit Q = src.commit().create(); | |||
final Repository db = src.getRepository(); | |||
Transport t = Transport.open(db, remoteURI); | |||
((TransportHttp) t).setUseSmartHttp(false); | |||
try { | |||
try { | |||
t.push(NullProgressMonitor.INSTANCE, push(src, Q)); | |||
fail("push incorrectly completed against a smart server"); | |||
} catch (NotSupportedException nse) { | |||
String exp = "smart HTTP push disabled"; | |||
assertEquals(exp, nse.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,85 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import java.net.HttpURLConnection; | |||
import java.net.URI; | |||
import junit.framework.TestCase; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import org.eclipse.jgit.http.server.glue.ErrorServlet; | |||
import org.eclipse.jgit.http.test.util.AppServer; | |||
public class ErrorServletTest extends TestCase { | |||
private AppServer server; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
server = new AppServer(); | |||
ServletContextHandler ctx = server.addContext("/"); | |||
ctx.addServlet(new ServletHolder(new ErrorServlet(404)), "/404"); | |||
ctx.addServlet(new ServletHolder(new ErrorServlet(500)), "/500"); | |||
server.setUp(); | |||
} | |||
protected void tearDown() throws Exception { | |||
if (server != null) { | |||
server.tearDown(); | |||
} | |||
super.tearDown(); | |||
} | |||
public void testHandler() throws Exception { | |||
final URI uri = server.getURI(); | |||
assertEquals(404, ((HttpURLConnection) uri.resolve("/404").toURL() | |||
.openConnection()).getResponseCode()); | |||
assertEquals(500, ((HttpURLConnection) uri.resolve("/500").toURL() | |||
.openConnection()).getResponseCode()); | |||
} | |||
} |
@@ -0,0 +1,137 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import org.eclipse.jgit.errors.RepositoryNotFoundException; | |||
import org.eclipse.jgit.http.server.resolver.FileResolver; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.lib.Repository; | |||
public class FileResolverTest extends LocalDiskRepositoryTestCase { | |||
public void testUnreasonableNames() throws ServiceNotEnabledException { | |||
assertUnreasonable(""); | |||
assertUnreasonable("a\\b"); | |||
assertUnreasonable("../b"); | |||
assertUnreasonable("a/../b"); | |||
assertUnreasonable("a/./b"); | |||
assertUnreasonable("a//b"); | |||
if (new File("/foo").isAbsolute()) | |||
assertUnreasonable("/foo"); | |||
if (new File("//server/share").isAbsolute()) | |||
assertUnreasonable("//server/share"); | |||
if (new File("C:/windows").isAbsolute()) | |||
assertUnreasonable("C:/windows"); | |||
} | |||
private void assertUnreasonable(String name) | |||
throws ServiceNotEnabledException { | |||
FileResolver r = new FileResolver(new File("."), false); | |||
try { | |||
r.open(null, name); | |||
fail("Opened unreasonable name \"" + name + "\""); | |||
} catch (RepositoryNotFoundException e) { | |||
assertEquals("repository not found: " + name, e.getMessage()); | |||
assertNull("has no cause", e.getCause()); | |||
} | |||
} | |||
public void testExportOk() throws IOException { | |||
final Repository a = createBareRepository(); | |||
final String name = a.getDirectory().getName(); | |||
final File base = a.getDirectory().getParentFile(); | |||
final File export = new File(a.getDirectory(), "git-daemon-export-ok"); | |||
FileResolver resolver; | |||
assertFalse("no git-daemon-export-ok", export.exists()); | |||
resolver = new FileResolver(base, false /* require flag */); | |||
try { | |||
resolver.open(null, name); | |||
fail("opened non-exported repository"); | |||
} catch (ServiceNotEnabledException e) { | |||
assertEquals("Service not enabled", e.getMessage()); | |||
} | |||
resolver = new FileResolver(base, true /* export all */); | |||
try { | |||
resolver.open(null, name).close(); | |||
} catch (ServiceNotEnabledException e) { | |||
fail("did not honor export-all flag"); | |||
} | |||
export.createNewFile(); | |||
assertTrue("has git-daemon-export-ok", export.exists()); | |||
resolver = new FileResolver(base, false /* require flag */); | |||
try { | |||
resolver.open(null, name).close(); | |||
} catch (ServiceNotEnabledException e) { | |||
fail("did not honor git-daemon-export-ok"); | |||
} | |||
} | |||
public void testNotAGitRepository() throws IOException, | |||
ServiceNotEnabledException { | |||
final Repository a = createBareRepository(); | |||
final String name = a.getDirectory().getName() + "-not-a-git"; | |||
final File base = a.getDirectory().getParentFile(); | |||
FileResolver resolver = new FileResolver(base, false); | |||
try { | |||
resolver.open(null, name); | |||
} catch (RepositoryNotFoundException e) { | |||
assertEquals("repository not found: " + name, e.getMessage()); | |||
Throwable why = e.getCause(); | |||
assertNotNull("has cause", why); | |||
assertEquals("repository not found: " | |||
+ new File(base, name).getAbsolutePath(), why.getMessage()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,119 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import java.util.List; | |||
import javax.servlet.ServletException; | |||
import junit.framework.TestCase; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import org.eclipse.jgit.http.server.GitServlet; | |||
import org.eclipse.jgit.http.test.util.AppServer; | |||
import org.eclipse.jgit.http.test.util.MockServletConfig; | |||
import org.eclipse.jgit.http.test.util.RecordingLogger; | |||
public class GitServletInitTest extends TestCase { | |||
private AppServer server; | |||
protected void tearDown() throws Exception { | |||
if (server != null) { | |||
server.tearDown(); | |||
server = null; | |||
} | |||
super.tearDown(); | |||
} | |||
public void testDefaultConstructor_NoBasePath() throws Exception { | |||
GitServlet s = new GitServlet(); | |||
try { | |||
s.init(new MockServletConfig()); | |||
fail("Init did not crash due to missing parameter"); | |||
} catch (ServletException e) { | |||
assertTrue(e.getMessage().contains("base-path")); | |||
} | |||
} | |||
public void testDefaultConstructor_WithBasePath() throws Exception { | |||
MockServletConfig c = new MockServletConfig(); | |||
c.setInitParameter("base-path", "."); | |||
c.setInitParameter("export-all", "false"); | |||
GitServlet s = new GitServlet(); | |||
s.init(c); | |||
s.destroy(); | |||
} | |||
public void testInitUnderContainer_NoBasePath() throws Exception { | |||
server = new AppServer(); | |||
ServletContextHandler app = server.addContext("/"); | |||
ServletHolder s = app.addServlet(GitServlet.class, "/git"); | |||
s.setInitOrder(1); | |||
server.setUp(); | |||
List<RecordingLogger.Warning> events = RecordingLogger.getWarnings(); | |||
assertFalse("Servlet started without base-path", events.isEmpty()); | |||
Throwable why = events.get(0).getCause(); | |||
assertTrue("Caught ServletException", why instanceof ServletException); | |||
assertTrue("Wanted base-path", why.getMessage().contains("base-path")); | |||
} | |||
public void testInitUnderContainer_WithBasePath() throws Exception { | |||
server = new AppServer(); | |||
ServletContextHandler app = server.addContext("/"); | |||
ServletHolder s = app.addServlet(GitServlet.class, "/git"); | |||
s.setInitOrder(1); | |||
s.setInitParameter("base-path", "."); | |||
s.setInitParameter("export-all", "true"); | |||
server.setUp(); | |||
assertTrue("no warnings", RecordingLogger.getWarnings().isEmpty()); | |||
} | |||
} |
@@ -0,0 +1,328 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
import java.io.File; | |||
import java.net.URI; | |||
import java.util.List; | |||
import javax.servlet.http.HttpServletRequest; | |||
import org.eclipse.jetty.servlet.DefaultServlet; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import org.eclipse.jgit.errors.NoRemoteRepositoryException; | |||
import org.eclipse.jgit.errors.RepositoryNotFoundException; | |||
import org.eclipse.jgit.errors.TransportException; | |||
import org.eclipse.jgit.http.server.GitServlet; | |||
import org.eclipse.jgit.http.server.resolver.RepositoryResolver; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.http.test.util.AccessEvent; | |||
import org.eclipse.jgit.http.test.util.HttpTestCase; | |||
import org.eclipse.jgit.junit.TestRepository; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.RefUpdate; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.FetchConnection; | |||
import org.eclipse.jgit.transport.Transport; | |||
import org.eclipse.jgit.transport.URIish; | |||
public class HttpClientTests extends HttpTestCase { | |||
private TestRepository remoteRepository; | |||
private URIish dumbAuthNoneURI; | |||
private URIish dumbAuthBasicURI; | |||
private URIish smartAuthNoneURI; | |||
private URIish smartAuthBasicURI; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
remoteRepository = createTestRepository(); | |||
remoteRepository.update(master, remoteRepository.commit().create()); | |||
ServletContextHandler dNone = dumb("/dnone"); | |||
ServletContextHandler dBasic = server.authBasic(dumb("/dbasic")); | |||
ServletContextHandler sNone = smart("/snone"); | |||
ServletContextHandler sBasic = server.authBasic(smart("/sbasic")); | |||
server.setUp(); | |||
final String srcName = nameOf(remoteRepository); | |||
dumbAuthNoneURI = toURIish(dNone, srcName); | |||
dumbAuthBasicURI = toURIish(dBasic, srcName); | |||
smartAuthNoneURI = toURIish(sNone, srcName); | |||
smartAuthBasicURI = toURIish(sBasic, srcName); | |||
} | |||
private ServletContextHandler dumb(final String path) { | |||
final File srcGit = remoteRepository.getRepository().getDirectory(); | |||
final URI base = srcGit.getParentFile().toURI(); | |||
ServletContextHandler ctx = server.addContext(path); | |||
ctx.setResourceBase(base.toString()); | |||
ctx.addServlet(DefaultServlet.class, "/"); | |||
return ctx; | |||
} | |||
private ServletContextHandler smart(final String path) { | |||
GitServlet gs = new GitServlet(); | |||
gs.setRepositoryResolver(new RepositoryResolver() { | |||
public Repository open(HttpServletRequest req, String name) | |||
throws RepositoryNotFoundException, | |||
ServiceNotEnabledException { | |||
if (!name.equals(nameOf(remoteRepository))) | |||
throw new RepositoryNotFoundException(name); | |||
final Repository db = remoteRepository.getRepository(); | |||
db.incrementOpen(); | |||
return db; | |||
} | |||
}); | |||
ServletContextHandler ctx = server.addContext(path); | |||
ctx.addServlet(new ServletHolder(gs), "/*"); | |||
return ctx; | |||
} | |||
private static String nameOf(final TestRepository db) { | |||
return db.getRepository().getDirectory().getName(); | |||
} | |||
public void testRepositoryNotFound_Dumb() throws Exception { | |||
URIish uri = toURIish("/dumb.none/not-found"); | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, uri); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("connection opened to not found repository"); | |||
} catch (NoRemoteRepositoryException err) { | |||
String exp = uri + ": " + uri | |||
+ "/info/refs?service=git-upload-pack not found"; | |||
assertEquals(exp, err.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
public void testRepositoryNotFound_Smart() throws Exception { | |||
URIish uri = toURIish("/smart.none/not-found"); | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, uri); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("connection opened to not found repository"); | |||
} catch (NoRemoteRepositoryException err) { | |||
String exp = uri + ": " + uri | |||
+ "/info/refs?service=git-upload-pack not found"; | |||
assertEquals(exp, err.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
public void testListRemote_Dumb_DetachedHEAD() throws Exception { | |||
Repository src = remoteRepository.getRepository(); | |||
RefUpdate u = src.updateRef(Constants.HEAD, true); | |||
RevCommit Q = remoteRepository.commit().message("Q").create(); | |||
u.setNewObjectId(Q); | |||
assertEquals(RefUpdate.Result.FORCED, u.forceUpdate()); | |||
Repository dst = createBareRepository(); | |||
Ref head; | |||
Transport t = Transport.open(dst, dumbAuthNoneURI); | |||
try { | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
head = c.getRef(Constants.HEAD); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
assertNotNull("has " + Constants.HEAD, head); | |||
assertEquals(Q, head.getObjectId()); | |||
} | |||
public void testListRemote_Dumb_NoHEAD() throws Exception { | |||
Repository src = remoteRepository.getRepository(); | |||
File headref = new File(src.getDirectory(), Constants.HEAD); | |||
assertTrue("HEAD used to be present", headref.delete()); | |||
assertFalse("HEAD is gone", headref.exists()); | |||
Repository dst = createBareRepository(); | |||
Ref head; | |||
Transport t = Transport.open(dst, dumbAuthNoneURI); | |||
try { | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
head = c.getRef(Constants.HEAD); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
assertNull("has no " + Constants.HEAD, head); | |||
} | |||
public void testListRemote_Smart_DetachedHEAD() throws Exception { | |||
Repository src = remoteRepository.getRepository(); | |||
RefUpdate u = src.updateRef(Constants.HEAD, true); | |||
RevCommit Q = remoteRepository.commit().message("Q").create(); | |||
u.setNewObjectId(Q); | |||
assertEquals(RefUpdate.Result.FORCED, u.forceUpdate()); | |||
Repository dst = createBareRepository(); | |||
Ref head; | |||
Transport t = Transport.open(dst, smartAuthNoneURI); | |||
try { | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
head = c.getRef(Constants.HEAD); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
assertNotNull("has " + Constants.HEAD, head); | |||
assertEquals(Q, head.getObjectId()); | |||
} | |||
public void testListRemote_Smart_WithQueryParameters() throws Exception { | |||
URIish myURI = toURIish("/snone/do?r=1&p=test.git"); | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, myURI); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("test did not fail to find repository as expected"); | |||
} catch (NoRemoteRepositoryException err) { | |||
// expected | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
List<AccessEvent> requests = getRequests(); | |||
assertEquals(1, requests.size()); | |||
AccessEvent info = requests.get(0); | |||
assertEquals("GET", info.getMethod()); | |||
assertEquals("/snone/do", info.getPath()); | |||
assertEquals(3, info.getParameters().size()); | |||
assertEquals("1", info.getParameter("r")); | |||
assertEquals("test.git/info/refs", info.getParameter("p")); | |||
assertEquals("git-upload-pack", info.getParameter("service")); | |||
assertEquals(404, info.getStatus()); | |||
} | |||
public void testListRemote_Dumb_NeedsAuth() throws Exception { | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, dumbAuthBasicURI); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("connection opened even info/refs needs auth basic"); | |||
} catch (TransportException err) { | |||
String status = "401 Unauthorized"; | |||
String exp = dumbAuthBasicURI + ": " + status; | |||
assertEquals(exp, err.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
public void testListRemote_Smart_UploadPackNeedsAuth() throws Exception { | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, smartAuthBasicURI); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("connection opened even though service disabled"); | |||
} catch (TransportException err) { | |||
String status = "401 Unauthorized"; | |||
String exp = smartAuthBasicURI + ": " + status; | |||
assertEquals(exp, err.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
public void testListRemote_Smart_UploadPackDisabled() throws Exception { | |||
Repository src = remoteRepository.getRepository(); | |||
src.getConfig().setBoolean("http", null, "uploadpack", false); | |||
src.getConfig().save(); | |||
Repository dst = createBareRepository(); | |||
Transport t = Transport.open(dst, smartAuthNoneURI); | |||
try { | |||
try { | |||
t.openFetch(); | |||
fail("connection opened even though service disabled"); | |||
} catch (TransportException err) { | |||
String exp = smartAuthNoneURI | |||
+ ": git-upload-pack not permitted"; | |||
assertEquals(exp, err.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,556 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test; | |||
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 java.io.IOException; | |||
import java.io.PrintWriter; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Map; | |||
import javax.servlet.Filter; | |||
import javax.servlet.FilterChain; | |||
import javax.servlet.FilterConfig; | |||
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.FilterMapping; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.servlet.ServletHolder; | |||
import org.eclipse.jgit.errors.RepositoryNotFoundException; | |||
import org.eclipse.jgit.errors.TransportException; | |||
import org.eclipse.jgit.http.server.GitServlet; | |||
import org.eclipse.jgit.http.server.resolver.RepositoryResolver; | |||
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; | |||
import org.eclipse.jgit.http.test.util.AccessEvent; | |||
import org.eclipse.jgit.http.test.util.HttpTestCase; | |||
import org.eclipse.jgit.junit.TestRepository; | |||
import org.eclipse.jgit.junit.TestRng; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.ReflogReader; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.lib.RepositoryConfig; | |||
import org.eclipse.jgit.revwalk.RevBlob; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.FetchConnection; | |||
import org.eclipse.jgit.transport.HttpTransport; | |||
import org.eclipse.jgit.transport.RemoteRefUpdate; | |||
import org.eclipse.jgit.transport.Transport; | |||
import org.eclipse.jgit.transport.TransportHttp; | |||
import org.eclipse.jgit.transport.URIish; | |||
public class SmartClientSmartServerTest extends HttpTestCase { | |||
private static final String HDR_TRANSFER_ENCODING = "Transfer-Encoding"; | |||
private Repository remoteRepository; | |||
private URIish remoteURI; | |||
private URIish brokenURI; | |||
private RevBlob A_txt; | |||
private RevCommit A, B; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
final TestRepository src = createTestRepository(); | |||
final String srcName = src.getRepository().getDirectory().getName(); | |||
ServletContextHandler app = server.addContext("/git"); | |||
GitServlet gs = new GitServlet(); | |||
gs.setRepositoryResolver(new RepositoryResolver() { | |||
public Repository open(HttpServletRequest req, String name) | |||
throws RepositoryNotFoundException, | |||
ServiceNotEnabledException { | |||
if (!name.equals(srcName)) | |||
throw new RepositoryNotFoundException(name); | |||
final Repository db = src.getRepository(); | |||
db.incrementOpen(); | |||
return db; | |||
} | |||
}); | |||
app.addServlet(new ServletHolder(gs), "/*"); | |||
ServletContextHandler broken = server.addContext("/bad"); | |||
broken.addFilter(new FilterHolder(new Filter() { | |||
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"); | |||
PrintWriter w = r.getWriter(); | |||
w.print("OK"); | |||
w.close(); | |||
} | |||
public void init(FilterConfig filterConfig) throws ServletException { | |||
// | |||
} | |||
public void destroy() { | |||
// | |||
} | |||
}), "/" + srcName + "/git-upload-pack", FilterMapping.DEFAULT); | |||
broken.addServlet(new ServletHolder(gs), "/*"); | |||
server.setUp(); | |||
remoteRepository = src.getRepository(); | |||
remoteURI = toURIish(app, srcName); | |||
brokenURI = toURIish(broken, 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); | |||
src.update("refs/garbage/a/very/long/ref/name/to/compress", B); | |||
} | |||
public void testListRemote() throws IOException { | |||
Repository dst = createBareRepository(); | |||
assertEquals("http", remoteURI.getScheme()); | |||
Map<String, Ref> map; | |||
Transport t = Transport.open(dst, remoteURI); | |||
try { | |||
// 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); | |||
FetchConnection c = t.openFetch(); | |||
try { | |||
map = c.getRefsMap(); | |||
} finally { | |||
c.close(); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
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)); | |||
} | |||
public void testInitialClone_Small() throws Exception { | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, remoteURI); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(dst.hasObject(A_txt)); | |||
assertEquals(B, dst.getRef(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)); | |||
assertNull("no compression (too small)", service | |||
.getRequestHeader(HDR_CONTENT_ENCODING)); | |||
assertEquals(200, service.getStatus()); | |||
assertEquals("application/x-git-upload-pack-result", service | |||
.getResponseHeader(HDR_CONTENT_TYPE)); | |||
assertNull("no compression (never compressed)", service | |||
.getResponseHeader(HDR_CONTENT_ENCODING)); | |||
} | |||
public void testFetchUpdateExisting() throws Exception { | |||
// Bootstrap by doing the clone. | |||
// | |||
TestRepository dst = createTestRepository(); | |||
Transport t = Transport.open(dst.getRepository(), remoteURI); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertEquals(B, dst.getRepository().getRef(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. | |||
// | |||
b = new TestRepository(remoteRepository).branch(master); | |||
RevCommit Z = b.commit().message("Z").create(); | |||
// Now incrementally update. | |||
// | |||
t = Transport.open(dst.getRepository(), remoteURI); | |||
try { | |||
t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertEquals(Z, dst.getRepository().getRef(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)); | |||
} | |||
public void testInitialClone_BrokenServer() throws Exception { | |||
Repository dst = createBareRepository(); | |||
assertFalse(dst.hasObject(A_txt)); | |||
Transport t = Transport.open(dst, brokenURI); | |||
try { | |||
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()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
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)); | |||
} | |||
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"; | |||
Transport t; | |||
// push anonymous shouldn't be allowed. | |||
// | |||
t = Transport.open(db, remoteURI); | |||
try { | |||
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 status = "401 Unauthorized"; | |||
final String exp = remoteURI.toString() + ": " + status; | |||
assertEquals(exp, e.getMessage()); | |||
} | |||
} finally { | |||
t.close(); | |||
} | |||
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()); | |||
} | |||
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"; | |||
Transport t; | |||
enableReceivePack(); | |||
t = Transport.open(db, remoteURI); | |||
try { | |||
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)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(remoteRepository.hasObject(Q_txt)); | |||
assertNotNull("has " + dstName, remoteRepository.getRef(dstName)); | |||
assertEquals(Q, remoteRepository.getRef(dstName).getObjectId()); | |||
fsck(remoteRepository, Q); | |||
final ReflogReader log = remoteRepository.getReflogReader(dstName); | |||
assertNotNull("has log for " + dstName); | |||
final ReflogReader.Entry 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)); | |||
} | |||
public void testPush_ChunkedEncoding() throws Exception { | |||
final TestRepository 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"; | |||
Transport t; | |||
enableReceivePack(); | |||
db.getConfig().setInt("core", null, "compression", 0); | |||
db.getConfig().setInt("http", null, "postbuffer", 8 * 1024); | |||
db.getConfig().save(); | |||
t = Transport.open(db, remoteURI); | |||
try { | |||
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)); | |||
} finally { | |||
t.close(); | |||
} | |||
assertTrue(remoteRepository.hasObject(Q_bin)); | |||
assertNotNull("has " + dstName, remoteRepository.getRef(dstName)); | |||
assertEquals(Q, remoteRepository.getRef(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 RepositoryConfig cfg = remoteRepository.getConfig(); | |||
cfg.setBoolean("http", null, "receivepack", true); | |||
cfg.save(); | |||
} | |||
} |
@@ -0,0 +1,181 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.util.Collections; | |||
import java.util.Enumeration; | |||
import java.util.Map; | |||
import java.util.TreeMap; | |||
import org.eclipse.jetty.server.Request; | |||
import org.eclipse.jetty.server.Response; | |||
/** A single request made through {@link AppServer}. */ | |||
public class AccessEvent { | |||
private final String method; | |||
private final String uri; | |||
private final Map<String, String> requestHeaders; | |||
private final Map<String, String[]> parameters; | |||
private final int status; | |||
private final Map<String, String> responseHeaders; | |||
AccessEvent(final Request req, final Response rsp) { | |||
method = req.getMethod(); | |||
uri = req.getRequestURI(); | |||
requestHeaders = cloneHeaders(req); | |||
parameters = clone(req.getParameterMap()); | |||
status = rsp.getStatus(); | |||
responseHeaders = cloneHeaders(rsp); | |||
} | |||
private static Map<String, String> cloneHeaders(final Request req) { | |||
Map<String, String> r = new TreeMap<String, String>(); | |||
Enumeration hn = req.getHeaderNames(); | |||
while (hn.hasMoreElements()) { | |||
String key = (String) hn.nextElement(); | |||
if (!r.containsKey(key)) { | |||
r.put(key, req.getHeader(key)); | |||
} | |||
} | |||
return Collections.unmodifiableMap(r); | |||
} | |||
private static Map<String, String> cloneHeaders(final Response rsp) { | |||
Map<String, String> r = new TreeMap<String, String>(); | |||
Enumeration<String> hn = rsp.getHttpFields().getFieldNames(); | |||
while (hn.hasMoreElements()) { | |||
String key = hn.nextElement(); | |||
if (!r.containsKey(key)) { | |||
Enumeration<String> v = rsp.getHttpFields().getValues(key); | |||
r.put(key, v.nextElement()); | |||
} | |||
} | |||
return Collections.unmodifiableMap(r); | |||
} | |||
@SuppressWarnings("unchecked") | |||
private static Map<String, String[]> clone(Map parameterMap) { | |||
return new TreeMap<String, String[]>(parameterMap); | |||
} | |||
/** @return {@code "GET"} or {@code "POST"} */ | |||
public String getMethod() { | |||
return method; | |||
} | |||
/** @return path of the file on the server, e.g. {@code /git/HEAD}. */ | |||
public String getPath() { | |||
return uri; | |||
} | |||
/** | |||
* @param name | |||
* name of the request header to read. | |||
* @return first value of the request header; null if not sent. | |||
*/ | |||
public String getRequestHeader(String name) { | |||
return requestHeaders.get(name); | |||
} | |||
/** | |||
* @param name | |||
* name of the request parameter to read. | |||
* @return first value of the request parameter; null if not sent. | |||
*/ | |||
public String getParameter(String name) { | |||
String[] r = parameters.get(name); | |||
return r != null && 1 <= r.length ? r[0] : null; | |||
} | |||
/** @return all parameters in the request. */ | |||
public Map<String, String[]> getParameters() { | |||
return parameters; | |||
} | |||
/** @return HTTP status code of the response, e.g. 200, 403, 500. */ | |||
public int getStatus() { | |||
return status; | |||
} | |||
/** | |||
* @param name | |||
* name of the response header to read. | |||
* @return first value of the response header; null if not sent. | |||
*/ | |||
public String getResponseHeader(String name) { | |||
return responseHeaders.get(name); | |||
} | |||
public String toString() { | |||
StringBuilder b = new StringBuilder(); | |||
b.append(method); | |||
b.append(' '); | |||
b.append(uri); | |||
if (!parameters.isEmpty()) { | |||
b.append('?'); | |||
boolean first = true; | |||
for (Map.Entry<String, String[]> e : parameters.entrySet()) { | |||
for (String val : e.getValue()) { | |||
if (!first) { | |||
b.append('&'); | |||
} | |||
first = false; | |||
b.append(e.getKey()); | |||
b.append('='); | |||
b.append(val); | |||
} | |||
} | |||
} | |||
b.append(' '); | |||
b.append(status); | |||
return b.toString(); | |||
} | |||
} |
@@ -0,0 +1,295 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.io.IOException; | |||
import java.net.InetAddress; | |||
import java.net.URI; | |||
import java.net.URISyntaxException; | |||
import java.net.UnknownHostException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import junit.framework.Assert; | |||
import org.eclipse.jetty.http.security.Constraint; | |||
import org.eclipse.jetty.http.security.Password; | |||
import org.eclipse.jetty.security.Authenticator; | |||
import org.eclipse.jetty.security.ConstraintMapping; | |||
import org.eclipse.jetty.security.ConstraintSecurityHandler; | |||
import org.eclipse.jetty.security.MappedLoginService; | |||
import org.eclipse.jetty.security.authentication.BasicAuthenticator; | |||
import org.eclipse.jetty.server.Connector; | |||
import org.eclipse.jetty.server.Server; | |||
import org.eclipse.jetty.server.UserIdentity; | |||
import org.eclipse.jetty.server.handler.ContextHandlerCollection; | |||
import org.eclipse.jetty.server.handler.RequestLogHandler; | |||
import org.eclipse.jetty.server.nio.SelectChannelConnector; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jetty.util.thread.QueuedThreadPool; | |||
import org.eclipse.jgit.transport.URIish; | |||
/** | |||
* Tiny web application server for unit testing. | |||
* <p> | |||
* Tests should start the server in their {@code setUp()} method and stop the | |||
* server in their {@code tearDown()} method. Only while started the server's | |||
* URL and/or port number can be obtained. | |||
*/ | |||
public class AppServer { | |||
/** Realm name for the secure access areas. */ | |||
public static final String realm = "Secure Area"; | |||
/** Username for secured access areas. */ | |||
public static final String username = "agitter"; | |||
/** Password for {@link #username} in secured access areas. */ | |||
public static final String password = "letmein"; | |||
static { | |||
// Install a logger that throws warning messages. | |||
// | |||
final String prop = "org.eclipse.jetty.util.log.class"; | |||
System.setProperty(prop, RecordingLogger.class.getName()); | |||
} | |||
private final Server server; | |||
private final Connector connector; | |||
private final ContextHandlerCollection contexts; | |||
private final TestRequestLog log; | |||
public AppServer() { | |||
connector = new SelectChannelConnector(); | |||
connector.setPort(0); | |||
try { | |||
final InetAddress me = InetAddress.getByName("localhost"); | |||
connector.setHost(me.getHostAddress()); | |||
} catch (UnknownHostException e) { | |||
throw new RuntimeException("Cannot find localhost", e); | |||
} | |||
// We need a handful of threads in the thread pool, otherwise | |||
// our tests will deadlock when they can't open enough requests. | |||
// In theory we only need 1 concurrent connection at a time, but | |||
// I suspect the JRE isn't doing request pipelining on existing | |||
// connections like we want it to. | |||
// | |||
final QueuedThreadPool pool = new QueuedThreadPool(); | |||
pool.setMinThreads(1); | |||
pool.setMaxThreads(4); | |||
pool.setMaxQueued(8); | |||
contexts = new ContextHandlerCollection(); | |||
log = new TestRequestLog(); | |||
final RequestLogHandler logHandler = new RequestLogHandler(); | |||
logHandler.setHandler(contexts); | |||
logHandler.setRequestLog(log); | |||
server = new Server(); | |||
server.setConnectors(new Connector[] { connector }); | |||
server.setThreadPool(pool); | |||
server.setHandler(logHandler); | |||
server.setStopAtShutdown(false); | |||
server.setGracefulShutdown(0); | |||
} | |||
/** | |||
* Create a new servlet context within the server. | |||
* <p> | |||
* This method should be invoked before the server is started, once for each | |||
* context the caller wants to register. | |||
* | |||
* @param path | |||
* path of the context; use "/" for the root context if binding | |||
* to the root is desired. | |||
* @return the context to add servlets into. | |||
*/ | |||
public ServletContextHandler addContext(String path) { | |||
assertNotYetSetUp(); | |||
if ("".equals(path)) | |||
path = "/"; | |||
ServletContextHandler ctx = new ServletContextHandler(); | |||
ctx.setContextPath(path); | |||
contexts.addHandler(ctx); | |||
return ctx; | |||
} | |||
public ServletContextHandler authBasic(ServletContextHandler ctx) { | |||
assertNotYetSetUp(); | |||
auth(ctx, new BasicAuthenticator()); | |||
return ctx; | |||
} | |||
private void auth(ServletContextHandler ctx, Authenticator authType) { | |||
final String role = "can-access"; | |||
MappedLoginService users = new MappedLoginService() { | |||
@Override | |||
protected UserIdentity loadUser(String who) { | |||
return null; | |||
} | |||
@Override | |||
protected void loadUsers() throws IOException { | |||
putUser(username, new Password(password), new String[] { role }); | |||
} | |||
}; | |||
ConstraintMapping cm = new ConstraintMapping(); | |||
cm.setConstraint(new Constraint()); | |||
cm.getConstraint().setAuthenticate(true); | |||
cm.getConstraint().setDataConstraint(Constraint.DC_NONE); | |||
cm.getConstraint().setRoles(new String[] { role }); | |||
cm.setPathSpec("/*"); | |||
ConstraintSecurityHandler sec = new ConstraintSecurityHandler(); | |||
sec.setStrict(false); | |||
sec.setRealmName(realm); | |||
sec.setAuthenticator(authType); | |||
sec.setLoginService(users); | |||
sec.setConstraintMappings(new ConstraintMapping[] { cm }); | |||
sec.setHandler(ctx); | |||
contexts.removeHandler(ctx); | |||
contexts.addHandler(sec); | |||
} | |||
/** | |||
* Start the server on a random local port. | |||
* | |||
* @throws Exception | |||
* the server cannot be started, testing is not possible. | |||
*/ | |||
public void setUp() throws Exception { | |||
RecordingLogger.clear(); | |||
log.clear(); | |||
server.start(); | |||
} | |||
/** | |||
* Shutdown the server. | |||
* | |||
* @throws Exception | |||
* the server refuses to halt, or wasn't running. | |||
*/ | |||
public void tearDown() throws Exception { | |||
RecordingLogger.clear(); | |||
log.clear(); | |||
server.stop(); | |||
} | |||
/** | |||
* Get the URI to reference this server. | |||
* <p> | |||
* The returned URI includes the proper host name and port number, but does | |||
* not contain a path. | |||
* | |||
* @return URI to reference this server's root context. | |||
*/ | |||
public URI getURI() { | |||
assertAlreadySetUp(); | |||
String host = connector.getHost(); | |||
if (host.contains(":") && !host.startsWith("[")) | |||
host = "[" + host + "]"; | |||
final String uri = "http://" + host + ":" + getPort(); | |||
try { | |||
return new URI(uri); | |||
} catch (URISyntaxException e) { | |||
throw new RuntimeException("Unexpected URI error on " + uri, e); | |||
} | |||
} | |||
/** @return the local port number the server is listening on. */ | |||
public int getPort() { | |||
assertAlreadySetUp(); | |||
return ((SelectChannelConnector) connector).getLocalPort(); | |||
} | |||
/** @return all requests since the server was started. */ | |||
public List<AccessEvent> getRequests() { | |||
return new ArrayList<AccessEvent>(log.getEvents()); | |||
} | |||
/** | |||
* @param base | |||
* base URI used to access the server. | |||
* @param path | |||
* the path to locate requests for, relative to {@code base}. | |||
* @return all requests which match the given path. | |||
*/ | |||
public List<AccessEvent> getRequests(URIish base, String path) { | |||
return getRequests(HttpTestCase.join(base, path)); | |||
} | |||
/** | |||
* @param path | |||
* the path to locate requests for. | |||
* @return all requests which match the given path. | |||
*/ | |||
public List<AccessEvent> getRequests(String path) { | |||
ArrayList<AccessEvent> r = new ArrayList<AccessEvent>(); | |||
for (AccessEvent event : log.getEvents()) { | |||
if (event.getPath().equals(path)) { | |||
r.add(event); | |||
} | |||
} | |||
return r; | |||
} | |||
private void assertNotYetSetUp() { | |||
Assert.assertFalse("server is not running", server.isRunning()); | |||
} | |||
private void assertAlreadySetUp() { | |||
Assert.assertTrue("server is running", server.isRunning()); | |||
} | |||
} |
@@ -0,0 +1,161 @@ | |||
/* | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.io.IOException; | |||
import java.net.URI; | |||
import java.net.URISyntaxException; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import org.eclipse.jetty.servlet.ServletContextHandler; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.junit.TestRepository; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
import org.eclipse.jgit.transport.RefSpec; | |||
import org.eclipse.jgit.transport.RemoteRefUpdate; | |||
import org.eclipse.jgit.transport.URIish; | |||
/** Base class for HTTP related transport testing. */ | |||
public abstract class HttpTestCase extends LocalDiskRepositoryTestCase { | |||
protected static final String master = Constants.R_HEADS + Constants.MASTER; | |||
/** In-memory application server; subclass must start. */ | |||
protected AppServer server; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
server = new AppServer(); | |||
} | |||
protected void tearDown() throws Exception { | |||
server.tearDown(); | |||
super.tearDown(); | |||
} | |||
protected TestRepository createTestRepository() throws Exception { | |||
return new TestRepository(createBareRepository()); | |||
} | |||
protected URIish toURIish(String path) throws URISyntaxException { | |||
URI u = server.getURI().resolve(path); | |||
return new URIish(u.toString()); | |||
} | |||
protected URIish toURIish(ServletContextHandler app, String name) | |||
throws URISyntaxException { | |||
String p = app.getContextPath(); | |||
if (!p.endsWith("/") && !name.startsWith("/")) | |||
p += "/"; | |||
p += name; | |||
return toURIish(p); | |||
} | |||
protected List<AccessEvent> getRequests() { | |||
return server.getRequests(); | |||
} | |||
protected List<AccessEvent> getRequests(URIish base, String path) { | |||
return server.getRequests(base, path); | |||
} | |||
protected List<AccessEvent> getRequests(String path) { | |||
return server.getRequests(path); | |||
} | |||
protected static void fsck(Repository db, RevObject... tips) | |||
throws Exception { | |||
new TestRepository(db).fsck(tips); | |||
} | |||
protected static Set<RefSpec> mirror(String... refs) { | |||
HashSet<RefSpec> r = new HashSet<RefSpec>(); | |||
for (String name : refs) { | |||
RefSpec rs = new RefSpec(name); | |||
rs = rs.setDestination(name); | |||
rs = rs.setForceUpdate(true); | |||
r.add(rs); | |||
} | |||
return r; | |||
} | |||
protected static Collection<RemoteRefUpdate> push(TestRepository from, | |||
RevCommit q) throws IOException { | |||
final Repository db = from.getRepository(); | |||
final String srcExpr = q.name(); | |||
final String dstName = master; | |||
final boolean forceUpdate = true; | |||
final String localName = null; | |||
final ObjectId oldId = null; | |||
RemoteRefUpdate u = new RemoteRefUpdate(db, srcExpr, dstName, | |||
forceUpdate, localName, oldId); | |||
return Collections.singleton(u); | |||
} | |||
public static String loose(URIish base, AnyObjectId id) { | |||
final String objectName = id.name(); | |||
final String d = objectName.substring(0, 2); | |||
final String f = objectName.substring(2); | |||
return join(base, "objects/" + d + "/" + f); | |||
} | |||
public static String join(URIish base, String path) { | |||
if (path.startsWith("/")) | |||
fail("Cannot join absolute path " + path + " to URIish " + base); | |||
String dir = base.getPath(); | |||
if (!dir.endsWith("/")) | |||
dir += "/"; | |||
return dir + path; | |||
} | |||
} |
@@ -0,0 +1,85 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.util.Enumeration; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
import javax.servlet.ServletConfig; | |||
import javax.servlet.ServletContext; | |||
public class MockServletConfig implements ServletConfig { | |||
private final Map<String, String> parameters = new HashMap<String, String>(); | |||
public void setInitParameter(String name, String value) { | |||
parameters.put(name, value); | |||
} | |||
public String getInitParameter(String name) { | |||
return parameters.get(name); | |||
} | |||
public Enumeration getInitParameterNames() { | |||
final Iterator<String> i = parameters.keySet().iterator(); | |||
return new Enumeration<String>() { | |||
public boolean hasMoreElements() { | |||
return i.hasNext(); | |||
} | |||
public String nextElement() { | |||
return i.next(); | |||
} | |||
}; | |||
} | |||
public String getServletName() { | |||
return "MOCK_SERVLET"; | |||
} | |||
public ServletContext getServletContext() { | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,146 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.eclipse.jetty.util.log.Logger; | |||
/** Logs warnings into an array for later inspection. */ | |||
public class RecordingLogger implements Logger { | |||
private static List<Warning> warnings = new ArrayList<Warning>(); | |||
/** Clear the warnings, automatically done by {@link AppServer#setUp()} */ | |||
public static void clear() { | |||
synchronized (warnings) { | |||
warnings.clear(); | |||
} | |||
} | |||
/** @return the warnings (if any) from the last execution */ | |||
public static List<Warning> getWarnings() { | |||
synchronized (warnings) { | |||
ArrayList<Warning> copy = new ArrayList<Warning>(warnings); | |||
return Collections.unmodifiableList(copy); | |||
} | |||
} | |||
@SuppressWarnings("serial") | |||
public static class Warning extends Exception { | |||
public Warning(String msg) { | |||
super(msg); | |||
} | |||
public Warning(String msg, Throwable cause) { | |||
super(msg, cause); | |||
} | |||
} | |||
private final String name; | |||
public RecordingLogger() { | |||
this(""); | |||
} | |||
public RecordingLogger(final String name) { | |||
this.name = name; | |||
} | |||
public Logger getLogger(@SuppressWarnings("hiding") String name) { | |||
return new RecordingLogger(name); | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public void warn(String msg, Object arg0, Object arg1) { | |||
synchronized (warnings) { | |||
warnings.add(new Warning(MessageFormat.format(msg, arg0, arg1))); | |||
} | |||
} | |||
public void warn(String msg, Throwable th) { | |||
synchronized (warnings) { | |||
warnings.add(new Warning(msg, th)); | |||
} | |||
} | |||
public void warn(String msg) { | |||
synchronized (warnings) { | |||
warnings.add(new Warning(msg)); | |||
} | |||
} | |||
public void debug(String msg, Object arg0, Object arg1) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
public void debug(String msg, Throwable th) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
public void debug(String msg) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
public void info(String msg, Object arg0, Object arg1) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
public void info(String msg) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
public boolean isDebugEnabled() { | |||
return false; | |||
} | |||
public void setDebugEnabled(boolean enabled) { | |||
// Ignore (not relevant to test failures) | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.http.test.util; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.eclipse.jetty.server.Request; | |||
import org.eclipse.jetty.server.RequestLog; | |||
import org.eclipse.jetty.server.Response; | |||
import org.eclipse.jetty.util.component.AbstractLifeCycle; | |||
/** Logs request made through {@link AppServer}. */ | |||
class TestRequestLog extends AbstractLifeCycle implements RequestLog { | |||
private final List<AccessEvent> events = new ArrayList<AccessEvent>(); | |||
/** Reset the log back to its original empty state. */ | |||
synchronized void clear() { | |||
events.clear(); | |||
} | |||
/** @return all of the events made since the last clear. */ | |||
synchronized List<AccessEvent> getEvents() { | |||
return events; | |||
} | |||
public synchronized void log(Request request, Response response) { | |||
events.add(new AccessEvent(request, response)); | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (C) 2009, Google Inc. | |||
* Copyright (C) 2009-2010, Google Inc. | |||
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> | |||
* Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org> | |||
* and other copyright owners as documented in the project's IP log. | |||
@@ -57,8 +57,10 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.concurrent.TimeUnit; | |||
import junit.framework.Assert; | |||
import junit.framework.TestCase; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.FileBasedConfig; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
@@ -404,6 +406,14 @@ public abstract class LocalDiskRepositoryTestCase extends TestCase { | |||
return new String(body, 0, body.length, "UTF-8"); | |||
} | |||
protected static void assertEquals(AnyObjectId exp, AnyObjectId act) { | |||
if (exp != null) | |||
exp = exp.copy(); | |||
if (act != null) | |||
act = act.copy(); | |||
Assert.assertEquals(exp, act); | |||
} | |||
private static String[] toEnvArray(final Map<String, String> env) { | |||
final String[] envp = new String[env.size()]; | |||
int i = 0; |
@@ -44,11 +44,15 @@ | |||
package org.eclipse.jgit.junit; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.security.MessageDigest; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import junit.framework.Assert; | |||
import junit.framework.AssertionFailedError; | |||
@@ -60,21 +64,30 @@ import org.eclipse.jgit.dircache.DirCacheEntry; | |||
import org.eclipse.jgit.dircache.DirCacheEditor.DeletePath; | |||
import org.eclipse.jgit.dircache.DirCacheEditor.DeleteTree; | |||
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit; | |||
import org.eclipse.jgit.errors.IncorrectObjectTypeException; | |||
import org.eclipse.jgit.errors.MissingObjectException; | |||
import org.eclipse.jgit.errors.ObjectWritingException; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Commit; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.FileMode; | |||
import org.eclipse.jgit.lib.LockFile; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.ObjectChecker; | |||
import org.eclipse.jgit.lib.ObjectDatabase; | |||
import org.eclipse.jgit.lib.ObjectDirectory; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.ObjectWriter; | |||
import org.eclipse.jgit.lib.PackFile; | |||
import org.eclipse.jgit.lib.PackWriter; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.RefUpdate; | |||
import org.eclipse.jgit.lib.RefWriter; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.lib.Tag; | |||
import org.eclipse.jgit.lib.PackIndex.MutableEntry; | |||
import org.eclipse.jgit.revwalk.ObjectWalk; | |||
import org.eclipse.jgit.revwalk.RevBlob; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
@@ -428,26 +441,25 @@ public class TestRepository { | |||
* @throws Exception | |||
*/ | |||
public void updateServerInfo() throws Exception { | |||
if (db.getObjectDatabase() instanceof ObjectDirectory) { | |||
final ObjectDatabase odb = db.getObjectDatabase(); | |||
if (odb instanceof ObjectDirectory) { | |||
RefWriter rw = new RefWriter(db.getAllRefs().values()) { | |||
@Override | |||
protected void writeFile(final String name, final byte[] bin) | |||
throws IOException { | |||
final File p = new File(db.getDirectory(), name); | |||
final LockFile lck = new LockFile(p); | |||
if (!lck.lock()) | |||
throw new ObjectWritingException("Can't write " + p); | |||
try { | |||
lck.write(bin); | |||
} catch (IOException ioe) { | |||
throw new ObjectWritingException("Can't write " + p); | |||
} | |||
if (!lck.commit()) | |||
throw new ObjectWritingException("Can't write " + p); | |||
TestRepository.this.writeFile(name, bin); | |||
} | |||
}; | |||
rw.writePackedRefs(); | |||
rw.writeInfoRefs(); | |||
final StringBuilder w = new StringBuilder(); | |||
for (PackFile p : ((ObjectDirectory) odb).getPacks()) { | |||
w.append("P "); | |||
w.append(p.getPackFile().getName()); | |||
w.append('\n'); | |||
} | |||
writeFile("objects/info/packs", Constants.encodeASCII(w.toString())); | |||
} | |||
} | |||
@@ -484,6 +496,132 @@ public class TestRepository { | |||
return new BranchBuilder(ref); | |||
} | |||
/** | |||
* Run consistency checks against the object database. | |||
* <p> | |||
* This method completes silently if the checks pass. A temporary revision | |||
* pool is constructed during the checking. | |||
* | |||
* @param tips | |||
* the tips to start checking from; if not supplied the refs of | |||
* the repository are used instead. | |||
* @throws MissingObjectException | |||
* @throws IncorrectObjectTypeException | |||
* @throws IOException | |||
*/ | |||
public void fsck(RevObject... tips) throws MissingObjectException, | |||
IncorrectObjectTypeException, IOException { | |||
ObjectWalk ow = new ObjectWalk(db); | |||
if (tips.length != 0) { | |||
for (RevObject o : tips) | |||
ow.markStart(ow.parseAny(o)); | |||
} else { | |||
for (Ref r : db.getAllRefs().values()) | |||
ow.markStart(ow.parseAny(r.getObjectId())); | |||
} | |||
ObjectChecker oc = new ObjectChecker(); | |||
for (;;) { | |||
final RevCommit o = ow.next(); | |||
if (o == null) | |||
break; | |||
final byte[] bin = db.openObject(o).getCachedBytes(); | |||
oc.checkCommit(bin); | |||
assertHash(o, bin); | |||
} | |||
for (;;) { | |||
final RevObject o = ow.nextObject(); | |||
if (o == null) | |||
break; | |||
final byte[] bin = db.openObject(o).getCachedBytes(); | |||
oc.check(o.getType(), bin); | |||
assertHash(o, bin); | |||
} | |||
} | |||
private static void assertHash(RevObject id, byte[] bin) { | |||
MessageDigest md = Constants.newMessageDigest(); | |||
md.update(Constants.encodedTypeString(id.getType())); | |||
md.update((byte) ' '); | |||
md.update(Constants.encodeASCII(bin.length)); | |||
md.update((byte) 0); | |||
md.update(bin); | |||
Assert.assertEquals(id.copy(), ObjectId.fromRaw(md.digest())); | |||
} | |||
/** | |||
* Pack all reachable objects in the repository into a single pack file. | |||
* <p> | |||
* All loose objects are automatically pruned. Existing packs however are | |||
* not removed. | |||
* | |||
* @throws Exception | |||
*/ | |||
public void packAndPrune() throws Exception { | |||
final ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase(); | |||
final PackWriter pw = new PackWriter(db, NullProgressMonitor.INSTANCE); | |||
Set<ObjectId> all = new HashSet<ObjectId>(); | |||
for (Ref r : db.getAllRefs().values()) | |||
all.add(r.getObjectId()); | |||
pw.preparePack(all, Collections.<ObjectId> emptySet()); | |||
final ObjectId name = pw.computeName(); | |||
FileOutputStream out; | |||
final File pack = nameFor(odb, name, ".pack"); | |||
out = new FileOutputStream(pack); | |||
try { | |||
pw.writePack(out); | |||
} finally { | |||
out.close(); | |||
} | |||
pack.setReadOnly(); | |||
final File idx = nameFor(odb, name, ".idx"); | |||
out = new FileOutputStream(idx); | |||
try { | |||
pw.writeIndex(out); | |||
} finally { | |||
out.close(); | |||
} | |||
idx.setReadOnly(); | |||
odb.openPack(pack, idx); | |||
updateServerInfo(); | |||
prunePacked(odb); | |||
} | |||
private void prunePacked(ObjectDirectory odb) { | |||
for (PackFile p : odb.getPacks()) { | |||
for (MutableEntry e : p) | |||
odb.fileFor(e.toObjectId()).delete(); | |||
} | |||
} | |||
private static File nameFor(ObjectDirectory odb, ObjectId name, String t) { | |||
File packdir = new File(odb.getDirectory(), "pack"); | |||
return new File(packdir, "pack-" + name.name() + t); | |||
} | |||
private void writeFile(final String name, final byte[] bin) | |||
throws IOException, ObjectWritingException { | |||
final File p = new File(db.getDirectory(), name); | |||
final LockFile lck = new LockFile(p); | |||
if (!lck.lock()) | |||
throw new ObjectWritingException("Can't write " + p); | |||
try { | |||
lck.write(bin); | |||
} catch (IOException ioe) { | |||
throw new ObjectWritingException("Can't write " + p); | |||
} | |||
if (!lck.commit()) | |||
throw new ObjectWritingException("Can't write " + p); | |||
} | |||
/** Helper to build a branch with one or more commits */ | |||
public class BranchBuilder { | |||
private final String ref; |
@@ -155,6 +155,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, | |||
private final ProxySelector proxySelector; | |||
private boolean useSmartHttp = true; | |||
TransportHttp(final Repository local, final URIish uri) | |||
throws NotSupportedException { | |||
super(local, uri); | |||
@@ -171,6 +173,20 @@ public class TransportHttp extends HttpTransport implements WalkTransport, | |||
proxySelector = ProxySelector.getDefault(); | |||
} | |||
/** | |||
* Toggle whether or not smart HTTP transport should be used. | |||
* <p> | |||
* This flag exists primarily to support backwards compatibility testing | |||
* within a testing framework, there is no need to modify it in most | |||
* applications. | |||
* | |||
* @param on | |||
* if {@code true} (default), smart HTTP is enabled. | |||
*/ | |||
public void setUseSmartHttp(final boolean on) { | |||
useSmartHttp = on; | |||
} | |||
@Override | |||
public FetchConnection openFetch() throws TransportException, | |||
NotSupportedException { | |||
@@ -271,6 +287,10 @@ public class TransportHttp extends HttpTransport implements WalkTransport, | |||
readSmartHeaders(in, service); | |||
return new SmartHttpPushConnection(in); | |||
} else if (!useSmartHttp) { | |||
final String msg = "smart HTTP push disabled"; | |||
throw new NotSupportedException(msg); | |||
} else { | |||
final String msg = "remote does not support smart HTTP push"; | |||
throw new NotSupportedException(msg); | |||
@@ -303,9 +323,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, | |||
b.append('/'); | |||
b.append(Constants.INFO_REFS); | |||
b.append(b.indexOf("?") < 0 ? '?' : '&'); | |||
b.append("service="); | |||
b.append(service); | |||
if (useSmartHttp) { | |||
b.append(b.indexOf("?") < 0 ? '?' : '&'); | |||
b.append("service="); | |||
b.append(service); | |||
} | |||
u = new URL(b.toString()); | |||
} catch (MalformedURLException e) { | |||
@@ -314,8 +336,12 @@ public class TransportHttp extends HttpTransport implements WalkTransport, | |||
try { | |||
final HttpURLConnection conn = httpOpen(u); | |||
String expType = "application/x-" + service + "-advertisement"; | |||
conn.setRequestProperty(HDR_ACCEPT, expType + ", */*"); | |||
if (useSmartHttp) { | |||
String expType = "application/x-" + service + "-advertisement"; | |||
conn.setRequestProperty(HDR_ACCEPT, expType + ", */*"); | |||
} else { | |||
conn.setRequestProperty(HDR_ACCEPT, "*/*"); | |||
} | |||
final int status = HttpSupport.response(conn); | |||
switch (status) { | |||
case HttpURLConnection.HTTP_OK: |
@@ -138,6 +138,8 @@ | |||
<servlet-api-CQ>CQ 3565</servlet-api-CQ> | |||
<servlet-api-version>2.5</servlet-api-version> | |||
<jetty-version>7.0.1.v20091125</jetty-version> | |||
</properties> | |||
<build> | |||
@@ -265,6 +267,12 @@ | |||
<artifactId>servlet-api</artifactId> | |||
<version>${servlet-api-version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.jetty</groupId> | |||
<artifactId>jetty-servlet</artifactId> | |||
<version>${jetty-version}</version> | |||
</dependency> | |||
</dependencies> | |||
</dependencyManagement> | |||
@@ -298,6 +306,8 @@ | |||
<module>org.eclipse.jgit.http.server</module> | |||
<module>org.eclipse.jgit.pgm</module> | |||
<module>org.eclipse.jgit.junit</module> | |||
<module>org.eclipse.jgit.test</module> | |||
<module>org.eclipse.jgit.http.test</module> | |||
</modules> | |||
</project> |