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