View Javadoc
1   /*
2    * Copyright (C) 2008-2010, Google Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.transport;
45  
46  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_ATOMIC;
47  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_DELETE_REFS;
48  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_OFS_DELTA;
49  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_PUSH_OPTIONS;
50  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_QUIET;
51  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REPORT_STATUS;
52  import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SIDE_BAND_64K;
53  import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
54  import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
55  import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR;
56  import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
57  import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
58  
59  import java.io.EOFException;
60  import java.io.IOException;
61  import java.io.InputStream;
62  import java.io.OutputStream;
63  import java.text.MessageFormat;
64  import java.util.ArrayList;
65  import java.util.Collections;
66  import java.util.HashSet;
67  import java.util.List;
68  import java.util.Map;
69  import java.util.Set;
70  import java.util.concurrent.TimeUnit;
71  
72  import org.eclipse.jgit.annotations.Nullable;
73  import org.eclipse.jgit.errors.InvalidObjectIdException;
74  import org.eclipse.jgit.errors.MissingObjectException;
75  import org.eclipse.jgit.errors.PackProtocolException;
76  import org.eclipse.jgit.errors.TooLargePackException;
77  import org.eclipse.jgit.internal.JGitText;
78  import org.eclipse.jgit.internal.storage.file.PackLock;
79  import org.eclipse.jgit.lib.BatchRefUpdate;
80  import org.eclipse.jgit.lib.Config;
81  import org.eclipse.jgit.lib.Constants;
82  import org.eclipse.jgit.lib.NullProgressMonitor;
83  import org.eclipse.jgit.lib.ObjectChecker;
84  import org.eclipse.jgit.lib.ObjectId;
85  import org.eclipse.jgit.lib.ObjectIdSubclassMap;
86  import org.eclipse.jgit.lib.ObjectInserter;
87  import org.eclipse.jgit.lib.PersonIdent;
88  import org.eclipse.jgit.lib.ProgressMonitor;
89  import org.eclipse.jgit.lib.Ref;
90  import org.eclipse.jgit.lib.Repository;
91  import org.eclipse.jgit.revwalk.ObjectWalk;
92  import org.eclipse.jgit.revwalk.RevBlob;
93  import org.eclipse.jgit.revwalk.RevCommit;
94  import org.eclipse.jgit.revwalk.RevFlag;
95  import org.eclipse.jgit.revwalk.RevObject;
96  import org.eclipse.jgit.revwalk.RevSort;
97  import org.eclipse.jgit.revwalk.RevTree;
98  import org.eclipse.jgit.revwalk.RevWalk;
99  import org.eclipse.jgit.transport.PacketLineIn.InputOverLimitIOException;
100 import org.eclipse.jgit.transport.ReceiveCommand.Result;
101 import org.eclipse.jgit.util.io.InterruptTimer;
102 import org.eclipse.jgit.util.io.LimitedInputStream;
103 import org.eclipse.jgit.util.io.TimeoutInputStream;
104 import org.eclipse.jgit.util.io.TimeoutOutputStream;
105 
106 /**
107  * Base implementation of the side of a push connection that receives objects.
108  * <p>
109  * Contains high-level operations for initializing and closing streams,
110  * advertising refs, reading commands, and receiving and applying a pack.
111  * Subclasses compose these operations into full service implementations.
112  */
113 public abstract class BaseReceivePack {
114 	/** Data in the first line of a request, the line itself plus capabilities. */
115 	public static class FirstLine {
116 		private final String line;
117 		private final Set<String> capabilities;
118 
119 		/**
120 		 * Parse the first line of a receive-pack request.
121 		 *
122 		 * @param line
123 		 *            line from the client.
124 		 */
125 		public FirstLine(String line) {
126 			final HashSet<String> caps = new HashSet<>();
127 			final int nul = line.indexOf('\0');
128 			if (nul >= 0) {
129 				for (String c : line.substring(nul + 1).split(" ")) //$NON-NLS-1$
130 					caps.add(c);
131 				this.line = line.substring(0, nul);
132 			} else
133 				this.line = line;
134 			this.capabilities = Collections.unmodifiableSet(caps);
135 		}
136 
137 		/** @return non-capabilities part of the line. */
138 		public String getLine() {
139 			return line;
140 		}
141 
142 		/** @return capabilities parsed from the line. */
143 		public Set<String> getCapabilities() {
144 			return capabilities;
145 		}
146 	}
147 
148 	/** Database we write the stored objects into. */
149 	private final Repository db;
150 
151 	/** Revision traversal support over {@link #db}. */
152 	private final RevWalk walk;
153 
154 	/**
155 	 * Is the client connection a bi-directional socket or pipe?
156 	 * <p>
157 	 * If true, this class assumes it can perform multiple read and write cycles
158 	 * with the client over the input and output streams. This matches the
159 	 * functionality available with a standard TCP/IP connection, or a local
160 	 * operating system or in-memory pipe.
161 	 * <p>
162 	 * If false, this class runs in a read everything then output results mode,
163 	 * making it suitable for single round-trip systems RPCs such as HTTP.
164 	 */
165 	private boolean biDirectionalPipe = true;
166 
167 	/** Expecting data after the pack footer */
168 	private boolean expectDataAfterPackFooter;
169 
170 	/** Should an incoming transfer validate objects? */
171 	private ObjectChecker objectChecker;
172 
173 	/** Should an incoming transfer permit create requests? */
174 	private boolean allowCreates;
175 
176 	/** Should an incoming transfer permit delete requests? */
177 	private boolean allowAnyDeletes;
178 	private boolean allowBranchDeletes;
179 
180 	/** Should an incoming transfer permit non-fast-forward requests? */
181 	private boolean allowNonFastForwards;
182 
183 	/** Should an incoming transfer permit push options? **/
184 	private boolean allowPushOptions;
185 
186 	/**
187 	 * Should the requested ref updates be performed as a single atomic
188 	 * transaction?
189 	 */
190 	private boolean atomic;
191 
192 	private boolean allowOfsDelta;
193 	private boolean allowQuiet = true;
194 
195 	/** Identity to record action as within the reflog. */
196 	private PersonIdent refLogIdent;
197 
198 	/** Hook used while advertising the refs to the client. */
199 	private AdvertiseRefsHook advertiseRefsHook;
200 
201 	/** Filter used while advertising the refs to the client. */
202 	private RefFilter refFilter;
203 
204 	/** Timeout in seconds to wait for client interaction. */
205 	private int timeout;
206 
207 	/** Timer to manage {@link #timeout}. */
208 	private InterruptTimer timer;
209 
210 	private TimeoutInputStream timeoutIn;
211 
212 	// Original stream passed to init(), since rawOut may be wrapped in a
213 	// sideband.
214 	private OutputStream origOut;
215 
216 	/** Raw input stream. */
217 	protected InputStream rawIn;
218 
219 	/** Raw output stream. */
220 	protected OutputStream rawOut;
221 
222 	/** Optional message output stream. */
223 	protected OutputStream msgOut;
224 	private SideBandOutputStream errOut;
225 
226 	/** Packet line input stream around {@link #rawIn}. */
227 	protected PacketLineIn pckIn;
228 
229 	/** Packet line output stream around {@link #rawOut}. */
230 	protected PacketLineOut pckOut;
231 
232 	private final MessageOutputWrapper msgOutWrapper = new MessageOutputWrapper();
233 
234 	private PackParser parser;
235 
236 	/** The refs we advertised as existing at the start of the connection. */
237 	private Map<String, Ref> refs;
238 
239 	/** All SHA-1s shown to the client, which can be possible edges. */
240 	private Set<ObjectId> advertisedHaves;
241 
242 	/** Capabilities requested by the client. */
243 	private Set<String> enabledCapabilities;
244 	String userAgent;
245 	private Set<ObjectId> clientShallowCommits;
246 	private List<ReceiveCommand> commands;
247 	private long maxCommandBytes;
248 	private long maxDiscardBytes;
249 
250 	private StringBuilder advertiseError;
251 
252 	/** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
253 	private boolean sideBand;
254 
255 	private boolean quiet;
256 
257 	/** Lock around the received pack file, while updating refs. */
258 	private PackLock packLock;
259 
260 	private boolean checkReferencedIsReachable;
261 
262 	/** Git object size limit */
263 	private long maxObjectSizeLimit;
264 
265 	/** Total pack size limit */
266 	private long maxPackSizeLimit = -1;
267 
268 	/** The size of the received pack, including index size */
269 	private Long packSize;
270 
271 	private PushCertificateParser pushCertificateParser;
272 	private SignedPushConfig signedPushConfig;
273 	private PushCertificate pushCert;
274 	private ReceivedPackStatistics stats;
275 
276 	/**
277 	 * Get the push certificate used to verify the pusher's identity.
278 	 * <p>
279 	 * Only valid after commands are read from the wire.
280 	 *
281 	 * @return the parsed certificate, or null if push certificates are disabled
282 	 *         or no cert was presented by the client.
283 	 * @since 4.1
284 	 */
285 	public PushCertificate getPushCertificate() {
286 		return pushCert;
287 	}
288 
289 	/**
290 	 * Set the push certificate used to verify the pusher's identity.
291 	 * <p>
292 	 * Should only be called if reconstructing an instance without going through
293 	 * the normal {@link #recvCommands()} flow.
294 	 *
295 	 * @param cert
296 	 *            the push certificate to set.
297 	 * @since 4.1
298 	 */
299 	public void setPushCertificate(PushCertificate cert) {
300 		pushCert = cert;
301 	}
302 
303 	/**
304 	 * Create a new pack receive for an open repository.
305 	 *
306 	 * @param into
307 	 *            the destination repository.
308 	 */
309 	protected BaseReceivePack(Repository into) {
310 		db = into;
311 		walk = new RevWalk(db);
312 
313 		TransferConfig tc = db.getConfig().get(TransferConfig.KEY);
314 		objectChecker = tc.newReceiveObjectChecker();
315 
316 		ReceiveConfig rc = db.getConfig().get(ReceiveConfig::new);
317 		allowCreates = rc.allowCreates;
318 		allowAnyDeletes = true;
319 		allowBranchDeletes = rc.allowDeletes;
320 		allowNonFastForwards = rc.allowNonFastForwards;
321 		allowOfsDelta = rc.allowOfsDelta;
322 		allowPushOptions = rc.allowPushOptions;
323 		maxCommandBytes = rc.maxCommandBytes;
324 		maxDiscardBytes = rc.maxDiscardBytes;
325 		advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
326 		refFilter = RefFilter.DEFAULT;
327 		advertisedHaves = new HashSet<>();
328 		clientShallowCommits = new HashSet<>();
329 		signedPushConfig = rc.signedPush;
330 	}
331 
332 	/** Configuration for receive operations. */
333 	protected static class ReceiveConfig {
334 		final boolean allowCreates;
335 		final boolean allowDeletes;
336 		final boolean allowNonFastForwards;
337 		final boolean allowOfsDelta;
338 		final boolean allowPushOptions;
339 		final long maxCommandBytes;
340 		final long maxDiscardBytes;
341 		final SignedPushConfig signedPush;
342 
343 		ReceiveConfig(Config config) {
344 			allowCreates = true;
345 			allowDeletes = !config.getBoolean("receive", "denydeletes", false); //$NON-NLS-1$ //$NON-NLS-2$
346 			allowNonFastForwards = !config.getBoolean("receive", //$NON-NLS-1$
347 					"denynonfastforwards", false); //$NON-NLS-1$
348 			allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset", //$NON-NLS-1$ //$NON-NLS-2$
349 					true);
350 			allowPushOptions = config.getBoolean("receive", "pushoptions", //$NON-NLS-1$ //$NON-NLS-2$
351 					false);
352 			maxCommandBytes = config.getLong("receive", //$NON-NLS-1$
353 					"maxCommandBytes", //$NON-NLS-1$
354 					3 << 20);
355 			maxDiscardBytes = config.getLong("receive", //$NON-NLS-1$
356 					"maxCommandDiscardBytes", //$NON-NLS-1$
357 					-1);
358 			signedPush = SignedPushConfig.KEY.parse(config);
359 		}
360 	}
361 
362 	/**
363 	 * Output stream that wraps the current {@link #msgOut}.
364 	 * <p>
365 	 * We don't want to expose {@link #msgOut} directly because it can change
366 	 * several times over the course of a session.
367 	 */
368 	class MessageOutputWrapper extends OutputStream {
369 		@Override
370 		public void write(int ch) {
371 			if (msgOut != null) {
372 				try {
373 					msgOut.write(ch);
374 				} catch (IOException e) {
375 					// Ignore write failures.
376 				}
377 			}
378 		}
379 
380 		@Override
381 		public void write(byte[] b, int off, int len) {
382 			if (msgOut != null) {
383 				try {
384 					msgOut.write(b, off, len);
385 				} catch (IOException e) {
386 					// Ignore write failures.
387 				}
388 			}
389 		}
390 
391 		@Override
392 		public void write(byte[] b) {
393 			write(b, 0, b.length);
394 		}
395 
396 		@Override
397 		public void flush() {
398 			if (msgOut != null) {
399 				try {
400 					msgOut.flush();
401 				} catch (IOException e) {
402 					// Ignore write failures.
403 				}
404 			}
405 		}
406 	}
407 
408 	/**
409 	 * Get the process name used for pack lock messages.
410 	 *
411 	 * @return the process name used for pack lock messages.
412 	 */
413 	protected abstract String getLockMessageProcessName();
414 
415 	/**
416 	 * Get the repository this receive completes into.
417 	 *
418 	 * @return the repository this receive completes into.
419 	 */
420 	public final Repository getRepository() {
421 		return db;
422 	}
423 
424 	/**
425 	 * Get the RevWalk instance used by this connection.
426 	 *
427 	 * @return the RevWalk instance used by this connection.
428 	 */
429 	public final RevWalk getRevWalk() {
430 		return walk;
431 	}
432 
433 	/**
434 	 * Get refs which were advertised to the client.
435 	 *
436 	 * @return all refs which were advertised to the client, or null if
437 	 *         {@link #setAdvertisedRefs(Map, Set)} has not been called yet.
438 	 */
439 	public final Map<String, Ref> getAdvertisedRefs() {
440 		return refs;
441 	}
442 
443 	/**
444 	 * Set the refs advertised by this ReceivePack.
445 	 * <p>
446 	 * Intended to be called from a
447 	 * {@link org.eclipse.jgit.transport.PreReceiveHook}.
448 	 *
449 	 * @param allRefs
450 	 *            explicit set of references to claim as advertised by this
451 	 *            ReceivePack instance. This overrides any references that may
452 	 *            exist in the source repository. The map is passed to the
453 	 *            configured {@link #getRefFilter()}. If null, assumes all refs
454 	 *            were advertised.
455 	 * @param additionalHaves
456 	 *            explicit set of additional haves to claim as advertised. If
457 	 *            null, assumes the default set of additional haves from the
458 	 *            repository.
459 	 */
460 	public void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additionalHaves) {
461 		refs = allRefs != null ? allRefs : db.getAllRefs();
462 		refs = refFilter.filter(refs);
463 		advertisedHaves.clear();
464 
465 		Ref head = refs.get(Constants.HEAD);
466 		if (head != null && head.isSymbolic())
467 			refs.remove(Constants.HEAD);
468 
469 		for (Ref ref : refs.values()) {
470 			if (ref.getObjectId() != null)
471 				advertisedHaves.add(ref.getObjectId());
472 		}
473 		if (additionalHaves != null)
474 			advertisedHaves.addAll(additionalHaves);
475 		else
476 			advertisedHaves.addAll(db.getAdditionalHaves());
477 	}
478 
479 	/**
480 	 * Get objects advertised to the client.
481 	 *
482 	 * @return the set of objects advertised to the as present in this repository,
483 	 *         or null if {@link #setAdvertisedRefs(Map, Set)} has not been called
484 	 *         yet.
485 	 */
486 	public final Set<ObjectId> getAdvertisedObjects() {
487 		return advertisedHaves;
488 	}
489 
490 	/**
491 	 * Whether this instance will validate all referenced, but not supplied by
492 	 * the client, objects are reachable from another reference.
493 	 *
494 	 * @return true if this instance will validate all referenced, but not
495 	 *         supplied by the client, objects are reachable from another
496 	 *         reference.
497 	 */
498 	public boolean isCheckReferencedObjectsAreReachable() {
499 		return checkReferencedIsReachable;
500 	}
501 
502 	/**
503 	 * Validate all referenced but not supplied objects are reachable.
504 	 * <p>
505 	 * If enabled, this instance will verify that references to objects not
506 	 * contained within the received pack are already reachable through at least
507 	 * one other reference displayed as part of {@link #getAdvertisedRefs()}.
508 	 * <p>
509 	 * This feature is useful when the application doesn't trust the client to
510 	 * not provide a forged SHA-1 reference to an object, in an attempt to
511 	 * access parts of the DAG that they aren't allowed to see and which have
512 	 * been hidden from them via the configured
513 	 * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} or
514 	 * {@link org.eclipse.jgit.transport.RefFilter}.
515 	 * <p>
516 	 * Enabling this feature may imply at least some, if not all, of the same
517 	 * functionality performed by {@link #setCheckReceivedObjects(boolean)}.
518 	 * Applications are encouraged to enable both features, if desired.
519 	 *
520 	 * @param b
521 	 *            {@code true} to enable the additional check.
522 	 */
523 	public void setCheckReferencedObjectsAreReachable(boolean b) {
524 		this.checkReferencedIsReachable = b;
525 	}
526 
527 	/**
528 	 * Whether this class expects a bi-directional pipe opened between the
529 	 * client and itself.
530 	 *
531 	 * @return true if this class expects a bi-directional pipe opened between
532 	 *         the client and itself. The default is true.
533 	 */
534 	public boolean isBiDirectionalPipe() {
535 		return biDirectionalPipe;
536 	}
537 
538 	/**
539 	 * Whether this class will assume the socket is a fully bidirectional pipe
540 	 * between the two peers and takes advantage of that by first transmitting
541 	 * the known refs, then waiting to read commands.
542 	 *
543 	 * @param twoWay
544 	 *            if true, this class will assume the socket is a fully
545 	 *            bidirectional pipe between the two peers and takes advantage
546 	 *            of that by first transmitting the known refs, then waiting to
547 	 *            read commands. If false, this class assumes it must read the
548 	 *            commands before writing output and does not perform the
549 	 *            initial advertising.
550 	 */
551 	public void setBiDirectionalPipe(boolean twoWay) {
552 		biDirectionalPipe = twoWay;
553 	}
554 
555 	/**
556 	 * Whether there is data expected after the pack footer.
557 	 *
558 	 * @return {@code true} if there is data expected after the pack footer.
559 	 */
560 	public boolean isExpectDataAfterPackFooter() {
561 		return expectDataAfterPackFooter;
562 	}
563 
564 	/**
565 	 * Whether there is additional data in InputStream after pack.
566 	 *
567 	 * @param e
568 	 *            {@code true} if there is additional data in InputStream after
569 	 *            pack.
570 	 */
571 	public void setExpectDataAfterPackFooter(boolean e) {
572 		expectDataAfterPackFooter = e;
573 	}
574 
575 	/**
576 	 * Whether this instance will verify received objects are formatted
577 	 * correctly.
578 	 *
579 	 * @return {@code true} if this instance will verify received objects are
580 	 *         formatted correctly. Validating objects requires more CPU time on
581 	 *         this side of the connection.
582 	 */
583 	public boolean isCheckReceivedObjects() {
584 		return objectChecker != null;
585 	}
586 
587 	/**
588 	 * Whether to enable checking received objects
589 	 *
590 	 * @param check
591 	 *            {@code true} to enable checking received objects; false to
592 	 *            assume all received objects are valid.
593 	 * @see #setObjectChecker(ObjectChecker)
594 	 */
595 	public void setCheckReceivedObjects(boolean check) {
596 		if (check && objectChecker == null)
597 			setObjectChecker(new ObjectChecker());
598 		else if (!check && objectChecker != null)
599 			setObjectChecker(null);
600 	}
601 
602 	/**
603 	 * Set the object checking instance to verify each received object with
604 	 *
605 	 * @param impl
606 	 *            if non-null the object checking instance to verify each
607 	 *            received object with; null to disable object checking.
608 	 * @since 3.4
609 	 */
610 	public void setObjectChecker(ObjectChecker impl) {
611 		objectChecker = impl;
612 	}
613 
614 	/**
615 	 * Whether the client can request refs to be created.
616 	 *
617 	 * @return {@code true} if the client can request refs to be created.
618 	 */
619 	public boolean isAllowCreates() {
620 		return allowCreates;
621 	}
622 
623 	/**
624 	 * Whether to permit create ref commands to be processed.
625 	 *
626 	 * @param canCreate
627 	 *            {@code true} to permit create ref commands to be processed.
628 	 */
629 	public void setAllowCreates(boolean canCreate) {
630 		allowCreates = canCreate;
631 	}
632 
633 	/**
634 	 * Whether the client can request refs to be deleted.
635 	 *
636 	 * @return {@code true} if the client can request refs to be deleted.
637 	 */
638 	public boolean isAllowDeletes() {
639 		return allowAnyDeletes;
640 	}
641 
642 	/**
643 	 * Whether to permit delete ref commands to be processed.
644 	 *
645 	 * @param canDelete
646 	 *            {@code true} to permit delete ref commands to be processed.
647 	 */
648 	public void setAllowDeletes(boolean canDelete) {
649 		allowAnyDeletes = canDelete;
650 	}
651 
652 	/**
653 	 * Whether the client can delete from {@code refs/heads/}.
654 	 *
655 	 * @return {@code true} if the client can delete from {@code refs/heads/}.
656 	 * @since 3.6
657 	 */
658 	public boolean isAllowBranchDeletes() {
659 		return allowBranchDeletes;
660 	}
661 
662 	/**
663 	 * Configure whether to permit deletion of branches from the
664 	 * {@code refs/heads/} namespace.
665 	 *
666 	 * @param canDelete
667 	 *            {@code true} to permit deletion of branches from the
668 	 *            {@code refs/heads/} namespace.
669 	 * @since 3.6
670 	 */
671 	public void setAllowBranchDeletes(boolean canDelete) {
672 		allowBranchDeletes = canDelete;
673 	}
674 
675 	/**
676 	 * Whether the client can request non-fast-forward updates of a ref,
677 	 * possibly making objects unreachable.
678 	 *
679 	 * @return {@code true} if the client can request non-fast-forward updates
680 	 *         of a ref, possibly making objects unreachable.
681 	 */
682 	public boolean isAllowNonFastForwards() {
683 		return allowNonFastForwards;
684 	}
685 
686 	/**
687 	 * Configure whether to permit the client to ask for non-fast-forward
688 	 * updates of an existing ref.
689 	 *
690 	 * @param canRewind
691 	 *            {@code true} to permit the client to ask for non-fast-forward
692 	 *            updates of an existing ref.
693 	 */
694 	public void setAllowNonFastForwards(boolean canRewind) {
695 		allowNonFastForwards = canRewind;
696 	}
697 
698 	/**
699 	 * Whether the client's commands should be performed as a single atomic
700 	 * transaction.
701 	 *
702 	 * @return {@code true} if the client's commands should be performed as a
703 	 *         single atomic transaction.
704 	 * @since 4.4
705 	 */
706 	public boolean isAtomic() {
707 		return atomic;
708 	}
709 
710 	/**
711 	 * Configure whether to perform the client's commands as a single atomic
712 	 * transaction.
713 	 *
714 	 * @param atomic
715 	 *            {@code true} to perform the client's commands as a single
716 	 *            atomic transaction.
717 	 * @since 4.4
718 	 */
719 	public void setAtomic(boolean atomic) {
720 		this.atomic = atomic;
721 	}
722 
723 	/**
724 	 * Get identity of the user making the changes in the reflog.
725 	 *
726 	 * @return identity of the user making the changes in the reflog.
727 	 */
728 	public PersonIdent getRefLogIdent() {
729 		return refLogIdent;
730 	}
731 
732 	/**
733 	 * Set the identity of the user appearing in the affected reflogs.
734 	 * <p>
735 	 * The timestamp portion of the identity is ignored. A new identity with the
736 	 * current timestamp will be created automatically when the updates occur
737 	 * and the log records are written.
738 	 *
739 	 * @param pi
740 	 *            identity of the user. If null the identity will be
741 	 *            automatically determined based on the repository
742 	 *            configuration.
743 	 */
744 	public void setRefLogIdent(PersonIdent pi) {
745 		refLogIdent = pi;
746 	}
747 
748 	/**
749 	 * Get the hook used while advertising the refs to the client
750 	 *
751 	 * @return the hook used while advertising the refs to the client
752 	 */
753 	public AdvertiseRefsHook getAdvertiseRefsHook() {
754 		return advertiseRefsHook;
755 	}
756 
757 	/**
758 	 * Get the filter used while advertising the refs to the client
759 	 *
760 	 * @return the filter used while advertising the refs to the client
761 	 */
762 	public RefFilter getRefFilter() {
763 		return refFilter;
764 	}
765 
766 	/**
767 	 * Set the hook used while advertising the refs to the client.
768 	 * <p>
769 	 * If the {@link org.eclipse.jgit.transport.AdvertiseRefsHook} chooses to
770 	 * call {@link #setAdvertisedRefs(Map,Set)}, only refs set by this hook
771 	 * <em>and</em> selected by the {@link org.eclipse.jgit.transport.RefFilter}
772 	 * will be shown to the client. Clients may still attempt to create or
773 	 * update a reference not advertised by the configured
774 	 * {@link org.eclipse.jgit.transport.AdvertiseRefsHook}. These attempts
775 	 * should be rejected by a matching
776 	 * {@link org.eclipse.jgit.transport.PreReceiveHook}.
777 	 *
778 	 * @param advertiseRefsHook
779 	 *            the hook; may be null to show all refs.
780 	 */
781 	public void setAdvertiseRefsHook(AdvertiseRefsHook advertiseRefsHook) {
782 		if (advertiseRefsHook != null)
783 			this.advertiseRefsHook = advertiseRefsHook;
784 		else
785 			this.advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
786 	}
787 
788 	/**
789 	 * Set the filter used while advertising the refs to the client.
790 	 * <p>
791 	 * Only refs allowed by this filter will be shown to the client. The filter
792 	 * is run against the refs specified by the
793 	 * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} (if applicable).
794 	 *
795 	 * @param refFilter
796 	 *            the filter; may be null to show all refs.
797 	 */
798 	public void setRefFilter(RefFilter refFilter) {
799 		this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT;
800 	}
801 
802 	/**
803 	 * Get timeout (in seconds) before aborting an IO operation.
804 	 *
805 	 * @return timeout (in seconds) before aborting an IO operation.
806 	 */
807 	public int getTimeout() {
808 		return timeout;
809 	}
810 
811 	/**
812 	 * Set the timeout before willing to abort an IO call.
813 	 *
814 	 * @param seconds
815 	 *            number of seconds to wait (with no data transfer occurring)
816 	 *            before aborting an IO read or write operation with the
817 	 *            connected client.
818 	 */
819 	public void setTimeout(int seconds) {
820 		timeout = seconds;
821 	}
822 
823 	/**
824 	 * Set the maximum number of command bytes to read from the client.
825 	 *
826 	 * @param limit
827 	 *            command limit in bytes; if 0 there is no limit.
828 	 * @since 4.7
829 	 */
830 	public void setMaxCommandBytes(long limit) {
831 		maxCommandBytes = limit;
832 	}
833 
834 	/**
835 	 * Set the maximum number of command bytes to discard from the client.
836 	 * <p>
837 	 * Discarding remaining bytes allows this instance to consume the rest of
838 	 * the command block and send a human readable over-limit error via the
839 	 * side-band channel. If the client sends an excessive number of bytes this
840 	 * limit kicks in and the instance disconnects, resulting in a non-specific
841 	 * 'pipe closed', 'end of stream', or similar generic error at the client.
842 	 * <p>
843 	 * When the limit is set to {@code -1} the implementation will default to
844 	 * the larger of {@code 3 * maxCommandBytes} or {@code 3 MiB}.
845 	 *
846 	 * @param limit
847 	 *            discard limit in bytes; if 0 there is no limit; if -1 the
848 	 *            implementation tries to set a reasonable default.
849 	 * @since 4.7
850 	 */
851 	public void setMaxCommandDiscardBytes(long limit) {
852 		maxDiscardBytes = limit;
853 	}
854 
855 	/**
856 	 * Set the maximum allowed Git object size.
857 	 * <p>
858 	 * If an object is larger than the given size the pack-parsing will throw an
859 	 * exception aborting the receive-pack operation.
860 	 *
861 	 * @param limit
862 	 *            the Git object size limit. If zero then there is not limit.
863 	 */
864 	public void setMaxObjectSizeLimit(long limit) {
865 		maxObjectSizeLimit = limit;
866 	}
867 
868 	/**
869 	 * Set the maximum allowed pack size.
870 	 * <p>
871 	 * A pack exceeding this size will be rejected.
872 	 *
873 	 * @param limit
874 	 *            the pack size limit, in bytes
875 	 * @since 3.3
876 	 */
877 	public void setMaxPackSizeLimit(long limit) {
878 		if (limit < 0)
879 			throw new IllegalArgumentException(MessageFormat.format(
880 					JGitText.get().receivePackInvalidLimit, Long.valueOf(limit)));
881 		maxPackSizeLimit = limit;
882 	}
883 
884 	/**
885 	 * Check whether the client expects a side-band stream.
886 	 *
887 	 * @return true if the client has advertised a side-band capability, false
888 	 *     otherwise.
889 	 * @throws org.eclipse.jgit.transport.RequestNotYetReadException
890 	 *             if the client's request has not yet been read from the wire, so
891 	 *             we do not know if they expect side-band. Note that the client
892 	 *             may have already written the request, it just has not been
893 	 *             read.
894 	 */
895 	public boolean isSideBand() throws RequestNotYetReadException {
896 		checkRequestWasRead();
897 		return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
898 	}
899 
900 	/**
901 	 * Whether clients may request avoiding noisy progress messages.
902 	 *
903 	 * @return true if clients may request avoiding noisy progress messages.
904 	 * @since 4.0
905 	 */
906 	public boolean isAllowQuiet() {
907 		return allowQuiet;
908 	}
909 
910 	/**
911 	 * Configure if clients may request the server skip noisy messages.
912 	 *
913 	 * @param allow
914 	 *            true to allow clients to request quiet behavior; false to
915 	 *            refuse quiet behavior and send messages anyway. This may be
916 	 *            necessary if processing is slow and the client-server network
917 	 *            connection can timeout.
918 	 * @since 4.0
919 	 */
920 	public void setAllowQuiet(boolean allow) {
921 		allowQuiet = allow;
922 	}
923 
924 	/**
925 	 * Whether the server supports receiving push options.
926 	 *
927 	 * @return true if the server supports receiving push options.
928 	 * @since 4.5
929 	 */
930 	public boolean isAllowPushOptions() {
931 		return allowPushOptions;
932 	}
933 
934 	/**
935 	 * Configure if the server supports receiving push options.
936 	 *
937 	 * @param allow
938 	 *            true to optionally accept option strings from the client.
939 	 * @since 4.5
940 	 */
941 	public void setAllowPushOptions(boolean allow) {
942 		allowPushOptions = allow;
943 	}
944 
945 	/**
946 	 * True if the client wants less verbose output.
947 	 *
948 	 * @return true if the client has requested the server to be less verbose.
949 	 * @throws org.eclipse.jgit.transport.RequestNotYetReadException
950 	 *             if the client's request has not yet been read from the wire,
951 	 *             so we do not know if they expect side-band. Note that the
952 	 *             client may have already written the request, it just has not
953 	 *             been read.
954 	 * @since 4.0
955 	 */
956 	public boolean isQuiet() throws RequestNotYetReadException {
957 		checkRequestWasRead();
958 		return quiet;
959 	}
960 
961 	/**
962 	 * Set the configuration for push certificate verification.
963 	 *
964 	 * @param cfg
965 	 *            new configuration; if this object is null or its {@link
966 	 *            SignedPushConfig#getCertNonceSeed()} is null, push certificate
967 	 *            verification will be disabled.
968 	 * @since 4.1
969 	 */
970 	public void setSignedPushConfig(SignedPushConfig cfg) {
971 		signedPushConfig = cfg;
972 	}
973 
974 	private PushCertificateParser getPushCertificateParser() {
975 		if (pushCertificateParser == null) {
976 			pushCertificateParser = new PushCertificateParser(db, signedPushConfig);
977 		}
978 		return pushCertificateParser;
979 	}
980 
981 	/**
982 	 * Get the user agent of the client.
983 	 * <p>
984 	 * If the client is new enough to use {@code agent=} capability that value
985 	 * will be returned. Older HTTP clients may also supply their version using
986 	 * the HTTP {@code User-Agent} header. The capability overrides the HTTP
987 	 * header if both are available.
988 	 * <p>
989 	 * When an HTTP request has been received this method returns the HTTP
990 	 * {@code User-Agent} header value until capabilities have been parsed.
991 	 *
992 	 * @return user agent supplied by the client. Available only if the client
993 	 *         is new enough to advertise its user agent.
994 	 * @since 4.0
995 	 */
996 	public String getPeerUserAgent() {
997 		return UserAgent.getAgent(enabledCapabilities, userAgent);
998 	}
999 
1000 	/**
1001 	 * Get all of the command received by the current request.
1002 	 *
1003 	 * @return all of the command received by the current request.
1004 	 */
1005 	public List<ReceiveCommand> getAllCommands() {
1006 		return Collections.unmodifiableList(commands);
1007 	}
1008 
1009 	/**
1010 	 * Send an error message to the client.
1011 	 * <p>
1012 	 * If any error messages are sent before the references are advertised to
1013 	 * the client, the errors will be sent instead of the advertisement and the
1014 	 * receive operation will be aborted. All clients should receive and display
1015 	 * such early stage errors.
1016 	 * <p>
1017 	 * If the reference advertisements have already been sent, messages are sent
1018 	 * in a side channel. If the client doesn't support receiving messages, the
1019 	 * message will be discarded, with no other indication to the caller or to
1020 	 * the client.
1021 	 * <p>
1022 	 * {@link org.eclipse.jgit.transport.PreReceiveHook}s should always try to
1023 	 * use
1024 	 * {@link org.eclipse.jgit.transport.ReceiveCommand#setResult(Result, String)}
1025 	 * with a result status of
1026 	 * {@link org.eclipse.jgit.transport.ReceiveCommand.Result#REJECTED_OTHER_REASON}
1027 	 * to indicate any reasons for rejecting an update. Messages attached to a
1028 	 * command are much more likely to be returned to the client.
1029 	 *
1030 	 * @param what
1031 	 *            string describing the problem identified by the hook. The
1032 	 *            string must not end with an LF, and must not contain an LF.
1033 	 */
1034 	public void sendError(String what) {
1035 		if (refs == null) {
1036 			if (advertiseError == null)
1037 				advertiseError = new StringBuilder();
1038 			advertiseError.append(what).append('\n');
1039 		} else {
1040 			msgOutWrapper.write(Constants.encode("error: " + what + "\n")); //$NON-NLS-1$ //$NON-NLS-2$
1041 		}
1042 	}
1043 
1044 	private void fatalError(String msg) {
1045 		if (errOut != null) {
1046 			try {
1047 				errOut.write(Constants.encode(msg));
1048 				errOut.flush();
1049 			} catch (IOException e) {
1050 				// Ignore write failures
1051 			}
1052 		} else {
1053 			sendError(msg);
1054 		}
1055 	}
1056 
1057 	/**
1058 	 * Send a message to the client, if it supports receiving them.
1059 	 * <p>
1060 	 * If the client doesn't support receiving messages, the message will be
1061 	 * discarded, with no other indication to the caller or to the client.
1062 	 *
1063 	 * @param what
1064 	 *            string describing the problem identified by the hook. The
1065 	 *            string must not end with an LF, and must not contain an LF.
1066 	 */
1067 	public void sendMessage(String what) {
1068 		msgOutWrapper.write(Constants.encode(what + "\n")); //$NON-NLS-1$
1069 	}
1070 
1071 	/**
1072 	 * Get an underlying stream for sending messages to the client.
1073 	 *
1074 	 * @return an underlying stream for sending messages to the client.
1075 	 */
1076 	public OutputStream getMessageOutputStream() {
1077 		return msgOutWrapper;
1078 	}
1079 
1080 	/**
1081 	 * Get the size of the received pack file including the index size.
1082 	 *
1083 	 * This can only be called if the pack is already received.
1084 	 *
1085 	 * @return the size of the received pack including index size
1086 	 * @throws java.lang.IllegalStateException
1087 	 *             if called before the pack has been received
1088 	 * @since 3.3
1089 	 */
1090 	public long getPackSize() {
1091 		if (packSize != null)
1092 			return packSize.longValue();
1093 		throw new IllegalStateException(JGitText.get().packSizeNotSetYet);
1094 	}
1095 
1096 	/**
1097 	 * Get the commits from the client's shallow file.
1098 	 *
1099 	 * @return if the client is a shallow repository, the list of edge commits
1100 	 *     that define the client's shallow boundary. Empty set if the client
1101 	 *     is earlier than Git 1.9, or is a full clone.
1102 	 * @since 3.5
1103 	 */
1104 	protected Set<ObjectId> getClientShallowCommits() {
1105 		return clientShallowCommits;
1106 	}
1107 
1108 	/**
1109 	 * Whether any commands to be executed have been read.
1110 	 *
1111 	 * @return {@code true} if any commands to be executed have been read.
1112 	 */
1113 	protected boolean hasCommands() {
1114 		return !commands.isEmpty();
1115 	}
1116 
1117 	/**
1118 	 * Whether an error occurred that should be advertised.
1119 	 *
1120 	 * @return true if an error occurred that should be advertised.
1121 	 */
1122 	protected boolean hasError() {
1123 		return advertiseError != null;
1124 	}
1125 
1126 	/**
1127 	 * Initialize the instance with the given streams.
1128 	 *
1129 	 * @param input
1130 	 *            raw input to read client commands and pack data from. Caller
1131 	 *            must ensure the input is buffered, otherwise read performance
1132 	 *            may suffer.
1133 	 * @param output
1134 	 *            response back to the Git network client. Caller must ensure
1135 	 *            the output is buffered, otherwise write performance may
1136 	 *            suffer.
1137 	 * @param messages
1138 	 *            secondary "notice" channel to send additional messages out
1139 	 *            through. When run over SSH this should be tied back to the
1140 	 *            standard error channel of the command execution. For most
1141 	 *            other network connections this should be null.
1142 	 */
1143 	protected void init(final InputStream input, final OutputStream output,
1144 			final OutputStream messages) {
1145 		origOut = output;
1146 		rawIn = input;
1147 		rawOut = output;
1148 		msgOut = messages;
1149 
1150 		if (timeout > 0) {
1151 			final Thread caller = Thread.currentThread();
1152 			timer = new InterruptTimer(caller.getName() + "-Timer"); //$NON-NLS-1$
1153 			timeoutIn = new TimeoutInputStream(rawIn, timer);
1154 			TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
1155 			timeoutIn.setTimeout(timeout * 1000);
1156 			o.setTimeout(timeout * 1000);
1157 			rawIn = timeoutIn;
1158 			rawOut = o;
1159 		}
1160 
1161 		pckIn = new PacketLineIn(rawIn);
1162 		pckOut = new PacketLineOut(rawOut);
1163 		pckOut.setFlushOnEnd(false);
1164 
1165 		enabledCapabilities = new HashSet<>();
1166 		commands = new ArrayList<>();
1167 	}
1168 
1169 	/**
1170 	 * Get advertised refs, or the default if not explicitly advertised.
1171 	 *
1172 	 * @return advertised refs, or the default if not explicitly advertised.
1173 	 */
1174 	protected Map<String, Ref> getAdvertisedOrDefaultRefs() {
1175 		if (refs == null)
1176 			setAdvertisedRefs(null, null);
1177 		return refs;
1178 	}
1179 
1180 	/**
1181 	 * Receive a pack from the stream and check connectivity if necessary.
1182 	 *
1183 	 * @throws java.io.IOException
1184 	 *             an error occurred during unpacking or connectivity checking.
1185 	 */
1186 	protected void receivePackAndCheckConnectivity() throws IOException {
1187 		receivePack();
1188 		if (needCheckConnectivity())
1189 			checkConnectivity();
1190 		parser = null;
1191 	}
1192 
1193 	/**
1194 	 * Unlock the pack written by this object.
1195 	 *
1196 	 * @throws java.io.IOException
1197 	 *             the pack could not be unlocked.
1198 	 */
1199 	protected void unlockPack() throws IOException {
1200 		if (packLock != null) {
1201 			packLock.unlock();
1202 			packLock = null;
1203 		}
1204 	}
1205 
1206 	/**
1207 	 * Generate an advertisement of available refs and capabilities.
1208 	 *
1209 	 * @param adv
1210 	 *            the advertisement formatter.
1211 	 * @throws java.io.IOException
1212 	 *             the formatter failed to write an advertisement.
1213 	 * @throws org.eclipse.jgit.transport.ServiceMayNotContinueException
1214 	 *             the hook denied advertisement.
1215 	 */
1216 	public void sendAdvertisedRefs(RefAdvertiser adv)
1217 			throws IOException, ServiceMayNotContinueException {
1218 		if (advertiseError != null) {
1219 			adv.writeOne("ERR " + advertiseError); //$NON-NLS-1$
1220 			return;
1221 		}
1222 
1223 		try {
1224 			advertiseRefsHook.advertiseRefs(this);
1225 		} catch (ServiceMayNotContinueException fail) {
1226 			if (fail.getMessage() != null) {
1227 				adv.writeOne("ERR " + fail.getMessage()); //$NON-NLS-1$
1228 				fail.setOutput();
1229 			}
1230 			throw fail;
1231 		}
1232 
1233 		adv.init(db);
1234 		adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
1235 		adv.advertiseCapability(CAPABILITY_DELETE_REFS);
1236 		adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
1237 		if (allowQuiet)
1238 			adv.advertiseCapability(CAPABILITY_QUIET);
1239 		String nonce = getPushCertificateParser().getAdvertiseNonce();
1240 		if (nonce != null) {
1241 			adv.advertiseCapability(nonce);
1242 		}
1243 		if (db.getRefDatabase().performsAtomicTransactions())
1244 			adv.advertiseCapability(CAPABILITY_ATOMIC);
1245 		if (allowOfsDelta)
1246 			adv.advertiseCapability(CAPABILITY_OFS_DELTA);
1247 		if (allowPushOptions) {
1248 			adv.advertiseCapability(CAPABILITY_PUSH_OPTIONS);
1249 		}
1250 		adv.advertiseCapability(OPTION_AGENT, UserAgent.get());
1251 		adv.send(getAdvertisedOrDefaultRefs());
1252 		for (ObjectId obj : advertisedHaves)
1253 			adv.advertiseHave(obj);
1254 		if (adv.isEmpty())
1255 			adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$
1256 		adv.end();
1257 	}
1258 
1259 	/**
1260 	 * Returns the statistics on the received pack if available. This should be
1261 	 * called after {@link #receivePack} is called.
1262 	 *
1263 	 * @return ReceivedPackStatistics
1264 	 * @since 4.6
1265 	 */
1266 	@Nullable
1267 	public ReceivedPackStatistics getReceivedPackStatistics() {
1268 		return stats;
1269 	}
1270 
1271 	/**
1272 	 * Receive a list of commands from the input.
1273 	 *
1274 	 * @throws java.io.IOException
1275 	 */
1276 	protected void recvCommands() throws IOException {
1277 		PacketLineIn pck = maxCommandBytes > 0
1278 				? new PacketLineIn(rawIn, maxCommandBytes)
1279 				: pckIn;
1280 		PushCertificateParser certParser = getPushCertificateParser();
1281 		boolean firstPkt = true;
1282 		try {
1283 			for (;;) {
1284 				String line;
1285 				try {
1286 					line = pck.readString();
1287 				} catch (EOFException eof) {
1288 					if (commands.isEmpty())
1289 						return;
1290 					throw eof;
1291 				}
1292 				if (line == PacketLineIn.END) {
1293 					break;
1294 				}
1295 
1296 				if (line.length() >= 48 && line.startsWith("shallow ")) { //$NON-NLS-1$
1297 					parseShallow(line.substring(8, 48));
1298 					continue;
1299 				}
1300 
1301 				if (firstPkt) {
1302 					firstPkt = false;
1303 					FirstLine firstLine = new FirstLine(line);
1304 					enabledCapabilities = firstLine.getCapabilities();
1305 					line = firstLine.getLine();
1306 					enableCapabilities();
1307 
1308 					if (line.equals(GitProtocolConstants.OPTION_PUSH_CERT)) {
1309 						certParser.receiveHeader(pck, !isBiDirectionalPipe());
1310 						continue;
1311 					}
1312 				}
1313 
1314 				if (line.equals(PushCertificateParser.BEGIN_SIGNATURE)) {
1315 					certParser.receiveSignature(pck);
1316 					continue;
1317 				}
1318 
1319 				ReceiveCommand cmd = parseCommand(line);
1320 				if (cmd.getRefName().equals(Constants.HEAD)) {
1321 					cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
1322 				} else {
1323 					cmd.setRef(refs.get(cmd.getRefName()));
1324 				}
1325 				commands.add(cmd);
1326 				if (certParser.enabled()) {
1327 					certParser.addCommand(cmd);
1328 				}
1329 			}
1330 			pushCert = certParser.build();
1331 			if (hasCommands()) {
1332 				readPostCommands(pck);
1333 			}
1334 		} catch (PackProtocolException e) {
1335 			discardCommands();
1336 			fatalError(e.getMessage());
1337 			throw e;
1338 		} catch (InputOverLimitIOException e) {
1339 			String msg = JGitText.get().tooManyCommands;
1340 			discardCommands();
1341 			fatalError(msg);
1342 			throw new PackProtocolException(msg);
1343 		}
1344 	}
1345 
1346 	private void discardCommands() {
1347 		if (sideBand) {
1348 			long max = maxDiscardBytes;
1349 			if (max < 0) {
1350 				max = Math.max(3 * maxCommandBytes, 3L << 20);
1351 			}
1352 			try {
1353 				new PacketLineIn(rawIn, max).discardUntilEnd();
1354 			} catch (IOException e) {
1355 				// Ignore read failures attempting to discard.
1356 			}
1357 		}
1358 	}
1359 
1360 	private void parseShallow(String idStr) throws PackProtocolException {
1361 		ObjectId id;
1362 		try {
1363 			id = ObjectId.fromString(idStr);
1364 		} catch (InvalidObjectIdException e) {
1365 			throw new PackProtocolException(e.getMessage(), e);
1366 		}
1367 		clientShallowCommits.add(id);
1368 	}
1369 
1370 	static ReceiveCommand parseCommand(String line) throws PackProtocolException {
1371           if (line == null || line.length() < 83) {
1372 			throw new PackProtocolException(
1373 					JGitText.get().errorInvalidProtocolWantedOldNewRef);
1374 		}
1375 		String oldStr = line.substring(0, 40);
1376 		String newStr = line.substring(41, 81);
1377 		ObjectId oldId, newId;
1378 		try {
1379 			oldId = ObjectId.fromString(oldStr);
1380 			newId = ObjectId.fromString(newStr);
1381 		} catch (InvalidObjectIdException e) {
1382 			throw new PackProtocolException(
1383 					JGitText.get().errorInvalidProtocolWantedOldNewRef, e);
1384 		}
1385 		String name = line.substring(82);
1386 		if (!Repository.isValidRefName(name)) {
1387 			throw new PackProtocolException(
1388 					JGitText.get().errorInvalidProtocolWantedOldNewRef);
1389 		}
1390 		return new ReceiveCommand(oldId, newId, name);
1391 	}
1392 
1393 	/**
1394 	 * @param in
1395 	 *            request stream.
1396 	 * @throws IOException
1397 	 *             request line cannot be read.
1398 	 */
1399 	void readPostCommands(PacketLineIn in) throws IOException {
1400 		// Do nothing by default.
1401 	}
1402 
1403 	/**
1404 	 * Enable capabilities based on a previously read capabilities line.
1405 	 */
1406 	protected void enableCapabilities() {
1407 		sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
1408 		quiet = allowQuiet && isCapabilityEnabled(CAPABILITY_QUIET);
1409 		if (sideBand) {
1410 			OutputStream out = rawOut;
1411 
1412 			rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
1413 			msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
1414 			errOut = new SideBandOutputStream(CH_ERROR, MAX_BUF, out);
1415 
1416 			pckOut = new PacketLineOut(rawOut);
1417 			pckOut.setFlushOnEnd(false);
1418 		}
1419 	}
1420 
1421 	/**
1422 	 * Check if the peer requested a capability.
1423 	 *
1424 	 * @param name
1425 	 *            protocol name identifying the capability.
1426 	 * @return true if the peer requested the capability to be enabled.
1427 	 */
1428 	protected boolean isCapabilityEnabled(String name) {
1429 		return enabledCapabilities.contains(name);
1430 	}
1431 
1432 	void checkRequestWasRead() {
1433 		if (enabledCapabilities == null)
1434 			throw new RequestNotYetReadException();
1435 	}
1436 
1437 	/**
1438 	 * Whether a pack is expected based on the list of commands.
1439 	 *
1440 	 * @return {@code true} if a pack is expected based on the list of commands.
1441 	 */
1442 	protected boolean needPack() {
1443 		for (ReceiveCommand cmd : commands) {
1444 			if (cmd.getType() != ReceiveCommand.Type.DELETE)
1445 				return true;
1446 		}
1447 		return false;
1448 	}
1449 
1450 	/**
1451 	 * Receive a pack from the input and store it in the repository.
1452 	 *
1453 	 * @throws IOException
1454 	 *             an error occurred reading or indexing the pack.
1455 	 */
1456 	private void receivePack() throws IOException {
1457 		// It might take the client a while to pack the objects it needs
1458 		// to send to us.  We should increase our timeout so we don't
1459 		// abort while the client is computing.
1460 		//
1461 		if (timeoutIn != null)
1462 			timeoutIn.setTimeout(10 * timeout * 1000);
1463 
1464 		ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
1465 		ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
1466 		if (sideBand && !quiet)
1467 			resolving = new SideBandProgressMonitor(msgOut);
1468 
1469 		try (ObjectInserter ins = db.newObjectInserter()) {
1470 			String lockMsg = "jgit receive-pack"; //$NON-NLS-1$
1471 			if (getRefLogIdent() != null)
1472 				lockMsg += " from " + getRefLogIdent().toExternalString(); //$NON-NLS-1$
1473 
1474 			parser = ins.newPackParser(packInputStream());
1475 			parser.setAllowThin(true);
1476 			parser.setNeedNewObjectIds(checkReferencedIsReachable);
1477 			parser.setNeedBaseObjectIds(checkReferencedIsReachable);
1478 			parser.setCheckEofAfterPackFooter(!biDirectionalPipe
1479 					&& !isExpectDataAfterPackFooter());
1480 			parser.setExpectDataAfterPackFooter(isExpectDataAfterPackFooter());
1481 			parser.setObjectChecker(objectChecker);
1482 			parser.setLockMessage(lockMsg);
1483 			parser.setMaxObjectSizeLimit(maxObjectSizeLimit);
1484 			packLock = parser.parse(receiving, resolving);
1485 			packSize = Long.valueOf(parser.getPackSize());
1486 			stats = parser.getReceivedPackStatistics();
1487 			ins.flush();
1488 		}
1489 
1490 		if (timeoutIn != null)
1491 			timeoutIn.setTimeout(timeout * 1000);
1492 	}
1493 
1494 	private InputStream packInputStream() {
1495 		InputStream packIn = rawIn;
1496 		if (maxPackSizeLimit >= 0) {
1497 			packIn = new LimitedInputStream(packIn, maxPackSizeLimit) {
1498 				@Override
1499 				protected void limitExceeded() throws TooLargePackException {
1500 					throw new TooLargePackException(limit);
1501 				}
1502 			};
1503 		}
1504 		return packIn;
1505 	}
1506 
1507 	private boolean needCheckConnectivity() {
1508 		return isCheckReceivedObjects()
1509 				|| isCheckReferencedObjectsAreReachable()
1510 				|| !getClientShallowCommits().isEmpty();
1511 	}
1512 
1513 	private void checkConnectivity() throws IOException {
1514 		ObjectIdSubclassMap<ObjectId> baseObjects = null;
1515 		ObjectIdSubclassMap<ObjectId> providedObjects = null;
1516 		ProgressMonitor checking = NullProgressMonitor.INSTANCE;
1517 		if (sideBand && !quiet) {
1518 			SideBandProgressMonitor m = new SideBandProgressMonitor(msgOut);
1519 			m.setDelayStart(750, TimeUnit.MILLISECONDS);
1520 			checking = m;
1521 		}
1522 
1523 		if (checkReferencedIsReachable) {
1524 			baseObjects = parser.getBaseObjectIds();
1525 			providedObjects = parser.getNewObjectIds();
1526 		}
1527 		parser = null;
1528 
1529 		try (ObjectWalk ow = new ObjectWalk(db)) {
1530 			if (baseObjects != null) {
1531 				ow.sort(RevSort.TOPO);
1532 				if (!baseObjects.isEmpty())
1533 					ow.sort(RevSort.BOUNDARY, true);
1534 			}
1535 
1536 			for (ReceiveCommand cmd : commands) {
1537 				if (cmd.getResult() != Result.NOT_ATTEMPTED)
1538 					continue;
1539 				if (cmd.getType() == ReceiveCommand.Type.DELETE)
1540 					continue;
1541 				ow.markStart(ow.parseAny(cmd.getNewId()));
1542 			}
1543 			for (ObjectId have : advertisedHaves) {
1544 				RevObject o = ow.parseAny(have);
1545 				ow.markUninteresting(o);
1546 
1547 				if (baseObjects != null && !baseObjects.isEmpty()) {
1548 					o = ow.peel(o);
1549 					if (o instanceof RevCommit)
1550 						o = ((RevCommit) o).getTree();
1551 					if (o instanceof RevTree)
1552 						ow.markUninteresting(o);
1553 				}
1554 			}
1555 
1556 			checking.beginTask(JGitText.get().countingObjects,
1557 					ProgressMonitor.UNKNOWN);
1558 			RevCommit c;
1559 			while ((c = ow.next()) != null) {
1560 				checking.update(1);
1561 				if (providedObjects != null //
1562 						&& !c.has(RevFlag.UNINTERESTING) //
1563 						&& !providedObjects.contains(c))
1564 					throw new MissingObjectException(c, Constants.TYPE_COMMIT);
1565 			}
1566 
1567 			RevObject o;
1568 			while ((o = ow.nextObject()) != null) {
1569 				checking.update(1);
1570 				if (o.has(RevFlag.UNINTERESTING))
1571 					continue;
1572 
1573 				if (providedObjects != null) {
1574 					if (providedObjects.contains(o))
1575 						continue;
1576 					else
1577 						throw new MissingObjectException(o, o.getType());
1578 				}
1579 
1580 				if (o instanceof RevBlob && !db.hasObject(o))
1581 					throw new MissingObjectException(o, Constants.TYPE_BLOB);
1582 			}
1583 			checking.endTask();
1584 
1585 			if (baseObjects != null) {
1586 				for (ObjectId id : baseObjects) {
1587 					o = ow.parseAny(id);
1588 					if (!o.has(RevFlag.UNINTERESTING))
1589 						throw new MissingObjectException(o, o.getType());
1590 				}
1591 			}
1592 		}
1593 	}
1594 
1595 	/**
1596 	 * Validate the command list.
1597 	 */
1598 	protected void validateCommands() {
1599 		for (ReceiveCommand cmd : commands) {
1600 			final Ref ref = cmd.getRef();
1601 			if (cmd.getResult() != Result.NOT_ATTEMPTED)
1602 				continue;
1603 
1604 			if (cmd.getType() == ReceiveCommand.Type.DELETE) {
1605 				if (!isAllowDeletes()) {
1606 					// Deletes are not supported on this repository.
1607 					cmd.setResult(Result.REJECTED_NODELETE);
1608 					continue;
1609 				}
1610 				if (!isAllowBranchDeletes()
1611 						&& ref.getName().startsWith(Constants.R_HEADS)) {
1612 					// Branches cannot be deleted, but other refs can.
1613 					cmd.setResult(Result.REJECTED_NODELETE);
1614 					continue;
1615 				}
1616 			}
1617 
1618 			if (cmd.getType() == ReceiveCommand.Type.CREATE) {
1619 				if (!isAllowCreates()) {
1620 					cmd.setResult(Result.REJECTED_NOCREATE);
1621 					continue;
1622 				}
1623 
1624 				if (ref != null && !isAllowNonFastForwards()) {
1625 					// Creation over an existing ref is certainly not going
1626 					// to be a fast-forward update. We can reject it early.
1627 					//
1628 					cmd.setResult(Result.REJECTED_NONFASTFORWARD);
1629 					continue;
1630 				}
1631 
1632 				if (ref != null) {
1633 					// A well behaved client shouldn't have sent us a
1634 					// create command for a ref we advertised to it.
1635 					//
1636 					cmd.setResult(Result.REJECTED_OTHER_REASON,
1637 							JGitText.get().refAlreadyExists);
1638 					continue;
1639 				}
1640 			}
1641 
1642 			if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null) {
1643 				ObjectId id = ref.getObjectId();
1644 				if (id == null) {
1645 					id = ObjectId.zeroId();
1646 				}
1647 				if (!ObjectId.zeroId().equals(cmd.getOldId())
1648 						&& !id.equals(cmd.getOldId())) {
1649 					// Delete commands can be sent with the old id matching our
1650 					// advertised value, *OR* with the old id being 0{40}. Any
1651 					// other requested old id is invalid.
1652 					//
1653 					cmd.setResult(Result.REJECTED_OTHER_REASON,
1654 							JGitText.get().invalidOldIdSent);
1655 					continue;
1656 				}
1657 			}
1658 
1659 			if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
1660 				if (ref == null) {
1661 					// The ref must have been advertised in order to be updated.
1662 					//
1663 					cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
1664 					continue;
1665 				}
1666 				ObjectId id = ref.getObjectId();
1667 				if (id == null) {
1668 					// We cannot update unborn branch
1669 					cmd.setResult(Result.REJECTED_OTHER_REASON,
1670 							JGitText.get().cannotUpdateUnbornBranch);
1671 					continue;
1672 				}
1673 
1674 				if (!id.equals(cmd.getOldId())) {
1675 					// A properly functioning client will send the same
1676 					// object id we advertised.
1677 					//
1678 					cmd.setResult(Result.REJECTED_OTHER_REASON,
1679 							JGitText.get().invalidOldIdSent);
1680 					continue;
1681 				}
1682 
1683 				// Is this possibly a non-fast-forward style update?
1684 				//
1685 				RevObject oldObj, newObj;
1686 				try {
1687 					oldObj = walk.parseAny(cmd.getOldId());
1688 				} catch (IOException e) {
1689 					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
1690 							.getOldId().name());
1691 					continue;
1692 				}
1693 
1694 				try {
1695 					newObj = walk.parseAny(cmd.getNewId());
1696 				} catch (IOException e) {
1697 					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
1698 							.getNewId().name());
1699 					continue;
1700 				}
1701 
1702 				if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
1703 					try {
1704 						if (walk.isMergedInto((RevCommit) oldObj,
1705 								(RevCommit) newObj))
1706 							cmd.setTypeFastForwardUpdate();
1707 						else
1708 							cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
1709 					} catch (MissingObjectException e) {
1710 						cmd.setResult(Result.REJECTED_MISSING_OBJECT, e
1711 								.getMessage());
1712 					} catch (IOException e) {
1713 						cmd.setResult(Result.REJECTED_OTHER_REASON);
1714 					}
1715 				} else {
1716 					cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
1717 				}
1718 
1719 				if (cmd.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD
1720 						&& !isAllowNonFastForwards()) {
1721 					cmd.setResult(Result.REJECTED_NONFASTFORWARD);
1722 					continue;
1723 				}
1724 			}
1725 
1726 			if (!cmd.getRefName().startsWith(Constants.R_REFS)
1727 					|| !Repository.isValidRefName(cmd.getRefName())) {
1728 				cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
1729 			}
1730 		}
1731 	}
1732 
1733 	/**
1734 	 * Whether any commands have been rejected so far.
1735 	 *
1736 	 * @return if any commands have been rejected so far.
1737 	 * @since 3.6
1738 	 */
1739 	protected boolean anyRejects() {
1740 		for (ReceiveCommand cmd : commands) {
1741 			if (cmd.getResult() != Result.NOT_ATTEMPTED && cmd.getResult() != Result.OK)
1742 				return true;
1743 		}
1744 		return false;
1745 	}
1746 
1747 	/**
1748 	 * Set the result to fail for any command that was not processed yet.
1749 	 *
1750 	 * @since 3.6
1751 	 */
1752 	protected void failPendingCommands() {
1753 		ReceiveCommand.abort(commands);
1754 	}
1755 
1756 	/**
1757 	 * Filter the list of commands according to result.
1758 	 *
1759 	 * @param want
1760 	 *            desired status to filter by.
1761 	 * @return a copy of the command list containing only those commands with the
1762 	 *         desired status.
1763 	 */
1764 	protected List<ReceiveCommand> filterCommands(Result want) {
1765 		return ReceiveCommand.filter(commands, want);
1766 	}
1767 
1768 	/**
1769 	 * Execute commands to update references.
1770 	 */
1771 	protected void executeCommands() {
1772 		List<ReceiveCommand> toApply = filterCommands(Result.NOT_ATTEMPTED);
1773 		if (toApply.isEmpty())
1774 			return;
1775 
1776 		ProgressMonitor updating = NullProgressMonitor.INSTANCE;
1777 		if (sideBand) {
1778 			SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
1779 			pm.setDelayStart(250, TimeUnit.MILLISECONDS);
1780 			updating = pm;
1781 		}
1782 
1783 		BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate();
1784 		batch.setAllowNonFastForwards(isAllowNonFastForwards());
1785 		batch.setAtomic(isAtomic());
1786 		batch.setRefLogIdent(getRefLogIdent());
1787 		batch.setRefLogMessage("push", true); //$NON-NLS-1$
1788 		batch.addCommand(toApply);
1789 		try {
1790 			batch.setPushCertificate(getPushCertificate());
1791 			batch.execute(walk, updating);
1792 		} catch (IOException err) {
1793 			for (ReceiveCommand cmd : toApply) {
1794 				if (cmd.getResult() == Result.NOT_ATTEMPTED)
1795 					cmd.reject(err);
1796 			}
1797 		}
1798 	}
1799 
1800 	/**
1801 	 * Send a status report.
1802 	 *
1803 	 * @param forClient
1804 	 *            true if this report is for a Git client, false if it is for an
1805 	 *            end-user.
1806 	 * @param unpackError
1807 	 *            an error that occurred during unpacking, or {@code null}
1808 	 * @param out
1809 	 *            the reporter for sending the status strings.
1810 	 * @throws java.io.IOException
1811 	 *             an error occurred writing the status report.
1812 	 */
1813 	protected void sendStatusReport(final boolean forClient,
1814 			final Throwable unpackError, final Reporter out) throws IOException {
1815 		if (unpackError != null) {
1816 			out.sendString("unpack error " + unpackError.getMessage()); //$NON-NLS-1$
1817 			if (forClient) {
1818 				for (ReceiveCommand cmd : commands) {
1819 					out.sendString("ng " + cmd.getRefName() //$NON-NLS-1$
1820 							+ " n/a (unpacker error)"); //$NON-NLS-1$
1821 				}
1822 			}
1823 			return;
1824 		}
1825 
1826 		if (forClient)
1827 			out.sendString("unpack ok"); //$NON-NLS-1$
1828 		for (ReceiveCommand cmd : commands) {
1829 			if (cmd.getResult() == Result.OK) {
1830 				if (forClient)
1831 					out.sendString("ok " + cmd.getRefName()); //$NON-NLS-1$
1832 				continue;
1833 			}
1834 
1835 			final StringBuilder r = new StringBuilder();
1836 			if (forClient)
1837 				r.append("ng ").append(cmd.getRefName()).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
1838 			else
1839 				r.append(" ! [rejected] ").append(cmd.getRefName()).append(" ("); //$NON-NLS-1$ //$NON-NLS-2$
1840 
1841 			switch (cmd.getResult()) {
1842 			case NOT_ATTEMPTED:
1843 				r.append("server bug; ref not processed"); //$NON-NLS-1$
1844 				break;
1845 
1846 			case REJECTED_NOCREATE:
1847 				r.append("creation prohibited"); //$NON-NLS-1$
1848 				break;
1849 
1850 			case REJECTED_NODELETE:
1851 				r.append("deletion prohibited"); //$NON-NLS-1$
1852 				break;
1853 
1854 			case REJECTED_NONFASTFORWARD:
1855 				r.append("non-fast forward"); //$NON-NLS-1$
1856 				break;
1857 
1858 			case REJECTED_CURRENT_BRANCH:
1859 				r.append("branch is currently checked out"); //$NON-NLS-1$
1860 				break;
1861 
1862 			case REJECTED_MISSING_OBJECT:
1863 				if (cmd.getMessage() == null)
1864 					r.append("missing object(s)"); //$NON-NLS-1$
1865 				else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH) {
1866 					r.append("object "); //$NON-NLS-1$
1867 					r.append(cmd.getMessage());
1868 					r.append(" missing"); //$NON-NLS-1$
1869 				} else
1870 					r.append(cmd.getMessage());
1871 				break;
1872 
1873 			case REJECTED_OTHER_REASON:
1874 				if (cmd.getMessage() == null)
1875 					r.append("unspecified reason"); //$NON-NLS-1$
1876 				else
1877 					r.append(cmd.getMessage());
1878 				break;
1879 
1880 			case LOCK_FAILURE:
1881 				r.append("failed to lock"); //$NON-NLS-1$
1882 				break;
1883 
1884 			case OK:
1885 				// We shouldn't have reached this case (see 'ok' case above).
1886 				continue;
1887 			}
1888 			if (!forClient)
1889 				r.append(")"); //$NON-NLS-1$
1890 			out.sendString(r.toString());
1891 		}
1892 	}
1893 
1894 	/**
1895 	 * Close and flush (if necessary) the underlying streams.
1896 	 *
1897 	 * @throws java.io.IOException
1898 	 */
1899 	protected void close() throws IOException {
1900 		if (sideBand) {
1901 			// If we are using side band, we need to send a final
1902 			// flush-pkt to tell the remote peer the side band is
1903 			// complete and it should stop decoding. We need to
1904 			// use the original output stream as rawOut is now the
1905 			// side band data channel.
1906 			//
1907 			((SideBandOutputStream) msgOut).flushBuffer();
1908 			((SideBandOutputStream) rawOut).flushBuffer();
1909 
1910 			PacketLineOut plo = new PacketLineOut(origOut);
1911 			plo.setFlushOnEnd(false);
1912 			plo.end();
1913 		}
1914 
1915 		if (biDirectionalPipe) {
1916 			// If this was a native git connection, flush the pipe for
1917 			// the caller. For smart HTTP we don't do this flush and
1918 			// instead let the higher level HTTP servlet code do it.
1919 			//
1920 			if (!sideBand && msgOut != null)
1921 				msgOut.flush();
1922 			rawOut.flush();
1923 		}
1924 	}
1925 
1926 	/**
1927 	 * Release any resources used by this object.
1928 	 *
1929 	 * @throws java.io.IOException
1930 	 *             the pack could not be unlocked.
1931 	 */
1932 	protected void release() throws IOException {
1933 		walk.close();
1934 		unlockPack();
1935 		timeoutIn = null;
1936 		rawIn = null;
1937 		rawOut = null;
1938 		msgOut = null;
1939 		pckIn = null;
1940 		pckOut = null;
1941 		refs = null;
1942 		// Keep the capabilities. If responses are sent after this release
1943 		// we need to remember at least whether sideband communication has to be
1944 		// used
1945 		commands = null;
1946 		if (timer != null) {
1947 			try {
1948 				timer.terminate();
1949 			} finally {
1950 				timer = null;
1951 			}
1952 		}
1953 	}
1954 
1955 	/** Interface for reporting status messages. */
1956 	static abstract class Reporter {
1957 			abstract void sendString(String s) throws IOException;
1958 	}
1959 }