junobuild_storage/
http_request.rs

1use crate::constants::{RESPONSE_STATUS_CODE_200, RESPONSE_STATUS_CODE_405};
2use crate::http::response::{
3    build_asset_response, build_redirect_raw_response, build_redirect_response, error_response,
4};
5use crate::http::types::{
6    HttpRequest, HttpResponse, StreamingCallbackHttpResponse, StreamingCallbackToken,
7};
8use crate::http::utils::create_token;
9use crate::routing::get_routing;
10use crate::strategies::StorageStateStrategy;
11use crate::types::http_request::{
12    Routing, RoutingDefault, RoutingRedirect, RoutingRedirectRaw, RoutingRewrite,
13};
14use ic_cdk::trap;
15
16// ---------------------------------------------------------
17// Http
18// ---------------------------------------------------------
19
20pub fn http_request(
21    HttpRequest {
22        method,
23        url,
24        headers: req_headers,
25        body: _,
26        certificate_version,
27    }: HttpRequest,
28    storage_state: &impl StorageStateStrategy,
29) -> HttpResponse {
30    if method != "GET" {
31        return error_response(RESPONSE_STATUS_CODE_405, "Method Not Allowed.".to_string());
32    }
33
34    let result = get_routing(url, &req_headers, true, storage_state);
35
36    match result {
37        Ok(routing) => match routing {
38            Routing::Default(RoutingDefault { url, asset }) => build_asset_response(
39                url,
40                req_headers,
41                certificate_version,
42                asset,
43                None,
44                RESPONSE_STATUS_CODE_200,
45                storage_state,
46            ),
47            Routing::Rewrite(RoutingRewrite {
48                url,
49                asset,
50                source,
51                status_code,
52            }) => build_asset_response(
53                url,
54                req_headers,
55                certificate_version,
56                asset,
57                Some(source),
58                status_code,
59                storage_state,
60            ),
61            Routing::Redirect(RoutingRedirect {
62                url,
63                redirect,
64                iframe,
65            }) => build_redirect_response(url, certificate_version, &redirect, &iframe),
66            Routing::RedirectRaw(RoutingRedirectRaw {
67                redirect_url,
68                iframe,
69            }) => build_redirect_raw_response(&redirect_url, &iframe),
70        },
71        Err(err) => error_response(
72            RESPONSE_STATUS_CODE_405,
73            ["Permission denied. Cannot perform this operation. ", err].join(""),
74        ),
75    }
76}
77
78pub fn http_request_streaming_callback(
79    StreamingCallbackToken {
80        token,
81        headers,
82        index,
83        sha256: _,
84        full_path,
85        encoding_type,
86        memory: _,
87    }: StreamingCallbackToken,
88    storage_state: &impl StorageStateStrategy,
89) -> StreamingCallbackHttpResponse {
90    let asset = storage_state.get_public_asset(full_path, token);
91
92    match asset {
93        Some((asset, memory)) => {
94            let encoding = asset.encodings.get(&encoding_type);
95
96            match encoding {
97                Some(encoding) => {
98                    let body = storage_state.get_content_chunks(encoding, index, &memory);
99
100                    match body {
101                        Some(body) => StreamingCallbackHttpResponse {
102                            token: create_token(
103                                &asset.key,
104                                index,
105                                encoding,
106                                &encoding_type,
107                                &headers,
108                                &memory,
109                            ),
110                            body: body.clone(),
111                        },
112                        None => trap("Streamed chunks not found."),
113                    }
114                }
115                None => trap("Streamed asset encoding not found."),
116            }
117        }
118        None => trap("Streamed asset not found."),
119    }
120}