/// <summary>Tell the peer we are disconnecting, if it cares to know.</summary> /// <remarks>Tell the peer we are disconnecting, if it cares to know.</remarks> protected internal virtual void EndOut() { if (outNeedsEnd && @out != null) { try { outNeedsEnd = false; pckOut.End(); } catch (IOException) { try { @out.Close(); } catch (IOException) { } finally { // Ignore any close errors. @out = null; pckOut = null; } } } }
/// <exception cref="System.IO.IOException"></exception> public override void Write(byte[] b, int off, int len) { while (0 < len) { int capacity = buffer.Length - cnt; if (cnt == HDR_SIZE && capacity < len) { // Our block to write is bigger than the packet size, // stream it out as-is to avoid unnecessary copies. PacketLineOut.FormatLength(buffer, buffer.Length); @out.Write(buffer, 0, HDR_SIZE); @out.Write(b, off, capacity); off += capacity; len -= capacity; } else { if (capacity == 0) { WriteBuffer(); } int n = Math.Min(len, capacity); System.Array.Copy(b, off, buffer, cnt, n); cnt += n; off += n; len -= n; } } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Transport.Resolver.ServiceNotEnabledException"></exception> /// <exception cref="NGit.Transport.Resolver.ServiceNotAuthorizedException"></exception> internal virtual void Execute(DaemonClient client, string commandLine) { string name = Sharpen.Runtime.Substring(commandLine, command.Length + 1); Repository db; try { db = client.GetDaemon().OpenRepository(client, name); } catch (ServiceMayNotContinueException e) { // An error when opening the repo means the client is expecting a ref // advertisement, so use that style of error. PacketLineOut pktOut = new PacketLineOut(client.GetOutputStream()); pktOut.WriteString("ERR " + e.Message + "\n"); db = null; } if (db == null) { return; } try { if (IsEnabledFor(db)) { Execute(client, db); } } finally { db.Close(); } }
public virtual void TestUsingHiddenDeltaBaseFails() { byte[] delta = new byte[] { unchecked ((int)(0x1)), unchecked ((int)(0x1)), unchecked ( (int)(0x1)), (byte)('c') }; TestRepository <Repository> s = new TestRepository <Repository>(src); RevCommit N = s.Commit().Parent(B).Add("q", s.Blob(BinaryDelta.Apply(dst.Open(b). GetCachedBytes(), delta))).Create(); TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); PackHeader(pack, 3); Copy(pack, src.Open(N)); Copy(pack, src.Open(s.ParseBody(N).Tree)); pack.Write((Constants.OBJ_REF_DELTA) << 4 | 4); b.CopyRawTo(pack); Deflate(pack, delta); Digest(pack); TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.WriteString(ObjectId.ZeroId.Name + ' ' + N.Name + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.End(); pack.WriteTo(inBuf, PM); TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); ReceivePack rp = new ReceivePack(dst); rp.SetCheckReceivedObjects(true); rp.SetCheckReferencedObjectsAreReachable(true); rp.SetAdvertiseRefsHook(new ReceivePackAdvertiseRefsHookTest.HidePrivateHook()); try { Receive(rp, inBuf, outBuf); NUnit.Framework.Assert.Fail("Expected UnpackException"); } catch (UnpackException failed) { Exception err = failed.InnerException; NUnit.Framework.Assert.IsTrue(err is MissingObjectException); MissingObjectException moe = (MissingObjectException)err; NUnit.Framework.Assert.AreEqual(b, moe.GetObjectId()); } PacketLineIn r = AsPacketLineIn(outBuf); string master = r.ReadString(); int nul = master.IndexOf('\0'); NUnit.Framework.Assert.IsTrue(nul > 0, "has capability list"); NUnit.Framework.Assert.AreEqual(B.Name + ' ' + R_MASTER, Sharpen.Runtime.Substring (master, 0, nul)); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); NUnit.Framework.Assert.AreEqual("unpack error Missing blob " + b.Name, r.ReadString ()); NUnit.Framework.Assert.AreEqual("ng refs/heads/s n/a (unpacker error)", r.ReadString ()); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); }
public virtual void TestUsingUnknownBlobFails() { // Try to use the 'n' blob that is not on the server. // TestRepository <Repository> s = new TestRepository <Repository>(src); RevBlob n = s.Blob("n"); RevCommit N = s.Commit().Parent(B).Add("q", n).Create(); // But don't include it in the pack. // TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); PackHeader(pack, 2); Copy(pack, src.Open(N)); Copy(pack, src.Open(s.ParseBody(N).Tree)); Digest(pack); TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.WriteString(ObjectId.ZeroId.Name + ' ' + N.Name + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.End(); pack.WriteTo(inBuf, PM); TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); ReceivePack rp = new ReceivePack(dst); rp.SetCheckReceivedObjects(true); rp.SetCheckReferencedObjectsAreReachable(true); rp.SetAdvertiseRefsHook(new ReceivePackAdvertiseRefsHookTest.HidePrivateHook()); try { Receive(rp, inBuf, outBuf); NUnit.Framework.Assert.Fail("Expected UnpackException"); } catch (UnpackException failed) { Exception err = failed.InnerException; NUnit.Framework.Assert.IsTrue(err is MissingObjectException); MissingObjectException moe = (MissingObjectException)err; NUnit.Framework.Assert.AreEqual(n, moe.GetObjectId()); } PacketLineIn r = AsPacketLineIn(outBuf); string master = r.ReadString(); int nul = master.IndexOf('\0'); NUnit.Framework.Assert.IsTrue(nul > 0, "has capability list"); NUnit.Framework.Assert.AreEqual(B.Name + ' ' + R_MASTER, Sharpen.Runtime.Substring (master, 0, nul)); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); NUnit.Framework.Assert.AreEqual("unpack error Missing blob " + n.Name, r.ReadString ()); NUnit.Framework.Assert.AreEqual("ng refs/heads/s n/a (unpacker error)", r.ReadString ()); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); }
public override void Close() { if (@out != null) { try { if (outNeedsEnd) { outNeedsEnd = false; pckOut.End(); } @out.Close(); } catch (IOException) { } finally { // Ignore any close errors. @out = null; pckOut = null; } } if (@in != null) { try { @in.Close(); } catch (IOException) { } finally { // Ignore any close errors. @in = null; pckIn = null; } } if (myTimer != null) { try { myTimer.Terminate(); } finally { myTimer = null; timeoutIn = null; timeoutOut = null; } } }
public virtual void TestCreateBranchAtHiddenCommitFails() { TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64); PackHeader(pack, 0); Digest(pack); TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256); PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.WriteString(ObjectId.ZeroId.Name + ' ' + P.Name + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.End(); pack.WriteTo(inBuf, PM); TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); ReceivePack rp = new ReceivePack(dst); rp.SetCheckReceivedObjects(true); rp.SetCheckReferencedObjectsAreReachable(true); rp.SetAdvertiseRefsHook(new ReceivePackAdvertiseRefsHookTest.HidePrivateHook()); try { Receive(rp, inBuf, outBuf); NUnit.Framework.Assert.Fail("Expected UnpackException"); } catch (UnpackException failed) { Exception err = failed.InnerException; NUnit.Framework.Assert.IsTrue(err is MissingObjectException); MissingObjectException moe = (MissingObjectException)err; NUnit.Framework.Assert.AreEqual(P, moe.GetObjectId()); } PacketLineIn r = AsPacketLineIn(outBuf); string master = r.ReadString(); int nul = master.IndexOf('\0'); NUnit.Framework.Assert.IsTrue(nul > 0, "has capability list"); NUnit.Framework.Assert.AreEqual(B.Name + ' ' + R_MASTER, Sharpen.Runtime.Substring (master, 0, nul)); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); NUnit.Framework.Assert.AreEqual("unpack error Missing commit " + P.Name, r.ReadString ()); NUnit.Framework.Assert.AreEqual("ng refs/heads/s n/a (unpacker error)", r.ReadString ()); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); }
/// <exception cref="System.IO.IOException"></exception> internal virtual void Service(string name, PacketLineOut pckOut) { StringBuilder cmd = new StringBuilder(); cmd.Append(name); cmd.Append(' '); cmd.Append(uri.GetPath()); cmd.Append('\0'); cmd.Append("host="); cmd.Append(uri.GetHost()); if (uri.GetPort() > 0 && uri.GetPort() != GIT_PORT) { cmd.Append(":"); cmd.Append(uri.GetPort()); } cmd.Append('\0'); pckOut.WriteString(cmd.ToString()); pckOut.Flush(); }
// If we cannot read the value of the ref skip it. /// <exception cref="System.IO.IOException"></exception> private bool SendWants(ICollection <Ref> want) { PacketLineOut p = statelessRPC ? pckState : pckOut; bool first = true; foreach (Ref r in want) { try { if (walk.ParseAny(r.GetObjectId()).Has(REACHABLE)) { // We already have this object. Asking for it is // not a very good idea. // continue; } } catch (IOException) { } // Its OK, we don't have it, but we want to fix that // by fetching the object from the other side. StringBuilder line = new StringBuilder(46); line.Append("want "); line.Append(r.GetObjectId().Name); if (first) { line.Append(EnableCapabilities()); first = false; } line.Append('\n'); p.WriteString(line.ToString()); } if (first) { return(false); } p.End(); outNeedsEnd = false; return(true); }
/// <summary>Configure this connection with the directional pipes.</summary> /// <remarks>Configure this connection with the directional pipes.</remarks> /// <param name="myIn"> /// input stream to receive data from the peer. Caller must ensure /// the input is buffered, otherwise read performance may suffer. /// </param> /// <param name="myOut"> /// output stream to transmit data to the peer. Caller must ensure /// the output is buffered, otherwise write performance may /// suffer. /// </param> protected internal void Init(InputStream myIn, OutputStream myOut) { int timeout = transport.GetTimeout(); if (timeout > 0) { Sharpen.Thread caller = Sharpen.Thread.CurrentThread(); myTimer = new InterruptTimer(caller.GetName() + "-Timer"); timeoutIn = new TimeoutInputStream(myIn, myTimer); timeoutOut = new TimeoutOutputStream(myOut, myTimer); timeoutIn.SetTimeout(timeout * 1000); timeoutOut.SetTimeout(timeout * 1000); myIn = timeoutIn; myOut = timeoutOut; } @in = myIn; @out = myOut; pckIn = new PacketLineIn(@in); pckOut = new PacketLineOut(@out); outNeedsEnd = true; }
/// <summary>Execute common ancestor negotiation and fetch the objects.</summary> /// <remarks>Execute common ancestor negotiation and fetch the objects.</remarks> /// <param name="monitor">progress monitor to receive status updates.</param> /// <param name="want">the advertised remote references the caller wants to fetch.</param> /// <param name="have"> /// additional objects to assume that already exist locally. This /// will be added to the set of objects reachable from the /// destination repository's references. /// </param> /// <exception cref="NGit.Errors.TransportException">if any exception occurs.</exception> protected internal virtual void DoFetch(ProgressMonitor monitor, ICollection <Ref> want, ICollection <ObjectId> have) { try { MarkRefsAdvertised(); MarkReachable(have, MaxTimeWanted(want)); if (statelessRPC) { state = new TemporaryBuffer.Heap(int.MaxValue); pckState = new PacketLineOut(state); } if (SendWants(want)) { Negotiate(monitor); walk.Dispose(); reachableCommits = null; state = null; pckState = null; ReceivePack(monitor); } } catch (BasePackFetchConnection.CancelledException) { Close(); return; } catch (IOException err) { // Caller should test (or just know) this themselves. Close(); throw new TransportException(err.Message, err); } catch (RuntimeException err) { Close(); throw new TransportException(err.Message, err); } }
/// <summary>Execute the upload task on the socket.</summary> /// <remarks>Execute the upload task on the socket.</remarks> /// <param name="input"> /// raw input to read client commands from. Caller must ensure the /// input is buffered, otherwise read performance may suffer. /// </param> /// <param name="output"> /// response back to the Git network client, to write the pack /// data onto. Caller must ensure the output is buffered, /// otherwise write performance may suffer. /// </param> /// <param name="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. /// </param> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void Upload(InputStream input, OutputStream output, OutputStream messages ) { try { rawIn = input; rawOut = output; if (timeout > 0) { Sharpen.Thread caller = Sharpen.Thread.CurrentThread(); timer = new InterruptTimer(caller.GetName() + "-Timer"); TimeoutInputStream i = new TimeoutInputStream(rawIn, timer); TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer); i.SetTimeout(timeout * 1000); o.SetTimeout(timeout * 1000); rawIn = i; rawOut = o; } pckIn = new PacketLineIn(rawIn); pckOut = new PacketLineOut(rawOut); Service(); } finally { walk.Release(); if (timer != null) { try { timer.Terminate(); } finally { timer = null; } } } }
/// <summary>Create a new advertiser for the supplied stream.</summary> /// <remarks>Create a new advertiser for the supplied stream.</remarks> /// <param name="out">the output stream.</param> public PacketLineOutRefAdvertiser(PacketLineOut @out) { pckOut = @out; }
/// <exception cref="System.IO.IOException"></exception> private void WriteBuffer() { PacketLineOut.FormatLength(buffer, cnt); @out.Write(buffer, 0, cnt); cnt = HDR_SIZE; }
public virtual void SetUp() { rawOut = new ByteArrayOutputStream(); @out = new PacketLineOut(rawOut); }
public virtual void TestUsingUnknownTreeFails() { TestRepository<Repository> s = new TestRepository<Repository>(src); RevCommit N = s.Commit().Parent(B).Add("q", s.Blob("a")).Create(); RevTree t = s.ParseBody(N).Tree; // Don't include the tree in the pack. // TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); PackHeader(pack, 1); Copy(pack, src.Open(N)); Digest(pack); TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.WriteString(ObjectId.ZeroId.Name + ' ' + N.Name + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.End(); pack.WriteTo(inBuf, PM); TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); ReceivePack rp = new ReceivePack(dst); rp.SetCheckReceivedObjects(true); rp.SetCheckReferencedObjectsAreReachable(true); rp.SetAdvertiseRefsHook(new ReceivePackAdvertiseRefsHookTest.HidePrivateHook()); try { Receive(rp, inBuf, outBuf); NUnit.Framework.Assert.Fail("Expected UnpackException"); } catch (UnpackException failed) { Exception err = failed.InnerException; NUnit.Framework.Assert.IsTrue(err is MissingObjectException); MissingObjectException moe = (MissingObjectException)err; NUnit.Framework.Assert.AreEqual(t, moe.GetObjectId()); } PacketLineIn r = AsPacketLineIn(outBuf); string master = r.ReadString(); int nul = master.IndexOf('\0'); NUnit.Framework.Assert.IsTrue(nul > 0, "has capability list"); NUnit.Framework.Assert.AreEqual(B.Name + ' ' + R_MASTER, Sharpen.Runtime.Substring (master, 0, nul)); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); NUnit.Framework.Assert.AreEqual("unpack error Missing tree " + t.Name, r.ReadString ()); NUnit.Framework.Assert.AreEqual("ng refs/heads/s n/a (unpacker error)", r.ReadString ()); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); }
public virtual void TestUsingHiddenDeltaBaseFails() { byte[] delta = new byte[] { unchecked((int)(0x1)), unchecked((int)(0x1)), unchecked( (int)(0x1)), (byte)('c') }; TestRepository<Repository> s = new TestRepository<Repository>(src); RevCommit N = s.Commit().Parent(B).Add("q", s.Blob(BinaryDelta.Apply(dst.Open(b). GetCachedBytes(), delta))).Create(); TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); PackHeader(pack, 3); Copy(pack, src.Open(N)); Copy(pack, src.Open(s.ParseBody(N).Tree)); pack.Write((Constants.OBJ_REF_DELTA) << 4 | 4); b.CopyRawTo(pack); Deflate(pack, delta); Digest(pack); TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.WriteString(ObjectId.ZeroId.Name + ' ' + N.Name + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.End(); pack.WriteTo(inBuf, PM); TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); ReceivePack rp = new ReceivePack(dst); rp.SetCheckReceivedObjects(true); rp.SetCheckReferencedObjectsAreReachable(true); rp.SetAdvertiseRefsHook(new ReceivePackAdvertiseRefsHookTest.HidePrivateHook()); try { Receive(rp, inBuf, outBuf); NUnit.Framework.Assert.Fail("Expected UnpackException"); } catch (UnpackException failed) { Exception err = failed.InnerException; NUnit.Framework.Assert.IsTrue(err is MissingObjectException); MissingObjectException moe = (MissingObjectException)err; NUnit.Framework.Assert.AreEqual(b, moe.GetObjectId()); } PacketLineIn r = AsPacketLineIn(outBuf); string master = r.ReadString(); int nul = master.IndexOf('\0'); NUnit.Framework.Assert.IsTrue(nul > 0, "has capability list"); NUnit.Framework.Assert.AreEqual(B.Name + ' ' + R_MASTER, Sharpen.Runtime.Substring (master, 0, nul)); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); NUnit.Framework.Assert.AreEqual("unpack error Missing blob " + b.Name, r.ReadString ()); NUnit.Framework.Assert.AreEqual("ng refs/heads/s n/a (unpacker error)", r.ReadString ()); NUnit.Framework.Assert.AreSame(PacketLineIn.END, r.ReadString()); }