Recover expired FTP control sessions
CI / checks (pull_request) Successful in 2m44s
Agents / bot (pull_request) Successful in 8m37s

This commit is contained in:
Danny Kim
2026-09-30 19:12:44 +09:00
parent cd4b4c5e70
commit 179c17a337
8 changed files with 365 additions and 30 deletions
+50
View File
@@ -0,0 +1,50 @@
//! Native test transport. Guest calls run only inside `spawn_blocking`;
//! production WASM always uses the host's sockets and network policy.
use std::cell::RefCell;
use std::io::{Read, Write};
use std::net::{IpAddr, SocketAddr, TcpStream};
use std::time::Duration;
pub use memona_plugin_sdk::HostError;
pub struct Tcp(RefCell<TcpStream>);
pub fn connect(name: &str, port: u16, tls: bool) -> Result<Tcp, HostError> {
if tls {
return Err(HostError::InvalidInput);
}
let ip: IpAddr = name.parse().map_err(|_| HostError::InvalidInput)?;
let timeout = Duration::from_secs(2);
let stream = TcpStream::connect_timeout(&SocketAddr::new(ip, port), timeout)
.map_err(|_| HostError::Unavailable)?;
stream
.set_read_timeout(Some(timeout))
.map_err(|_| HostError::Unavailable)?;
stream
.set_write_timeout(Some(timeout))
.map_err(|_| HostError::Unavailable)?;
Ok(Tcp(RefCell::new(stream)))
}
impl Tcp {
pub fn read(&self, limit: u32) -> Result<Vec<u8>, HostError> {
let mut bytes = vec![0; limit as usize];
let count = self
.0
.borrow_mut()
.read(&mut bytes)
.map_err(|_| HostError::Unavailable)?;
bytes.truncate(count);
Ok(bytes)
}
pub fn write(&self, bytes: &[u8]) -> Result<u32, HostError> {
self
.0
.borrow_mut()
.write(bytes)
.map(|count| count as u32)
.map_err(|_| HostError::Unavailable)
}
}