fast_down/utils/
puller.rs1use crate::{
2 FileId, ProgressEntry, PullResult, PullStream,
3 http::{HttpError, HttpPuller},
4};
5use fast_pull::Puller;
6use parking_lot::Mutex;
7use reqwest::{Client, ClientBuilder, Proxy, Response, header::HeaderMap};
8use std::sync::Arc;
9use url::Url;
10
11pub fn build_client(
12 headers: &HeaderMap,
13 proxy: &str,
14 accept_invalid_certs: bool,
15 accept_invalid_hostnames: bool,
16) -> Result<reqwest::Client, reqwest::Error> {
17 let mut client = ClientBuilder::new()
18 .default_headers(headers.clone())
19 .danger_accept_invalid_certs(accept_invalid_certs)
20 .danger_accept_invalid_hostnames(accept_invalid_hostnames);
21 if !proxy.is_empty() {
22 client = client.proxy(Proxy::all(proxy)?);
23 }
24 let client = client.build()?;
25 Ok(client)
26}
27
28#[derive(Debug)]
29pub struct FastDownPuller {
30 inner: HttpPuller<Client>,
31 headers: Arc<HeaderMap>,
32 proxy: Arc<str>,
33 url: Arc<Url>,
34 multiplexing: bool,
35 accept_invalid_certs: bool,
36 accept_invalid_hostnames: bool,
37 file_id: FileId,
38 resp: Option<Arc<Mutex<Option<Response>>>>,
39}
40
41pub struct FastDownPullerOptions<'a> {
42 pub url: Url,
43 pub headers: Arc<HeaderMap>,
44 pub proxy: &'a str,
45 pub multiplexing: bool,
46 pub accept_invalid_certs: bool,
47 pub accept_invalid_hostnames: bool,
48 pub file_id: FileId,
49 pub resp: Option<Arc<Mutex<Option<Response>>>>,
50}
51
52impl FastDownPuller {
53 pub fn new(option: FastDownPullerOptions) -> Result<Self, reqwest::Error> {
54 let client = build_client(
55 &option.headers,
56 option.proxy,
57 option.accept_invalid_certs,
58 option.accept_invalid_hostnames,
59 )?;
60 Ok(Self {
61 inner: HttpPuller::new(
62 option.url.clone(),
63 client,
64 option.resp.clone(),
65 option.file_id.clone(),
66 ),
67 resp: option.resp,
68 headers: option.headers,
69 proxy: Arc::from(option.proxy),
70 url: Arc::new(option.url),
71 multiplexing: option.multiplexing,
72 accept_invalid_certs: option.accept_invalid_certs,
73 accept_invalid_hostnames: option.accept_invalid_hostnames,
74 file_id: option.file_id,
75 })
76 }
77}
78
79impl Clone for FastDownPuller {
80 fn clone(&self) -> Self {
81 Self {
82 inner: if !self.multiplexing
83 && let Ok(client) = build_client(
84 &self.headers,
85 &self.proxy,
86 self.accept_invalid_certs,
87 self.accept_invalid_hostnames,
88 ) {
89 HttpPuller::new(
90 self.url.as_ref().clone(),
91 client,
92 self.resp.clone(),
93 self.file_id.clone(),
94 )
95 } else {
96 self.inner.clone()
97 },
98 resp: self.resp.clone(),
99 headers: self.headers.clone(),
100 proxy: self.proxy.clone(),
101 url: self.url.clone(),
102 multiplexing: self.multiplexing,
103 accept_invalid_certs: self.accept_invalid_certs,
104 accept_invalid_hostnames: self.accept_invalid_hostnames,
105 file_id: self.file_id.clone(),
106 }
107 }
108}
109
110impl Puller for FastDownPuller {
111 type Error = HttpError<Client>;
112 async fn pull(
113 &mut self,
114 range: Option<&ProgressEntry>,
115 ) -> PullResult<impl PullStream<Self::Error>, Self::Error> {
116 Puller::pull(&mut self.inner, range).await
117 }
118}