1#![doc(test(attr(deny(warnings))))]
3#![doc(test(attr(allow(dead_code))))]
4#![doc(test(attr(allow(unused_variables))))]
5#![deny(rustdoc::broken_intra_doc_links)]
6#![deny(rustdoc::invalid_codeblock_attributes)]
7
8use std::fmt;
9
10use http::HeaderValue;
11
12pub const MAX_PENDING_REQS: u32 = 16 * 1024;
16
17pub const INVALID_ACL_HANDLE: u32 = u32::MAX - 1;
20pub const INVALID_BODY_HANDLE: u32 = u32::MAX - 1;
21pub const INVALID_CACHE_BUSY_HANDLE: u32 = u32::MAX - 1;
22pub const INVALID_CACHE_HANDLE: u32 = u32::MAX - 1;
23pub const INVALID_CACHE_REPLACE_HANDLE: u32 = u32::MAX - 1;
24pub const INVALID_CONFIG_STORE_HANDLE: u32 = u32::MAX - 1;
25pub const INVALID_DICTIONARY_HANDLE: u32 = u32::MAX - 1;
26pub const INVALID_KV_PENDING_DELETE_HANDLE: u32 = u32::MAX - 1;
27pub const INVALID_KV_PENDING_INSERT_HANDLE: u32 = u32::MAX - 1;
28pub const INVALID_KV_PENDING_LIST_HANDLE: u32 = u32::MAX - 1;
29pub const INVALID_KV_PENDING_LOOKUP_HANDLE: u32 = u32::MAX - 1;
30pub const INVALID_KV_STORE_HANDLE: u32 = u32::MAX - 1;
31pub const INVALID_PENDING_REQUEST_HANDLE: u32 = u32::MAX - 1;
32pub const INVALID_REQUEST_HANDLE: u32 = u32::MAX - 1;
33pub const INVALID_REQUEST_PROMISE_HANDLE: u32 = u32::MAX - 1;
34pub const INVALID_RESPONSE_HANDLE: u32 = u32::MAX - 1;
35pub const INVALID_SECRET_HANDLE: u32 = u32::MAX - 1;
36pub const INVALID_SECRET_STORE_HANDLE: u32 = u32::MAX - 1;
37
38#[allow(non_snake_case)]
40#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41#[repr(u32)]
42pub enum SslVersion {
43 TLS1 = 0,
44 TLS1_1 = 1,
45 TLS1_2 = 2,
46 TLS1_3 = 3,
47}
48
49impl SslVersion {
50 pub fn as_u32(&self) -> u32 {
51 *self as u32
52 }
53}
54
55impl TryFrom<u32> for SslVersion {
58 type Error = String;
59 fn try_from(x: u32) -> Result<Self, Self::Error> {
60 if x == Self::TLS1 as u32 {
61 Ok(Self::TLS1)
62 } else if x == Self::TLS1_1 as u32 {
63 Ok(Self::TLS1_1)
64 } else if x == Self::TLS1_2 as u32 {
65 Ok(Self::TLS1_2)
66 } else if x == Self::TLS1_3 as u32 {
67 Ok(Self::TLS1_3)
68 } else {
69 Err(format!("unknown ssl version enum value: {x}"))
70 }
71 }
72}
73
74#[derive(Clone, Copy, Eq, PartialEq)]
75#[repr(transparent)]
76#[must_use = "Errors should never pass silently."]
77pub struct FastlyStatus {
78 pub code: i32,
79}
80
81impl FastlyStatus {
82 pub const OK: Self = Self { code: 0 };
86 pub const ERROR: Self = Self { code: 1 };
90 pub const INVAL: Self = Self { code: 2 };
92 pub const BADF: Self = Self { code: 3 };
96 pub const BUFLEN: Self = Self { code: 4 };
100 pub const UNSUPPORTED: Self = Self { code: 5 };
104 pub const BADALIGN: Self = Self { code: 6 };
108 pub const HTTPINVALID: Self = Self { code: 7 };
112 pub const HTTPUSER: Self = Self { code: 8 };
118 pub const HTTPINCOMPLETE: Self = Self { code: 9 };
122 pub const NONE: Self = Self { code: 10 };
127 pub const HTTPHEADTOOLARGE: Self = Self { code: 11 };
131 pub const HTTPINVALIDSTATUS: Self = Self { code: 12 };
135 pub const LIMITEXCEEDED: Self = Self { code: 13 };
140 pub const AGAIN: Self = Self { code: 14 };
145
146 pub fn is_ok(&self) -> bool {
147 self == &Self::OK
148 }
149
150 pub fn is_err(&self) -> bool {
151 !self.is_ok()
152 }
153
154 pub fn result(self) -> Result<(), Self> {
160 if let Self::OK = self {
161 Ok(())
162 } else {
163 Err(self)
164 }
165 }
166}
167
168impl fmt::Debug for FastlyStatus {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 write!(f, "FastlyStatus::")?;
171 match *self {
172 Self::OK => write!(f, "OK"),
173 Self::ERROR => write!(f, "ERROR"),
174 Self::INVAL => write!(f, "INVAL"),
175 Self::BADF => write!(f, "BADF"),
176 Self::BUFLEN => write!(f, "BUFLEN"),
177 Self::UNSUPPORTED => write!(f, "UNSUPPORTED"),
178 Self::BADALIGN => write!(f, "BADALIGN"),
179 Self::HTTPINVALID => write!(f, "HTTP_INVALID_ERROR"),
180 Self::HTTPUSER => write!(f, "HTTP_USER_ERROR"),
181 Self::HTTPINCOMPLETE => write!(f, "HTTP_INCOMPLETE_MESSAGE"),
182 Self::NONE => write!(f, "NONE"),
183 Self::HTTPHEADTOOLARGE => write!(f, "HTTP_HEAD_TOO_LARGE"),
184 Self::HTTPINVALIDSTATUS => write!(f, "HTTP_INVALID_STATUS"),
185 Self::LIMITEXCEEDED => write!(f, "LIMIT_EXCEEDED"),
186 Self::AGAIN => write!(f, "AGAIN"),
187 _ => write!(f, "UNKNOWN ({})", self.code),
188 }
189 }
190}
191
192pub const FASTLY_ABI_VERSION: u64 = 1;
193
194#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
196#[repr(u32)]
197pub enum HttpVersion {
198 Http09 = 0,
199 Http10 = 1,
200 Http11 = 2,
201 H2 = 3,
202 H3 = 4,
203}
204
205impl HttpVersion {
206 pub fn as_u32(&self) -> u32 {
207 *self as u32
208 }
209}
210
211impl TryFrom<u32> for HttpVersion {
214 type Error = String;
215
216 fn try_from(x: u32) -> Result<Self, Self::Error> {
217 if x == Self::Http09 as u32 {
218 Ok(Self::Http09)
219 } else if x == Self::Http10 as u32 {
220 Ok(Self::Http10)
221 } else if x == Self::Http11 as u32 {
222 Ok(Self::Http11)
223 } else if x == Self::H2 as u32 {
224 Ok(Self::H2)
225 } else if x == Self::H3 as u32 {
226 Ok(Self::H3)
227 } else {
228 Err(format!("unknown http version enum value: {x}"))
229 }
230 }
231}
232
233impl From<http::Version> for HttpVersion {
234 fn from(v: http::Version) -> Self {
235 match v {
236 http::Version::HTTP_09 => Self::Http09,
237 http::Version::HTTP_10 => Self::Http10,
238 http::Version::HTTP_11 => Self::Http11,
239 http::Version::HTTP_2 => Self::H2,
240 http::Version::HTTP_3 => Self::H3,
241 _ => unreachable!(),
242 }
243 }
244}
245
246impl From<HttpVersion> for http::Version {
247 fn from(v: HttpVersion) -> Self {
248 match v {
249 HttpVersion::Http09 => Self::HTTP_09,
250 HttpVersion::Http10 => Self::HTTP_10,
251 HttpVersion::Http11 => Self::HTTP_11,
252 HttpVersion::H2 => Self::HTTP_2,
253 HttpVersion::H3 => Self::HTTP_3,
254 }
255 }
256}
257
258#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
259#[repr(u32)]
260pub enum BodyWriteEnd {
261 Back = 0,
262 Front = 1,
263}
264
265#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
268#[repr(u32)]
269pub enum FramingHeadersMode {
270 #[default]
278 Automatic = 0,
279
280 ManuallyFromHeaders = 1,
293}
294
295#[doc(hidden)]
300#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
301#[repr(u32)]
302pub enum HttpKeepaliveMode {
303 #[default]
305 Automatic = 0,
306
307 NoKeepalive = 1,
310}
311
312#[derive(Clone, Debug)]
314pub enum CacheOverride {
315 None,
317 Pass,
319 Override {
323 ttl: Option<u32>,
324 stale_while_revalidate: Option<u32>,
325 pci: bool,
326 surrogate_key: Option<HeaderValue>,
327 },
328}
329
330impl Default for CacheOverride {
331 fn default() -> Self {
332 Self::default()
333 }
334}
335
336impl CacheOverride {
337 pub const fn none() -> Self {
338 Self::None
339 }
340
341 pub const fn pass() -> Self {
342 Self::Pass
343 }
344
345 pub fn is_pass(&self) -> bool {
346 matches!(self, Self::Pass)
347 }
348
349 pub const fn ttl(ttl: u32) -> Self {
350 Self::Override {
351 ttl: Some(ttl),
352 stale_while_revalidate: None,
353 pci: false,
354 surrogate_key: None,
355 }
356 }
357
358 pub const fn stale_while_revalidate(swr: u32) -> Self {
359 Self::Override {
360 ttl: None,
361 stale_while_revalidate: Some(swr),
362 pci: false,
363 surrogate_key: None,
364 }
365 }
366
367 pub const fn pci(pci: bool) -> Self {
368 Self::Override {
369 ttl: None,
370 stale_while_revalidate: None,
371 pci,
372 surrogate_key: None,
373 }
374 }
375
376 pub const fn surrogate_key(sk: HeaderValue) -> Self {
377 Self::Override {
378 ttl: None,
379 stale_while_revalidate: None,
380 pci: false,
381 surrogate_key: Some(sk),
382 }
383 }
384
385 pub fn set_none(&mut self) {
386 *self = Self::None;
387 }
388
389 pub fn set_pass(&mut self, pass: bool) {
390 if pass {
391 *self = Self::Pass;
392 } else if let Self::Pass = self {
393 *self = Self::None;
394 }
395 }
396
397 pub fn get_ttl(&self) -> Option<u32> {
398 if let Self::Override { ttl, .. } = self {
399 *ttl
400 } else {
401 None
402 }
403 }
404
405 pub fn set_ttl(&mut self, new_ttl: u32) {
406 match self {
407 Self::Override { ttl, .. } => *ttl = Some(new_ttl),
408 _ => *self = Self::ttl(new_ttl),
409 }
410 }
411
412 pub fn get_stale_while_revalidate(&self) -> Option<u32> {
413 if let Self::Override {
414 stale_while_revalidate,
415 ..
416 } = self
417 {
418 *stale_while_revalidate
419 } else {
420 None
421 }
422 }
423
424 pub fn set_stale_while_revalidate(&mut self, new_swr: u32) {
425 match self {
426 Self::Override {
427 stale_while_revalidate,
428 ..
429 } => *stale_while_revalidate = Some(new_swr),
430 _ => *self = Self::stale_while_revalidate(new_swr),
431 }
432 }
433
434 pub fn get_pci(&self) -> Option<bool> {
435 if let Self::Override { pci, .. } = self {
436 Some(*pci)
437 } else {
438 None
439 }
440 }
441
442 pub fn set_pci(&mut self, new_pci: bool) {
443 match self {
444 Self::Override { pci, .. } => *pci = new_pci,
445 _ => *self = Self::pci(new_pci),
446 }
447 }
448
449 pub fn get_surrogate_key(&self) -> Option<&HeaderValue> {
450 if let Self::Override { surrogate_key, .. } = self {
451 surrogate_key.as_ref()
452 } else {
453 None
454 }
455 }
456
457 pub fn set_surrogate_key(&mut self, new_surrogate_key: HeaderValue) {
458 match self {
459 Self::Override { surrogate_key, .. } => *surrogate_key = Some(new_surrogate_key),
460 _ => *self = Self::surrogate_key(new_surrogate_key),
461 }
462 }
463
464 pub const fn default() -> Self {
465 Self::None
466 }
467
468 #[doc(hidden)]
473 pub fn to_abi(&self) -> (u32, u32, u32, Option<&[u8]>) {
474 match *self {
475 Self::None => (CacheOverrideTag::empty().bits(), 0, 0, None),
476 Self::Pass => (CacheOverrideTag::PASS.bits(), 0, 0, None),
477 Self::Override {
478 ttl,
479 stale_while_revalidate,
480 pci,
481 ref surrogate_key,
482 } => {
483 let mut tag = CacheOverrideTag::empty();
484 let ttl = if let Some(ttl) = ttl {
485 tag |= CacheOverrideTag::TTL;
486 ttl
487 } else {
488 0
489 };
490 let swr = if let Some(swr) = stale_while_revalidate {
491 tag |= CacheOverrideTag::STALE_WHILE_REVALIDATE;
492 swr
493 } else {
494 0
495 };
496 if pci {
497 tag |= CacheOverrideTag::PCI;
498 }
499 let sk = surrogate_key.as_ref().map(HeaderValue::as_bytes);
500 (tag.bits(), ttl, swr, sk)
501 }
502 }
503 }
504}
505
506bitflags::bitflags! {
507 struct CacheOverrideTag: u32 {
511 const PASS = 1 << 0;
512 const TTL = 1 << 1;
513 const STALE_WHILE_REVALIDATE = 1 << 2;
514 const PCI = 1 << 3;
515 }
516}
517
518#[derive(Debug, Clone, Copy, Eq, PartialEq)]
519pub enum ClientCertVerifyResult {
520 Ok,
524 BadCertificate,
529 CertificateRevoked,
533 CertificateExpired,
537 UnknownCa,
543 CertificateMissing,
547 CertificateUnknown,
552}
553
554impl ClientCertVerifyResult {
555 pub fn from_u32(value: u32) -> ClientCertVerifyResult {
556 match value {
557 0 => ClientCertVerifyResult::Ok,
558 1 => ClientCertVerifyResult::BadCertificate,
559 2 => ClientCertVerifyResult::CertificateRevoked,
560 3 => ClientCertVerifyResult::CertificateExpired,
561 4 => ClientCertVerifyResult::UnknownCa,
562 5 => ClientCertVerifyResult::CertificateMissing,
563 _ => ClientCertVerifyResult::CertificateUnknown,
564 }
565 }
566}