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