}
private void receivePack(final ProgressMonitor monitor) throws IOException {
+ onReceivePack();
InputStream input = in;
if (sideband)
input = new SideBandInputStream(input, monitor, getMessageWriter());
}
}
+ /**
+ * Notification event delivered just before the pack is received from the
+ * network. This event can be used by RPC such as {@link TransportHttp} to
+ * disable its request magic and ensure the pack stream is read correctly.
+ */
+ protected void onReceivePack() {
+ // By default do nothing for TCP based protocols.
+ }
+
private static class CancelledException extends Exception {
private static final long serialVersionUID = 1L;
}
}
class SmartHttpFetchConnection extends BasePackFetchConnection {
+ private Service svc;
+
SmartHttpFetchConnection(final InputStream advertisement)
throws TransportException {
super(TransportHttp.this);
protected void doFetch(final ProgressMonitor monitor,
final Collection<Ref> want, final Set<ObjectId> have)
throws TransportException {
- final Service svc = new Service(SVC_UPLOAD_PACK);
- init(svc.in, svc.out);
- super.doFetch(monitor, want, have);
+ try {
+ svc = new Service(SVC_UPLOAD_PACK);
+ init(svc.in, svc.out);
+ super.doFetch(monitor, want, have);
+ } finally {
+ svc = null;
+ }
+ }
+
+ @Override
+ protected void onReceivePack() {
+ svc.finalRequest = true;
}
}
private final HttpExecuteStream execute;
+ boolean finalRequest;
+
final UnionInputStream in;
final HttpOutputStream out;
out.close();
if (conn == null) {
- // Output hasn't started yet, because everything fit into
- // our request buffer. Send with a Content-Length header.
- //
if (out.length() == 0) {
+ // Request output hasn't started yet, but more data is being
+ // requested. If there is no request data buffered and the
+ // final request was already sent, do nothing to ensure the
+ // caller is shown EOF on the InputStream; otherwise an
+ // programming error has occurred within this module.
+ if (finalRequest)
+ return;
throw new TransportException(uri,
JGitText.get().startingReadStageWithoutWrittenRequestDataPendingIsNotSupported);
}
}
in.add(openInputStream(conn));
- in.add(execute);
+ if (!finalRequest)
+ in.add(execute);
conn = null;
}