kipuka_coap/
content_format.rs1pub const APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE: u16 = 280;
16
17pub const APPLICATION_PKCS7_MIME_CERTS_ONLY: u16 = 281;
22
23pub const APPLICATION_PKCS7_MIME_CMC_REQUEST: u16 = 282;
27
28pub const APPLICATION_PKCS7_MIME_CMC_RESPONSE: u16 = 283;
32
33pub const APPLICATION_PKCS7_MIME: u16 = 284;
37
38pub const APPLICATION_PKCS10: u16 = 285;
43
44pub const APPLICATION_PKCS8: u16 = 286;
49
50pub const APPLICATION_CSRATTRS: u16 = 287;
55
56pub const MULTIPART_CORE: u16 = 62;
61
62pub fn to_http_content_type(format_id: u16) -> Option<&'static str> {
71 match format_id {
72 APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE => {
73 Some("application/pkcs7-mime; smime-type=server-generated")
74 }
75 APPLICATION_PKCS7_MIME_CERTS_ONLY => Some("application/pkcs7-mime; smime-type=certs-only"),
76 APPLICATION_PKCS7_MIME_CMC_REQUEST => {
77 Some("application/pkcs7-mime; smime-type=CMC-Request")
78 }
79 APPLICATION_PKCS7_MIME_CMC_RESPONSE => {
80 Some("application/pkcs7-mime; smime-type=CMC-Response")
81 }
82 APPLICATION_PKCS7_MIME => Some("application/pkcs7-mime"),
83 APPLICATION_PKCS10 => Some("application/pkcs10"),
84 APPLICATION_PKCS8 => Some("application/pkcs8"),
85 APPLICATION_CSRATTRS => Some("application/csrattrs"),
86 MULTIPART_CORE => Some("multipart/core"),
87 _ => None,
88 }
89}
90
91pub fn from_http_content_type(mime: &str) -> Option<u16> {
101 let lower = mime.to_ascii_lowercase();
102 let lower = lower.trim();
103
104 if lower.starts_with("application/pkcs7-mime") {
106 if lower.contains("server-generated") {
107 return Some(APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE);
108 }
109 if lower.contains("certs-only") {
110 return Some(APPLICATION_PKCS7_MIME_CERTS_ONLY);
111 }
112 if lower.contains("cmc-request") {
113 return Some(APPLICATION_PKCS7_MIME_CMC_REQUEST);
114 }
115 if lower.contains("cmc-response") {
116 return Some(APPLICATION_PKCS7_MIME_CMC_RESPONSE);
117 }
118 return Some(APPLICATION_PKCS7_MIME);
119 }
120
121 let base = lower.split(';').next().unwrap_or("").trim();
123
124 match base {
125 "application/pkcs10" => Some(APPLICATION_PKCS10),
126 "application/pkcs8" => Some(APPLICATION_PKCS8),
127 "application/csrattrs" => Some(APPLICATION_CSRATTRS),
128 "multipart/core" => Some(MULTIPART_CORE),
129 _ => None,
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_content_format_constants() {
139 assert_eq!(APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE, 280);
140 assert_eq!(APPLICATION_PKCS7_MIME_CERTS_ONLY, 281);
141 assert_eq!(APPLICATION_PKCS7_MIME_CMC_REQUEST, 282);
142 assert_eq!(APPLICATION_PKCS7_MIME_CMC_RESPONSE, 283);
143 assert_eq!(APPLICATION_PKCS7_MIME, 284);
144 assert_eq!(APPLICATION_PKCS10, 285);
145 assert_eq!(APPLICATION_PKCS8, 286);
146 assert_eq!(APPLICATION_CSRATTRS, 287);
147 assert_eq!(MULTIPART_CORE, 62);
148 }
149
150 #[test]
151 fn test_to_http_content_type() {
152 assert_eq!(
153 to_http_content_type(APPLICATION_PKCS10),
154 Some("application/pkcs10")
155 );
156 assert_eq!(
157 to_http_content_type(APPLICATION_PKCS8),
158 Some("application/pkcs8")
159 );
160 assert_eq!(
161 to_http_content_type(APPLICATION_PKCS7_MIME_CERTS_ONLY),
162 Some("application/pkcs7-mime; smime-type=certs-only")
163 );
164 assert_eq!(
165 to_http_content_type(APPLICATION_CSRATTRS),
166 Some("application/csrattrs")
167 );
168 assert_eq!(to_http_content_type(MULTIPART_CORE), Some("multipart/core"));
169 assert_eq!(to_http_content_type(9999), None);
170 }
171
172 #[test]
173 fn test_from_http_content_type_exact() {
174 assert_eq!(
175 from_http_content_type("application/pkcs10"),
176 Some(APPLICATION_PKCS10)
177 );
178 assert_eq!(
179 from_http_content_type("application/pkcs8"),
180 Some(APPLICATION_PKCS8)
181 );
182 assert_eq!(
183 from_http_content_type("application/csrattrs"),
184 Some(APPLICATION_CSRATTRS)
185 );
186 }
187
188 #[test]
189 fn test_from_http_content_type_case_insensitive() {
190 assert_eq!(
191 from_http_content_type("Application/PKCS10"),
192 Some(APPLICATION_PKCS10)
193 );
194 assert_eq!(
195 from_http_content_type("APPLICATION/PKCS8"),
196 Some(APPLICATION_PKCS8)
197 );
198 }
199
200 #[test]
201 fn test_from_http_content_type_pkcs7_variants() {
202 assert_eq!(
203 from_http_content_type("application/pkcs7-mime; smime-type=certs-only"),
204 Some(APPLICATION_PKCS7_MIME_CERTS_ONLY)
205 );
206 assert_eq!(
207 from_http_content_type("application/pkcs7-mime; smimeType=CMC-Request"),
208 Some(APPLICATION_PKCS7_MIME_CMC_REQUEST)
209 );
210 assert_eq!(
211 from_http_content_type("application/pkcs7-mime; smimeType=CMC-Response"),
212 Some(APPLICATION_PKCS7_MIME_CMC_RESPONSE)
213 );
214 assert_eq!(
215 from_http_content_type("application/pkcs7-mime; smime-type=server-generated"),
216 Some(APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE)
217 );
218 assert_eq!(
219 from_http_content_type("application/pkcs7-mime"),
220 Some(APPLICATION_PKCS7_MIME)
221 );
222 }
223
224 #[test]
225 fn test_from_http_content_type_unknown() {
226 assert_eq!(from_http_content_type("text/plain"), None);
227 assert_eq!(from_http_content_type("application/json"), None);
228 }
229
230 #[test]
231 fn test_roundtrip_all_formats() {
232 let ids = [
233 APPLICATION_PKCS7_MIME_SERVER_GEN_TYPE,
234 APPLICATION_PKCS7_MIME_CERTS_ONLY,
235 APPLICATION_PKCS7_MIME_CMC_REQUEST,
236 APPLICATION_PKCS7_MIME_CMC_RESPONSE,
237 APPLICATION_PKCS7_MIME,
238 APPLICATION_PKCS10,
239 APPLICATION_PKCS8,
240 APPLICATION_CSRATTRS,
241 MULTIPART_CORE,
242 ];
243
244 for id in ids {
245 let mime = to_http_content_type(id).expect("known format should have MIME type");
246 let back = from_http_content_type(mime).expect("known MIME type should have format ID");
247 assert_eq!(back, id, "roundtrip failed for format ID {id}: {mime}");
248 }
249 }
250}