summaryrefslogtreecommitdiff
path: root/rust/tests
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-09-27 17:39:19 -0400
committerMason Reed <mason@vector35.com>2025-10-22 00:36:24 -0400
commit31ec051fd683d3747f10a0981b497d90f08d25a3 (patch)
tree039f28498656a427297406d90955766981bc0b06 /rust/tests
parent058800a116bf25f1f215b758663366d4695f0e31 (diff)
[Rust] Refactor download provider module to allow for custom implementations
Diffstat (limited to 'rust/tests')
-rw-r--r--rust/tests/download.rs135
-rw-r--r--rust/tests/download_provider.rs34
2 files changed, 135 insertions, 34 deletions
diff --git a/rust/tests/download.rs b/rust/tests/download.rs
new file mode 100644
index 00000000..69bf0f30
--- /dev/null
+++ b/rust/tests/download.rs
@@ -0,0 +1,135 @@
+use binaryninja::download::{
+ register_download_provider, CustomDownloadInstance, CustomDownloadProvider, DownloadInstance,
+ DownloadInstanceInputOutputCallbacks, DownloadInstanceOutputCallbacks, DownloadProvider,
+ DownloadResponse,
+};
+use binaryninja::headless::Session;
+use binaryninja::rc::Ref;
+use std::collections::HashMap;
+use std::sync::mpsc;
+
+#[test]
+fn test_download_provider() {
+ let _session = Session::new().expect("Failed to initialize session");
+ let provider = DownloadProvider::try_default().expect("Couldn't get default download provider");
+ let mut inst = provider
+ .create_instance()
+ .expect("Couldn't create download instance");
+ let (tx, rx) = mpsc::channel();
+ let write = move |data: &[u8]| -> usize {
+ tx.send(data.to_vec()).expect("Couldn't send data");
+ data.len()
+ };
+ let result = inst
+ .perform_custom_request(
+ "GET",
+ "http://httpbin.org/get",
+ vec![],
+ &DownloadInstanceInputOutputCallbacks {
+ read: None,
+ write: Some(Box::new(write)),
+ progress: None,
+ },
+ )
+ .expect("Couldn't perform custom request");
+ assert_eq!(result.status_code, 200);
+ let written = rx.recv().expect("Couldn't receive data");
+ let written_str = String::from_utf8(written).expect("Couldn't convert data to string");
+ println!("{}", written_str);
+ assert!(written_str.contains("httpbin.org/get"));
+}
+
+struct MyDownloadProvider {
+ core: DownloadProvider,
+}
+
+impl CustomDownloadProvider for MyDownloadProvider {
+ type Instance = MyDownloadInstance;
+
+ fn handle(&self) -> DownloadProvider {
+ self.core
+ }
+
+ fn from_core(core: DownloadProvider) -> Self {
+ Self { core }
+ }
+}
+
+struct MyDownloadInstance {
+ core: Ref<DownloadInstance>,
+}
+
+impl CustomDownloadInstance for MyDownloadInstance {
+ fn from_core(core: Ref<DownloadInstance>) -> Self {
+ Self { core }
+ }
+
+ fn handle(&self) -> Ref<DownloadInstance> {
+ self.core.clone()
+ }
+
+ fn perform_custom_request<I>(
+ &self,
+ method: &str,
+ url: &str,
+ headers: I,
+ ) -> Result<DownloadResponse, String>
+ where
+ I: IntoIterator<Item = (String, String)>,
+ {
+ assert_eq!(method, "GET");
+ assert_eq!(url, "test");
+ let headers: HashMap<_, _> = headers.into_iter().collect();
+ assert_eq!("value", headers.get("test").unwrap_or(&"value".to_string()));
+
+ // Inform the caller of progress and write some data.
+ self.core.write_callback(b"Hello World!");
+
+ Ok(DownloadResponse {
+ status_code: 200,
+ headers: {
+ let mut h = HashMap::new();
+ h.insert("test".to_string(), "value".to_string());
+ h
+ },
+ })
+ }
+}
+
+#[test]
+fn test_custom_download_provider() {
+ let _session = Session::new().expect("Failed to initialize session");
+ let custom_provider = register_download_provider::<MyDownloadProvider>("RustDownloadProvider");
+ let mut instance = custom_provider
+ .create_instance()
+ .expect("Couldn't create download instance");
+
+ let write_cb = move |data: &[u8]| -> usize {
+ assert_eq!(data, b"Hello World!");
+ data.len()
+ };
+ let callbacks = DownloadInstanceOutputCallbacks {
+ write: Some(Box::new(write_cb)),
+ progress: None,
+ };
+
+ instance
+ .perform_request("test", &callbacks)
+ .expect("Couldn't perform request");
+
+ let read_cb = move |data: &mut [u8]| -> Option<usize> { None };
+ let custom_callbacks = DownloadInstanceInputOutputCallbacks {
+ read: Some(Box::new(read_cb)),
+ write: Some(Box::new(write_cb)),
+ progress: None,
+ };
+
+ instance
+ .perform_custom_request(
+ "GET",
+ "test",
+ [("test".to_string(), "value".to_string())],
+ &custom_callbacks,
+ )
+ .expect("Couldn't perform custom request");
+}
diff --git a/rust/tests/download_provider.rs b/rust/tests/download_provider.rs
deleted file mode 100644
index f3b62263..00000000
--- a/rust/tests/download_provider.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use binaryninja::download_provider::{DownloadInstanceInputOutputCallbacks, DownloadProvider};
-use binaryninja::headless::Session;
-use std::sync::mpsc;
-
-#[test]
-fn test_download_provider() {
- let _session = Session::new().expect("Failed to initialize session");
- let provider = DownloadProvider::try_default().expect("Couldn't get default download provider");
- let mut inst = provider
- .create_instance()
- .expect("Couldn't create download instance");
- let (tx, rx) = mpsc::channel();
- let write = move |data: &[u8]| -> usize {
- tx.send(data.to_vec()).expect("Couldn't send data");
- data.len()
- };
- let result = inst
- .perform_custom_request(
- "GET",
- "http://httpbin.org/get",
- vec![],
- &DownloadInstanceInputOutputCallbacks {
- read: None,
- write: Some(Box::new(write)),
- progress: None,
- },
- )
- .expect("Couldn't perform custom request");
- assert_eq!(result.status_code, 200);
- let written = rx.recv().expect("Couldn't receive data");
- let written_str = String::from_utf8(written).expect("Couldn't convert data to string");
- println!("{}", written_str);
- assert!(written_str.contains("httpbin.org/get"));
-}