private void receivePack() throws IOException { // It might take the client a while to pack the objects it needs // to send to us. We should increase our timeout so we don't // abort while the client is computing. // if (timeoutIn != null) timeoutIn.setTimeout(10 * timeout * 1000); ProgressMonitor receiving = NullProgressMonitor.INSTANCE; ProgressMonitor resolving = NullProgressMonitor.INSTANCE; if (sideBand) resolving = new SideBandProgressMonitor(msgOut); ObjectInserter ins = db.newObjectInserter(); try { String lockMsg = "jgit receive-pack"; if (getRefLogIdent() != null) lockMsg += " from " + getRefLogIdent().toExternalString(); parser = ins.newPackParser(rawIn); parser.setAllowThin(true); parser.setNeedNewObjectIds(checkReferencedIsReachable); parser.setNeedBaseObjectIds(checkReferencedIsReachable); parser.setCheckEofAfterPackFooter(!biDirectionalPipe); parser.setObjectChecking(isCheckReceivedObjects()); parser.setLockMessage(lockMsg); parser.setMaxObjectSizeLimit(maxObjectSizeLimit); packLock = parser.parse(receiving, resolving); ins.flush(); } finally { ins.release(); } if (timeoutIn != null) timeoutIn.setTimeout(timeout * 1000); }
/** * 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; } } } } }