1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#![cfg_attr(feature = "unstable-doc", feature(external_doc))]
#![doc(test(attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code))))]
#![doc(test(attr(allow(unused_variables))))]
#![cfg_attr(not(feature = "unstable-doc"), doc = "# ⚠ Warning: incomplete docs!")]
#![cfg_attr(
not(feature = "unstable-doc"),
doc = "The rustdoc for this crate relies on nightly features."
)]
#![cfg_attr(
not(feature = "unstable-doc"),
doc = "To build the complete documentation, run:"
)]
#![cfg_attr(
not(feature = "unstable-doc"),
doc = "```text\ncargo +nightly doc --features unstable-doc\n```"
)]
mod abi;
mod backend;
mod body;
pub mod convert;
pub mod dictionary;
pub mod error;
pub mod geo;
pub mod handle;
pub mod limits;
pub mod log;
#[macro_use]
pub mod response;
pub mod request;
pub use crate::backend::{Backend, BackendError};
pub use crate::body::{Body, StreamingBody};
pub use crate::convert::{ToHeaderName, ToHeaderValue};
pub use crate::error::{Error, SendError};
pub use crate::request::{select, PendingRequest, Request};
pub use crate::response::Response;
pub use fastly_macros::main;
pub use http::{self, Method};
pub use mime::{self, Mime};
pub use url::Url;
pub fn uap_parse(
user_agent: &str,
) -> Result<(String, Option<String>, Option<String>, Option<String>), Error> {
let user_agent: &[u8] = user_agent.as_ref();
let max_length = 255;
let mut family = Vec::with_capacity(max_length);
let mut major = Vec::with_capacity(max_length);
let mut minor = Vec::with_capacity(max_length);
let mut patch = Vec::with_capacity(max_length);
let mut family_nwritten = 0;
let mut major_nwritten = 0;
let mut minor_nwritten = 0;
let mut patch_nwritten = 0;
let status = unsafe {
abi::fastly_uap::parse(
user_agent.as_ptr(),
user_agent.len(),
family.as_mut_ptr(),
family.capacity(),
&mut family_nwritten,
major.as_mut_ptr(),
major.capacity(),
&mut major_nwritten,
minor.as_mut_ptr(),
minor.capacity(),
&mut minor_nwritten,
patch.as_mut_ptr(),
patch.capacity(),
&mut patch_nwritten,
)
};
if status.is_err() {
return Err(Error::msg("fastly_uap::parse failed"));
}
assert!(
family_nwritten <= family.capacity(),
"fastly_uap::parse wrote too many bytes for family"
);
unsafe {
family.set_len(family_nwritten);
}
assert!(
major_nwritten <= major.capacity(),
"fastly_uap::parse wrote too many bytes for major"
);
unsafe {
major.set_len(major_nwritten);
}
assert!(
minor_nwritten <= minor.capacity(),
"fastly_uap::parse wrote too many bytes for minor"
);
unsafe {
minor.set_len(minor_nwritten);
}
assert!(
patch_nwritten <= patch.capacity(),
"fastly_uap::parse wrote too many bytes for patch"
);
unsafe {
patch.set_len(patch_nwritten);
}
Ok((
String::from_utf8_lossy(&family).to_string(),
Some(String::from_utf8_lossy(&major).to_string()),
Some(String::from_utf8_lossy(&minor).to_string()),
Some(String::from_utf8_lossy(&patch).to_string()),
))
}
pub fn init() {
unsafe { abi::fastly_abi::init(abi::FASTLY_ABI_VERSION) };
}