InternalPushConnection.java

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

  10. package org.eclipse.jgit.transport;

  11. import java.io.IOException;
  12. import java.io.PipedInputStream;
  13. import java.io.PipedOutputStream;
  14. import java.io.UncheckedIOException;

  15. import org.eclipse.jgit.errors.TransportException;
  16. import org.eclipse.jgit.internal.JGitText;
  17. import org.eclipse.jgit.lib.Repository;
  18. import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
  19. import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
  20. import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;

  21. class InternalPushConnection<C> extends BasePackPushConnection {
  22.     private Thread worker;

  23.     /**
  24.      * Constructor for InternalPushConnection.
  25.      *
  26.      * @param transport
  27.      *            a {@link org.eclipse.jgit.transport.PackTransport}
  28.      * @param receivePackFactory
  29.      *            a
  30.      *            {@link org.eclipse.jgit.transport.resolver.ReceivePackFactory}
  31.      * @param req
  32.      *            a request
  33.      * @param remote
  34.      *            the {@link org.eclipse.jgit.lib.Repository}
  35.      * @throws org.eclipse.jgit.errors.TransportException
  36.      *             if any.
  37.      */
  38.     public InternalPushConnection(PackTransport transport,
  39.             final ReceivePackFactory<C> receivePackFactory,
  40.             final C req, final Repository remote) throws TransportException {
  41.         super(transport);

  42.         final PipedInputStream in_r;
  43.         final PipedOutputStream in_w;

  44.         final PipedInputStream out_r;
  45.         final PipedOutputStream out_w;
  46.         try {
  47.             in_r = new PipedInputStream();
  48.             in_w = new PipedOutputStream(in_r);

  49.             out_r = new PipedInputStream();
  50.             out_w = new PipedOutputStream(out_r);
  51.         } catch (IOException err) {
  52.             remote.close();
  53.             throw new TransportException(uri, JGitText.get().cannotConnectPipes, err);
  54.         }

  55.         worker = new Thread("JGit-Receive-Pack") { //$NON-NLS-1$
  56.             @Override
  57.             public void run() {
  58.                 try {
  59.                     final ReceivePack rp = receivePackFactory.create(req, remote);
  60.                     rp.receive(out_r, in_w, System.err);
  61.                 } catch (ServiceNotEnabledException
  62.                         | ServiceNotAuthorizedException e) {
  63.                     // Ignored. Client cannot use this repository.
  64.                 } catch (IOException e) {
  65.                     // Since the InternalPushConnection is used in tests, we
  66.                     // want to avoid hiding exceptions because they can point to
  67.                     // programming errors on the server side. By rethrowing, the
  68.                     // default handler will dump it to stderr.
  69.                     throw new UncheckedIOException(e);
  70.                 } finally {
  71.                     try {
  72.                         out_r.close();
  73.                     } catch (IOException e2) {
  74.                         // Ignore close failure, we probably crashed above.
  75.                     }

  76.                     try {
  77.                         in_w.close();
  78.                     } catch (IOException e2) {
  79.                         // Ignore close failure, we probably crashed above.
  80.                     }

  81.                     remote.close();
  82.                 }
  83.             }
  84.         };
  85.         worker.start();

  86.         init(in_r, out_w);
  87.         readAdvertisedRefs();
  88.     }

  89.     /** {@inheritDoc} */
  90.     @Override
  91.     public void close() {
  92.         super.close();

  93.         if (worker != null) {
  94.             try {
  95.                 worker.join();
  96.             } catch (InterruptedException ie) {
  97.                 // Stop waiting and return anyway.
  98.             } finally {
  99.                 worker = null;
  100.             }
  101.         }
  102.     }
  103. }