internal SftpContextStream(SftpSession session, string path, FileMode mode, FileAccess access, SftpFileAttributes attributes) { Flags flags = Flags.None; switch (access) { case FileAccess.Read: flags = Flags.Read; break; case FileAccess.Write: flags = Flags.Write; break; case FileAccess.ReadWrite: flags = Flags.Read | Flags.Write; break; } switch (mode) { case FileMode.Append: flags |= Flags.Append; break; case FileMode.Create: if (attributes == null) { flags |= Flags.CreateNew; } else { flags |= Flags.Truncate; } break; case FileMode.CreateNew: flags |= Flags.CreateNew; break; case FileMode.Open: break; case FileMode.OpenOrCreate: flags |= Flags.CreateNewOrOpen; break; case FileMode.Truncate: flags |= Flags.Truncate; break; } _session = session; _handle = _session.RequestOpen(path, flags); _attributes = attributes ?? _session.RequestFStat(_handle); if (access.HasFlag(FileAccess.Write)) { _writeBuffer = new byte[WRITE_BUFFER_SIZE]; _writeMode = true; } _position = mode != FileMode.Append ? 0 : _attributes.Size; }
protected void Arrange() { var random = new Random(); _operationTimeout = TimeSpan.FromMilliseconds(random.Next(100, 500)); _encoding = Encoding.UTF8; _bAvail = (ulong) random.Next(0, int.MaxValue); _sessionMock = new Mock<ISession>(MockBehavior.Strict); _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict); var sequence = new MockSequence(); _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object); _channelSessionMock.InSequence(sequence).Setup(p => p.Open()); _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { // generate response for SftpInitRequest var versionInfoResponse = SftpVersionResponseBuilder.Create(3) .AddExtension("*****@*****.**", "") .Build(); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, versionInfoResponse)); }); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC"); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, sftpNameResponse)); } ); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { var statVfsReplyBuilder = StatVfsReplyBuilder.Create(2); statVfsReplyBuilder.WithBAvail(_bAvail); var statVfsReply = statVfsReplyBuilder.Build(); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, statVfsReply)); } ); _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding); _sftpSession.Connect(); }
/// <summary> /// Initializes a new instance of the <see cref="SftpFile"/> class. /// </summary> /// <param name="sftpSession">The SFTP session.</param> /// <param name="fullName">Full path of the directory or file.</param> /// <param name="attributes">Attributes of the directory or file.</param> internal SftpFile(SftpSession sftpSession, string fullName, SftpFileAttributes attributes) { if (attributes == null) throw new ArgumentNullException("attributes"); if (fullName == null) throw new ArgumentNullException("fullName"); this._sftpSession = sftpSession; this.Attributes = attributes; this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1); this.FullName = fullName; }
/// <summary> /// Initializes a new instance of the <see cref="SftpFile"/> class. /// </summary> /// <param name="sftpSession">The SFTP session.</param> /// <param name="fullName">Full path of the directory or file.</param> /// <param name="attributes">Attributes of the directory or file.</param> /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception> internal SftpFile(SftpSession sftpSession, string fullName, SftpFileAttributes attributes) { if (attributes == null) { throw new ArgumentNullException("attributes"); } if (fullName == null) { throw new ArgumentNullException("fullName"); } this._sftpSession = sftpSession; this.Attributes = attributes; this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1); this.FullName = fullName; }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize) : this(session, path, mode, access, bufferSize, false) { // Nothing to do here. }
internal SftpFileStream(SftpSession session, byte[] handle, FileAccess access, bool ownsHandle, int bufferSize) : this(session, handle, access, ownsHandle, bufferSize, false) { // Nothing to do here. }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync) { // Validate the parameters. if (session == null) throw new SshConnectionException("Client not connected."); if (path == null) { throw new ArgumentNullException("path"); } if (bufferSize <= 0 || bufferSize > 16 * 1024) { throw new ArgumentOutOfRangeException("bufferSize"); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } if (mode < FileMode.CreateNew || mode > FileMode.Append) { throw new ArgumentOutOfRangeException("mode"); } this.Timeout = TimeSpan.FromSeconds(30); this.Name = path; // Initialize the object state. this._session = session; this._access = access; this._ownsHandle = true; this._isAsync = useAsync; this._path = path; this._bufferSize = bufferSize; this._buffer = new byte[bufferSize]; this._bufferPosn = 0; this._bufferLen = 0; this._bufferOwnedByWrite = false; this._canSeek = true; this._position = 0; this._serverFilePosition = 0; this._session.Disconnected += Session_Disconnected; var flags = Flags.None; switch (access) { case FileAccess.Read: flags |= Flags.Read; break; case FileAccess.Write: flags |= Flags.Write; break; case FileAccess.ReadWrite: flags |= Flags.Read; flags |= Flags.Write; break; default: break; } switch (mode) { case FileMode.Append: flags |= Flags.Append; break; case FileMode.Create: this._handle = this._session.RequestOpen(path, flags | Flags.Truncate, true); if (this._handle == null) { flags |= Flags.CreateNew; } else { flags |= Flags.Truncate; } break; case FileMode.CreateNew: flags |= Flags.CreateNew; break; case FileMode.Open: break; case FileMode.OpenOrCreate: flags |= Flags.CreateNewOrOpen; break; case FileMode.Truncate: flags |= Flags.Truncate; break; default: break; } if (this._handle == null) this._handle = this._session.RequestOpen(this._path, flags); this._attributes = this._session.RequestFStat(this._handle); if (mode == FileMode.Append) { this._position = this._attributes.Size; this._serverFilePosition = (ulong)this._attributes.Size; } }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access) : this(session, path, mode, access, 4096, false) { // Nothing to do here. }
/// <summary> /// Called when client is connected to the server. /// </summary> protected override void OnConnected() { base.OnConnected(); this._sftpSession = new SftpSession(this.Session, this.OperationTimeout); this._sftpSession.Connect(); // Resolve current running version this.ProtocolVersion = this._sftpSession.ProtocolVersion; }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access) : this(session, path, mode, access, 4096) { }
/// <summary> /// Initializes a new <see cref="SftpFileStream"/> instance with a read and write buffer /// of 4 KB. /// </summary> internal SftpFileStream(SftpSession session, string path, FileMode mode) : this(session, path, mode, FileAccess.ReadWrite) { }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync) : this(session, path, mode, access, bufferSize, useAsync, null) { // Nothing to do here. }
protected void Arrange() { var random = new Random(); _operationTimeout = TimeSpan.FromMilliseconds(random.Next(100, 500)); _expected = new byte[random.Next(30, 50)]; _encoding = Encoding.UTF8; random.NextBytes(_expected); _sessionMock = new Mock<ISession>(MockBehavior.Strict); _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict); var sequence = new MockSequence(); _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object); _channelSessionMock.InSequence(sequence).Setup(p => p.Open()); _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { // generate response for SftpInitRequest var versionInfoResponse = SftpVersionResponseBuilder.Create(3) .Build(); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, versionInfoResponse)); }); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC"); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, sftpNameResponse)); } ); _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback( () => { var sftpDataResponse = CreateSftpDataResponse(2, _expected); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, sftpDataResponse.Take(0, 20))); _channelSessionMock.Raise( c => c.DataReceived += null, new ChannelDataEventArgs(0, sftpDataResponse.Take(20, sftpDataResponse.Length - 20))); } ); _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding); _sftpSession.Connect(); }
internal SftpFileStream(SftpSession session, byte[] handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync) { // TODO: See if it make sense to have "handle" constructors // Validate the parameters. if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize"); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } // Initialize the object state. this._handle = handle; this._access = access; this._ownsHandle = ownsHandle; this._isAsync = isAsync; this._bufferSize = bufferSize; this._buffer = new byte[bufferSize]; this._bufferPosn = 0; this._bufferLen = 0; this._bufferOwnedByWrite = false; this._canSeek = true; this._position = 0; // Assumption is that no other object uses the same file handle this._attributes = this._session.RequestFStat(this._handle); //if (mode == FileMode.Append) //{ // // TODO: Validate Size property value exists // this._position = (long)this._attributes.Size.Value; //} }
internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync) { // Validate the parameters. if (path == null) { throw new ArgumentNullException("path"); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize"); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } if (mode < FileMode.CreateNew || mode > FileMode.Append) { throw new ArgumentOutOfRangeException("mode"); } this.Timeout = TimeSpan.FromSeconds(30); this.Name = path; // Initialize the object state. this._session = session; this._access = access; this._ownsHandle = true; this._isAsync = useAsync; this._path = path; this._bufferSize = bufferSize; this._buffer = new byte[bufferSize]; this._bufferPosn = 0; this._bufferLen = 0; this._bufferOwnedByWrite = false; this._canSeek = true; this._position = 0; var flags = Flags.None; switch (access) { case FileAccess.Read: flags |= Flags.Read; break; case FileAccess.Write: flags |= Flags.Write; break; case FileAccess.ReadWrite: flags |= Flags.Read; flags |= Flags.Write; break; default: break; } switch (mode) { case FileMode.Append: flags |= Flags.Append; break; case FileMode.Create: this._handle = this._session.RequestOpen(path, flags | Flags.Truncate, true); if (this._handle == null) { flags |= Flags.CreateNew; } else { flags |= Flags.Truncate; } break; case FileMode.CreateNew: flags |= Flags.CreateNew; break; case FileMode.Open: break; case FileMode.OpenOrCreate: flags |= Flags.CreateNewOrOpen; break; case FileMode.Truncate: flags |= Flags.Truncate; break; default: break; } if (this._handle == null) { this._handle = this._session.RequestOpen(this._path, flags); } this._attributes = this._session.RequestFStat(this._handle); if (mode == FileMode.Append) { this._position = this._attributes.Size; } }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param> protected override void Dispose(bool disposing) { if (this._sftpSession != null) { this._sftpSession.Dispose(); this._sftpSession = null; } base.Dispose(disposing); }
/// <summary> /// Called when client is connected to the server. /// </summary> protected override void OnConnected() { base.OnConnected(); this._sftpSession = new SftpSession(this.Session, this.OperationTimeout, this.ConnectionInfo.Encoding); this._sftpSession.Connect(); }
/// <summary> /// Called when client is disconnecting from the server. /// </summary> protected override void OnDisconnecting() { base.OnDisconnecting(); // disconnect and dispose the SFTP session // the dispose is necessary since we create a new SFTP session // on each connect if (_sftpSession != null) { this._sftpSession.Disconnect(); this._sftpSession.Dispose(); this._sftpSession = null; } }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param> protected override void Dispose(bool disposing) { if (this._sftpSession != null) { this._sftpSession.Dispose(); this._sftpSession = null; } if (this._disposeConnectionInfo) ((IDisposable)this.ConnectionInfo).Dispose(); base.Dispose(disposing); }
public SftpContext(SftpSession session, string path, FileMode mode, FileAccess access, SftpFileAttributes attributes) { _stream = new SftpContextStream(session, path, mode, access, attributes); }
private void Session_Disconnected(object sender, EventArgs e) { lock (this._lock) { this._session.Disconnected -= Session_Disconnected; this._session = null; } }
protected override void OnConnected() { base.OnConnected(); _sftpSession = new SftpSession(Session, _operationTimeout, Encoding.UTF8); _sftpSession.Connect(); _userId = GetUserId(); if (_userId != -1) _userGroups = new HashSet<int>(GetUserGroupsIds()); if (String.IsNullOrWhiteSpace(_rootpath)) { _rootpath = _sftpSession.RequestRealPath(".").First().Key; } _supportsPosixRename = _sftpSession._supportedExtensions.Contains(new KeyValuePair<string, string>("*****@*****.**", "1")); _supportsStatVfs = _sftpSession._supportedExtensions.Contains(new KeyValuePair<string, string>("*****@*****.**", "2")); // KeepAliveInterval=TimeSpan.FromSeconds(5); // Session.Disconnected+= (sender, args) => Debugger.Break(); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { base.Dispose(disposing); if (this._session != null) { lock (this._lock) { if (this._session != null) { if (this._handle != null) { if (this._bufferOwnedByWrite) { this.FlushWriteBuffer(); } if (this._ownsHandle) { this._session.RequestClose(this._handle); } this._handle = null; } this._session.Disconnected -= Session_Disconnected; this._session = null; } } } }
internal SftpFileStream(SftpSession session, byte[] handle, FileAccess access) : this(session, handle, access, true, 4096, false) { // Nothing to do here. }