junobuild_storage/http/
response.rs1use crate::constants::{
2 RESPONSE_STATUS_CODE_308, RESPONSE_STATUS_CODE_404, RESPONSE_STATUS_CODE_406,
3 RESPONSE_STATUS_CODE_500,
4};
5use crate::http::headers::build_redirect_headers;
6use crate::http::types::{HeaderField, HttpResponse, StatusCode};
7use crate::http::utils::{
8 build_encodings, build_response_headers, build_response_redirect_headers, streaming_strategy,
9};
10use crate::strategies::{StorageCertificateStrategy, StorageStateStrategy};
11use crate::types::config::{StorageConfigIFrame, StorageConfigRedirect};
12use crate::types::store::Asset;
13use junobuild_collections::types::rules::Memory;
14
15#[allow(clippy::too_many_arguments)]
16pub fn build_asset_response(
17 requested_url: String,
18 requested_headers: Vec<HeaderField>,
19 certificate_version: Option<u16>,
20 asset: Option<(Asset, Memory)>,
21 rewrite_source: Option<String>,
22 status_code: StatusCode,
23 storage_state: &impl StorageStateStrategy,
24 certificate: &impl StorageCertificateStrategy,
25) -> HttpResponse {
26 match asset {
27 Some((asset, memory)) => {
28 let encodings = build_encodings(requested_headers);
29
30 for encoding_type in encodings.iter() {
31 if let Some(encoding) = asset.encodings.get(encoding_type) {
32 let headers = build_response_headers(
33 &requested_url,
34 &asset,
35 encoding,
36 encoding_type,
37 &certificate_version,
38 &rewrite_source,
39 &storage_state.get_config(),
40 certificate.get_pruned_labeled_sigs_root_hash_tree(),
41 );
42
43 let Asset { key, .. } = &asset;
44
45 match headers {
46 Ok(headers) => {
47 let body = storage_state.get_content_chunks(encoding, 0, &memory);
51
52 match body {
58 Some(body) => {
59 return HttpResponse {
60 body: body.clone(),
61 headers: headers.clone(),
62 status_code,
63 streaming_strategy: streaming_strategy(
64 key,
65 encoding,
66 encoding_type,
67 &headers,
68 &memory,
69 ),
70 }
71 }
72 None => {
73 return HttpResponse {
74 body: vec![],
75 headers: headers.clone(),
76 status_code,
77 streaming_strategy: None,
78 }
79 }
80 }
81 }
82 Err(err) => {
83 return error_response(
84 RESPONSE_STATUS_CODE_406,
85 ["Permission denied. Invalid headers. ", err].join(""),
86 );
87 }
88 }
89 }
90 }
91
92 error_response(
93 RESPONSE_STATUS_CODE_500,
94 "No asset encoding found.".to_string(),
95 )
96 }
97 None => error_response(RESPONSE_STATUS_CODE_404, "No asset found.".to_string()),
98 }
99}
100
101pub fn build_redirect_response(
102 requested_url: String,
103 certificate_version: Option<u16>,
104 redirect: &StorageConfigRedirect,
105 iframe: &StorageConfigIFrame,
106 certificate: &impl StorageCertificateStrategy,
107) -> HttpResponse {
108 let headers = build_response_redirect_headers(
109 &requested_url,
110 &redirect.location,
111 iframe,
112 &certificate_version,
113 certificate.get_pruned_labeled_sigs_root_hash_tree(),
114 )
115 .unwrap();
116
117 HttpResponse {
118 body: Vec::new().clone(),
119 headers: headers.clone(),
120 status_code: redirect.status_code,
121 streaming_strategy: None,
122 }
123}
124
125pub fn build_redirect_raw_response(
126 redirect_url: &str,
127 iframe: &StorageConfigIFrame,
128) -> HttpResponse {
129 let headers = build_redirect_headers(redirect_url, iframe);
130
131 HttpResponse {
132 body: Vec::new().clone(),
133 headers: headers.clone(),
134 status_code: RESPONSE_STATUS_CODE_308,
135 streaming_strategy: None,
136 }
137}
138
139pub fn error_response(status_code: StatusCode, body: String) -> HttpResponse {
140 HttpResponse {
141 body: body.as_bytes().to_vec(),
142 headers: Vec::new(),
143 status_code,
144 streaming_strategy: None,
145 }
146}