public override void Flush() { if (channel != CH_DATA) { pckOut.Flush(); } }
/// <summary> /// Execute the receive task on the socket. /// </summary> /// <param name="input">Raw input to read client commands and pack data from. Caller must ensure the input is buffered, otherwise read performance may suffer. Response back to the Git network client. 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> public void receive(Stream input, Stream output, Stream messages) { try { rawInput = input; rawOutput = output; pckIn = new PacketLineIn(rawInput); pckOut = new PacketLineOut(rawOutput); // TODO: [henon] port jgit's timeout behavior which is obviously missing here if (messages != null) { msgs = new StreamWriter(messages, Constants.CHARSET); } enabledCapabilities = new List <string>(); commands = new List <ReceiveCommand>(); Service(); } finally { try { if (pckOut != null) { pckOut.Flush(); } if (msgs != null) { 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 { // TODO : [nulltoken] Aren't we missing some Dispose() love, here ? UnlockPack(); rawInput = null; rawOutput = null; pckIn = null; pckOut = null; msgs = null; refs = null; enabledCapabilities = null; commands = null; } } }
private void Negotiate() { string lastName = string.Empty; while (true) { string line = _pckIn.ReadString(); if (line.Length == 0) { if (_commonBase.Count == 0 || _multiAck) { _pckOut.WriteString("NAK\n"); } _pckOut.Flush(); } else if (line.StartsWith("have ") && line.Length == 45) { string name = line.Substring(5); ObjectId id = ObjectId.FromString(name); if (MatchHave(id)) { if (_multiAck) { lastName = name; _pckOut.WriteString("ACK " + name + " continue\n"); } else if (_commonBase.Count == 1) { _pckOut.WriteString("ACK " + name + "\n"); } } else { if (_multiAck && OkToGiveUp()) { _pckOut.WriteString("ACK " + name + " continue\n"); } } } else if (line.Equals("done")) { if (_commonBase.Count == 0) { _pckOut.WriteString("NAK\n"); } else if (_multiAck) { _pckOut.WriteString("ACK " + lastName + "\n"); } break; } else { throw new PackProtocolException("expected have; got " + line); } } }
private void Service(string name, PacketLineOut pckOut) { var cmd = new StringBuilder(); cmd.Append(name); cmd.Append(' '); cmd.Append(Uri.Path); cmd.Append('\0'); cmd.Append("host="); cmd.Append(Uri.Host); if (Uri.Port > 0 && Uri.Port != GIT_PORT) { cmd.Append(":"); cmd.Append(Uri.Port); } cmd.Append('\0'); pckOut.WriteString(cmd.ToString()); pckOut.Flush(); }
private void Service(string name, PacketLineOut pckOut) { var cmd = new StringBuilder(); cmd.Append(name); cmd.Append(' '); cmd.Append(Uri.Path); cmd.Append('\0'); cmd.Append("host="); cmd.Append(Uri.Host); if (Uri.Port > 0 && Uri.Port != GIT_PORT) { cmd.Append(":"); cmd.Append(Uri.Port); } cmd.Append('\0'); pckOut.WriteString(cmd.ToString()); pckOut.Flush(); }
private bool Negotiate() { ObjectId last = ObjectId.ZeroId; while (true) { string line = _pckIn.ReadString(); if (line == PacketLineIn.END) { if (_commonBase.Count == 0 || _multiAck != BasePackFetchConnection.MultiAck.OFF) { _pckOut.WriteString("NAK\n"); } _pckOut.Flush(); if (!biDirectionalPipe) { return(false); } } else if (line.StartsWith("have ") && line.Length == 45) { ObjectId id = ObjectId.FromString(line.Substring(5)); if (MatchHave(id)) { // Both sides have the same object; let the client know. // last = id; switch (_multiAck) { case BasePackFetchConnection.MultiAck.OFF: if (_commonBase.Count == 1) { _pckOut.WriteString("ACK " + id.Name + "\n"); } break; case BasePackFetchConnection.MultiAck.CONTINUE: _pckOut.WriteString("ACK " + id.Name + " continue\n"); break; case BasePackFetchConnection.MultiAck.DETAILED: _pckOut.WriteString("ACK " + id.Name + " common\n"); break; } } else if (OkToGiveUp()) { // They have this object; we don't. // switch (_multiAck) { case BasePackFetchConnection.MultiAck.OFF: break; case BasePackFetchConnection.MultiAck.CONTINUE: _pckOut.WriteString("ACK " + id.Name + " continue\n"); break; case BasePackFetchConnection.MultiAck.DETAILED: _pckOut.WriteString("ACK " + id.Name + " ready\n"); break; } } } else if (line.Equals("done")) { if (_commonBase.Count == 0) { _pckOut.WriteString("NAK\n"); } else if (_multiAck != BasePackFetchConnection.MultiAck.OFF) { _pckOut.WriteString("ACK " + last.Name + "\n"); } return(true); } else { throw new PackProtocolException("expected have; got " + line); } } }