diff options
author | Masaya Suzuki <masayasuzuki@google.com> | 2019-11-08 10:48:03 -0800 |
---|---|---|
committer | Masaya Suzuki <masayasuzuki@google.com> | 2019-12-02 14:17:44 -0800 |
commit | 75ec5b746dcaabbd0448dcffb8e3d2ed0d0f3943 (patch) | |
tree | 14cd3cff1f5269613271a78dd221b7c5b0c671bc /org.eclipse.jgit.http.server/src | |
parent | e75e95e5352b790e542898b1cad8fc7230246447 (diff) | |
download | jgit-75ec5b746dcaabbd0448dcffb8e3d2ed0d0f3943.tar.gz jgit-75ec5b746dcaabbd0448dcffb8e3d2ed0d0f3943.zip |
server: Add a custom error handler
Same as UploadPack, add a custom error handler.
Change-Id: I9c708aa5a22e01214c1d997fa6f72f4b8bf814f0
Signed-off-by: Masaya Suzuki <masayasuzuki@google.com>
Diffstat (limited to 'org.eclipse.jgit.http.server/src')
3 files changed, 117 insertions, 28 deletions
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 e9462eeb4c..06970a7693 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 @@ -96,6 +96,8 @@ public class GitFilter extends MetaFilter { private ReceivePackFactory<HttpServletRequest> receivePackFactory = new DefaultReceivePackFactory(); + private ReceivePackErrorHandler receivePackErrorHandler; + private final List<Filter> uploadPackFilters = new LinkedList<>(); private final List<Filter> receivePackFilters = new LinkedList<>(); @@ -190,6 +192,17 @@ public class GitFilter extends MetaFilter { } /** + * Set a custom error handler for git-receive-pack. + * + * @param h + * A custom error handler for git-receive-pack. + */ + public void setReceivePackErrorHandler(ReceivePackErrorHandler h) { + assertNotInitialized(); + this.receivePackErrorHandler = h; + } + + /** * Add receive-pack filter * * @param filter @@ -233,7 +246,7 @@ public class GitFilter extends MetaFilter { b = b.through(new ReceivePackServlet.Factory(receivePackFactory)); for (Filter f : receivePackFilters) b = b.through(f); - b.with(new ReceivePackServlet()); + b.with(new ReceivePackServlet(receivePackErrorHandler)); } ServletBinder refs = serve("*/" + Constants.INFO_REFS); diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java new file mode 100644 index 0000000000..ee66cb102f --- /dev/null +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.http.server; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.ServiceMayNotContinueException; + +/** + * Handle git-receive-pack errors. + * + * <p> + * This is an entry point for customizing an error handler for git-receive-pack. + * Right before calling {@link ReceivePack#receiveWithExceptionPropagation}, + * JGit will call this handler if specified through {@link GitFilter}. The + * implementation of this handler is responsible for calling + * {@link ReceivePackRunnable} and handling exceptions for clients. + * + * <p> + * If a custom handler is not specified, JGit will use the default error + * handler. + * + * @since 5.6 + */ +public interface ReceivePackErrorHandler { + /** + * @param req + * The HTTP request + * @param rsp + * The HTTP response + * @param r + * A continuation that handles a git-receive-pack request. + * @throws IOException + */ + void receive(HttpServletRequest req, HttpServletResponse rsp, + ReceivePackRunnable r) throws IOException; + + /** Process a git-receive-pack request. */ + public interface ReceivePackRunnable { + /** + * See {@link ReceivePack#receiveWithExceptionPropagation}. + * + * @throws ServiceMayNotContinueException + * @throws IOException + */ + void receive() throws ServiceMayNotContinueException, IOException; + } + +} 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 aed36560a8..eb130d0a28 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 @@ -71,6 +71,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.UnpackException; @@ -161,6 +162,13 @@ class ReceivePackServlet extends HttpServlet { } } + @Nullable + private final ReceivePackErrorHandler handler; + + ReceivePackServlet(@Nullable ReceivePackErrorHandler handler) { + this.handler = handler; + } + /** {@inheritDoc} */ @Override public void doPost(final HttpServletRequest req, @@ -178,34 +186,42 @@ class ReceivePackServlet extends HttpServlet { }; ReceivePack rp = (ReceivePack) req.getAttribute(ATTRIBUTE_HANDLER); - try { - rp.setBiDirectionalPipe(false); - rsp.setContentType(RECEIVE_PACK_RESULT_TYPE); - - rp.receive(getInputStream(req), out, null); - out.close(); - } catch (CorruptObjectException e ) { - // This should be already reported to the client. - getServletContext().log(MessageFormat.format( - HttpServerText.get().receivedCorruptObject, - e.getMessage(), - ServletUtils.identify(rp.getRepository()))); - consumeRequestBody(req); - out.close(); - - } catch (UnpackException | PackProtocolException e) { - // This should be already reported to the client. - log(rp.getRepository(), e.getCause()); - consumeRequestBody(req); - out.close(); - - } catch (Throwable e) { - log(rp.getRepository(), e); - if (!rsp.isCommitted()) { - rsp.reset(); - sendError(req, rsp, SC_INTERNAL_SERVER_ERROR); + rp.setBiDirectionalPipe(false); + rsp.setContentType(RECEIVE_PACK_RESULT_TYPE); + + if (handler != null) { + handler.receive(req, rsp, () -> { + rp.receiveWithExceptionPropagation(getInputStream(req), out, + null); + out.close(); + }); + } else { + try { + rp.receive(getInputStream(req), out, null); + out.close(); + } catch (CorruptObjectException e ) { + // This should be already reported to the client. + getServletContext().log(MessageFormat.format( + HttpServerText.get().receivedCorruptObject, + e.getMessage(), + ServletUtils.identify(rp.getRepository()))); + consumeRequestBody(req); + out.close(); + + } catch (UnpackException | PackProtocolException e) { + // This should be already reported to the client. + log(rp.getRepository(), e.getCause()); + consumeRequestBody(req); + out.close(); + + } catch (Throwable e) { + log(rp.getRepository(), e); + if (!rsp.isCommitted()) { + rsp.reset(); + sendError(req, rsp, SC_INTERNAL_SERVER_ERROR); + } + return; } - return; } } |