opendal/services/vercel_artifacts/
core.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19use std::sync::Arc;
20
21use http::header;
22use http::Request;
23use http::Response;
24
25use crate::raw::*;
26use crate::*;
27
28pub struct VercelArtifactsCore {
29    pub info: Arc<AccessorInfo>,
30    pub(crate) access_token: String,
31}
32
33impl Debug for VercelArtifactsCore {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        let mut de = f.debug_struct("VercelArtifactsCore");
36        de.field("access_token", &self.access_token);
37        de.finish()
38    }
39}
40
41impl VercelArtifactsCore {
42    pub(crate) async fn vercel_artifacts_get(
43        &self,
44        hash: &str,
45        range: BytesRange,
46        _: &OpRead,
47    ) -> Result<Response<HttpBody>> {
48        let url: String = format!(
49            "https://api.vercel.com/v8/artifacts/{}",
50            percent_encode_path(hash)
51        );
52
53        let mut req = Request::get(&url);
54
55        if !range.is_full() {
56            req = req.header(header::RANGE, range.to_header());
57        }
58
59        let auth_header_content = format!("Bearer {}", self.access_token);
60        req = req.header(header::AUTHORIZATION, auth_header_content);
61
62        req = req.extension(Operation::Read);
63
64        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
65
66        self.info.http_client().fetch(req).await
67    }
68
69    pub(crate) async fn vercel_artifacts_put(
70        &self,
71        hash: &str,
72        size: u64,
73        body: Buffer,
74    ) -> Result<Response<Buffer>> {
75        let url = format!(
76            "https://api.vercel.com/v8/artifacts/{}",
77            percent_encode_path(hash)
78        );
79
80        let mut req = Request::put(&url);
81
82        let auth_header_content = format!("Bearer {}", self.access_token);
83        req = req.header(header::CONTENT_TYPE, "application/octet-stream");
84        req = req.header(header::AUTHORIZATION, auth_header_content);
85        req = req.header(header::CONTENT_LENGTH, size);
86
87        req = req.extension(Operation::Write);
88
89        let req = req.body(body).map_err(new_request_build_error)?;
90
91        self.info.http_client().send(req).await
92    }
93
94    pub(crate) async fn vercel_artifacts_stat(&self, hash: &str) -> Result<Response<Buffer>> {
95        let url = format!(
96            "https://api.vercel.com/v8/artifacts/{}",
97            percent_encode_path(hash)
98        );
99
100        let mut req = Request::head(&url);
101
102        let auth_header_content = format!("Bearer {}", self.access_token);
103        req = req.header(header::AUTHORIZATION, auth_header_content);
104        req = req.header(header::CONTENT_LENGTH, 0);
105
106        req = req.extension(Operation::Stat);
107
108        let req = req.body(Buffer::new()).map_err(new_request_build_error)?;
109
110        self.info.http_client().send(req).await
111    }
112}