Ejemplo n.º 1
0
  /**
   * Execute the receive task on the socket.
   *
   * @param input raw input to read client commands and pack data from. Caller must ensure the input
   *     is buffered, otherwise read performance may suffer.
   * @param output response back to the Git network client. Caller must ensure the output is
   *     buffered, otherwise write performance may suffer.
   * @param messages secondary "notice" channel to send additional messages out through. When run
   *     over SSH this should be tied back to the standard error channel of the command execution.
   *     For most other network connections this should be null.
   * @throws IOException
   */
  public void receive(
      final InputStream input, final OutputStream output, final OutputStream messages)
      throws IOException {
    try {
      rawIn = input;
      rawOut = output;
      msgOut = messages;

      if (timeout > 0) {
        final Thread caller = Thread.currentThread();
        timer = new InterruptTimer(caller.getName() + "-Timer");
        timeoutIn = new TimeoutInputStream(rawIn, timer);
        TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
        timeoutIn.setTimeout(timeout * 1000);
        o.setTimeout(timeout * 1000);
        rawIn = timeoutIn;
        rawOut = o;
      }

      pckIn = new PacketLineIn(rawIn);
      pckOut = new PacketLineOut(rawOut);
      pckOut.setFlushOnEnd(false);

      enabledCapablities = new HashSet<String>();
      commands = new ArrayList<ReceiveCommand>();

      service();
    } finally {
      walk.release();
      try {
        if (sideBand) {
          // If we are using side band, we need to send a final
          // flush-pkt to tell the remote peer the side band is
          // complete and it should stop decoding. We need to
          // use the original output stream as rawOut is now the
          // side band data channel.
          //
          ((SideBandOutputStream) msgOut).flushBuffer();
          ((SideBandOutputStream) rawOut).flushBuffer();

          PacketLineOut plo = new PacketLineOut(output);
          plo.setFlushOnEnd(false);
          plo.end();
        }

        if (biDirectionalPipe) {
          // If this was a native git connection, flush the pipe for
          // the caller. For smart HTTP we don't do this flush and
          // instead let the higher level HTTP servlet code do it.
          //
          if (!sideBand && msgOut != null) msgOut.flush();
          rawOut.flush();
        }
      } finally {
        unlockPack();
        timeoutIn = null;
        rawIn = null;
        rawOut = null;
        msgOut = null;
        pckIn = null;
        pckOut = null;
        refs = null;
        enabledCapablities = null;
        commands = null;
        if (timer != null) {
          try {
            timer.terminate();
          } finally {
            timer = null;
          }
        }
      }
    }
  }