Refactor SFTP to prepare for multiple SFTP version support and add suport for versions 0 thru 3

This commit is contained in:
olegkap_cp
2012-12-28 14:33:36 +00:00
parent 086936aa6b
commit 44b447afc4
32 changed files with 162 additions and 91 deletions
@@ -16,8 +16,8 @@ namespace Renci.SshNet.Sftp.Requests
public string NewPath { get; private set; }
public PosixRenameRequest(uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public PosixRenameRequest(uint protocolVersion, uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.OldPath = oldPath;
this.NewPath = newPath;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public byte[] Handle { get; private set; }
public SftpCloseRequest(uint requestId, byte[] handle, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpCloseRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
}
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
public SftpFileAttributes Attributes { get; private set; }
public SftpFSetStatRequest(uint requestId, byte[] handle, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpFSetStatRequest(uint protocolVersion, uint requestId, byte[] handle, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
this.Attributes = attributes;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public byte[] Handle { get; private set; }
public SftpFStatRequest(uint requestId, byte[] handle, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpFStatRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
this.SetAction(attrsAction);
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpLStatRequest(uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpLStatRequest(uint protocolVersion, uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.SetAction(attrsAction);
@@ -17,15 +17,15 @@ namespace Renci.SshNet.Sftp.Requests
public SftpFileAttributes Attributes { get; private set; }
public SftpMkDirRequest(uint requestId, string path, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpMkDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.Attributes = new SftpFileAttributes();
}
public SftpMkDirRequest(uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpMkDirRequest(uint protocolVersion, uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.Attributes = attributes;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpOpenDirRequest(uint requestId, string path, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpOpenDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.SetAction(handleAction);
@@ -19,13 +19,13 @@ namespace Renci.SshNet.Sftp.Requests
public SftpFileAttributes Attributes { get; private set; }
public SftpOpenRequest(uint requestId, string fileName, Flags flags, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: this(requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction)
public SftpOpenRequest(uint protocolVersion, uint requestId, string fileName, Flags flags, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: this(protocolVersion, requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction)
{
}
public SftpOpenRequest(uint requestId, string fileName, Flags flags, SftpFileAttributes attributes, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpOpenRequest(uint protocolVersion, uint requestId, string fileName, Flags flags, SftpFileAttributes attributes, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Filename = fileName;
this.Flags = flags;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public byte[] Handle { get; private set; }
public SftpReadDirRequest(uint requestId, byte[] handle, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpReadDirRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
this.SetAction(nameAction);
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpReadLinkRequest(uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpReadLinkRequest(uint protocolVersion, uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.SetAction(nameAction);
@@ -19,8 +19,8 @@ namespace Renci.SshNet.Sftp.Requests
public UInt32 Length { get; private set; }
public SftpReadRequest(uint requestId, byte[] handle, UInt64 offset, UInt32 length, Action<SftpDataResponse> dataAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpReadRequest(uint protocolVersion, uint requestId, byte[] handle, UInt64 offset, UInt32 length, Action<SftpDataResponse> dataAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
this.Offset = offset;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpRealPathRequest(uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpRealPathRequest(uint protocolVersion, uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
if (nameAction == null)
throw new ArgumentNullException("name");
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Filename { get; private set; }
public SftpRemoveRequest(uint requestId, string filename, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpRemoveRequest(uint protocolVersion, uint requestId, string filename, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Filename = filename;
}
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
public string NewPath { get; private set; }
public SftpRenameRequest(uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpRenameRequest(uint protocolVersion, uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.OldPath = oldPath;
this.NewPath = newPath;
@@ -17,10 +17,13 @@ namespace Renci.SshNet.Sftp.Requests
private Action<SftpNameResponse> _nameAction;
public uint RequestId { get; private set; }
public uint ProtocolVersion { get; private set; }
public SftpRequest(uint requestId, Action<SftpStatusResponse> statusAction)
public SftpRequest(uint protocolVersion, uint requestId, Action<SftpStatusResponse> statusAction)
{
this.RequestId = requestId;
this.ProtocolVersion = protocolVersion;
this._statusAction = statusAction;
}
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpRmDirRequest(uint requestId, string path, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpRmDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
}
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
public SftpFileAttributes Attributes { get; private set; }
public SftpSetStatRequest(uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpSetStatRequest(uint protocolVersion, uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.Attributes = attributes;
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public SftpStatRequest(uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpStatRequest(uint protocolVersion, uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.SetAction(attrsAction);
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
public string ExistingPath { get; set; }
public SftpSymLinkRequest(uint requestId, string newLinkPath, string existingPath, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpSymLinkRequest(uint protocolVersion, uint requestId, string newLinkPath, string existingPath, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.NewLinkPath = newLinkPath;
this.ExistingPath = existingPath;
@@ -19,8 +19,8 @@ namespace Renci.SshNet.Sftp.Requests
public byte[] Data { get; private set; }
public SftpWriteRequest(uint requestId, byte[] handle, UInt64 offset, byte[] data, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public SftpWriteRequest(uint protocolVersion, uint requestId, byte[] handle, UInt64 offset, byte[] data, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Handle = handle;
this.Offset = offset;
@@ -14,8 +14,8 @@ namespace Renci.SshNet.Sftp.Requests
public string Path { get; private set; }
public StatVfsRequest(uint requestId, string path, Action<SftpExtendedReplyResponse> extendedAction, Action<SftpStatusResponse> statusAction)
: base(requestId, statusAction)
public StatVfsRequest(uint protocolVersion, uint requestId, string path, Action<SftpExtendedReplyResponse> extendedAction, Action<SftpStatusResponse> statusAction)
: base(protocolVersion, requestId, statusAction)
{
this.Path = path;
this.SetAction(extendedAction);
@@ -14,6 +14,11 @@ namespace Renci.SshNet.Sftp.Responses
public SftpFileAttributes Attributes { get; private set; }
public SftpAttrsResponse(uint protocolVersion)
: base(protocolVersion)
{
}
protected override void LoadData()
{
base.LoadData();
@@ -16,6 +16,11 @@ namespace Renci.SshNet.Sftp.Responses
public bool IsEof { get; set; }
public SftpDataResponse(uint protocolVersion)
: base(protocolVersion)
{
}
protected override void LoadData()
{
base.LoadData();
@@ -11,5 +11,10 @@ namespace Renci.SshNet.Sftp.Responses
{
get { return SftpMessageTypes.ExtendedReply; }
}
public SftpExtendedReplyResponse(uint protocolVersion)
: base(protocolVersion)
{
}
}
}
@@ -14,6 +14,11 @@ namespace Renci.SshNet.Sftp.Responses
public byte[] Handle { get; private set; }
public SftpHandleResponse(uint protocolVersion)
: base(protocolVersion)
{
}
protected override void LoadData()
{
base.LoadData();
@@ -16,9 +16,10 @@ namespace Renci.SshNet.Sftp.Responses
public KeyValuePair<string, SftpFileAttributes>[] Files { get; private set; }
public SftpNameResponse()
public SftpNameResponse(uint protocolVersion)
: base(protocolVersion)
{
this.Files = new KeyValuePair<string,SftpFileAttributes>[0];
this.Files = new KeyValuePair<string, SftpFileAttributes>[0];
}
protected override void LoadData()
@@ -9,6 +9,13 @@ namespace Renci.SshNet.Sftp.Responses
{
public uint ResponseId { get; private set; }
public uint ProtocolVersion { get; private set; }
public SftpResponse(uint protocolVersion)
{
this.ProtocolVersion = protocolVersion;
}
protected override void LoadData()
{
base.LoadData();
@@ -12,19 +12,28 @@ namespace Renci.SshNet.Sftp.Responses
get { return SftpMessageTypes.Status; }
}
public SftpStatusResponse(uint protocolVersion)
: base(protocolVersion)
{
}
public StatusCodes StatusCode { get; private set; }
public string ErrorMessage { get; private set; }
public string Language { get; private set; }
protected override void LoadData()
{
base.LoadData();
this.StatusCode = (StatusCodes)this.ReadUInt32();
if (this.ProtocolVersion < 3)
{
return;
}
if (!this.IsEndOfData)
{
this.ErrorMessage = this.ReadString();
@@ -4,6 +4,11 @@
{
public SftpFileSytemInformation Information { get; private set; }
public StatVfsResponse()
: base(0)
{
}
protected override void LoadData()
{
base.LoadData();
@@ -9,11 +9,11 @@ namespace Renci.SshNet.Sftp
{
internal abstract class SftpMessage : SshData
{
public new static SftpMessage Load(byte[] data)
public new static SftpMessage Load(uint protocolVersion, byte[] data)
{
var messageType = (SftpMessageTypes)data.FirstOrDefault();
return Load(data, messageType);
return Load(protocolVersion, data, messageType);
}
protected override int ZeroReaderIndex
@@ -152,7 +152,7 @@ namespace Renci.SshNet.Sftp
}
}
private static SftpMessage Load(byte[] data, SftpMessageTypes messageType)
private static SftpMessage Load(uint protocolVersion, byte[] data, SftpMessageTypes messageType)
{
SftpMessage message = null;
@@ -162,22 +162,22 @@ namespace Renci.SshNet.Sftp
message = new SftpVersionResponse();
break;
case SftpMessageTypes.Status:
message = new SftpStatusResponse();
message = new SftpStatusResponse(protocolVersion);
break;
case SftpMessageTypes.Data:
message = new SftpDataResponse();
message = new SftpDataResponse(protocolVersion);
break;
case SftpMessageTypes.Handle:
message = new SftpHandleResponse();
message = new SftpHandleResponse(protocolVersion);
break;
case SftpMessageTypes.Name:
message = new SftpNameResponse();
message = new SftpNameResponse(protocolVersion);
break;
case SftpMessageTypes.Attrs:
message = new SftpAttrsResponse();
message = new SftpAttrsResponse(protocolVersion);
break;
case SftpMessageTypes.ExtendedReply:
message = new SftpExtendedReplyResponse();
message = new SftpExtendedReplyResponse(protocolVersion);
break;
default:
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", messageType));
@@ -15,6 +15,10 @@ namespace Renci.SshNet.Sftp
{
internal class SftpSession : SubsystemSession
{
private const int MAXIMUM_SUPPORTED_VERSION = 3;
private const int MINIMUM_SUPPORTED_VERSION = 0;
private Dictionary<uint, SftpRequest> _requests = new Dictionary<uint, SftpRequest>();
private List<byte> _data = new List<byte>(16 * 1024);
@@ -29,7 +33,7 @@ namespace Renci.SshNet.Sftp
/// <summary>
/// Gets SFTP protocol version.
/// </summary>
public int ProtocolVersion { get; private set; }
public uint ProtocolVersion { get; private set; }
private long _requestId;
/// <summary>
@@ -164,11 +168,14 @@ namespace Renci.SshNet.Sftp
protected override void OnChannelOpen()
{
this.SendMessage(new SftpInitRequest(3));
this.SendMessage(new SftpInitRequest(MAXIMUM_SUPPORTED_VERSION));
this.WaitHandle(this._sftpVersionConfirmed, this._operationTimeout);
this.ProtocolVersion = 3;
if (this.ProtocolVersion > MAXIMUM_SUPPORTED_VERSION || this.ProtocolVersion < MINIMUM_SUPPORTED_VERSION)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Server SFTP version {0} is not supported.", this.ProtocolVersion));
}
// Resolve current directory
this.WorkingDirectory = this.RequestRealPath(".").First().Key;
@@ -202,21 +209,16 @@ namespace Renci.SshNet.Sftp
this._data.RemoveRange(0, packetLength);
// Load SFTP Message and handle it
var response = SftpMessage.Load(packetData);
var response = SftpMessage.Load(this.ProtocolVersion, packetData);
try
{
var versionResponse = response as SftpVersionResponse;
if (versionResponse != null)
{
if (versionResponse.Version == 3)
{
this._sftpVersionConfirmed.Set();
}
else
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Server SFTP version {0} is not supported.", versionResponse.Version));
}
this.ProtocolVersion = versionResponse.Version;
this._sftpVersionConfirmed.Set();
}
else
{
@@ -270,7 +272,7 @@ namespace Renci.SshNet.Sftp
using (var wait = new AutoResetEvent(false))
{
var request = new SftpOpenRequest(this.NextRequestId, path, flags,
var request = new SftpOpenRequest(this.ProtocolVersion, this.NextRequestId, path, flags,
(response) =>
{
handle = response.Handle;
@@ -304,7 +306,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpCloseRequest(this.NextRequestId, handle,
var request = new SftpCloseRequest(this.ProtocolVersion, this.NextRequestId, handle,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -336,7 +338,7 @@ namespace Renci.SshNet.Sftp
using (var wait = new AutoResetEvent(false))
{
var request = new SftpReadRequest(this.NextRequestId, handle, offset, length,
var request = new SftpReadRequest(this.ProtocolVersion, this.NextRequestId, handle, offset, length,
(response) =>
{
data = response.Data;
@@ -371,7 +373,7 @@ namespace Renci.SshNet.Sftp
/// <param name="wait">The wait event handle if needed.</param>
internal void RequestWrite(byte[] handle, UInt64 offset, byte[] data, EventWaitHandle wait, Action<SftpStatusResponse> writeCompleted = null)
{
var request = new SftpWriteRequest(this.NextRequestId, handle, offset, data,
var request = new SftpWriteRequest(this.ProtocolVersion, this.NextRequestId, handle, offset, data,
(response) =>
{
if (writeCompleted != null)
@@ -409,7 +411,7 @@ namespace Renci.SshNet.Sftp
SftpFileAttributes attributes = null;
using (var wait = new AutoResetEvent(false))
{
var request = new SftpLStatRequest(this.NextRequestId, path,
var request = new SftpLStatRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
attributes = response.Attributes;
@@ -441,7 +443,7 @@ namespace Renci.SshNet.Sftp
SftpFileAttributes attributes = null;
using (var wait = new AutoResetEvent(false))
{
var request = new SftpFStatRequest(this.NextRequestId, handle,
var request = new SftpFStatRequest(this.ProtocolVersion, this.NextRequestId, handle,
(response) =>
{
attributes = response.Attributes;
@@ -469,7 +471,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpSetStatRequest(this.NextRequestId, path, attributes,
var request = new SftpSetStatRequest(this.ProtocolVersion, this.NextRequestId, path, attributes,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -497,7 +499,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpFSetStatRequest(this.NextRequestId, handle, attributes,
var request = new SftpFSetStatRequest(this.ProtocolVersion, this.NextRequestId, handle, attributes,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -528,7 +530,7 @@ namespace Renci.SshNet.Sftp
using (var wait = new AutoResetEvent(false))
{
var request = new SftpOpenDirRequest(this.NextRequestId, path,
var request = new SftpOpenDirRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
handle = response.Handle;
@@ -565,7 +567,7 @@ namespace Renci.SshNet.Sftp
using (var wait = new AutoResetEvent(false))
{
var request = new SftpReadDirRequest(this.NextRequestId, handle,
var request = new SftpReadDirRequest(this.ProtocolVersion, this.NextRequestId, handle,
(response) =>
{
result = response.Files;
@@ -599,7 +601,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpRemoveRequest(this.NextRequestId, path,
var request = new SftpRemoveRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -626,7 +628,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpMkDirRequest(this.NextRequestId, path,
var request = new SftpMkDirRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -653,7 +655,7 @@ namespace Renci.SshNet.Sftp
{
using (var wait = new AutoResetEvent(false))
{
var request = new SftpRmDirRequest(this.NextRequestId, path,
var request = new SftpRmDirRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -684,7 +686,7 @@ namespace Renci.SshNet.Sftp
using (var wait = new AutoResetEvent(false))
{
var request = new SftpRealPathRequest(this.NextRequestId, path,
var request = new SftpRealPathRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
result = response.Files;
@@ -724,7 +726,7 @@ namespace Renci.SshNet.Sftp
SftpFileAttributes attributes = null;
using (var wait = new AutoResetEvent(false))
{
var request = new SftpStatRequest(this.NextRequestId, path,
var request = new SftpStatRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
attributes = response.Attributes;
@@ -757,9 +759,13 @@ namespace Renci.SshNet.Sftp
/// <param name="newPath">The new path.</param>
internal void RequestRename(string oldPath, string newPath)
{
if (this.ProtocolVersion < 2)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_RENAME operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
}
using (var wait = new AutoResetEvent(false))
{
var request = new SftpRenameRequest(this.NextRequestId, oldPath, newPath,
var request = new SftpRenameRequest(this.ProtocolVersion, this.NextRequestId, oldPath, newPath,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -786,11 +792,16 @@ namespace Renci.SshNet.Sftp
/// <returns></returns>
internal KeyValuePair<string, SftpFileAttributes>[] RequestReadLink(string path, bool nullOnError = false)
{
if (this.ProtocolVersion < 3)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_READLINK operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
}
KeyValuePair<string, SftpFileAttributes>[] result = null;
using (var wait = new AutoResetEvent(false))
{
var request = new SftpReadLinkRequest(this.NextRequestId, path,
var request = new SftpReadLinkRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
result = response.Files;
@@ -824,9 +835,14 @@ namespace Renci.SshNet.Sftp
/// <param name="targetpath">The targetpath.</param>
internal void RequestSymLink(string linkpath, string targetpath)
{
if (this.ProtocolVersion < 3)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_SYMLINK operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
}
using (var wait = new AutoResetEvent(false))
{
var request = new SftpSymLinkRequest(this.NextRequestId, linkpath, targetpath,
var request = new SftpSymLinkRequest(this.ProtocolVersion, this.NextRequestId, linkpath, targetpath,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -852,9 +868,14 @@ namespace Renci.SshNet.Sftp
/// <param name="newPath">The new path.</param>
internal void RequestPosixRename(string oldPath, string newPath)
{
if (this.ProtocolVersion < 3)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_EXTENDED operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
}
using (var wait = new AutoResetEvent(false))
{
var request = new PosixRenameRequest(this.NextRequestId, oldPath, newPath,
var request = new PosixRenameRequest(this.ProtocolVersion, this.NextRequestId, oldPath, newPath,
(response) =>
{
if (response.StatusCode == StatusCodes.Ok)
@@ -881,10 +902,15 @@ namespace Renci.SshNet.Sftp
/// <returns></returns>
internal SftpFileSytemInformation RequestStatVfs(string path, bool nullOnError = false)
{
if (this.ProtocolVersion < 3)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_EXTENDED operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
}
SftpFileSytemInformation information = null;
using (var wait = new AutoResetEvent(false))
{
var request = new StatVfsRequest(this.NextRequestId, path,
var request = new StatVfsRequest(this.ProtocolVersion, this.NextRequestId, path,
(response) =>
{
information = response.OfType<StatVfsResponse>().Information;
+1 -1
View File
@@ -1448,7 +1448,7 @@ namespace Renci.SshNet
this._sftpSession.Connect();
// Resolve current running version
this.ProtocolVersion = this._sftpSession.ProtocolVersion;
this.ProtocolVersion = (int)this._sftpSession.ProtocolVersion;
}
/// <summary>