#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(all(
not(feature = "runtime-tokio"),
not(feature = "runtime-async-std"),
not(doc)
))]
compile_error!(
"An async runtime have to be specified by feature: \"runtime-tokio\" \"runtime-async-std\""
);
mod request;
mod response;
#[cfg(feature = "runtime-async-std")]
use async_std::io::{Read, Write};
use httparse::Error as HttpParseError;
#[cfg(feature = "runtime-async-std")]
use response::recv_and_check_response_async_std;
#[cfg(feature = "runtime-tokio")]
use response::recv_and_check_response_tokio;
use std::io::Error as IoError;
use thiserror::Error as ThisError;
#[cfg(feature = "runtime-tokio")]
use tokio::io::{AsyncRead, AsyncWrite, BufStream};
pub const MAXIMUM_RESPONSE_HEADER_LENGTH: usize = 4096;
pub const MAXIMUM_RESPONSE_HEADERS: usize = 16;
#[derive(Debug, ThisError)]
pub enum HttpError {
#[error("IO Error: {0}")]
IoError(#[from] IoError),
#[error("HTTP parse error: {0}")]
HttpParseError(#[from] HttpParseError),
#[error("The maximum response header length is exceeded: {0}")]
MaximumResponseHeaderLengthExceeded(String),
#[error("The end of file is reached")]
EndOfFile,
#[error("No HTTP code was found in the response")]
NoHttpCode,
#[error("The HTTP code is not equal 200: {0}")]
HttpCode200(u16),
#[error("No HTTP reason was found in the response")]
NoHttpReason,
#[error("The HTTP reason is not equal 'ConnectionEstablished': {0}")]
HttpReasonConnectionEstablished(String),
}
#[cfg(feature = "runtime-tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "runtime-tokio")))]
pub async fn http_connect_tokio<IO>(io: &mut IO, host: &str, port: u16) -> Result<(), HttpError>
where
IO: AsyncRead + AsyncWrite + Unpin,
{
let mut stream = BufStream::new(io);
request::send_request_tokio(&mut stream, host, port).await?;
recv_and_check_response_tokio(&mut stream).await?;
Ok(())
}
#[cfg(all(feature = "runtime-tokio", feature = "basic-auth"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "runtime-tokio", feature = "basic-auth")))
)]
pub async fn http_connect_tokio_with_basic_auth<IO>(
io: &mut IO,
host: &str,
port: u16,
username: &str,
password: &str,
) -> Result<(), HttpError>
where
IO: AsyncRead + AsyncWrite + Unpin,
{
let mut stream = BufStream::new(io);
request::send_request_tokio_with_basic_auth(&mut stream, host, port, username, password)
.await?;
recv_and_check_response_tokio(&mut stream).await?;
Ok(())
}
#[cfg(feature = "runtime-async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "runtime-async-std")))]
pub async fn http_connect_async_std<IO>(io: &mut IO, host: &str, port: u16) -> Result<(), HttpError>
where
IO: Read + Write + Unpin,
{
request::send_request_async_std(io, host, port).await?;
recv_and_check_response_async_std(io).await?;
Ok(())
}
#[cfg(all(feature = "runtime-async-std", feature = "basic-auth"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "runtime-async-std", feature = "basic-auth")))
)]
pub async fn http_connect_async_std_with_basic_auth<IO>(
io: &mut IO,
host: &str,
port: u16,
username: &str,
password: &str,
) -> Result<(), HttpError>
where
IO: Read + Write + Unpin,
{
request::send_request_async_std_with_basic_auth(io, host, port, username, password).await?;
recv_and_check_response_async_std(io).await?;
Ok(())
}