Decrease alloc on auth resp parsing
This commit is contained in:
parent
2aa8c87e35
commit
ff48dc9755
4 changed files with 27 additions and 14 deletions
|
|
@ -29,6 +29,7 @@ imap-proto = "0.8"
|
|||
nom = "4.0"
|
||||
base64 = "0.10"
|
||||
chrono = "0.4"
|
||||
lazy_static = "1.4"
|
||||
|
||||
[dev-dependencies]
|
||||
lettre = "0.9"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use std::collections::HashSet;
|
|||
use std::io::{Read, Write};
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::str;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use super::authenticator::Authenticator;
|
||||
|
|
@ -346,13 +347,19 @@ impl<T: Read + Write> Client<T> {
|
|||
ok_or_unauth_client_err!(self.readline(&mut line), self);
|
||||
|
||||
if line.starts_with(b"+ ") {
|
||||
let data = ok_or_unauth_client_err!(
|
||||
parse_authenticate_response(String::from_utf8(line).unwrap()),
|
||||
let line_str = ok_or_unauth_client_err!(
|
||||
match str::from_utf8(line.as_slice()) {
|
||||
Ok(line_str) => Ok(line_str),
|
||||
Err(e) => Err(Error::Parse(ParseError::DataNotUtf8(line, e))),
|
||||
},
|
||||
self
|
||||
);
|
||||
let data = ok_or_unauth_client_err!(parse_authenticate_response(line_str), self);
|
||||
let challenge = ok_or_unauth_client_err!(
|
||||
base64::decode(data.as_str())
|
||||
.map_err(|e| Error::Parse(ParseError::Authentication(data, Some(e)))),
|
||||
base64::decode(data).map_err(|e| Error::Parse(ParseError::Authentication(
|
||||
data.to_string(),
|
||||
Some(e)
|
||||
))),
|
||||
self
|
||||
);
|
||||
let raw_response = &authenticator.process(&challenge);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::fmt;
|
|||
use std::io::Error as IoError;
|
||||
use std::net::TcpStream;
|
||||
use std::result;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::str::Utf8Error;
|
||||
|
||||
use base64::DecodeError;
|
||||
use bufstream::IntoInnerError as BufError;
|
||||
|
|
@ -111,7 +111,7 @@ impl StdError for Error {
|
|||
Error::Io(ref e) => Some(e),
|
||||
Error::Tls(ref e) => Some(e),
|
||||
Error::TlsHandshake(ref e) => Some(e),
|
||||
Error::Parse(ParseError::DataNotUtf8(ref e)) => Some(e),
|
||||
Error::Parse(ParseError::DataNotUtf8(_, ref e)) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ pub enum ParseError {
|
|||
/// The client could not find or decode the server's authentication challenge.
|
||||
Authentication(String, Option<DecodeError>),
|
||||
/// The client receive data that was not UTF-8 encoded.
|
||||
DataNotUtf8(FromUtf8Error),
|
||||
DataNotUtf8(Vec<u8>, Utf8Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseError {
|
||||
|
|
@ -144,7 +144,7 @@ impl StdError for ParseError {
|
|||
ParseError::Invalid(_) => "Unable to parse status response",
|
||||
ParseError::Unexpected(_) => "Encountered unexpected parsed response",
|
||||
ParseError::Authentication(_, _) => "Unable to parse authentication response",
|
||||
ParseError::DataNotUtf8(_) => "Unable to parse data as UTF-8 text",
|
||||
ParseError::DataNotUtf8(_, _) => "Unable to parse data as UTF-8 text",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
17
src/parse.rs
17
src/parse.rs
|
|
@ -1,4 +1,5 @@
|
|||
use imap_proto::{self, MailboxDatum, Response};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::mpsc;
|
||||
|
|
@ -6,15 +7,19 @@ use std::sync::mpsc;
|
|||
use super::error::{Error, ParseError, Result};
|
||||
use super::types::*;
|
||||
|
||||
pub fn parse_authenticate_response(line: String) -> Result<String> {
|
||||
let authenticate_regex = Regex::new("^\\+ (.*)\r\n").unwrap();
|
||||
lazy_static! {
|
||||
static ref AUTH_RESP_REGEX: Regex = Regex::new("^\\+ (.*)\r\n").unwrap();
|
||||
}
|
||||
|
||||
if let Some(cap) = authenticate_regex.captures_iter(line.as_str()).next() {
|
||||
pub fn parse_authenticate_response(line: &str) -> Result<&str> {
|
||||
if let Some(cap) = AUTH_RESP_REGEX.captures_iter(line).next() {
|
||||
let data = cap.get(1).map(|x| x.as_str()).unwrap_or("");
|
||||
return Ok(String::from(data));
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
Err(Error::Parse(ParseError::Authentication(line, None)))
|
||||
Err(Error::Parse(ParseError::Authentication(
|
||||
line.to_string(),
|
||||
None,
|
||||
)))
|
||||
}
|
||||
|
||||
enum MapOrNot<T> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue