ReceivePack: Enable side-band-64k capability for status reports
We now advertise the side-band-64k capability inside of ReceivePack, allowing hooks to echo status messages down the side band channel instead of over the optional stderr stream. This change permits hooks running inside of an http:// based push invocation to still message the end-user with more detailed errors than the small per-command string in the status report. Change-Id: I64f251ef2d13ab3fd0e1a319a4683725455e5244 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
4c44810df4
commit
d33f939e8e
|
@ -86,6 +86,8 @@ class BasePackPushConnection extends BasePackConnection implements
|
||||||
|
|
||||||
static final String CAPABILITY_OFS_DELTA = "ofs-delta";
|
static final String CAPABILITY_OFS_DELTA = "ofs-delta";
|
||||||
|
|
||||||
|
static final String CAPABILITY_SIDE_BAND_64K = "side-band-64k";
|
||||||
|
|
||||||
private final boolean thinPack;
|
private final boolean thinPack;
|
||||||
|
|
||||||
private boolean capableDeleteRefs;
|
private boolean capableDeleteRefs;
|
||||||
|
|
|
@ -43,13 +43,20 @@
|
||||||
|
|
||||||
package org.eclipse.jgit.transport;
|
package org.eclipse.jgit.transport;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_DELETE_REFS;
|
||||||
|
import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_OFS_DELTA;
|
||||||
|
import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
|
||||||
|
import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
|
||||||
|
import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
|
||||||
|
import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
|
||||||
|
import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintWriter;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -84,12 +91,6 @@
|
||||||
* Implements the server side of a push connection, receiving objects.
|
* Implements the server side of a push connection, receiving objects.
|
||||||
*/
|
*/
|
||||||
public class ReceivePack {
|
public class ReceivePack {
|
||||||
static final String CAPABILITY_REPORT_STATUS = BasePackPushConnection.CAPABILITY_REPORT_STATUS;
|
|
||||||
|
|
||||||
static final String CAPABILITY_DELETE_REFS = BasePackPushConnection.CAPABILITY_DELETE_REFS;
|
|
||||||
|
|
||||||
static final String CAPABILITY_OFS_DELTA = BasePackPushConnection.CAPABILITY_OFS_DELTA;
|
|
||||||
|
|
||||||
/** Database we write the stored objects into. */
|
/** Database we write the stored objects into. */
|
||||||
private final Repository db;
|
private final Repository db;
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ public class ReceivePack {
|
||||||
|
|
||||||
private PacketLineOut pckOut;
|
private PacketLineOut pckOut;
|
||||||
|
|
||||||
private PrintWriter msgs;
|
private Writer msgs;
|
||||||
|
|
||||||
/** The refs we advertised as existing at the start of the connection. */
|
/** The refs we advertised as existing at the start of the connection. */
|
||||||
private Map<String, Ref> refs;
|
private Map<String, Ref> refs;
|
||||||
|
@ -165,9 +166,12 @@ public class ReceivePack {
|
||||||
/** An exception caught while unpacking and fsck'ing the objects. */
|
/** An exception caught while unpacking and fsck'ing the objects. */
|
||||||
private Throwable unpackError;
|
private Throwable unpackError;
|
||||||
|
|
||||||
/** if {@link #enabledCapablities} has {@link #CAPABILITY_REPORT_STATUS} */
|
/** If {@link BasePackPushConnection#CAPABILITY_REPORT_STATUS} is enabled. */
|
||||||
private boolean reportStatus;
|
private boolean reportStatus;
|
||||||
|
|
||||||
|
/** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
|
||||||
|
private boolean sideBand;
|
||||||
|
|
||||||
/** Lock around the received pack file, while updating refs. */
|
/** Lock around the received pack file, while updating refs. */
|
||||||
private PackLock packLock;
|
private PackLock packLock;
|
||||||
|
|
||||||
|
@ -440,7 +444,12 @@ public List<ReceiveCommand> getAllCommands() {
|
||||||
* string must not end with an LF, and must not contain an LF.
|
* string must not end with an LF, and must not contain an LF.
|
||||||
*/
|
*/
|
||||||
public void sendError(final String what) {
|
public void sendError(final String what) {
|
||||||
sendMessage("error", what);
|
try {
|
||||||
|
if (msgs != null)
|
||||||
|
msgs.write("error: " + what + "\n");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore write failures.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -454,12 +463,12 @@ public void sendError(final String what) {
|
||||||
* string must not end with an LF, and must not contain an LF.
|
* string must not end with an LF, and must not contain an LF.
|
||||||
*/
|
*/
|
||||||
public void sendMessage(final String what) {
|
public void sendMessage(final String what) {
|
||||||
sendMessage("remote", what);
|
try {
|
||||||
}
|
|
||||||
|
|
||||||
private void sendMessage(final String type, final String what) {
|
|
||||||
if (msgs != null)
|
if (msgs != null)
|
||||||
msgs.println(type + ": " + what);
|
msgs.write(what + "\n");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore write failures.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -499,16 +508,8 @@ public void receive(final InputStream input, final OutputStream output,
|
||||||
|
|
||||||
pckIn = new PacketLineIn(rawIn);
|
pckIn = new PacketLineIn(rawIn);
|
||||||
pckOut = new PacketLineOut(rawOut);
|
pckOut = new PacketLineOut(rawOut);
|
||||||
if (messages != null) {
|
if (messages != null)
|
||||||
msgs = new PrintWriter(new BufferedWriter(
|
msgs = new OutputStreamWriter(messages, Constants.CHARSET);
|
||||||
new OutputStreamWriter(messages, Constants.CHARSET),
|
|
||||||
8192)) {
|
|
||||||
@Override
|
|
||||||
public void println() {
|
|
||||||
print('\n');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledCapablities = new HashSet<String>();
|
enabledCapablities = new HashSet<String>();
|
||||||
commands = new ArrayList<ReceiveCommand>();
|
commands = new ArrayList<ReceiveCommand>();
|
||||||
|
@ -516,8 +517,19 @@ public void println() {
|
||||||
service();
|
service();
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (msgs != null) {
|
if (pckOut != null)
|
||||||
|
pckOut.flush();
|
||||||
|
if (msgs != null)
|
||||||
msgs.flush();
|
msgs.flush();
|
||||||
|
|
||||||
|
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.
|
||||||
|
//
|
||||||
|
new PacketLineOut(output).end();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
unlockPack();
|
unlockPack();
|
||||||
|
@ -581,10 +593,9 @@ void sendString(final String s) throws IOException {
|
||||||
} else if (msgs != null) {
|
} else if (msgs != null) {
|
||||||
sendStatusReport(false, new Reporter() {
|
sendStatusReport(false, new Reporter() {
|
||||||
void sendString(final String s) throws IOException {
|
void sendString(final String s) throws IOException {
|
||||||
msgs.println(s);
|
msgs.write(s + "\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
msgs.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
postReceive.onPostReceive(this, filterCommands(Result.OK));
|
postReceive.onPostReceive(this, filterCommands(Result.OK));
|
||||||
|
@ -609,6 +620,7 @@ private void unlockPack() {
|
||||||
public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException {
|
public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException {
|
||||||
final RevFlag advertised = walk.newFlag("ADVERTISED");
|
final RevFlag advertised = walk.newFlag("ADVERTISED");
|
||||||
adv.init(walk, advertised);
|
adv.init(walk, advertised);
|
||||||
|
adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
|
||||||
adv.advertiseCapability(CAPABILITY_DELETE_REFS);
|
adv.advertiseCapability(CAPABILITY_DELETE_REFS);
|
||||||
adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
|
adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
|
||||||
if (allowOfsDelta)
|
if (allowOfsDelta)
|
||||||
|
@ -667,6 +679,16 @@ private void recvCommands() throws IOException {
|
||||||
|
|
||||||
private void enableCapabilities() {
|
private void enableCapabilities() {
|
||||||
reportStatus = enabledCapablities.contains(CAPABILITY_REPORT_STATUS);
|
reportStatus = enabledCapablities.contains(CAPABILITY_REPORT_STATUS);
|
||||||
|
|
||||||
|
sideBand = enabledCapablities.contains(CAPABILITY_SIDE_BAND_64K);
|
||||||
|
if (sideBand) {
|
||||||
|
OutputStream out = rawOut;
|
||||||
|
|
||||||
|
rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
|
||||||
|
pckOut = new PacketLineOut(rawOut);
|
||||||
|
msgs = new OutputStreamWriter(new SideBandOutputStream(CH_PROGRESS,
|
||||||
|
MAX_BUF, out), Constants.CHARSET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needPack() {
|
private boolean needPack() {
|
||||||
|
|
Loading…
Reference in New Issue