-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d35a40a
commit 8753a87
Showing
11 changed files
with
369 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
/target | ||
/Cargo.lock | ||
target | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "hyper-capi" | ||
version = "0.0.0" | ||
description = "A fast and correct HTTP library." | ||
readme = "README.md" | ||
homepage = "https://hyper.rs" | ||
documentation = "https://github.com/hyperium/hyper/tree/master/hyper-capi" | ||
repository = "https://github.com/hyperium/hyper" | ||
license = "MIT" | ||
authors = ["Sean McArthur <sean@seanmonstar.com>"] | ||
edition = "2018" | ||
|
||
publish = false | ||
|
||
[lib] | ||
name = "hyper_c" | ||
crate-type = ["staticlib", "cdylib"] | ||
|
||
[dependencies] | ||
libc = "0.2" | ||
hyper = { version = "0.13", path = "..", default-features = false } | ||
tokio = "0.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use crate::hyper_str; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use hyper::client::conn; | ||
use hyper::{Body, Request}; | ||
|
||
use crate::io::Io; | ||
use crate::task::Task; | ||
|
||
pub struct Options { | ||
builder: conn::Builder, | ||
} | ||
|
||
pub struct ClientConn { | ||
tx: conn::SendRequest<hyper::Body>, | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_clientconn_handshake(io: *mut Io, options: *mut Options) -> *mut Task { | ||
let options = unsafe { Box::from_raw(options) }; | ||
let io = unsafe { Box::from_raw(io) }; | ||
|
||
Box::into_raw(Task::boxed(options.builder.handshake::<_, hyper::Body>(io))) | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_clientconn_send(conn: *mut ClientConn, req: *mut Request<Body>) -> *mut Task { | ||
let req = unsafe { Box::from_raw(req) }; | ||
let fut = unsafe { &mut *conn }.tx.send_request(*req); | ||
|
||
Box::into_raw(Task::boxed(fut)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use hyper::{Body, HeaderMap, Method, Request, Response, Uri}; | ||
use libc::size_t; | ||
use std::ffi::c_void; | ||
|
||
use crate::{hyper_error, hyper_str}; | ||
|
||
// ===== impl Request ===== | ||
|
||
ffi_fn! { | ||
fn hyper_request_new() -> *mut Request<Body> { | ||
Box::into_raw(Box::new(Request::new(Body::empty()))) | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_request_free(req: *mut Request<Body>) { | ||
drop(unsafe { Box::from_raw(req) }); | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_request_set_method(req: *mut Request<Body>, method: *const u8, method_len: size_t) -> hyper_error { | ||
let bytes = unsafe { | ||
std::slice::from_raw_parts(method, method_len as usize) | ||
}; | ||
match Method::from_bytes(bytes) { | ||
Ok(m) => { | ||
*unsafe { &mut *req }.method_mut() = m; | ||
hyper_error::Ok | ||
}, | ||
Err(_) => { | ||
hyper_error::Kaboom | ||
} | ||
} | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_request_set_uri(req: *mut Request<Body>, uri: *const u8, uri_len: size_t) -> hyper_error { | ||
let bytes = unsafe { | ||
std::slice::from_raw_parts(uri, uri_len as usize) | ||
}; | ||
match Uri::from_maybe_shared(bytes) { | ||
Ok(u) => { | ||
*unsafe { &mut *req }.uri_mut() = u; | ||
hyper_error::Ok | ||
}, | ||
Err(_) => { | ||
hyper_error::Kaboom | ||
} | ||
} | ||
} | ||
} | ||
|
||
// ===== impl Response ===== | ||
|
||
ffi_fn! { | ||
fn hyper_response_free(resp: *mut Response<Body>) { | ||
drop(unsafe { Box::from_raw(resp) }); | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_response_status(resp: *const Response<Body>) -> u16 { | ||
unsafe { &*resp }.status().as_u16() | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_response_headers(resp: *mut Response<Body>) -> *mut HeaderMap { | ||
unsafe { &mut *resp }.headers_mut() | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_response_body(resp: *mut Response<Body>) -> *mut Body { | ||
unsafe { &mut *resp }.body_mut() | ||
} | ||
} | ||
|
||
// ===== impl Headers ===== | ||
|
||
#[repr(C)] | ||
#[derive(PartialEq)] | ||
pub enum IterStep { | ||
Continue = 0, | ||
#[allow(unused)] | ||
Break, | ||
} | ||
|
||
type IterFn = extern "C" fn(*mut c_void, hyper_str, hyper_str) -> IterStep; | ||
|
||
ffi_fn! { | ||
fn hyper_headers_iter(headers: *const HeaderMap, func: IterFn, userdata: *mut c_void) { | ||
for (name, value) in unsafe { &*headers }.iter() { | ||
let raw_name = hyper_str { | ||
buf: name.as_str().as_bytes().as_ptr(), | ||
len: name.as_str().as_bytes().len(), | ||
}; | ||
let raw_val = hyper_str { | ||
buf: value.as_bytes().as_ptr(), | ||
len: value.as_bytes().len(), | ||
}; | ||
|
||
if IterStep::Continue != func(userdata, raw_name, raw_val) { | ||
break; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use std::pin::Pin; | ||
use std::task::{Context, Poll}; | ||
|
||
use libc::size_t; | ||
use tokio::io::{AsyncRead, AsyncWrite}; | ||
|
||
use crate::task::hyper_waker; | ||
|
||
type ReadFn = extern "C" fn(*mut (), *const hyper_waker, *mut u8, size_t) -> size_t; | ||
type WriteFn = extern "C" fn(*mut (), *const hyper_waker, *const u8, size_t) -> size_t; | ||
|
||
/// `typedef struct hyper_io hyper_io` | ||
pub struct Io { | ||
read: ReadFn, | ||
write: WriteFn, | ||
userdata: *mut (), | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_io_new() -> *mut Io { | ||
Box::into_raw(Box::new(Io { | ||
read: read_noop, | ||
write: write_noop, | ||
userdata: std::ptr::null_mut(), | ||
})) | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_io_set_data(io: *mut Io, data: *mut ()) { | ||
unsafe { &mut *io }.userdata = data; | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_io_set_read(io: *mut Io, func: ReadFn) { | ||
unsafe { &mut *io }.read = func; | ||
} | ||
} | ||
|
||
ffi_fn! { | ||
fn hyper_io_set_write(io: *mut Io, func: WriteFn) { | ||
unsafe { &mut *io }.write = func; | ||
} | ||
} | ||
|
||
extern "C" fn read_noop( | ||
_userdata: *mut (), | ||
_: *const hyper_waker, | ||
_buf: *mut u8, | ||
_buf_len: size_t, | ||
) -> size_t { | ||
0 | ||
} | ||
|
||
extern "C" fn write_noop( | ||
_userdata: *mut (), | ||
_: *const hyper_waker, | ||
_buf: *const u8, | ||
_buf_len: size_t, | ||
) -> size_t { | ||
0 | ||
} | ||
|
||
impl AsyncRead for Io { | ||
fn poll_read( | ||
self: Pin<&mut Self>, | ||
_: &mut Context<'_>, | ||
_buf: &mut [u8], | ||
) -> Poll<std::io::Result<usize>> { | ||
todo!("poll_read"); | ||
} | ||
} | ||
|
||
impl AsyncWrite for Io { | ||
fn poll_write( | ||
self: Pin<&mut Self>, | ||
_: &mut Context<'_>, | ||
_buf: &[u8], | ||
) -> Poll<std::io::Result<usize>> { | ||
todo!("poll_write"); | ||
} | ||
|
||
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<std::io::Result<()>> { | ||
Poll::Ready(Ok(())) | ||
} | ||
|
||
fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<std::io::Result<()>> { | ||
Poll::Ready(Ok(())) | ||
} | ||
} | ||
|
||
unsafe impl Send for Io {} | ||
unsafe impl Sync for Io {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#[macro_use] | ||
mod macros; | ||
|
||
mod body; | ||
mod client; | ||
mod http_types; | ||
mod io; | ||
mod task; | ||
|
||
#[repr(C)] | ||
pub struct hyper_str { | ||
pub buf: *const u8, | ||
pub len: libc::size_t, | ||
} | ||
|
||
#[repr(C)] | ||
pub enum hyper_error { | ||
Ok = 0, | ||
Kaboom = 1, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
macro_rules! ffi_fn { | ||
(fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block) => { | ||
#[no_mangle] | ||
pub extern fn $name($($arg: $arg_ty),*) -> $ret { | ||
use std::panic::{self, AssertUnwindSafe}; | ||
|
||
match panic::catch_unwind(AssertUnwindSafe(move || $body)) { | ||
Ok(v) => v, | ||
Err(_) => todo!("FFI UNWIND"), | ||
} | ||
} | ||
}; | ||
|
||
(fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block) => { | ||
ffi_fn!(fn $name($($arg: $arg_ty),*) -> () $body); | ||
}; | ||
} |
Oops, something went wrong.