mirror of
				https://github.com/TeamPiped/reqwest4j.git
				synced 2024-08-14 23:54:39 +00:00 
			
		
		
		
	
						commit
						41073ce8d5
					
				
					 3 changed files with 84 additions and 37 deletions
				
			
		| 
						 | 
					@ -8,4 +8,5 @@ rust {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    targets += target("aarch64-unknown-linux-gnu", "libreqwest.so")
 | 
					    targets += target("aarch64-unknown-linux-gnu", "libreqwest.so")
 | 
				
			||||||
    targets += target("x86_64-unknown-linux-gnu", "libreqwest.so")
 | 
					    targets += target("x86_64-unknown-linux-gnu", "libreqwest.so")
 | 
				
			||||||
 | 
					    targets += target("x86_64-pc-windows-gnu", "libreqwest.dll")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,9 @@
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::sync::OnceLock;
 | 
					use std::sync::OnceLock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use jni::JNIEnv;
 | 
					 | 
				
			||||||
use jni::objects::{JByteArray, JClass, JMap, JObject, JString};
 | 
					use jni::objects::{JByteArray, JClass, JMap, JObject, JString};
 | 
				
			||||||
use jni::sys::jobject;
 | 
					use jni::sys::jobject;
 | 
				
			||||||
 | 
					use jni::JNIEnv;
 | 
				
			||||||
use once_cell::sync::Lazy;
 | 
					use once_cell::sync::Lazy;
 | 
				
			||||||
use reqwest::{Client, Method, Url};
 | 
					use reqwest::{Client, Method, Url};
 | 
				
			||||||
use tokio::runtime::Runtime;
 | 
					use tokio::runtime::Runtime;
 | 
				
			||||||
| 
						 | 
					@ -26,13 +26,10 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_init(
 | 
				
			||||||
            let proxy = reqwest::Proxy::all(proxy).unwrap();
 | 
					            let proxy = reqwest::Proxy::all(proxy).unwrap();
 | 
				
			||||||
            builder.proxy(proxy)
 | 
					            builder.proxy(proxy)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Err(_) => {
 | 
					        Err(_) => builder,
 | 
				
			||||||
            builder
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let client = builder.build()
 | 
					    let client = builder.build().unwrap();
 | 
				
			||||||
        .unwrap();
 | 
					 | 
				
			||||||
    CLIENT.set(client).unwrap();
 | 
					    CLIENT.set(client).unwrap();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +42,6 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
    body: JByteArray,
 | 
					    body: JByteArray,
 | 
				
			||||||
    headers: JObject,
 | 
					    headers: JObject,
 | 
				
			||||||
) -> jobject {
 | 
					) -> jobject {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // set method, url, body, headers
 | 
					    // set method, url, body, headers
 | 
				
			||||||
    let method = Method::from_bytes(env.get_string(&method).unwrap().to_bytes()).unwrap();
 | 
					    let method = Method::from_bytes(env.get_string(&method).unwrap().to_bytes()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,7 +49,11 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
    let url = url.to_str();
 | 
					    let url = url.to_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if url.is_err() {
 | 
					    if url.is_err() {
 | 
				
			||||||
        env.throw_new("java/lang/IllegalArgumentException", "Invalid URL provided, couldn't get string as UTF-8").unwrap();
 | 
					        env.throw_new(
 | 
				
			||||||
 | 
					            "java/lang/IllegalArgumentException",
 | 
				
			||||||
 | 
					            "Invalid URL provided, couldn't get string as UTF-8",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
        return JObject::null().into_raw();
 | 
					        return JObject::null().into_raw();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,15 +64,24 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
    let mut headers = HashMap::new();
 | 
					    let mut headers = HashMap::new();
 | 
				
			||||||
    while let Some((key, value)) = java_headers.next(&mut env).unwrap() {
 | 
					    while let Some((key, value)) = java_headers.next(&mut env).unwrap() {
 | 
				
			||||||
        headers.insert(
 | 
					        headers.insert(
 | 
				
			||||||
            env.get_string(&JString::from(key)).unwrap().to_str().unwrap().to_string(),
 | 
					            env.get_string(&JString::from(key))
 | 
				
			||||||
            env.get_string(&JString::from(value)).unwrap().to_str().unwrap().to_string(),
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .to_str()
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .to_string(),
 | 
				
			||||||
 | 
					            env.get_string(&JString::from(value))
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .to_str()
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .to_string(),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let client = CLIENT.get();
 | 
					    let client = CLIENT.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if client.is_none() {
 | 
					    if client.is_none() {
 | 
				
			||||||
        env.throw_new("java/lang/IllegalStateException", "Client not initialized").unwrap();
 | 
					        env.throw_new("java/lang/IllegalStateException", "Client not initialized")
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
        return JObject::null().into_raw();
 | 
					        return JObject::null().into_raw();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,9 +89,9 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let request = client.request(method, url);
 | 
					    let request = client.request(method, url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let request = headers.into_iter().fold(request, |request, (key, value)| {
 | 
					    let request = headers
 | 
				
			||||||
        request.header(key, value)
 | 
					        .into_iter()
 | 
				
			||||||
    });
 | 
					        .fold(request, |request, (key, value)| request.header(key, value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let request = if body.is_empty() {
 | 
					    let request = if body.is_empty() {
 | 
				
			||||||
        request
 | 
					        request
 | 
				
			||||||
| 
						 | 
					@ -94,14 +103,14 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
    let jvm = env.get_java_vm().unwrap();
 | 
					    let jvm = env.get_java_vm().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // create CompletableFuture
 | 
					    // create CompletableFuture
 | 
				
			||||||
    let _future = env.new_object("java/util/concurrent/CompletableFuture", "()V", &[]).unwrap();
 | 
					    let _future = env
 | 
				
			||||||
 | 
					        .new_object("java/util/concurrent/CompletableFuture", "()V", &[])
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
    let future = env.new_global_ref(&_future).unwrap();
 | 
					    let future = env.new_global_ref(&_future).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RUNTIME.spawn_blocking(move || {
 | 
					    RUNTIME.spawn_blocking(move || {
 | 
				
			||||||
        // send request
 | 
					        // send request
 | 
				
			||||||
        let response = RUNTIME.block_on(async {
 | 
					        let response = RUNTIME.block_on(async { request.send().await });
 | 
				
			||||||
            request.send().await
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut env = jvm.attach_current_thread().unwrap();
 | 
					        let mut env = jvm.attach_current_thread().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,12 +118,22 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
            let error = error.to_string();
 | 
					            let error = error.to_string();
 | 
				
			||||||
            let error = env.new_string(error).unwrap();
 | 
					            let error = env.new_string(error).unwrap();
 | 
				
			||||||
            // create Exception
 | 
					            // create Exception
 | 
				
			||||||
            let exception = env.new_object("java/lang/Exception", "(Ljava/lang/String;)V", &[
 | 
					            let exception = env
 | 
				
			||||||
                (&error).into(),
 | 
					                .new_object(
 | 
				
			||||||
            ]).unwrap();
 | 
					                    "java/lang/Exception",
 | 
				
			||||||
 | 
					                    "(Ljava/lang/String;)V",
 | 
				
			||||||
 | 
					                    &[(&error).into()],
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
            // pass error to CompletableFuture
 | 
					            // pass error to CompletableFuture
 | 
				
			||||||
            env.call_method(future, "completeExceptionally", "(Ljava/lang/Throwable;)Z", &[(&exception).into()]).unwrap();
 | 
					            env.call_method(
 | 
				
			||||||
            return ();
 | 
					                future,
 | 
				
			||||||
 | 
					                "completeExceptionally",
 | 
				
			||||||
 | 
					                "(Ljava/lang/Throwable;)Z",
 | 
				
			||||||
 | 
					                &[(&exception).into()],
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let response = response.unwrap();
 | 
					        let response = response.unwrap();
 | 
				
			||||||
| 
						 | 
					@ -128,29 +147,41 @@ pub extern "system" fn Java_rocks_kavin_reqwest4j_ReqwestUtils_fetch(
 | 
				
			||||||
        response.headers().iter().for_each(|(key, value)| {
 | 
					        response.headers().iter().for_each(|(key, value)| {
 | 
				
			||||||
            let key = env.new_string(key.as_str()).unwrap();
 | 
					            let key = env.new_string(key.as_str()).unwrap();
 | 
				
			||||||
            let value = env.new_string(value.to_str().unwrap()).unwrap();
 | 
					            let value = env.new_string(value.to_str().unwrap()).unwrap();
 | 
				
			||||||
            headers.put(&mut env, &JObject::from(key), &JObject::from(value)).unwrap();
 | 
					            headers
 | 
				
			||||||
 | 
					                .put(&mut env, &JObject::from(key), &JObject::from(value))
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let final_url = response.url().to_string();
 | 
					        let final_url = response.url().to_string();
 | 
				
			||||||
        let final_url = env.new_string(final_url).unwrap();
 | 
					        let final_url = env.new_string(final_url).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let body = RUNTIME.block_on(async {
 | 
					        let body = RUNTIME.block_on(async { response.bytes().await.unwrap_or_default().to_vec() });
 | 
				
			||||||
            response.bytes().await.unwrap_or_default().to_vec()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let body = env.byte_array_from_slice(&body).unwrap();
 | 
					        let body = env.byte_array_from_slice(&body).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // return response to CompletableFuture
 | 
					        // return response to CompletableFuture
 | 
				
			||||||
        let response = env.new_object("rocks/kavin/reqwest4j/Response", "(ILjava/util/Map;[BLjava/lang/String;)V", &[
 | 
					        let response = env
 | 
				
			||||||
            status.into(),
 | 
					            .new_object(
 | 
				
			||||||
            (&headers).into(),
 | 
					                "rocks/kavin/reqwest4j/Response",
 | 
				
			||||||
            (&body).into(),
 | 
					                "(ILjava/util/Map;[BLjava/lang/String;)V",
 | 
				
			||||||
            (&final_url).into(),
 | 
					                &[
 | 
				
			||||||
        ]).unwrap();
 | 
					                    status.into(),
 | 
				
			||||||
 | 
					                    (&headers).into(),
 | 
				
			||||||
 | 
					                    (&body).into(),
 | 
				
			||||||
 | 
					                    (&final_url).into(),
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let future = future.as_obj();
 | 
					        let future = future.as_obj();
 | 
				
			||||||
        env.call_method(future, "complete", "(Ljava/lang/Object;)Z", &[(&response).into()]).unwrap();
 | 
					        env.call_method(
 | 
				
			||||||
 | 
					            future,
 | 
				
			||||||
 | 
					            "complete",
 | 
				
			||||||
 | 
					            "(Ljava/lang/Object;)Z",
 | 
				
			||||||
 | 
					            &[(&response).into()],
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return _future.into_raw();
 | 
					    _future.into_raw()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,10 +15,25 @@ public class ReqwestUtils {
 | 
				
			||||||
            default -> throw new RuntimeException("Unsupported architecture");
 | 
					            default -> throw new RuntimeException("Unsupported architecture");
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String os = System.getProperty("os.name").toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String extension;
 | 
				
			||||||
 | 
					        String native_folder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (os.contains("win")) {
 | 
				
			||||||
 | 
					            extension = ".dll";
 | 
				
			||||||
 | 
					            native_folder = "windows";
 | 
				
			||||||
 | 
					        } else if (os.contains("linux")) {
 | 
				
			||||||
 | 
					            extension = ".so";
 | 
				
			||||||
 | 
					            native_folder = "linux";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            throw new RuntimeException("OS not supported");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        File nativeFile;
 | 
					        File nativeFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            nativeFile = File.createTempFile("libreqwest", ".so");
 | 
					            nativeFile = File.createTempFile("libreqwest", extension);
 | 
				
			||||||
            nativeFile.deleteOnExit();
 | 
					            nativeFile.deleteOnExit();
 | 
				
			||||||
        } catch (IOException e) {
 | 
					        } catch (IOException e) {
 | 
				
			||||||
            throw new RuntimeException(e);
 | 
					            throw new RuntimeException(e);
 | 
				
			||||||
| 
						 | 
					@ -26,7 +41,7 @@ public class ReqwestUtils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final var cl = ReqwestUtils.class.getClassLoader();
 | 
					        final var cl = ReqwestUtils.class.getClassLoader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try (var stream = cl.getResourceAsStream("META-INF/natives/linux/" + arch + "/libreqwest.so")) {
 | 
					        try (var stream = cl.getResourceAsStream("META-INF/natives/" + native_folder + "/" + arch + "/libreqwest" + extension)) {
 | 
				
			||||||
            stream.transferTo(new FileOutputStream(nativeFile));
 | 
					            stream.transferTo(new FileOutputStream(nativeFile));
 | 
				
			||||||
        } catch (IOException e) {
 | 
					        } catch (IOException e) {
 | 
				
			||||||
            throw new RuntimeException(e);
 | 
					            throw new RuntimeException(e);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue