diff --git a/Cargo.toml b/Cargo.toml index ac25ff0e9d0b19a0282da0d03d81fcb9c221095c..97ea94900c5b16959b06a472d065288685303dcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,5 @@ resolver = "2" members = [ "ylong_http", "ylong_http_client", + "ylong_http_client_exec", ] diff --git a/bundle.json b/bundle.json index 69212b9b727d17f5fe25797a0c8e27cf9795ad3f..bddef0113428ffa7beb3116655754831245a23cb 100644 --- a/bundle.json +++ b/bundle.json @@ -41,6 +41,13 @@ "header_base": [], "header_files": [] } + }, + { + "name": "//commonlibrary/rust/ylong_http/ylong_http_client_exec:ylong_http_client_exec", + "header": { + "header_base": [], + "header_files": [] + } } ], "test": [ diff --git a/ylong_http_client_exec/BUILD.gn b/ylong_http_client_exec/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..075f0c90fad9bab307cb9bb0f14ece53c0298dbe --- /dev/null +++ b/ylong_http_client_exec/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2023 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_executable("ylong_http_client_exec") { + part_name = "ylong_http" + subsystem_name = "commonlibrary" + + sources = [ "src/main.rs" ] + + deps = [ "../ylong_http_client:ylong_http_client_inner" ] + + external_deps = [ "ylong_runtime:ylong_runtime" ] +} diff --git a/ylong_http_client_exec/Cargo.toml b/ylong_http_client_exec/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b1457f29fc66841258f2cb3585cb41774c46c5e3 --- /dev/null +++ b/ylong_http_client_exec/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ylong_http_client_exec" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ylong_http_client = { path = "../ylong_http_client", features = ["async", "http1_1", "http2", "ylong_base", "c_openssl_3_0"]} +ylong_runtime = { git = "https://gitee.com/openharmony/commonlibrary_rust_ylong_runtime.git", features = ["net", "sync", "fs", "macros", "time"] } \ No newline at end of file diff --git a/ylong_http_client_exec/src/main.rs b/ylong_http_client_exec/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..e3cc8d457fcee02c3ef3154641ca08130eb485c5 --- /dev/null +++ b/ylong_http_client_exec/src/main.rs @@ -0,0 +1,99 @@ +// Copyright (c) 2023 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. + +//! This is a simple asynchronous HTTP client example using the +//! ylong_http_client crate. It demonstrates creating a client, making a +//! request, and reading the response asynchronously. + +use std::pin::Pin; +use std::task::{Context, Poll}; +use std::time::Instant; + +use ylong_http_client_inner::async_impl::{ + Body, Client, DownloadOperator, Downloader, PercentEncoder, Request, +}; +use ylong_http_client_inner::HttpClientError; +use ylong_runtime::fs::File; +use ylong_runtime::io::AsyncWrite; + +fn main() { + let handle = ylong_runtime::spawn(async move { + client_send().await.unwrap(); + }); + + ylong_runtime::block_on(handle).unwrap(); +} + +async fn client_send() -> Result<(), HttpClientError> { + let builder = Client::builder(); + let client = builder.build().unwrap(); + let url = + PercentEncoder::encode("http://120.24.213.150/五维记忆/人教一上语文识字.zpf").unwrap(); + let request = Request::builder() + .url(url.as_str()) + .header("user-agent", "quiche") + .body(Body::empty()) + .unwrap(); + + // Sends request and receives a `Response`. + let response = client.request(request).await?; + + let op = TaskOperator { + file: File::create("./人教一上语文识字.zpf") + .await + .unwrap(), + }; + let mut downloader = Downloader::builder().body(response).operator(op).build(); + let start = Instant::now(); + let _ = downloader.download().await; + println!("==================>耗时: {:?}", start.elapsed()); + Ok(()) +} + +pub(crate) struct TaskOperator { + pub(crate) file: File, +} + +impl DownloadOperator for TaskOperator { + fn poll_download( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + data: &[u8], + ) -> Poll> { + let op = self.get_mut(); + op.poll_write_file(cx, data) + } + + fn poll_progress( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + _downloaded: u64, + _total: Option, + ) -> Poll> { + Poll::Ready(Ok(())) + } +} + +impl TaskOperator { + pub(crate) fn poll_write_file( + &mut self, + cx: &mut Context<'_>, + data: &[u8], + ) -> Poll> { + match Pin::new(&mut self.file).poll_write(cx, data) { + Poll::Ready(Ok(size)) => Poll::Ready(Ok(size)), + Poll::Pending => Poll::Pending, + Poll::Ready(Err(e)) => Poll::Ready(Err(HttpClientError::other(e))), + } + } +}