]> source.dussan.org Git - jgit.git/commitdiff
server: Add a custom error handler 62/152362/3
authorMasaya Suzuki <masayasuzuki@google.com>
Fri, 8 Nov 2019 18:48:03 +0000 (10:48 -0800)
committerMasaya Suzuki <masayasuzuki@google.com>
Mon, 2 Dec 2019 22:17:44 +0000 (14:17 -0800)
Same as UploadPack, add a custom error handler.

Change-Id: I9c708aa5a22e01214c1d997fa6f72f4b8bf814f0
Signed-off-by: Masaya Suzuki <masayasuzuki@google.com>
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java [new file with mode: 0644]
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java

index e9462eeb4c16871d4394112b106205dfa126f9f6..06970a76931f408ef14ad3c1ae1cad0ae405cf7f 100644 (file)
@@ -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<>();
@@ -189,6 +191,17 @@ public class GitFilter extends MetaFilter {
                this.receivePackFactory = f != null ? f : (ReceivePackFactory<HttpServletRequest>)ReceivePackFactory.DISABLED;
        }
 
+       /**
+        * 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
         *
@@ -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 (file)
index 0000000..ee66cb1
--- /dev/null
@@ -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;
+       }
+
+}
index aed36560a8c8e4f9661e0a3d41ebaf27a29ab3b7..eb130d0a28285959f733a11a139c475abf00739f 100644 (file)
@@ -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;
                }
        }