rusmes_loadtest/protocols/
imap.rs1use anyhow::{Context, Result};
4use std::time::Duration;
5use tokio::io::{AsyncReadExt, AsyncWriteExt};
6use tokio::net::TcpStream;
7use tokio::time::timeout;
8
9pub struct ImapClient;
11
12impl ImapClient {
13 pub async fn fetch_messages(host: &str, port: u16) -> Result<usize> {
15 let addr = format!("{}:{}", host, port);
16
17 let connect_timeout = Duration::from_secs(5);
18 let stream = timeout(connect_timeout, TcpStream::connect(&addr))
19 .await
20 .context("Connection timeout")?
21 .context("Failed to connect")?;
22
23 let mut stream = stream;
24 let mut buffer = vec![0u8; 4096];
25
26 let n = timeout(Duration::from_secs(5), stream.read(&mut buffer))
28 .await
29 .context("Read timeout")?
30 .context("Failed to read greeting")?;
31
32 let mut bytes_received = n;
33
34 stream
36 .write_all(b"A001 LOGIN testuser testpass\r\n")
37 .await?;
38 let n = stream.read(&mut buffer).await?;
39 bytes_received += n;
40
41 stream.write_all(b"A002 SELECT INBOX\r\n").await?;
43 let n = stream.read(&mut buffer).await?;
44 bytes_received += n;
45
46 stream.write_all(b"A003 FETCH 1:10 (FLAGS)\r\n").await?;
48 let n = stream.read(&mut buffer).await?;
49 bytes_received += n;
50
51 stream.write_all(b"A004 LOGOUT\r\n").await?;
53 let _ = stream.read(&mut buffer).await;
54
55 Ok(bytes_received)
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[tokio::test]
64 async fn test_imap_client_timeout() {
65 let result = ImapClient::fetch_messages("192.0.2.1", 143).await;
67 assert!(result.is_err());
68 }
69}