pub mod models;
pub mod errors;
pub mod cookies;
pub mod hsts;
pub mod responses;
pub mod finalizer;
pub mod websocket;
pub mod tls;
pub mod api {
pub mod common;
pub mod client;
pub mod server;
pub mod gate;
pub mod cluster;
}
pub mod protocol {
pub mod common;
pub mod quic;
pub mod h1;
pub mod h2;
pub mod h3;
}
pub mod helpers {
pub mod base64;
pub mod scan;
pub mod text;
pub mod sha1;
pub mod sync;
pub mod huffman;
pub mod fields;
pub mod hpack;
pub mod qpack;
pub mod compression;
}
pub use errors::Status;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Slice {
pub data: *const u8,
pub len: usize,
}
impl Slice {
pub const ABSENT: Self = Self { data: std::ptr::null(), len: 0 };
pub fn new(octets: &[u8]) -> Self {
Self { data: octets.as_ptr(), len: octets.len() }
}
pub fn text(text: &str) -> Self {
Self::new(text.as_bytes())
}
pub fn maybe(text: Option<&str>) -> Self {
match text {
Some(text) => Self::text(text),
None => Self::ABSENT,
}
}
pub fn is_absent(&self) -> bool {
self.data.is_null()
}
pub unsafe fn borrow<'a>(data: *const u8, len: usize) -> Option<&'a [u8]> {
if data.is_null() {
return None;
}
Some(unsafe { std::slice::from_raw_parts(data, len) })
}
pub unsafe fn borrow_text<'a>(data: *const u8, len: usize) -> Option<&'a str> {
std::str::from_utf8(unsafe { Self::borrow(data, len) }?).ok()
}
}
#[repr(C)]
pub struct Buffer {
pub data: *mut u8,
pub len: usize,
pub capacity: usize,
}
impl Buffer {
pub const EMPTY: Self = Self { data: std::ptr::null_mut(), len: 0, capacity: 0 };
pub fn new(octets: Vec<u8>) -> Self {
if octets.is_empty() {
return Self::EMPTY;
}
let mut octets = std::mem::ManuallyDrop::new(octets);
Self { data: octets.as_mut_ptr(), len: octets.len(), capacity: octets.capacity() }
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_buffer_free(buffer: Buffer) {
if !buffer.data.is_null() {
drop(unsafe { Vec::from_raw_parts(buffer.data, buffer.len, buffer.capacity) });
}
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_version() -> Slice {
Slice::text(env!("CARGO_PKG_VERSION"))
}
pub struct SendPtr<T: ?Sized>(pub *mut T);
unsafe impl<T: ?Sized> Send for SendPtr<T> {}
pub struct Runtime(pub tokio::runtime::Runtime);
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_runtime_new(workers: u32) -> *mut Runtime {
let mut builder = tokio::runtime::Builder::new_multi_thread();
builder.enable_all();
if workers > 0 {
builder.worker_threads(workers as usize);
}
match builder.build() {
Ok(runtime) => Box::into_raw(Box::new(Runtime(runtime))),
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_runtime_free(runtime: *mut Runtime) {
if !runtime.is_null() {
drop(unsafe { Box::from_raw(runtime) });
}
}