From e7c65efed062ba1ec912cea761a9624322e61579 Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Fri, 30 May 2025 11:24:07 +0200 Subject: [PATCH 1/3] Fix invlid code after primitive type refactor Change-Id: I0615ceabceb8503b09b036dbbb595fe63eda1bc7 Signed-off-by: Martin Sajti --- .../ets/ani/http/ets/@ohos.net.http.ets | 54 +++++++++---------- .../ets/@ohos.net.networkSecurity.d.ets | 8 +-- .../web_socket/ets/@ohos.net.webSocket.d.ets | 46 ++++++++-------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/frameworks/ets/ani/http/ets/@ohos.net.http.ets b/frameworks/ets/ani/http/ets/@ohos.net.http.ets index 0d4fd9a9e..a17e51024 100644 --- a/frameworks/ets/ani/http/ets/@ohos.net.http.ets +++ b/frameworks/ets/ani/http/ets/@ohos.net.http.ets @@ -40,9 +40,9 @@ export default namespace http { export enum AddressFamily { DEFAULT = 'CURL_IPRESOLVE_WHATEVER', - + ONLY_V4 = 'CURL_IPRESOLVE_V4', - + ONLY_V6 = 'CURL_IPRESOLVE_V6' } @@ -86,9 +86,9 @@ export default namespace http { certificatePinning?: CertificatePinning | CertificatePinning[]; remoteValidation?: RemoteValidation; - + tlsOptions?: TlsOptions; - + serverAuthentication?: ServerAuthentication; addressFamily?: AddressFamily; @@ -98,40 +98,40 @@ export default namespace http { credential: Credential; authenticationType?: AuthenticationType; } - + export type TlsOptions = 'system' | TlsConfig; - + export type RemoteValidation = 'system' | 'skip'; - + export type AuthenticationType = 'basic' | 'ntlm' | 'digest'; - + export interface Credential { username: string; password: string; } - + export interface TlsConfig { tlsVersionMin: TlsVersion; tlsVersionMax: TlsVersion; cipherSuites?: CipherSuite[]; } - + export type TlsV13SpecificCipherSuite = 'TLS_AES_128_GCM_SHA256' | 'TLS_AES_256_GCM_SHA384' | 'TLS_CHACHA20_POLY1305_SHA256'; - + export type TlsV12SpecificCipherSuite = 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256' | 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256' | 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384' | 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384' | 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256' | 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256' | 'TLS_RSA_WITH_AES_128_GCM_SHA256' | 'TLS_RSA_WITH_AES_256_GCM_SHA384'; - + export type TlsV10SpecificCipherSuite = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA' | 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA' | 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA' | 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA' | 'TLS_RSA_WITH_AES_128_CBC_SHA' | 'TLS_RSA_WITH_AES_256_CBC_SHA' | 'TLS_RSA_WITH_3DES_EDE_CBC_SHA'; - + export type CipherSuite = TlsV13CipherSuite; - + export type TlsV13CipherSuite = TlsV12CipherSuite | TlsV13SpecificCipherSuite; - + export type TlsV12CipherSuite = TlsV11CipherSuite | TlsV12SpecificCipherSuite; - + export type TlsV11CipherSuite = TlsV10CipherSuite; - + export type TlsV10CipherSuite = TlsV10SpecificCipherSuite; - + export enum TlsVersion { TLS_V_1_0 = 4, @@ -530,8 +530,8 @@ export default namespace http { }) p1.then(() => { callback(new BusinessError(), undefined); - }, (err: BusinessError): void => { - callback(err, undefined); + }, (err: Error): void => { + callback(err as BusinessError, undefined); }); } @@ -541,8 +541,8 @@ export default namespace http { return this.flushSync(); }).then(() => { resolve(undefined); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); }); } @@ -555,8 +555,8 @@ export default namespace http { }) p1.then(() => { callback(new BusinessError(), undefined); - }, (err: BusinessError): void => { - callback(err, undefined); + }, (err: Error): void => { + callback(err as BusinessError, undefined); }); } @@ -566,8 +566,8 @@ export default namespace http { return this.deleteSync(); }).then(() => { resolve(undefined); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); }); } @@ -576,4 +576,4 @@ export default namespace http { function main() { let a = http.createHttp(); -} \ No newline at end of file +} diff --git a/frameworks/ets/ani/net_ssl/ets/@ohos.net.networkSecurity.d.ets b/frameworks/ets/ani/net_ssl/ets/@ohos.net.networkSecurity.d.ets index 5eedda234..7aa4c99da 100644 --- a/frameworks/ets/ani/net_ssl/ets/@ohos.net.networkSecurity.d.ets +++ b/frameworks/ets/ani/net_ssl/ets/@ohos.net.networkSecurity.d.ets @@ -37,8 +37,8 @@ export default namespace networkSecurity { return certVerificationSync(cert, caCert); }).then((content: NullishType) => { resolve(content as int); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); }); } @@ -46,11 +46,11 @@ export default namespace networkSecurity { export native function certVerificationSync(cert: CertBlob, caCert?: CertBlob): int; export native function isCleartextPermitted(): boolean; - + export native function isCleartextPermittedByHostName(hostName: string): boolean; } function main() { let w = networkSecurity.isCleartextPermitted(); console.log(w); -} \ No newline at end of file +} diff --git a/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets b/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets index e34750158..8fef388a7 100644 --- a/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets +++ b/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets @@ -52,7 +52,7 @@ export default namespace webSocket { export interface ClientCert { certPath: string; - + keyPath: string; keyPassword?: string; @@ -141,8 +141,8 @@ export default namespace webSocket { }) p1.then((content: NullishType) => { callback(new BusinessError(), content as boolean); - }, (err: BusinessError): void => { - callback(err, false); + }, (err: Error): void => { + callback(err as BusinessError, false); }); } @@ -152,8 +152,8 @@ export default namespace webSocket { }) p1.then((content: NullishType) => { callback(new BusinessError(), content as boolean); - }, (err: BusinessError): void => { - callback(err, false); + }, (err: Error): void => { + callback(err as BusinessError, false); }); } @@ -163,10 +163,10 @@ export default namespace webSocket { return this.connectSync(url, options); }).then((content: NullishType) => { resolve(content as boolean); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); - }); + }); } native sendSync(data: string | ArrayBuffer): boolean; @@ -177,8 +177,8 @@ export default namespace webSocket { }) p1.then((content: NullishType) => { callback(new BusinessError(), content as boolean); - }, (err: BusinessError): void => { - callback(err, false); + }, (err: Error): void => { + callback(err as BusinessError, false); }); } @@ -188,22 +188,22 @@ export default namespace webSocket { return this.sendSync(data); }).then((content: NullishType) => { resolve(content as boolean); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); - }); + }); } native closeSync(options?: WebSocketCloseOptions): boolean; - + close(callback: AsyncCallback): void { let p1 = taskpool.execute((): boolean => { return this.closeSync(); }) p1.then((content: NullishType) => { callback(new BusinessError(), content as boolean); - }, (err: BusinessError): void => { - callback(err, false); + }, (err: Error): void => { + callback(err as BusinessError, false); }); } @@ -213,8 +213,8 @@ export default namespace webSocket { }) p1.then((content: NullishType) => { callback(new BusinessError(), content as boolean); - }, (err: BusinessError): void => { - callback(err, false); + }, (err: Error): void => { + callback(err as BusinessError, false); }); } @@ -224,10 +224,10 @@ export default namespace webSocket { return this.closeSync(options); }).then((content: NullishType) => { resolve(content as boolean); - }, (err: BusinessError): void => { - reject(err); + }, (err: Error): void => { + reject(err as BusinessError); }); - }); + }); } } } @@ -235,7 +235,7 @@ export default namespace webSocket { function main() { try { let options: webSocket.WebSocketRequestOptions = { - + } let w = webSocket.createWebSocket(); await w.connect("https://baidu.com", { @@ -245,4 +245,4 @@ function main() { } catch (e:BusinessError) { console.log(e); } -} \ No newline at end of file +} -- Gitee From 37c3a4683d978be4ddc189048d3d5c0a9459c948 Mon Sep 17 00:00:00 2001 From: fqwert Date: Fri, 13 Jun 2025 15:39:53 +0800 Subject: [PATCH 2/3] =?UTF-8?q?http,=20websocket=20arkts1.2=E8=A1=A5?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fqwert Change-Id: If5c37e2baebdca236a988bd438cb83231ce6a1f4 --- Cargo.toml | 2 +- frameworks/ets/ani/common/BUILD.gn | 35 +++++ frameworks/ets/ani/common/Cargo.toml | 19 +++ frameworks/ets/ani/common/src/hilog.rs | 44 ++++++ frameworks/ets/ani/common/src/lib.rs | 15 ++ frameworks/ets/ani/http/BUILD.gn | 2 + frameworks/ets/ani/http/Cargo.toml | 2 + .../ets/ani/http/ets/@ohos.net.http.ets | 42 ++++- frameworks/ets/ani/http/src/bridge.rs | 35 ++++- frameworks/ets/ani/http/src/callback.rs | 105 ++++++------- frameworks/ets/ani/http/src/http.rs | 143 +++++++++++++----- frameworks/ets/ani/http/src/lib.rs | 31 +++- .../net_ssl/src/cxx/network_security_ani.cpp | 18 +-- frameworks/ets/ani/net_ssl/src/security.rs | 7 +- frameworks/ets/ani/web_socket/BUILD.gn | 1 + frameworks/ets/ani/web_socket/Cargo.toml | 1 + .../web_socket/ets/@ohos.net.webSocket.d.ets | 21 +-- .../ani/web_socket/include/websocket_ani.h | 6 + frameworks/ets/ani/web_socket/src/bridge.rs | 23 ++- .../ani/web_socket/src/cxx/websocket_ani.cpp | 23 ++- frameworks/ets/ani/web_socket/src/lib.rs | 17 ++- .../ets/ani/web_socket/src/web_socket.rs | 21 ++- frameworks/ets/ani/web_socket/src/wrapper.rs | 29 +++- 23 files changed, 490 insertions(+), 152 deletions(-) create mode 100644 frameworks/ets/ani/common/BUILD.gn create mode 100644 frameworks/ets/ani/common/Cargo.toml create mode 100644 frameworks/ets/ani/common/src/hilog.rs create mode 100644 frameworks/ets/ani/common/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 31afa0235..cf0762bce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,5 +18,5 @@ members = [ "interfaces/innerkits/rust/netstack_rs", "interfaces/innerkits/rust/ffrt_rs", "frameworks/ets/ani/net_ssl", - "frameworks/ets/ani/web_socket", + "frameworks/ets/ani/web_socket", "frameworks/ets/ani/common", ] diff --git a/frameworks/ets/ani/common/BUILD.gn b/frameworks/ets/ani/common/BUILD.gn new file mode 100644 index 000000000..acb03d7de --- /dev/null +++ b/frameworks/ets/ani/common/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_rust_static_library("netstack_common") { + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + all_ubsan = true + debug = false + } + + sources = [ "src/lib.rs" ] + + external_deps = [ + "hilog:hilog_rust", + ] + + clippy_lints = "none" + + part_name = "netstack" + subsystem_name = "communication" +} \ No newline at end of file diff --git a/frameworks/ets/ani/common/Cargo.toml b/frameworks/ets/ani/common/Cargo.toml new file mode 100644 index 000000000..d29bd7781 --- /dev/null +++ b/frameworks/ets/ani/common/Cargo.toml @@ -0,0 +1,19 @@ +# Copyright (C) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[package] +name = "netstack_common" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/frameworks/ets/ani/common/src/hilog.rs b/frameworks/ets/ani/common/src/hilog.rs new file mode 100644 index 000000000..2ae37f9ae --- /dev/null +++ b/frameworks/ets/ani/common/src/hilog.rs @@ -0,0 +1,44 @@ +// Copyright (C) 2025 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// hilog label. +#[macro_export] +macro_rules! debug { + ($fmt: literal $(, $args:expr)* $(,)?) => {{ + use hilog_rust::hilog; + use std::ffi::{c_char, CString}; + use crate::LOG_LABEL; + hilog_rust::debug!(LOG_LABEL, $fmt $(, @public($args))*); + }} +} + +#[macro_export] +macro_rules! info { + ($fmt: literal $(, $args:expr)* $(,)?) => {{ + use hilog_rust::hilog; + use std::ffi::{c_char, CString}; + use crate::LOG_LABEL; + + hilog_rust::info!(LOG_LABEL, $fmt $(, @public($args))*); + }} +} +#[macro_export] +macro_rules! error { + ($fmt: literal $(, $args:expr)* $(,)?) => {{ + use hilog_rust::hilog; + use std::ffi::{c_char, CString}; + use crate::LOG_LABEL; + + hilog_rust::error!(LOG_LABEL, $fmt $(, @public($args))*); + }} +} diff --git a/frameworks/ets/ani/common/src/lib.rs b/frameworks/ets/ani/common/src/lib.rs new file mode 100644 index 000000000..f69cdde05 --- /dev/null +++ b/frameworks/ets/ani/common/src/lib.rs @@ -0,0 +1,15 @@ +// Copyright (C) 2025 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_use] +mod hilog; diff --git a/frameworks/ets/ani/http/BUILD.gn b/frameworks/ets/ani/http/BUILD.gn index 8121c888d..f6197637a 100644 --- a/frameworks/ets/ani/http/BUILD.gn +++ b/frameworks/ets/ani/http/BUILD.gn @@ -27,11 +27,13 @@ ohos_rust_shared_library("http_ani") { sources = [ "src/lib.rs" ] external_deps = [ + "hilog:hilog_rust", "runtime_core:ani", "netmanager_base:ani_rs", ] deps = [ + "../common:netstack_common", "//third_party/rust/crates/serde/serde:lib", "$NETSTACK_INNERKITS_DIR/rust/netstack_rs:netstack_rs", ] diff --git a/frameworks/ets/ani/http/Cargo.toml b/frameworks/ets/ani/http/Cargo.toml index e7667b6b6..98de85913 100644 --- a/frameworks/ets/ani/http/Cargo.toml +++ b/frameworks/ets/ani/http/Cargo.toml @@ -21,3 +21,5 @@ ani_rs = { path = "../../../../../netmanager_base/common/ani_rs" } cxx = "1.0.115" serde = { version = "1.0", features = ["derive"] } netstack_rs = { path = "../../../../interfaces/innerkits/rust/netstack_rs" } +hilog_rust = { git = "https://gitee.com/openharmony/hiviewdfx_hilog" } +netstack_common = { path = "../common" } diff --git a/frameworks/ets/ani/http/ets/@ohos.net.http.ets b/frameworks/ets/ani/http/ets/@ohos.net.http.ets index a17e51024..710e3ba51 100644 --- a/frameworks/ets/ani/http/ets/@ohos.net.http.ets +++ b/frameworks/ets/ani/http/ets/@ohos.net.http.ets @@ -453,7 +453,21 @@ export default namespace http { responseCode: ResponseCode | int; - header: Object; + header: Record; + + cookies: string; + + performanceTiming: PerformanceTiming; + } + + class HttpResponseInner implements HttpResponse { + result: string | Object | ArrayBuffer; + + resultType: HttpDataType; + + responseCode: ResponseCode | int; + + header: Record; cookies: string; @@ -482,6 +496,28 @@ export default namespace http { totalTiming: int; } + class PerformanceTimingInner implements PerformanceTiming { + dnsTiming: int; + + tcpTiming: int; + + tlsTiming: int; + + firstSendTiming: int; + + firstReceiveTiming: int; + + totalFinishTiming: int; + + redirectTiming: int; + + responseHeaderTiming: int; + + responseBodyTiming: int; + + totalTiming: int; + } + export interface DataReceiveProgressInfo { receiveSize: int; totalSize: int; @@ -573,7 +609,3 @@ export default namespace http { } } } - -function main() { - let a = http.createHttp(); -} diff --git a/frameworks/ets/ani/http/src/bridge.rs b/frameworks/ets/ani/http/src/bridge.rs index 7cd71bdd8..145a65e6e 100644 --- a/frameworks/ets/ani/http/src/bridge.rs +++ b/frameworks/ets/ani/http/src/bridge.rs @@ -13,6 +13,7 @@ use std::collections::HashMap; +use ani_rs::box_type::BoxI32; use serde::{Deserialize, Serialize}; #[ani_rs::ani] @@ -277,19 +278,28 @@ pub enum HttpDataType { ArrayBuffer = 2, } -#[ani_rs::ani(path = "L@ohos/net/http/http/HttpResponse")] +#[derive(Serialize)] +pub enum ResponseCodeOutput { + #[serde(rename = "L@ohos/net/http/http/ResponseCode")] + Code(ResponseCode), + I32(BoxI32), +} + +#[ani_rs::ani(path = "L@ohos/net/http/http/HttpResponseInner", output = "only")] pub struct HttpResponse { // pub result: String | Object | VecBuffer, + pub result_type: HttpDataType, - // pub response_code: ResponseCode | i32, - // pub header: Object, + pub response_code: ResponseCodeOutput, + + pub header: HashMap, pub cookies: String, pub performance_timing: PerformanceTiming, } -#[ani_rs::ani(path = "L@ohos/net/http/http/HttpResponse")] +#[ani_rs::ani(path = "L@ohos/net/http/http/PerformanceTimingInner")] pub struct PerformanceTiming { pub dns_timing: i32, @@ -312,6 +322,23 @@ pub struct PerformanceTiming { pub total_timing: i32, } +impl PerformanceTiming { + pub fn new() -> Self { + Self { + dns_timing: 0, + tcp_timing: 0, + tls_timing: 0, + first_send_timing: 0, + first_receive_timing: 0, + total_finish_timing: 0, + redirect_timing: 0, + response_header_timing: 0, + response_body_timing: 0, + total_timing: 0, + } + } +} + #[ani_rs::ani(path = "L@ohos/net/http/http/HttpResponse")] pub struct DataReceiveProgressInfo { pub receive_size: i32, diff --git a/frameworks/ets/ani/http/src/callback.rs b/frameworks/ets/ani/http/src/callback.rs index 858fc19dd..3ab631ca2 100644 --- a/frameworks/ets/ani/http/src/callback.rs +++ b/frameworks/ets/ani/http/src/callback.rs @@ -13,80 +13,75 @@ use std::{collections::HashMap, sync::Mutex}; -use ani_rs::objects::GlobalRefCallback; -use netstack_rs::request::RequestCallback; +use ani_rs::{box_type::BoxI32, objects::GlobalRefAsyncCallback}; +use netstack_rs::{request::RequestCallback, response::Response}; -use crate::bridge::{DataReceiveProgressInfo, DataSendProgressInfo, HttpResponse}; +use crate::bridge::{ + DataReceiveProgressInfo, DataSendProgressInfo, HttpDataType, HttpResponse, PerformanceTiming, + ResponseCode, ResponseCodeOutput, +}; pub struct TaskCallback { - pub on_response: Mutex>>, - pub on_header_receive: Mutex,)>>>, - pub on_headers_receive: Mutex,)>>>, - pub on_data_receive: Mutex,)>>>, - - pub on_data_end: Mutex>>, - pub on_data_receive_progress: Mutex>>, - pub on_data_send_progress: Mutex>>, + pub on_response: Option>, + pub on_header_receive: Option,)>>, + pub on_headers_receive: Option,)>>, + pub on_data_receive: Option,)>>, + + pub on_data_end: Option>, + pub on_data_receive_progress: Option>, + pub on_data_send_progress: Option>, } impl TaskCallback { pub fn new() -> Self { Self { - on_response: Mutex::new(None), - on_header_receive: Mutex::new(None), - on_headers_receive: Mutex::new(None), - on_data_receive: Mutex::new(None), - - on_data_end: Mutex::new(None), - on_data_receive_progress: Mutex::new(None), - on_data_send_progress: Mutex::new(None), + on_response: None, + on_header_receive: None, + on_headers_receive: None, + on_data_receive: None, + + on_data_end: None, + on_data_receive_progress: None, + on_data_send_progress: None, } } } -impl TaskCallback { - pub fn set_on_response(&self, callback: GlobalRefCallback<(HttpResponse,)>) { - *self.on_response.lock().unwrap() = Some(callback); - } - - pub fn set_on_header_receive(&self, callback: GlobalRefCallback<(HashMap,)>) { - *self.on_header_receive.lock().unwrap() = Some(callback); - } - - pub fn set_on_headers_receive(&self, callback: GlobalRefCallback<(HashMap,)>) { - *self.on_headers_receive.lock().unwrap() = Some(callback); - } - - pub fn set_on_data_receive(&self, callback: GlobalRefCallback<(Vec,)>) { - *self.on_data_receive.lock().unwrap() = Some(callback); - } - - pub fn set_on_data_end(&self, callback: GlobalRefCallback<()>) { - *self.on_data_end.lock().unwrap() = Some(callback); - } - - pub fn set_on_data_receive_progress( - &self, - callback: GlobalRefCallback<(DataReceiveProgressInfo,)>, - ) { - *self.on_data_receive_progress.lock().unwrap() = Some(callback); - } - - pub fn set_on_data_send_progress(&self, callback: GlobalRefCallback<(DataSendProgressInfo,)>) { - *self.on_data_send_progress.lock().unwrap() = Some(callback); - } -} - impl RequestCallback for TaskCallback { fn on_success(&mut self, response: netstack_rs::response::Response) { - panic!("Request succeeded with response"); + let code = response.status() as i32; + info!("request success: {:?}", code); + if let Some(callback) = self.on_data_end.take() { + info!("on_data_end callback set"); + callback.execute(None, ()); + } } fn on_fail(&mut self, error: netstack_rs::error::HttpClientError) { - panic!("Request failed with error"); + info!("request fail"); } fn on_cancel(&mut self) {} - fn on_data_receive(&mut self, data: &[u8], task: netstack_rs::task::RequestTask) {} + fn on_data_receive(&mut self, data: &[u8], mut task: netstack_rs::task::RequestTask) { + let headers = task.headers(); + if let Some(callback) = self.on_response.take() { + let response = task.response(); + let code = response.status() as i32; + let response = HttpResponse { + result_type: HttpDataType::String, + response_code: ResponseCodeOutput::I32(BoxI32::new(code)), + header: response.headers(), + cookies: String::new(), + performance_timing: PerformanceTiming::new(), + }; + info!("on_response callback set"); + callback.execute(None, (response,)); + } + + if let Some(callback) = self.on_header_receive.as_ref() { + info!("on_header_receive callback set"); + callback.execute(None, (headers.clone(),)); + } + } } diff --git a/frameworks/ets/ani/http/src/http.rs b/frameworks/ets/ani/http/src/http.rs index bcb6f262b..e7a00efbf 100644 --- a/frameworks/ets/ani/http/src/http.rs +++ b/frameworks/ets/ani/http/src/http.rs @@ -11,42 +11,43 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{ffi::CStr, sync::Arc}; +use std::ffi::CStr; use ani_rs::{ business_error::BusinessError, - objects::{AniFnObject, AniRef}, + objects::{AniAsyncCallback, AniRef}, AniEnv, }; use netstack_rs::{request::Request, task::RequestTask}; use crate::{ - bridge::{Cleaner, HttpRequest, HttpRequestOptions, HttpResponse, HttpResponseCache}, + bridge::{Cleaner, HttpRequest, HttpRequestOptions, HttpResponseCache}, callback::TaskCallback, }; -static HTTP_REQUEST_CLASS: &CStr = - unsafe { CStr::from_bytes_with_nul_unchecked(b"L@ohos/net/http/http/HttpRequestInner;\0") }; -static CTOR_SIGNATURE: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"J:V\0") }; - pub struct Task { pub request_task: Option, - pub callback: Arc, + pub callback: Option, } impl Task { pub fn new() -> Self { Self { request_task: None, - callback: Arc::new(TaskCallback::new()), + callback: None, } } } -pub(crate) fn create_http<'local>(env: &AniEnv<'local>) -> Result, BusinessError> { - let request = Box::new(Task::new()); +#[ani_rs::native] +pub fn create_http<'local>(env: &AniEnv<'local>) -> Result, BusinessError> { + static HTTP_REQUEST_CLASS: &CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(b"L@ohos/net/http/http/HttpRequestInner;\0") }; + static CTOR_SIGNATURE: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"J:V\0") }; + let request = Box::new(Task::new()); let ptr = Box::into_raw(request); + let class = env.find_class(HTTP_REQUEST_CLASS).unwrap(); let obj = env .new_object_with_signature(&class, CTOR_SIGNATURE, (ptr as i64,)) @@ -59,14 +60,18 @@ pub(crate) fn request( env: &AniEnv, this: HttpRequest, url: String, - callback: AniFnObject, + async_callback: AniAsyncCallback, options: Option, ) -> Result<(), BusinessError> { + info!("request url :{}", url); let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; let mut request = Request::::new(); + request.url(url.as_str()); - *task.callback.on_response.lock().unwrap() = Some(callback.into_global_callback(env).unwrap()); + let mut cb = task.callback.take().unwrap_or_else(TaskCallback::new); + cb.on_response = Some(async_callback.into_global_callback(env).unwrap()); + request.callback(cb); let mut request_task = request.build(); request_task.start(); task.request_task = Some(request_task); @@ -77,7 +82,7 @@ pub(crate) fn request( pub(crate) fn request_in_stream( this: HttpRequest, url: String, - callback: AniFnObject, + async_callback: AniAsyncCallback, options: Option, ) -> Result { todo!() @@ -109,18 +114,28 @@ pub(crate) fn clean_http_cache(this: Cleaner) -> Result<(), BusinessError> { pub(crate) fn on_header_receive( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_header_receive(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_header_receive = Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_header_receive = + Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } #[ani_rs::native] pub(crate) fn off_header_receive( this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -129,18 +144,28 @@ pub(crate) fn off_header_receive( pub(crate) fn on_headers_receive( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_headers_receive(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_headers_receive = Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_headers_receive = + Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } #[ani_rs::native] pub(crate) fn off_headers_receive( this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -149,18 +174,27 @@ pub(crate) fn off_headers_receive( pub(crate) fn on_data_receive( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_data_receive(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_data_receive = Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_data_receive = Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } #[ani_rs::native] pub(crate) fn off_data_receive( this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -169,11 +203,20 @@ pub(crate) fn off_data_receive( pub(crate) fn on_data_end( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_data_end(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_data_end = Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_data_end = Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } @@ -181,7 +224,7 @@ pub(crate) fn on_data_end( pub(crate) fn off_data_end( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -190,18 +233,29 @@ pub(crate) fn off_data_end( pub(crate) fn on_data_receive_progress( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_data_receive_progress(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_data_receive_progress = + Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_data_receive_progress = + Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } #[ani_rs::native] pub(crate) fn off_data_receive_progress( this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -210,18 +264,29 @@ pub(crate) fn off_data_receive_progress( pub(crate) fn on_data_send_progress( env: &AniEnv, this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { let task = unsafe { &mut (*(this.native_ptr as *mut Task)) }; - let callback = callback.into_global_callback(env).unwrap(); - task.callback.set_on_data_send_progress(callback); + match task.callback { + Some(ref mut callback) => { + // Convert the async callback to a global reference + callback.on_data_send_progress = + Some(async_callback.into_global_callback(env).unwrap()); + } + None => { + let mut task_callback = TaskCallback::new(); + task_callback.on_data_send_progress = + Some(async_callback.into_global_callback(env).unwrap()); + task.callback = Some(task_callback); + } + } Ok(()) } #[ani_rs::native] pub(crate) fn off_data_send_progress( this: HttpRequest, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } @@ -230,7 +295,7 @@ pub(crate) fn off_data_send_progress( pub(crate) fn once( this: HttpRequest, ty: String, - callback: AniFnObject, + async_callback: AniAsyncCallback, ) -> Result<(), BusinessError> { todo!() } diff --git a/frameworks/ets/ani/http/src/lib.rs b/frameworks/ets/ani/http/src/lib.rs index 72a491451..5d2b723cd 100644 --- a/frameworks/ets/ani/http/src/lib.rs +++ b/frameworks/ets/ani/http/src/lib.rs @@ -11,6 +11,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +const LOG_LABEL: hilog_rust::HiLogLabel = hilog_rust::HiLogLabel { + log_type: hilog_rust::LogType::LogCore, + domain: 0xD0015B0, + tag: "HttpAni", +}; + +#[macro_use] +extern crate netstack_common; + mod bridge; mod callback; mod http; @@ -20,11 +29,6 @@ ani_rs::ani_constructor! { [ "createHttp" : http::create_http ] - class "L@ohos/net/http/http/Cleaner" - [ - "cleanHttp" : http::clean_http_request, - "cleanCache" : http::clean_http_cache, - ] class "L@ohos/net/http/http/HttpRequestInner" [ "requestInner" : http::request, @@ -49,4 +53,21 @@ ani_rs::ani_constructor! { "flushSync" : http::flush, "deleteSync": http::delete, ] + class "L@ohos/net/http/http/Cleaner" + [ + "cleanHttp" : http::clean_http_request, + "cleanCache" : http::clean_http_cache, + ] } + +#[used] +#[link_section = ".init_array"] +static A: extern "C" fn() = { + #[link_section = ".text.startup"] + extern "C" fn init() { + std::panic::set_hook(Box::new(|info| { + info!("Panic occurred: {:?}", info); + })); + } + init +}; diff --git a/frameworks/ets/ani/net_ssl/src/cxx/network_security_ani.cpp b/frameworks/ets/ani/net_ssl/src/cxx/network_security_ani.cpp index 6a230c147..3dcea585e 100644 --- a/frameworks/ets/ani/net_ssl/src/cxx/network_security_ani.cpp +++ b/frameworks/ets/ani/net_ssl/src/cxx/network_security_ani.cpp @@ -24,21 +24,21 @@ namespace NetStackAni { uint32_t NetStackVerifyCertificationCa(const CertBlob &cert, const CertBlob &caCert) { std::string a; - NetStack::Ssl::CertBlob nativeCert{ .type = cert.cert_type, - .size = cert.data.size(), - .data = reinterpret_cast(const_cast(cert.data.data())) }; + NetStack::Ssl::CertBlob nativeCert{.type = cert.cert_type, + .size = cert.data.size(), + .data = reinterpret_cast(const_cast(cert.data.data()))}; - NetStack::Ssl::CertBlob nativeCaCert{ .type = caCert.cert_type, - .size = caCert.data.size(), - .data = reinterpret_cast(const_cast(caCert.data.data())) }; + NetStack::Ssl::CertBlob nativeCaCert{.type = caCert.cert_type, + .size = caCert.data.size(), + .data = reinterpret_cast(const_cast(caCert.data.data()))}; return NetStack::Ssl::NetStackVerifyCertification(&nativeCert, &nativeCaCert); } uint32_t NetStackVerifyCertification(const CertBlob &cert) { - NetStack::Ssl::CertBlob nativeCert{ .type = cert.cert_type, - .size = cert.data.size(), - .data = reinterpret_cast(const_cast(cert.data.data())) }; + NetStack::Ssl::CertBlob nativeCert{.type = cert.cert_type, + .size = cert.data.size(), + .data = reinterpret_cast(const_cast(cert.data.data()))}; return NetStack::Ssl::NetStackVerifyCertification(&nativeCert); } diff --git a/frameworks/ets/ani/net_ssl/src/security.rs b/frameworks/ets/ani/net_ssl/src/security.rs index d6da5d8a2..970bcfc90 100644 --- a/frameworks/ets/ani/net_ssl/src/security.rs +++ b/frameworks/ets/ani/net_ssl/src/security.rs @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ani_rs::{business_error::BusinessError, AniEnv}; +use ani_rs::business_error::BusinessError; use crate::{bridge::CertBlob, wrapper::NetworkSecurityClient}; @@ -28,10 +28,7 @@ pub fn is_cleartext_permitted() -> Result { } #[ani_rs::native] -pub fn is_cleartext_permitted_by_host_name( - env: &AniEnv, - host_name: String, -) -> Result { +pub fn is_cleartext_permitted_by_host_name(host_name: String) -> Result { NetworkSecurityClient::is_cleartext_permitted_by_host_name(host_name) .map_err(|e| { BusinessError::new( diff --git a/frameworks/ets/ani/web_socket/BUILD.gn b/frameworks/ets/ani/web_socket/BUILD.gn index 8294da97e..77daf83c5 100644 --- a/frameworks/ets/ani/web_socket/BUILD.gn +++ b/frameworks/ets/ani/web_socket/BUILD.gn @@ -73,6 +73,7 @@ ohos_rust_shared_library("websocket_ani") { "netmanager_base:ani_rs", ] deps = [ + "../common:netstack_common", ":websocket_ani_static", "//third_party/rust/crates/cxx:lib", "//third_party/rust/crates/serde/serde:lib" diff --git a/frameworks/ets/ani/web_socket/Cargo.toml b/frameworks/ets/ani/web_socket/Cargo.toml index 0416d4918..ac38bfc8b 100644 --- a/frameworks/ets/ani/web_socket/Cargo.toml +++ b/frameworks/ets/ani/web_socket/Cargo.toml @@ -21,3 +21,4 @@ ani_rs = { git = "https://gitee.com/openharmony/communication_netmanager_base", cxx = "1.0.97" serde = { version = "1.0", features = ["derive"] } hilog_rust = { git = "https://gitee.com/openharmony/hiviewdfx_hilog" } +netstack_common = { path = "../common" } diff --git a/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets b/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets index 8fef388a7..3a7492186 100644 --- a/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets +++ b/frameworks/ets/ani/web_socket/ets/@ohos.net.webSocket.d.ets @@ -15,11 +15,11 @@ import type { AsyncCallback, ErrorCallback, Callback } from '@ohos.base'; -// import type connection from '@ohos.net.connection'; +import type connection from '@ohos.net.connection'; import { BusinessError } from '@ohos.base'; export default namespace webSocket { - // type HttpProxy = connection.HttpProxy; + type HttpProxy = connection.HttpProxy; loadLibrary("websocket_ani"); @@ -48,7 +48,7 @@ export default namespace webSocket { protocol?: string; } - export type ProxyConfiguration = 'system' | 'no-proxy' // | HttpProxy; + export type ProxyConfiguration = 'system' | 'no-proxy' | HttpProxy; export interface ClientCert { certPath: string; @@ -231,18 +231,3 @@ export default namespace webSocket { } } } - -function main() { - try { - let options: webSocket.WebSocketRequestOptions = { - - } - let w = webSocket.createWebSocket(); - await w.connect("https://baidu.com", { - caPath: "niaaani", - }); - w.close(); - } catch (e:BusinessError) { - console.log(e); - } -} diff --git a/frameworks/ets/ani/web_socket/include/websocket_ani.h b/frameworks/ets/ani/web_socket/include/websocket_ani.h index 730850914..d4e4a061e 100644 --- a/frameworks/ets/ani/web_socket/include/websocket_ani.h +++ b/frameworks/ets/ani/web_socket/include/websocket_ani.h @@ -31,6 +31,12 @@ struct CloseOption; std::unique_ptr CreateWebSocket(); int32_t Connect(NetStack::WebSocketClient::WebSocketClient &client, const rust::str url, ConnectOptions options); + +void SetCaPath(NetStack::WebSocketClient::WebSocketClient &client, const rust::str caPath); +void SetClientCert(NetStack::WebSocketClient::WebSocketClient &client, const rust::str clientCert, + const rust::str clientKey); +void SetCertPassword(NetStack::WebSocketClient::WebSocketClient &client, const rust::str password); + int32_t Send(NetStack::WebSocketClient::WebSocketClient &client, const rust::str data); int32_t Close(NetStack::WebSocketClient::WebSocketClient &client, CloseOption options); diff --git a/frameworks/ets/ani/web_socket/src/bridge.rs b/frameworks/ets/ani/web_socket/src/bridge.rs index 189b935e4..5d09809e7 100644 --- a/frameworks/ets/ani/web_socket/src/bridge.rs +++ b/frameworks/ets/ani/web_socket/src/bridge.rs @@ -13,6 +13,8 @@ use std::collections::HashMap; +use serde::Deserialize; + #[ani_rs::ani] pub struct Cleaner { pub native_ptr: i64, @@ -23,6 +25,25 @@ pub struct WebSocket { pub native_ptr: i64, } +#[ani_rs::ani(path = "L@ohos/net/connection/connection/HttpProxyInner")] +pub struct HttpProxy { + pub host: String, + + pub port: i32, + + pub username: Option, + + pub password: Option, + + pub exclusion_list: Vec, +} + +#[derive(Deserialize)] +pub enum ProxyConfiguration { + S(String), + Proxy(HttpProxy), +} + #[ani_rs::ani] pub struct WebSocketRequestOptions { pub header: Option>, @@ -31,7 +52,7 @@ pub struct WebSocketRequestOptions { pub client_cert: Option, - // proxy: Option, + pub proxy: Option, pub protocol: Option, } diff --git a/frameworks/ets/ani/web_socket/src/cxx/websocket_ani.cpp b/frameworks/ets/ani/web_socket/src/cxx/websocket_ani.cpp index ed3131a80..490e1cd41 100644 --- a/frameworks/ets/ani/web_socket/src/cxx/websocket_ani.cpp +++ b/frameworks/ets/ani/web_socket/src/cxx/websocket_ani.cpp @@ -15,9 +15,10 @@ #include "websocket_ani.h" +#include "secure_char.h" +#include "wrapper.rs.h" #include -#include "wrapper.rs.h" namespace OHOS { namespace NetStackAni { @@ -45,6 +46,26 @@ int32_t Connect(NetStack::WebSocketClient::WebSocketClient &client, const rust:: return client.Connect(std::string(url), openOptions); } +void SetCaPath(NetStack::WebSocketClient::WebSocketClient &client, const rust::str caPath) +{ + auto context = client.GetClientContext(); + context->SetUserCertPath(std::string(caPath)); +} + +void SetClientCert(NetStack::WebSocketClient::WebSocketClient &client, const rust::str clientCert, + const rust::str clientKey) +{ + auto context = client.GetClientContext(); + context->clientCert = std::string(clientCert); + context->clientKey = NetStack::Secure::SecureChar(std::string(clientKey)); +} + +void SetCertPassword(NetStack::WebSocketClient::WebSocketClient &client, const rust::str password) +{ + auto context = client.GetClientContext(); + context->keyPassword = NetStack::Secure::SecureChar(std::string(password)); +} + int32_t Send(NetStack::WebSocketClient::WebSocketClient &client, const rust::str data) { return client.Send(const_cast(data.data()), data.size()); diff --git a/frameworks/ets/ani/web_socket/src/lib.rs b/frameworks/ets/ani/web_socket/src/lib.rs index 88a44fc8d..86dd3198a 100644 --- a/frameworks/ets/ani/web_socket/src/lib.rs +++ b/frameworks/ets/ani/web_socket/src/lib.rs @@ -11,6 +11,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +const LOG_LABEL: hilog_rust::HiLogLabel = hilog_rust::HiLogLabel { + log_type: hilog_rust::LogType::LogCore, + domain: 0xD0015B0, + tag: "WebSocketAni", +}; + +#[macro_use] +extern crate netstack_common; + mod bridge; mod web_socket; mod wrapper; @@ -18,13 +27,13 @@ mod wrapper; ani_rs::ani_constructor! { namespace "L@ohos/net/webSocket/webSocket" [ - "create_webSocket" : web_socket::create_web_socket + "createWebSocket" : web_socket::create_web_socket ] class "L@ohos/net/webSocket/webSocket/WebSocketInner" [ - "connect_sync" : web_socket::connect_sync, - "send_sync" : web_socket::send_sync, - "close_sync" : web_socket::close_sync, + "connectSync" : web_socket::connect_sync, + "sendSync" : web_socket::send_sync, + "closeSync" : web_socket::close_sync, ] class "L@ohos/net/webSocket/webSocket/Cleaner" [ diff --git a/frameworks/ets/ani/web_socket/src/web_socket.rs b/frameworks/ets/ani/web_socket/src/web_socket.rs index 68a590b3e..699a8055c 100644 --- a/frameworks/ets/ani/web_socket/src/web_socket.rs +++ b/frameworks/ets/ani/web_socket/src/web_socket.rs @@ -28,7 +28,9 @@ pub(crate) fn web_socket_clean(this: Cleaner) -> Result<(), BusinessError> { Ok(()) } -pub(crate) fn create_web_socket<'local>(env: AniEnv<'local>, _: AniRef<'local>) -> AniRef<'local> { +#[ani_rs::native] +pub fn create_web_socket<'local>(env: &AniEnv<'local>) -> Result, BusinessError> { + info!("Creating WebSocket instance"); static WEB_SOCKET_CLASS: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"L@ohos/net/webSocket/webSocket/WebSocketInner;\0") }; @@ -39,7 +41,7 @@ pub(crate) fn create_web_socket<'local>(env: AniEnv<'local>, _: AniRef<'local>) let obj = env .new_object_with_signature(&class, CTOR_SIGNATURE, (ptr as i64,)) .unwrap(); - obj.into() + Ok(obj.into()) } #[ani_rs::native] @@ -48,15 +50,28 @@ pub(crate) fn connect_sync( url: String, options: Option, ) -> Result { + info!("Connecting to WebSocket at URL: {}", url); + let web_socket = unsafe { &mut *(this.native_ptr as *mut WebSocket) }; let mut headers = HashMap::new(); + let (mut ca_path, mut client_cert, mut protocol) = (None, None, None); + if let Some(options) = options { if let Some(header) = options.header { headers = header; } + if let Some(path) = options.ca_path { + ca_path = Some(path); + } + if let Some(cert) = options.client_cert { + client_cert = Some(cert); + } + if let Some(p) = options.protocol { + protocol = Some(p); + } } web_socket - .connect(&url, headers) + .connect(&url, headers, ca_path, client_cert, protocol) .map(|_| true) .map_err(|e| BusinessError::new(e, format!("Failed to connect"))) } diff --git a/frameworks/ets/ani/web_socket/src/wrapper.rs b/frameworks/ets/ani/web_socket/src/wrapper.rs index 60e9e5a3f..747dffc34 100644 --- a/frameworks/ets/ani/web_socket/src/wrapper.rs +++ b/frameworks/ets/ani/web_socket/src/wrapper.rs @@ -13,6 +13,8 @@ use std::collections::HashMap; +use crate::bridge::ClientCert; + pub struct WebSocket { client: cxx::UniquePtr, } @@ -23,7 +25,14 @@ impl WebSocket { WebSocket { client } } - pub fn connect(&mut self, url: &str, headers: HashMap) -> Result<(), i32> { + pub fn connect( + &mut self, + url: &str, + headers: HashMap, + ca_path: Option, + client_cert: Option, + protocol: Option, + ) -> Result<(), i32> { let options = ffi::ConnectOptions { headers: headers .iter() @@ -31,6 +40,16 @@ impl WebSocket { .flatten() .collect(), }; + if let Some(ca_path) = ca_path { + ffi::SetCaPath(self.client.pin_mut(), &ca_path); + } + if let Some(cert) = client_cert { + ffi::SetClientCert(self.client.pin_mut(), &cert.cert_path, &cert.key_path); + if let Some(password) = cert.key_password { + ffi::SetCertPassword(self.client.pin_mut(), &password); + } + } + let ret = ffi::Connect(self.client.pin_mut(), url, options); if ret != 0 { return Err(ret); @@ -60,7 +79,7 @@ impl WebSocket { mod ffi { pub struct ConnectOptions<'a> { - headers: Vec<&'a str>, + pub headers: Vec<&'a str>, } struct CloseOption<'a> { @@ -78,6 +97,12 @@ mod ffi { fn Connect(client: Pin<&mut WebSocketClient>, url: &str, options: ConnectOptions) -> i32; + fn SetCaPath(client: Pin<&mut WebSocketClient>, ca_path: &str); + + fn SetClientCert(client: Pin<&mut WebSocketClient>, cert_path: &str, key: &str); + + fn SetCertPassword(client: Pin<&mut WebSocketClient>, password: &str); + fn Send(client: Pin<&mut WebSocketClient>, data: &str) -> i32; fn Close(client: Pin<&mut WebSocketClient>, options: CloseOption) -> i32; -- Gitee From 78d42612585724892edc6c83c92f97bb0caa8c96 Mon Sep 17 00:00:00 2001 From: fqwert Date: Wed, 18 Jun 2025 12:08:36 +0800 Subject: [PATCH 3/3] =?UTF-8?q?AsyncCallback=20=E6=8E=A5=E5=8F=A3=E6=95=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fqwert Change-Id: I8a01055cc7f15a6242ed10bd5561b8d19788cd87 --- frameworks/ets/ani/http/ets/@ohos.net.http.ets | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frameworks/ets/ani/http/ets/@ohos.net.http.ets b/frameworks/ets/ani/http/ets/@ohos.net.http.ets index 710e3ba51..6ec5aac9b 100644 --- a/frameworks/ets/ani/http/ets/@ohos.net.http.ets +++ b/frameworks/ets/ani/http/ets/@ohos.net.http.ets @@ -230,11 +230,11 @@ export default namespace http { request(url: string, options?: HttpRequestOptions): Promise { return new Promise((resolve, reject) => { - this.requestInner(url, (err: BusinessError, data: HttpResponse) => { - if (err.code !=0 ) { + this.requestInner(url, (err: BusinessError | null, data: HttpResponse| undefined) => { + if (err) { reject(err); } else { - resolve(data); + resolve(data as HttpResponse); } }, options); }); @@ -252,11 +252,11 @@ export default namespace http { requestInStream(url: string, options?: HttpRequestOptions): Promise { return new Promise((resolve, reject) => { - this.requestInStreamInner(url, (err: BusinessError, data: int) => { - if (err.code !=0 ) { + this.requestInStreamInner(url, (err: BusinessError | null, data: int | undefined) => { + if (err) { reject(err); } else { - resolve(data); + resolve(data as int); } }, options); }); -- Gitee