opendal/services/http/
core.rs1use std::fmt::Debug;
19use std::sync::Arc;
20
21use http::Request;
22use http::Response;
23use http::header;
24use http::header::IF_MATCH;
25use http::header::IF_NONE_MATCH;
26
27use crate::raw::*;
28use crate::*;
29
30pub struct HttpCore {
31 pub info: Arc<AccessorInfo>,
32
33 pub endpoint: String,
34 pub root: String,
35
36 pub authorization: Option<String>,
37}
38
39impl Debug for HttpCore {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.debug_struct("HttpCore")
42 .field("endpoint", &self.endpoint)
43 .field("root", &self.root)
44 .finish_non_exhaustive()
45 }
46}
47
48impl HttpCore {
49 pub fn has_authorization(&self) -> bool {
50 self.authorization.is_some()
51 }
52
53 pub fn http_get_request(
54 &self,
55 path: &str,
56 range: BytesRange,
57 args: &OpRead,
58 ) -> Result<Request<Buffer>> {
59 let p = build_rooted_abs_path(&self.root, path);
60
61 let url = format!("{}{}", self.endpoint, percent_encode_path(&p));
62
63 let mut req = Request::get(&url);
64
65 if let Some(if_match) = args.if_match() {
66 req = req.header(IF_MATCH, if_match);
67 }
68
69 if let Some(if_none_match) = args.if_none_match() {
70 req = req.header(IF_NONE_MATCH, if_none_match);
71 }
72
73 if let Some(auth) = &self.authorization {
74 req = req.header(header::AUTHORIZATION, auth.clone())
75 }
76
77 if !range.is_full() {
78 req = req.header(header::RANGE, range.to_header());
79 }
80
81 let req = req.extension(Operation::Read);
82
83 req.body(Buffer::new()).map_err(new_request_build_error)
84 }
85
86 pub async fn http_get(
87 &self,
88 path: &str,
89 range: BytesRange,
90 args: &OpRead,
91 ) -> Result<Response<HttpBody>> {
92 let req = self.http_get_request(path, range, args)?;
93 self.info.http_client().fetch(req).await
94 }
95
96 pub fn http_head_request(&self, path: &str, args: &OpStat) -> Result<Request<Buffer>> {
97 let p = build_rooted_abs_path(&self.root, path);
98
99 let url = format!("{}{}", self.endpoint, percent_encode_path(&p));
100
101 let mut req = Request::head(&url);
102
103 if let Some(if_match) = args.if_match() {
104 req = req.header(IF_MATCH, if_match);
105 }
106
107 if let Some(if_none_match) = args.if_none_match() {
108 req = req.header(IF_NONE_MATCH, if_none_match);
109 }
110
111 if let Some(auth) = &self.authorization {
112 req = req.header(header::AUTHORIZATION, auth.clone())
113 }
114
115 let req = req.extension(Operation::Stat);
116
117 req.body(Buffer::new()).map_err(new_request_build_error)
118 }
119
120 pub async fn http_head(&self, path: &str, args: &OpStat) -> Result<Response<Buffer>> {
121 let req = self.http_head_request(path, args)?;
122 self.info.http_client().send(req).await
123 }
124}