Skip to content

Commit

Permalink
add https support
Browse files Browse the repository at this point in the history
  • Loading branch information
axos88 committed Sep 26, 2022
1 parent cc64eb6 commit ae40df3
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
pub mod client;
#[cfg(esp_idf_comp_esp_http_server_enabled)]
pub mod server;
#[cfg(all(esp_idf_esp_tls_server_sni_hook, esp_idf_comp_esp_http_server_enabled))]
pub mod sni;
120 changes: 112 additions & 8 deletions src/http/server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::cell::UnsafeCell;
use core::fmt::{Debug, Display};
use core::fmt::{Debug, Display, Formatter};
use core::sync::atomic::{AtomicBool, Ordering};
use core::time::*;
use core::{mem, ptr};
Expand Down Expand Up @@ -27,9 +27,14 @@ use uncased::{Uncased, UncasedStr};
use crate::errors::EspIOError;
use crate::handle::RawHandle;
use crate::private::common::Newtype;
use crate::private::cstr::{CStr, CString};
use crate::private::cstr::{CStr, CString, to_ptr_with_len};
use crate::private::mutex::{Mutex, RawMutex};

//Cannot specialize drop impl
#[derive(Debug)]
pub struct CHttpsSslConfig(pub httpd_ssl_config_t);


#[derive(Copy, Clone, Debug)]
pub struct Configuration {
pub http_port: u16,
Expand Down Expand Up @@ -87,6 +92,78 @@ impl From<&Configuration> for Newtype<httpd_config_t> {
}
}

#[derive(Debug)]
pub struct SslConfiguration<'a> {
pub http_configuration: Configuration,
pub client_verify_cert: Option<&'a str>,
pub cacert: Option<&'a str>,
pub prvtkey: Option<&'a str>,
pub transport_mode_secure: bool,
pub session_tickets: bool,
}

impl<'a> From<&SslConfiguration<'a>> for Newtype<httpd_config_t> {
fn from(conf: &SslConfiguration<'a>) -> Self {
Self::from(&conf.http_configuration)
}
}

impl<'a> From<&SslConfiguration<'a>> for CHttpsSslConfig {
fn from(conf: &SslConfiguration) -> Self {
let client_verify_cert = conf.client_verify_cert.map(to_ptr_with_len).unwrap_or((ptr::null_mut(), 0));
let cacert = conf.cacert.map(to_ptr_with_len).unwrap_or((ptr::null_mut(), 0));
let pkey = conf.prvtkey.map(to_ptr_with_len).unwrap_or((ptr::null_mut(), 0));

Self(httpd_ssl_config_t {
httpd: httpd_config_t {
..Newtype::<httpd_config_t>::from(conf).0
},
client_verify_cert_pem: client_verify_cert.0 as _,
client_verify_cert_len: client_verify_cert.1 as _,
cacert_pem: cacert.0 as _,
cacert_len: cacert.1 as _,
prvtkey_pem: pkey.0 as _,
prvtkey_len: pkey.1 as _,
transport_mode: httpd_ssl_transport_mode_t_HTTPD_SSL_TRANSPORT_SECURE,
port_secure: conf.http_configuration.https_port,
port_insecure: conf.http_configuration.http_port,
session_tickets: conf.session_tickets,
user_cb: None
})
}
}

impl<'a> Default for SslConfiguration<'a> {
fn default() -> Self {
SslConfiguration {
http_configuration: Default::default(),
client_verify_cert: None,
cacert: None,
prvtkey: None,
transport_mode_secure: true,
session_tickets: false
}
}
}

impl Drop for CHttpsSslConfig {
fn drop(&mut self) {
unsafe {
if !self.0.client_verify_cert_pem.is_null() {
drop(CString::from_raw(self.0.client_verify_cert_pem as _));
}

if !self.0.cacert_pem.is_null() {
drop(CString::from_raw(self.0.cacert_pem as _));
}

if !self.0.prvtkey_pem.is_null() {
drop(CString::from_raw(self.0.prvtkey_pem as _));
}
}
}
}

#[allow(non_upper_case_globals)]
impl From<Newtype<c_types::c_uint>> for Method {
fn from(method: Newtype<c_types::c_uint>) -> Self {
Expand Down Expand Up @@ -182,7 +259,9 @@ pub struct EspHttpServer {
}

impl EspHttpServer {
pub fn new(conf: &Configuration) -> Result<Self, EspIOError> {
pub fn new<T: Into<Newtype<httpd_config_t>> + Debug>(conf: T) -> Result<Self, EspIOError> {
info!("Starting Httpd server with config {:?}", conf);

let mut config: Newtype<httpd_config_t> = conf.into();
config.0.close_fn = Some(Self::close_fn);

Expand All @@ -191,18 +270,43 @@ impl EspHttpServer {

esp!(unsafe { httpd_start(handle_ref, &config.0 as *const _) })?;

info!("Started Httpd server with config {:?}", conf);
info!("Started Httpd server");

unsafe {
CLOSE_HANDLERS.lock().insert(handle as _, Vec::new());
}

let server = EspHttpServer {
Ok(EspHttpServer {
sd: handle,
registrations: Vec::new(),
};
})
}

pub fn new_https<T: Into<CHttpsSslConfig>>(conf: T) -> Result<Self, EspIOError>
{
let mut config: CHttpsSslConfig = conf.into();

config.0.httpd.close_fn = Some(Self::close_fn);

let mut handle: httpd_handle_t = ptr::null_mut();

info!("httpd_ssl_start {:?}", config);

esp!(unsafe { httpd_ssl_start(&mut handle, &mut config.0) })?;

info!("httpd_ssl_started");

unsafe {
CLOSE_HANDLERS.lock().insert(server.sd as _, Vec::new());
CLOSE_HANDLERS.lock().insert(handle as _, Vec::new());
}

Ok(server)
info!("handle");


Ok(EspHttpServer {
sd: handle,
registrations: Vec::new(),
})
}

fn unregister(&mut self, uri: CString, conf: httpd_uri_t) -> Result<(), EspIOError> {
Expand Down
8 changes: 8 additions & 0 deletions src/private/cstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ pub fn from_cstr(buf: &[u8]) -> &str {
.unwrap()
}

//Since we are using .into_raw(), we are leaking the buffer!
//Make sure to call drop(CString::from_raw()) at some point!
pub fn to_ptr_with_len(s: &str) -> (*mut c_types::c_char, usize) {
let s = CString::new(s).expect("String must not contain NUL bytes!");
let len = s.as_bytes_with_nul().len();
(s.into_raw(), len)
}

#[cfg(feature = "alloc")]
pub struct RawCstrs(alloc::vec::Vec<CString>);

Expand Down

0 comments on commit ae40df3

Please sign in to comment.