Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties1
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java4
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java309
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java1
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java18
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java75
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java21
-rw-r--r--org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java22
8 files changed, 355 insertions, 96 deletions
diff --git a/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties b/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties
index a7643c5f9e..e811891904 100644
--- a/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties
+++ b/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties
@@ -3,6 +3,7 @@ cannotGetLengthOf=Cannot get length of {0}
encodingNotSupportedByThisLibrary={0} "{1}": not supported by this library.
expectedRepositoryAttribute=Expected Repository attribute
filterMustNotBeNull=filter must not be null
+internalServerError=Internal server error
internalErrorDuringReceivePack=Internal error during receive-pack
internalErrorDuringUploadPack=Internal error during upload-pack
internalServerErrorRequestAttributeWasAlreadySet=Internal server error, request attribute {0} was already set when {1} was invoked.
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
index 7b88ae346a..980d246d2d 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
@@ -196,7 +196,7 @@ public class GitFilter extends MetaFilter {
initialized = true;
if (uploadPackFactory != UploadPackFactory.DISABLED) {
- ServletBinder b = serve("*/git-upload-pack");
+ ServletBinder b = serve("*/" + GitSmartHttpTools.UPLOAD_PACK);
b = b.through(new UploadPackServlet.Factory(uploadPackFactory));
for (Filter f : uploadPackFilters)
b = b.through(f);
@@ -204,7 +204,7 @@ public class GitFilter extends MetaFilter {
}
if (receivePackFactory != ReceivePackFactory.DISABLED) {
- ServletBinder b = serve("*/git-receive-pack");
+ ServletBinder b = serve("*/" + GitSmartHttpTools.RECEIVE_PACK);
b = b.through(new ReceivePackServlet.Factory(receivePackFactory));
for (Filter f : receivePackFilters)
b = b.through(f);
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java
new file mode 100644
index 0000000000..3d2aff174d
--- /dev/null
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2011, 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.server;
+
+import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
+import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.PacketLineOut;
+
+/**
+ * Utility functions for handling the Git-over-HTTP protocol.
+ */
+public class GitSmartHttpTools {
+ private static final String INFO_REFS = Constants.INFO_REFS;
+
+ /** Name of the git-upload-pack service. */
+ public static final String UPLOAD_PACK = "git-upload-pack";
+
+ /** Name of the git-receive-pack service. */
+ public static final String RECEIVE_PACK = "git-receive-pack";
+
+ /** Content type supplied by the client to the /git-upload-pack handler. */
+ public static final String UPLOAD_PACK_REQUEST_TYPE =
+ "application/x-git-upload-pack-request";
+
+ /** Content type returned from the /git-upload-pack handler. */
+ public static final String UPLOAD_PACK_RESULT_TYPE =
+ "application/x-git-upload-pack-result";
+
+ /** Content type supplied by the client to the /git-receive-pack handler. */
+ public static final String RECEIVE_PACK_REQUEST_TYPE =
+ "application/x-git-receive-pack-request";
+
+ /** Content type returned from the /git-receive-pack handler. */
+ public static final String RECEIVE_PACK_RESULT_TYPE =
+ "application/x-git-receive-pack-result";
+
+ /** Git service names accepted by the /info/refs?service= handler. */
+ public static final List<String> VALID_SERVICES =
+ Collections.unmodifiableList(Arrays.asList(new String[] {
+ UPLOAD_PACK, RECEIVE_PACK }));
+
+ private static final String INFO_REFS_PATH = "/" + INFO_REFS;
+ private static final String UPLOAD_PACK_PATH = "/" + UPLOAD_PACK;
+ private static final String RECEIVE_PACK_PATH = "/" + RECEIVE_PACK;
+
+ private static final List<String> SERVICE_SUFFIXES =
+ Collections.unmodifiableList(Arrays.asList(new String[] {
+ INFO_REFS_PATH, UPLOAD_PACK_PATH, RECEIVE_PACK_PATH }));
+
+ /**
+ * Check a request for Git-over-HTTP indicators.
+ *
+ * @param req
+ * the current HTTP request that may have been made by Git.
+ * @return true if the request is likely made by a Git client program.
+ */
+ public static boolean isGitClient(HttpServletRequest req) {
+ return isInfoRefs(req) || isUploadPack(req) || isReceivePack(req);
+ }
+
+ /**
+ * Send an error to the Git client or browser.
+ * <p>
+ * Server implementors may use this method to send customized error messages
+ * to a Git protocol client using an HTTP 200 OK response with the error
+ * embedded in the payload. If the request was not issued by a Git client,
+ * an HTTP response code is returned instead.
+ *
+ * @param req
+ * current request.
+ * @param res
+ * current response.
+ * @param httpStatus
+ * HTTP status code to set if the client is not a Git client.
+ * @throws IOException
+ * the response cannot be sent.
+ */
+ public static void sendError(HttpServletRequest req,
+ HttpServletResponse res, int httpStatus) throws IOException {
+ sendError(req, res, httpStatus, null);
+ }
+
+ /**
+ * Send an error to the Git client or browser.
+ * <p>
+ * Server implementors may use this method to send customized error messages
+ * to a Git protocol client using an HTTP 200 OK response with the error
+ * embedded in the payload. If the request was not issued by a Git client,
+ * an HTTP response code is returned instead.
+ *
+ * @param req
+ * current request.
+ * @param res
+ * current response.
+ * @param httpStatus
+ * HTTP status code to set if the client is not a Git client.
+ * @param textForGit
+ * plain text message to display on the user's console. This is
+ * shown only if the client is likely to be a Git client. If null
+ * or the empty string a default text is chosen based on the HTTP
+ * response code.
+ * @throws IOException
+ * the response cannot be sent.
+ */
+ public static void sendError(HttpServletRequest req,
+ HttpServletResponse res, int httpStatus, String textForGit)
+ throws IOException {
+ if (textForGit == null || textForGit.length() == 0) {
+ switch (httpStatus) {
+ case SC_FORBIDDEN:
+ textForGit = HttpServerText.get().repositoryAccessForbidden;
+ break;
+ case SC_NOT_FOUND:
+ textForGit = HttpServerText.get().repositoryNotFound;
+ break;
+ case SC_INTERNAL_SERVER_ERROR:
+ textForGit = HttpServerText.get().internalServerError;
+ break;
+ default:
+ textForGit = "HTTP " + httpStatus;
+ break;
+ }
+ }
+
+ ByteArrayOutputStream buf = new ByteArrayOutputStream(128);
+ PacketLineOut pck = new PacketLineOut(buf);
+
+ if (isInfoRefs(req)) {
+ String svc = req.getParameter("service");
+ pck.writeString("# service=" + svc + "\n");
+ pck.end();
+ pck.writeString("ERR " + textForGit);
+ send(res, infoRefsResultType(svc), buf.toByteArray());
+ } else if (isUploadPack(req)) {
+ pck.writeString("ERR " + textForGit);
+ send(res, UPLOAD_PACK_RESULT_TYPE, buf.toByteArray());
+ } else if (isReceivePack(req)) {
+ pck.writeString("ERR " + textForGit);
+ send(res, RECEIVE_PACK_RESULT_TYPE, buf.toByteArray());
+ } else {
+ res.sendError(httpStatus);
+ }
+ }
+
+ private static void send(HttpServletResponse res, String type, byte[] buf)
+ throws IOException {
+ res.setStatus(HttpServletResponse.SC_OK);
+ res.setContentType(type);
+ res.setContentLength(buf.length);
+ ServletOutputStream os = res.getOutputStream();
+ try {
+ os.write(buf);
+ } finally {
+ os.close();
+ }
+ }
+
+ /**
+ * Get the response Content-Type a client expects for the request.
+ * <p>
+ * This method should only be invoked if
+ * {@link #isGitClient(HttpServletRequest)} is true.
+ *
+ * @param req
+ * current request.
+ * @return the Content-Type the client expects.
+ * @throws IllegalArgumentException
+ * the request is not a Git client request. See
+ * {@link #isGitClient(HttpServletRequest)}.
+ */
+ public static String getResponseContentType(HttpServletRequest req) {
+ if (isInfoRefs(req))
+ return infoRefsResultType(req.getParameter("service"));
+ else if (isUploadPack(req))
+ return UPLOAD_PACK_RESULT_TYPE;
+ else if (isReceivePack(req))
+ return RECEIVE_PACK_RESULT_TYPE;
+ else
+ throw new IllegalArgumentException();
+ }
+
+ static String infoRefsResultType(String svc) {
+ return "application/x-" + svc + "-advertisement";
+ }
+
+ /**
+ * Strip the Git service suffix from a request path.
+ *
+ * Generally the suffix is stripped by the {@code SuffixPipeline} handling
+ * the request, so this method is rarely needed.
+ *
+ * @param path
+ * the path of the request.
+ * @return the path up to the last path component before the service suffix;
+ * the path as-is if it contains no service suffix.
+ */
+ public static String stripServiceSuffix(String path) {
+ for (String suffix : SERVICE_SUFFIXES) {
+ if (path.endsWith(suffix))
+ return path.substring(0, path.length() - suffix.length());
+ }
+ return path;
+ }
+
+ /**
+ * Check if the HTTP request was for the /info/refs?service= Git handler.
+ *
+ * @param req
+ * current request.
+ * @return true if the request is for the /info/refs service.
+ */
+ public static boolean isInfoRefs(HttpServletRequest req) {
+ return req.getRequestURI().endsWith(INFO_REFS_PATH)
+ && VALID_SERVICES.contains(req.getParameter("service"));
+ }
+
+ /**
+ * Check if the HTTP request path ends with the /git-upload-pack handler.
+ *
+ * @param pathOrUri
+ * path or URI of the request.
+ * @return true if the request is for the /git-upload-pack handler.
+ */
+ public static boolean isUploadPack(String pathOrUri) {
+ return pathOrUri != null && pathOrUri.endsWith(UPLOAD_PACK_PATH);
+ }
+
+ /**
+ * Check if the HTTP request was for the /git-upload-pack Git handler.
+ *
+ * @param req
+ * current request.
+ * @return true if the request is for the /git-upload-pack handler.
+ */
+ public static boolean isUploadPack(HttpServletRequest req) {
+ return isUploadPack(req.getRequestURI())
+ && UPLOAD_PACK_REQUEST_TYPE.equals(req.getContentType());
+ }
+
+ /**
+ * Check if the HTTP request was for the /git-receive-pack Git handler.
+ *
+ * @param req
+ * current request.
+ * @return true if the request is for the /git-receive-pack handler.
+ */
+ public static boolean isReceivePack(HttpServletRequest req) {
+ String uri = req.getRequestURI();
+ return uri != null && uri.endsWith(RECEIVE_PACK_PATH)
+ && RECEIVE_PACK_REQUEST_TYPE.equals(req.getContentType());
+ }
+
+ private GitSmartHttpTools() {
+ }
+}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java
index 18743989ba..2342fea3ca 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java
@@ -65,6 +65,7 @@ public class HttpServerText extends TranslationBundle {
/***/ public String filterMustNotBeNull;
/***/ public String internalErrorDuringReceivePack;
/***/ public String internalErrorDuringUploadPack;
+ /***/ public String internalServerError;
/***/ public String internalServerErrorRequestAttributeWasAlreadySet;
/***/ public String invalidBoolean;
/***/ public String invalidIndex;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
index 0c856d4aa5..6af28ba0d3 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
@@ -47,6 +47,10 @@ import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import static javax.servlet.http.HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.RECEIVE_PACK;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.RECEIVE_PACK_REQUEST_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.RECEIVE_PACK_RESULT_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError;
import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER;
import static org.eclipse.jgit.http.server.ServletUtils.getInputStream;
import static org.eclipse.jgit.http.server.ServletUtils.getRepository;
@@ -74,10 +78,6 @@ import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
/** Server side implementation of smart push over HTTP. */
class ReceivePackServlet extends HttpServlet {
- private static final String REQ_TYPE = "application/x-git-receive-pack-request";
-
- private static final String RSP_TYPE = "application/x-git-receive-pack-result";
-
private static final long serialVersionUID = 1L;
static class InfoRefs extends SmartServiceInfoRefs {
@@ -85,7 +85,7 @@ class ReceivePackServlet extends HttpServlet {
InfoRefs(ReceivePackFactory<HttpServletRequest> receivePackFactory,
List<Filter> filters) {
- super("git-receive-pack", filters);
+ super(RECEIVE_PACK, filters);
this.receivePackFactory = receivePackFactory;
}
@@ -129,7 +129,7 @@ class ReceivePackServlet extends HttpServlet {
return;
} catch (ServiceNotEnabledException e) {
- RepositoryFilter.sendError(SC_FORBIDDEN, req, rsp);
+ sendError(req, rsp, SC_FORBIDDEN);
return;
}
@@ -153,7 +153,7 @@ class ReceivePackServlet extends HttpServlet {
@Override
public void doPost(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
- if (!REQ_TYPE.equals(req.getContentType())) {
+ if (!RECEIVE_PACK_REQUEST_TYPE.equals(req.getContentType())) {
rsp.sendError(SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
@@ -161,7 +161,7 @@ class ReceivePackServlet extends HttpServlet {
ReceivePack rp = (ReceivePack) req.getAttribute(ATTRIBUTE_HANDLER);
try {
rp.setBiDirectionalPipe(false);
- rsp.setContentType(RSP_TYPE);
+ rsp.setContentType(RECEIVE_PACK_RESULT_TYPE);
final SmartOutputStream out = new SmartOutputStream(req, rsp) {
@Override
@@ -181,7 +181,7 @@ class ReceivePackServlet extends HttpServlet {
getServletContext().log(HttpServerText.get().internalErrorDuringReceivePack, e);
if (!rsp.isCommitted()) {
rsp.reset();
- rsp.sendError(SC_INTERNAL_SERVER_ERROR);
+ sendError(req, rsp, SC_INTERNAL_SERVER_ERROR);
}
return;
}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
index d1bd9024e9..571183682f 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
@@ -47,8 +47,8 @@ import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError;
import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_REPOSITORY;
-import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT;
import java.io.IOException;
import java.text.MessageFormat;
@@ -65,7 +65,6 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.PacketLineOut;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
@@ -109,23 +108,24 @@ public class RepositoryFilter implements Filter {
}
public void doFilter(final ServletRequest request,
- final ServletResponse rsp, final FilterChain chain)
+ final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
+
if (request.getAttribute(ATTRIBUTE_REPOSITORY) != null) {
context.log(MessageFormat.format(HttpServerText.get().internalServerErrorRequestAttributeWasAlreadySet
, ATTRIBUTE_REPOSITORY
, getClass().getName()));
- ((HttpServletResponse) rsp).sendError(SC_INTERNAL_SERVER_ERROR);
+ sendError(req, res, SC_INTERNAL_SERVER_ERROR);
return;
}
- final HttpServletRequest req = (HttpServletRequest) request;
-
String name = req.getPathInfo();
while (name != null && 0 < name.length() && name.charAt(0) == '/')
name = name.substring(1);
if (name == null || name.length() == 0) {
- ((HttpServletResponse) rsp).sendError(SC_NOT_FOUND);
+ sendError(req, res, SC_NOT_FOUND);
return;
}
@@ -133,74 +133,21 @@ public class RepositoryFilter implements Filter {
try {
db = resolver.open(req, name);
} catch (RepositoryNotFoundException e) {
- sendError(SC_NOT_FOUND, req, (HttpServletResponse) rsp);
+ sendError(req, res, SC_NOT_FOUND);
return;
} catch (ServiceNotEnabledException e) {
- sendError(SC_FORBIDDEN, req, (HttpServletResponse) rsp);
+ sendError(req, res, SC_FORBIDDEN);
return;
} catch (ServiceNotAuthorizedException e) {
- ((HttpServletResponse) rsp).sendError(SC_UNAUTHORIZED);
+ res.sendError(SC_UNAUTHORIZED);
return;
}
try {
request.setAttribute(ATTRIBUTE_REPOSITORY, db);
- chain.doFilter(request, rsp);
+ chain.doFilter(request, response);
} finally {
request.removeAttribute(ATTRIBUTE_REPOSITORY);
db.close();
}
}
-
- static void sendError(int statusCode, HttpServletRequest req,
- HttpServletResponse rsp) throws IOException {
- String svc = req.getParameter("service");
-
- if (req.getRequestURI().endsWith("/info/refs") && isService(svc)) {
- // Smart HTTP service request, use an ERR response.
- rsp.setContentType("application/x-" + svc + "-advertisement");
-
- SmartOutputStream buf = new SmartOutputStream(req, rsp);
- PacketLineOut out = new PacketLineOut(buf);
- out.writeString("# service=" + svc + "\n");
- out.end();
- out.writeString("ERR " + translate(statusCode));
- buf.close();
- return;
- }
-
- String accept = req.getHeader(HDR_ACCEPT);
- if (accept != null && accept.contains(UploadPackServlet.RSP_TYPE)) {
- // An upload-pack wants ACK or NAK, return ERR
- // and the client will print this instead.
- rsp.setContentType(UploadPackServlet.RSP_TYPE);
- SmartOutputStream buf = new SmartOutputStream(req, rsp);
- PacketLineOut out = new PacketLineOut(buf);
- out.writeString("ERR " + translate(statusCode));
- buf.close();
- return;
- }
-
- // Otherwise fail with an HTTP error code instead of an
- // application level message. This may not be as pretty
- // of a result for the user, but its better than nothing.
- //
- rsp.sendError(statusCode);
- }
-
- private static boolean isService(String svc) {
- return "git-upload-pack".equals(svc) || "git-receive-pack".equals(svc);
- }
-
- private static String translate(int statusCode) {
- switch (statusCode) {
- case SC_NOT_FOUND:
- return HttpServerText.get().repositoryNotFound;
-
- case SC_FORBIDDEN:
- return HttpServerText.get().repositoryAccessForbidden;
-
- default:
- return String.valueOf(statusCode);
- }
- }
}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
index 935867cef3..c0f1f6335b 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
@@ -44,8 +44,9 @@
package org.eclipse.jgit.http.server;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
-import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.infoRefsResultType;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError;
import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER;
import static org.eclipse.jgit.http.server.ServletUtils.getRepository;
@@ -90,17 +91,17 @@ abstract class SmartServiceInfoRefs implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
- final HttpServletResponse rsp = (HttpServletResponse) response;
+ final HttpServletResponse res = (HttpServletResponse) response;
if (svc.equals(req.getParameter("service"))) {
final Repository db = getRepository(req);
try {
begin(req, db);
} catch (ServiceNotAuthorizedException e) {
- rsp.sendError(SC_UNAUTHORIZED);
+ res.sendError(SC_UNAUTHORIZED);
return;
} catch (ServiceNotEnabledException e) {
- rsp.sendError(SC_FORBIDDEN);
+ sendError(req, res, SC_FORBIDDEN);
return;
}
@@ -120,10 +121,10 @@ abstract class SmartServiceInfoRefs implements Filter {
private void service(ServletRequest request, ServletResponse response)
throws IOException {
final HttpServletRequest req = (HttpServletRequest) request;
- final HttpServletResponse rsp = (HttpServletResponse) response;
- final SmartOutputStream buf = new SmartOutputStream(req, rsp);
+ final HttpServletResponse res = (HttpServletResponse) response;
+ final SmartOutputStream buf = new SmartOutputStream(req, res);
try {
- rsp.setContentType("application/x-" + svc + "-advertisement");
+ res.setContentType(infoRefsResultType(svc));
final PacketLineOut out = new PacketLineOut(buf);
out.writeString("# service=" + svc + "\n");
@@ -131,16 +132,16 @@ abstract class SmartServiceInfoRefs implements Filter {
advertise(req, new PacketLineOutRefAdvertiser(out));
buf.close();
} catch (ServiceNotAuthorizedException e) {
- rsp.sendError(SC_UNAUTHORIZED);
+ res.sendError(SC_UNAUTHORIZED);
} catch (ServiceNotEnabledException e) {
- rsp.sendError(SC_FORBIDDEN);
+ sendError(req, res, SC_FORBIDDEN);
} catch (UploadPackMayNotContinueException e) {
if (e.isOutput())
buf.close();
else
- rsp.sendError(SC_SERVICE_UNAVAILABLE);
+ sendError(req, res, SC_FORBIDDEN, e.getMessage());
}
}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
index 178473c401..c7891dfc77 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
@@ -45,9 +45,12 @@ package org.eclipse.jgit.http.server;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
-import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import static javax.servlet.http.HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.UPLOAD_PACK;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.UPLOAD_PACK_REQUEST_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.UPLOAD_PACK_RESULT_TYPE;
+import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError;
import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER;
import static org.eclipse.jgit.http.server.ServletUtils.getInputStream;
import static org.eclipse.jgit.http.server.ServletUtils.getRepository;
@@ -76,10 +79,6 @@ import org.eclipse.jgit.transport.resolver.UploadPackFactory;
/** Server side implementation of smart fetch over HTTP. */
class UploadPackServlet extends HttpServlet {
- private static final String REQ_TYPE = "application/x-git-upload-pack-request";
-
- static final String RSP_TYPE = "application/x-git-upload-pack-result";
-
private static final long serialVersionUID = 1L;
static class InfoRefs extends SmartServiceInfoRefs {
@@ -87,7 +86,7 @@ class UploadPackServlet extends HttpServlet {
InfoRefs(UploadPackFactory<HttpServletRequest> uploadPackFactory,
List<Filter> filters) {
- super("git-upload-pack", filters);
+ super(UPLOAD_PACK, filters);
this.uploadPackFactory = uploadPackFactory;
}
@@ -132,7 +131,7 @@ class UploadPackServlet extends HttpServlet {
return;
} catch (ServiceNotEnabledException e) {
- RepositoryFilter.sendError(SC_FORBIDDEN, req, rsp);
+ sendError(req, rsp, SC_FORBIDDEN);
return;
}
@@ -156,7 +155,7 @@ class UploadPackServlet extends HttpServlet {
@Override
public void doPost(final HttpServletRequest req,
final HttpServletResponse rsp) throws IOException {
- if (!REQ_TYPE.equals(req.getContentType())) {
+ if (!UPLOAD_PACK_REQUEST_TYPE.equals(req.getContentType())) {
rsp.sendError(SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
@@ -164,7 +163,7 @@ class UploadPackServlet extends HttpServlet {
UploadPack up = (UploadPack) req.getAttribute(ATTRIBUTE_HANDLER);
try {
up.setBiDirectionalPipe(false);
- rsp.setContentType(RSP_TYPE);
+ rsp.setContentType(UPLOAD_PACK_RESULT_TYPE);
final SmartOutputStream out = new SmartOutputStream(req, rsp) {
@Override
@@ -178,11 +177,12 @@ class UploadPackServlet extends HttpServlet {
} catch (UploadPackMayNotContinueException e) {
if (!e.isOutput() && !rsp.isCommitted()) {
rsp.reset();
- rsp.sendError(SC_SERVICE_UNAVAILABLE);
+ sendError(req, rsp, SC_FORBIDDEN, e.getMessage());
}
return;
} catch (UploadPackInternalServerErrorException e) {
+ // Special case exception, error message was sent to client.
getServletContext().log(
HttpServerText.get().internalErrorDuringUploadPack,
e.getCause());
@@ -191,7 +191,7 @@ class UploadPackServlet extends HttpServlet {
getServletContext().log(HttpServerText.get().internalErrorDuringUploadPack, e);
if (!rsp.isCommitted()) {
rsp.reset();
- rsp.sendError(SC_INTERNAL_SERVER_ERROR);
+ sendError(req, rsp, SC_INTERNAL_SERVER_ERROR);
}
return;
}

Back to the top