-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Client side implementation #4
Comments
I will be glad if you share your experience with other libraries, it will help me to think over a better solution during development. |
Sure. The library I use today is wezterm-ssh written by an old colleague of mine. It acts as a wrapper around both ssh2 and libssh client libraries, themselves wrappers around the associated For using ssh with sftp, the entrypoint starts from crating an ssh session and then creating a new SFTP channel via Session::sftp. I actually wrote the original code for the SFTP wrapper for wezterm-ssh, and the API itself is okay, but the client libraries themselves are a bit buggy and poor-performing, so I'm hoping that a Rust-native implementation will eventually reach better stability. You can see how I use the SFTP abstraction from The SFTP APIThe high-level SFTP channel API can be found here: https://docs.rs/wezterm-ssh/0.4.0/wezterm_ssh/struct.Sftp.html. Because this library was abstracting across two different client implementations, you find wrapper implementations like wezterm_ssh::SftpWrap to invoke the underlying library method, but you shouldn't need to do this yourself since you'd be using russh and your own implementation on top. In a nutshell, it provides a flat collection of async functions to perform common filesystem actions. Many of these mirror those you'd find in the std::fs module:
AbstractionsWhen I first wrote the sftp abstraction, I had exported types that represented high-level wrappers across API usage. Those specifically were:
|
@chipsenkbeil I researched this issue and the current implementation of serialization and deserialization is not very good for extending the code with the client side, so I will do that first and then add a small client example. I'll provide the basis for the client side soon, hopefully you can help expand the client side in the future |
@AspectUnk great! Keep me posted on the updates. |
@AspectUnk any update here? Anything else I can contribute to help? |
@chipsenkbeil sorry, i didn't have much time before this. i'll try to provide a new beta version for feedback one of these days |
I'm interested in adding client support but I have a few questions first.
|
@oh-yes-0-fps Welcome
If you have any suggestions that require a longer discussion, please create a new issue. Thank you |
I opened a PR #5 with an almost completely ready raw api and partly a ready high level api. @chipsenkbeil I apologize again for the long inactivity, I'll try not to repeat this. For the most part, I just have to implement the high level api for folders and files, while I'm doing this, could you please evaluate the current implementation. I tried to leave the high level api exactly the same as in your crate to make it easier for you to integrate. After looking through your crate, I had a question. Is its high functionality superficial and maybe it should be expanded? |
Thanks for this and no worries about inactivity! You're doing this in your spare time and for free, so I'm appreciative when you take my needs into consideration. I skimmed through it earlier, and will try to take a deeper look and leave comments in the next week or so.
Sorry, I don't understand the question. Can you rephrase it? Are you asking if the high level API should be expanded to include other features? |
Yes, I think it can be significantly expanded. Btw I did not see an AsyncSeek implementation for a file in your crate. Why is this so? Now I have already implemented read_dir by analogy with std::fs::read_dir, file and their async i/o implementation (btw AsyncSeek too), and all other methods from your crate. An example of using the client can be found here. I hope this is what you wanted 😅 A couple of points:
|
No reason. Wasn't needed for the minimum implementation at the time. So if you've already implemented it, that's great!
You've done so much! I can take a stab and trying to use it as a replacement for
I don't use the options in my downstream library powering distant. It was just created to expose some options you could provide during a rename. The libssh backend doesn't even support the rename options, so I'd say they could just be ignored. pub fn rename(
&self,
src: &Utf8Path,
dest: &Utf8Path,
#[cfg_attr(not(feature = "ssh2"), allow(unused_variables))] opts: RenameOptions,
) -> SftpChannelResult<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(sftp) => {
Ok(sftp.rename(src.as_std_path(), dest.as_std_path(), Some(opts.into()))?)
}
#[cfg(feature = "libssh-rs")]
Self::LibSsh(sftp) => Ok(sftp.rename(src.as_str(), dest.as_str())?),
}
}
It was just part of me exposing a friendly wrapper on top of the ssh libraries. I don't see it being used in my downstream library within distant, so if it simplifies things I'd say leave it out. I'm not familiar with extensions, so what does |
It provides the client with information about server limits such as the max open of handles, the max number of bytes to read/write per packet, and the max length of the packet itself. If the client violates these limits, the server may terminate the connection. So this is a pretty important part |
How common is this extension? If a server doesn't implement the extension, can you still use all of the other features of sftp if the server supports that subsystem? |
Almost every modern server has it. And no, due to its absence the protocol is not limited. In any case, you don't have to worry about this, I have already implemented support for Now I can be sure that this is a completely ready sftp client with advanced abstraction and methods, but there may still be errors or flaw so I hope you can test it. Btw, I saw your issue, if you need help with integration let me know 😼 |
Fantastic!
Yep! Was planning to use So once you've published a beta, I can give it a go to try to swap my usage of |
It's now published as |
Woo hoo! I'm going to give it a try to implement in a branch I'd started to migrate over to |
@chipsenkbeil I did not notice one flaw that made it into the published version. New |
Got it. I've updated my branch with that beta version. Didn't have time this weekend to work on it, but hoping to tackle this coming weekend. At least within the next couple of weeks! The harder part for me is the general switch to |
I'm eagerly awaiting a Rust-native implementation of an ssh client that includes sftp. This is because I offer a remote editing experience through distant and distant.nvim respectively, which can be done both through a custom server written in Rust and ssh.
The two existing ssh client library wrappers, ssh2 and libssh, are both error-prone and add extra complexity to support.
Just wanted to drop a line that I'm watching the work being done here and am hopeful that I'll be able to adopt russh and this 3rd party addon to for sftp support in the near future!
The text was updated successfully, but these errors were encountered: