Skip to content

Commit

Permalink
Partial header and timeout implementaton.. (#19)
Browse files Browse the repository at this point in the history
* Partial header impl

* Minor fixup

* Update grip.inc

* Some more work on testing
  • Loading branch information
Alik Aslanyan authored Jan 17, 2019
1 parent ae2ef38 commit e96c3a6
Show file tree
Hide file tree
Showing 9 changed files with 446 additions and 187 deletions.
8 changes: 7 additions & 1 deletion cpp/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extern "C" {
cell grip_destroy_body(const void* amx, cell body);

typedef void (*GripHandler)(cell, cell, cell);
cell grip_request(const void* amx, cell forward_id, const char *uri, cell body_handle, cell request_type, GripHandler handler, cell user_data);
cell grip_request(const void* amx, cell forward_id, const char *uri, cell body_handle, cell request_type, GripHandler handler, cell options_handle, cell user_data);

cell grip_cancel_request(const void* amx, cell cancellation_id);
cell grip_get_response_state(const void* amx);
Expand All @@ -30,5 +30,11 @@ extern "C" {
cell grip_parse_response_body_as_json(const void* amx, char *error_buffer, cell error_buffer_size);

cell grip_destroy_json_value(const void* amx, cell json_value);

cell grip_create_default_options(const void *amx, double timeout);

cell grip_destroy_options(const void* amx, cell options_handle);

cell grip_options_add_header(const void* amx, cell options_handle, const char* header_name, const char* header_value);
}
#endif //RESTRY_FFI_H
29 changes: 25 additions & 4 deletions cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ cell AMX_NATIVE_CALL grip_request_amxx(AMX *amx, cell *params) {
return 0;
}

cell options = params[arg_options]; // TODO: Handle options.

return grip_request(amx, handler_forward, uri, params[arg_body_handle], params[arg_type], request_handler, params[arg_user_data]);
return grip_request(amx, handler_forward, uri, params[arg_body_handle], params[arg_type], request_handler, params[arg_options], params[arg_user_data]);
}

cell AMX_NATIVE_CALL grip_cancel_request_amxx(AMX *amx, cell *params) {
Expand Down Expand Up @@ -138,8 +136,28 @@ cell AMX_NATIVE_CALL grip_destroy_json_value_amxx(AMX *amx, cell *params) {
return grip_destroy_json_value(amx, params[arg_json_value]);
}

cell AMX_NATIVE_CALL grip_create_default_options_amxx(AMX *amx, cell *params) {
enum { arg_count, arg_timeout};

return grip_create_default_options(amx, amx_ctof(params[arg_timeout]));
}

cell AMX_NATIVE_CALL grip_destroy_options_amxx(AMX *amx, cell *params) {
enum { arg_count, arg_options_handle};

return grip_destroy_options(amx, params[arg_options_handle]);
}

cell AMX_NATIVE_CALL grip_options_add_header_amxx(AMX *amx, cell *params) {
enum { arg_count, arg_options_handle, arg_header_name, arg_header_value};

return grip_options_add_header(amx, params[arg_options_handle],
MF_GetAmxString(amx, params[arg_header_name], 0, &dummy),
MF_GetAmxString(amx, params[arg_header_name], 1, &dummy));
}

AMX_NATIVE_INFO grip_exports[] = {
{"grip_request", grip_request_amxx},
{"grip_request", grip_request_amxx},
{"grip_destroy_body", grip_destroy_body_amxx},
{"grip_body_from_string", grip_body_from_string_amxx},
{"grip_cancel_request", grip_cancel_request_amxx},
Expand All @@ -149,6 +167,9 @@ AMX_NATIVE_INFO grip_exports[] = {
{"grip_get_response_body_string", grip_get_response_body_string_amxx},
{"grip_parse_response_body_as_json", grip_parse_response_body_as_json_amxx},
{"grip_destroy_json_value", grip_destroy_json_value_amxx},
{"grip_create_default_options", grip_create_default_options_amxx},
{"grip_destroy_options", grip_destroy_options_amxx},
{"grip_options_add_header", grip_options_add_header_amxx},
{nullptr, nullptr}
};

Expand Down
16 changes: 16 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ rust-ini = "0.13.0"
clone_all = "0.1.1"
either = "1.5.0"
lazy_static = "1.2.0"
serde_json = "1.0.35"
serde_json = "1.0.35"
float-cmp = "0.4.0"
135 changes: 111 additions & 24 deletions rust/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::errors::*;
type Cell = isize;

static INVALID_CELL: Cell = 0;
use crate::networking_queue::{Queue, RequestBuilder, RequestCancellation, RequestType, Response};
use crate::networking_queue::{
Queue, RequestBuilder, RequestCancellation, RequestOptions, RequestType, Response,
};
use std::prelude::v1::Vec;

use crate::cell_map::CellMap;
Expand All @@ -28,6 +30,7 @@ struct ModuleStorage {
pub bodies_handles: CellMap<Vec<u8>>,
pub cancellations_handles: CellMap<RequestCancellation>,
pub json_handles: CellMap<serde_json::Value>,
pub options_handles: CellMap<RequestOptions>,
pub error_logger: extern "C" fn(*const c_void, *const c_char),
pub callbacks_per_frame: usize,
pub microseconds_delay_between_attempts: usize,
Expand All @@ -40,19 +43,15 @@ pub unsafe extern "C" fn grip_init(
error_logger: extern "C" fn(*const c_void, *const c_char),
config_file_path: *const c_char,
) {
let ini = Ini::load_from_file(
CStr::from_ptr(config_file_path as *const i8)
.to_str()
.unwrap(),
)
.map_err(|e| {
println!(
"Error: Can't parse/open grip config. Examine carefully ini parser log message\n{}",
let ini = Ini::load_from_file(CStr::from_ptr(config_file_path).to_str().unwrap())
.map_err(|e| {
println!(
"Error: Can't parse/open grip config. Examine carefully ini parser log message\n{}",
e
);
e
);
e
})
.unwrap();
})
.unwrap();

let dns_section = ini
.section(Some("dns".to_owned()))
Expand Down Expand Up @@ -88,6 +87,7 @@ pub unsafe extern "C" fn grip_init(
current_response: None,
bodies_handles: CellMap::new(),
json_handles: CellMap::new(),
options_handles: CellMap::new(),
error_logger,
callbacks_per_frame: {
queue_section
Expand Down Expand Up @@ -166,6 +166,7 @@ pub unsafe extern "C" fn grip_request(
body_handle: Cell,
request_type: Cell,
handler: Option<extern "C" fn(forward_handle: Cell, user_data: Cell) -> c_void>,
options_handle: Cell,
user_data: Cell,
) -> Cell {
let request_type = try_and_log_ffi!(
Expand Down Expand Up @@ -205,8 +206,24 @@ pub unsafe extern "C" fn grip_request(
.chain_err(|| ffi_error(format!("Invalid body handle: {}", body_handle)))
);

// TODO: Get body in the AMXX.
// TODO: grip_get_error_description etc
let options = try_and_log_ffi!(
amx,
get_module()
.options_handles
.get_with_id(options_handle)
.or_else(|| if options_handle == -1 {
lazy_static! {
static ref empty_options: RequestOptions =
RequestOptions::new(hyper::HeaderMap::new(), None);
}
Some(&empty_options)
} else {
None
})
.chain_err(|| ffi_error(format!("Invalid options handle: {}", options_handle)))
);

// TODO: JSON, Headers, Timeout.

let next_cancellation_id = get_module().cancellations_handles.peek_id();
let cancellation = get_module_mut().global_queue.send_request(
Expand All @@ -218,6 +235,7 @@ pub unsafe extern "C" fn grip_request(
uri.parse()
.chain_err(|| ffi_error(format!("URI parsing error: {}", uri)))
))
.options(options.clone())
.build()
.unwrap(),
move |response| {
Expand Down Expand Up @@ -399,11 +417,7 @@ pub unsafe extern "C" fn grip_parse_response_body_as_json(
use error_chain::ChainedError;
libc::strncpy(
error_buffer,
format!(
"{}\0",
error.display_chain()
)
.as_ptr() as *const c_char,
format!("{}\0", error.display_chain()).as_ptr() as *const c_char,
try_and_log_ffi!(
amx,
if error_buffer_size >= 0 {
Expand All @@ -427,10 +441,7 @@ pub unsafe extern "C" fn grip_parse_response_body_as_json(
}

#[no_mangle]
pub unsafe extern "C" fn grip_destroy_json_value(
amx: *const c_void,
json_value: Cell
) -> Cell {
pub unsafe extern "C" fn grip_destroy_json_value(amx: *const c_void, json_value: Cell) -> Cell {
try_and_log_ffi!(
amx,
get_module_mut()
Expand All @@ -442,6 +453,82 @@ pub unsafe extern "C" fn grip_destroy_json_value(
1
}

#[no_mangle]
pub unsafe extern "C" fn grip_create_default_options(amx: *const c_void, timeout: f64) -> Cell {
use float_cmp::ApproxEq;

get_module_mut()
.options_handles
.insert_with_unique_id(RequestOptions::new(
hyper::HeaderMap::default(),
try_and_log_ffi!(
amx,
if timeout.approx_eq(&-1.0, std::f64::EPSILON, 2) {
Ok(None)
} else if timeout >= 0.0 {
Ok(Some(std::time::Duration::from_millis(
(timeout * 1000.0) as u64,
)))
} else {
Err(ffi_error(format!("Invalid timeout: {}", timeout)))
}
),
))
}

#[no_mangle]
pub unsafe extern "C" fn grip_destroy_options(amx: *const c_void, options_handle: Cell) -> Cell {
try_and_log_ffi!(
amx,
get_module_mut()
.options_handles
.remove_with_id(options_handle)
.chain_err(|| ffi_error(format!("Invalid options handle {}", options_handle)))
);

1
}

#[no_mangle]
pub unsafe extern "C" fn grip_options_add_header(
amx: *const c_void,
options_handle: Cell,
header_name: *const c_char,
header_value: *const c_char,
) -> Cell {
let option = try_and_log_ffi!(
amx,
get_module_mut()
.options_handles
.get_mut_with_id(options_handle)
.chain_err(|| ffi_error(format!("Invalid options handle: {}", options_handle))),
);

let header_name = try_and_log_ffi!(
amx,
CStr::from_ptr(header_name)
.to_str()
.chain_err(|| ffi_error("Invalid header name. Can't create UTF-8 string"))
);

let header_value = try_and_log_ffi!(
amx,
CStr::from_ptr(header_value)
.to_str()
.chain_err(|| ffi_error("Invalid header value. Can't create UTF-8 string"))
);

let header_value = try_and_log_ffi!(
amx,
hyper::header::HeaderValue::from_str(header_value)
.chain_err(|| ffi_error(format!("Header value contains invalid byte sequences or was rejected by Hyper HTTP implementation: {}", header_value)))
);

option.headers.insert(header_name, header_value);

1
}

#[no_mangle]
pub unsafe extern "C" fn grip_process_request() {
let multiplier = std::cmp::min(
Expand Down
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ extern crate lazy_static;

extern crate serde_json;

extern crate float_cmp;

mod errors {
error_chain! {
errors {
Expand Down
11 changes: 11 additions & 0 deletions rust/src/networking_queue/ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pub trait RequestExt {
fn extend_headers(self, headers: hyper::HeaderMap) -> Self;
}

impl<T> RequestExt for hyper::Request<T> {
fn extend_headers(mut self, headers: hyper::HeaderMap) -> Self {
self.headers_mut().extend(headers);

self
}
}
Loading

0 comments on commit e96c3a6

Please sign in to comment.