Merge pull request #138 from brycefisher/feat/rustls-support
(feat) Provide example integration with Rustls crate
This commit is contained in:
commit
c8288ea19b
5 changed files with 70 additions and 2 deletions
|
|
@ -34,3 +34,4 @@ lazy_static = "1.4"
|
|||
[dev-dependencies]
|
||||
lettre = "0.9"
|
||||
lettre_email = "0.9"
|
||||
rustls-connector = "0.8.0"
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ stages:
|
|||
# This represents the minimum Rust version supported.
|
||||
# Tests are not run as tests may require newer versions of rust.
|
||||
- stage: msrv
|
||||
displayName: "Minimum supported Rust version: 1.32.0"
|
||||
displayName: "Minimum supported Rust version: 1.36.0"
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: azure/cargo-check.yml@templates
|
||||
parameters:
|
||||
rust: 1.32.0
|
||||
rust: 1.36.0
|
||||
- stage: test
|
||||
displayName: Test suite
|
||||
dependsOn: check
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ This directory contains examples of working with the IMAP client.
|
|||
Examples:
|
||||
* basic - This is a very basic example of using the client.
|
||||
* gmail_oauth2 - This is an example using oauth2 for logging into gmail as a secure appplication.
|
||||
* rustls - This demonstrates how to use Rustls instead of Openssl for secure connections (helpful for cross compilation).
|
||||
|
|
|
|||
63
examples/rustls.rs
Normal file
63
examples/rustls.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
extern crate imap;
|
||||
extern crate rustls_connector;
|
||||
|
||||
use std::{env, error::Error, net::TcpStream};
|
||||
|
||||
use rustls_connector::RustlsConnector;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Read config from environment or .env file
|
||||
let host = env::var("HOST").expect("missing envvar host");
|
||||
let user = env::var("MAILUSER").expect("missing envvar USER");
|
||||
let password = env::var("PASSWORD").expect("missing envvar password");
|
||||
let port = 993;
|
||||
|
||||
if let Some(email) = fetch_inbox_top(host, user, password, port)? {
|
||||
println!("{}", &email);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fetch_inbox_top(
|
||||
host: String,
|
||||
user: String,
|
||||
password: String,
|
||||
port: u16,
|
||||
) -> Result<Option<String>, Box<dyn Error>> {
|
||||
// Setup Rustls TcpStream
|
||||
let stream = TcpStream::connect((host.as_ref(), port))?;
|
||||
let tls = RustlsConnector::default();
|
||||
let tlsstream = tls.connect(&host, stream)?;
|
||||
|
||||
// we pass in the domain twice to check that the server's TLS
|
||||
// certificate is valid for the domain we're connecting to.
|
||||
let client = imap::Client::new(tlsstream);
|
||||
|
||||
// the client we have here is unauthenticated.
|
||||
// to do anything useful with the e-mails, we need to log in
|
||||
let mut imap_session = client.login(&user, &password).map_err(|e| e.0)?;
|
||||
|
||||
// we want to fetch the first email in the INBOX mailbox
|
||||
imap_session.select("INBOX")?;
|
||||
|
||||
// fetch message number 1 in this mailbox, along with its RFC822 field.
|
||||
// RFC 822 dictates the format of the body of e-mails
|
||||
let messages = imap_session.fetch("1", "RFC822")?;
|
||||
let message = if let Some(m) = messages.iter().next() {
|
||||
m
|
||||
} else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
// extract the message's body
|
||||
let body = message.body().expect("message did not have a body!");
|
||||
let body = std::str::from_utf8(body)
|
||||
.expect("message was not valid utf-8")
|
||||
.to_string();
|
||||
|
||||
// be nice to the server and log out
|
||||
imap_session.logout()?;
|
||||
|
||||
Ok(Some(body))
|
||||
}
|
||||
|
|
@ -222,6 +222,9 @@ macro_rules! ok_or_unauth_client_err {
|
|||
impl<T: Read + Write> Client<T> {
|
||||
/// Creates a new client over the given stream.
|
||||
///
|
||||
/// For an example of how to use this method to provide a pure-Rust TLS integration, see the
|
||||
/// rustls.rs in the examples/ directory.
|
||||
///
|
||||
/// This method primarily exists for writing tests that mock the underlying transport, but can
|
||||
/// also be used to support IMAP over custom tunnels.
|
||||
pub fn new(stream: T) -> Client<T> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue