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
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) -> 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}