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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#![cfg_attr(feature = "unstable-doc", feature(external_doc))]
// Warnings (other than unused variables) in doctests are promoted to errors.
#![doc(test(attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code))))]
#![doc(test(attr(allow(unused_variables))))]
#![warn(missing_docs)]
#![deny(broken_intra_doc_links)]
// Not yet a stable lint as of 1.48.0
#![cfg_attr(feature = "unstable-doc", deny(private_intra_doc_links))]
#![deny(invalid_codeblock_attributes)]

//! # Rust SDK for Compute@Edge.
//!
#![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```"
)]
//!
//! This Rustdoc page is a reference for how to use individual APIs from this SDK. For a guide-level
//! introduction to using Compute@Edge with this SDK, see [Rust on
//! Compute@Edge](https://developer.fastly.com/learning/compute/rust) at the Fastly Developer Hub.
//!
//! ## Migrating from SDK version `0.5.*` and earlier
//!
//! Version `0.6.0` introduced some substantial changes to the API to improve convenience,
//! capability, and discoverability. While there are many changed names and new types, the execution
//! model of a Compute@Edge program has not changed. This guide highlights the changes that most
//! existing Compute@Edge programs will need to make in order to work with the improved API.
//!
//! ### New `Request` and `Response`; no more `RequestExt` and `ResponseExt`
//!
//! Replace `Request<Body>` with [`Request`], and `Response<Body>` with [`Response`], and then remove
//! references to `RequestExt` and `ResponseExt`.
//!
//! In previous versions of the API, `Request` and `Response` were provided by the third-party
//! [`http`] crate. While those types are flexible enough to represent Compute@Edge HTTP values, the
//! new types are purpose-built for Compute@Edge and include a number of conveniences, such as
//! automatic conversion of method argument types and built-in support for JSON and form
//! data. Methods like `Request::send()` that were previously in the extension traits `RequestExt`
//! and `ResponseExt` are now defined directly on the types, so those traits are no longer needed.
//!
//! For example, a minimal program using [`#[fastly::main]`][`main`] now looks like:
//!
//! ```no_run
//! use fastly::{Error, Request, Response};
//!
//! #[fastly::main]
//! fn main(ds_req: Request) -> Result<Response, Error> {
//!     Ok(ds_req.send("example_backend")?)
//! }
//! ```
//!
//! ### "Client" instead of "downstream"
//!
//! Call [`Request::from_client()`] to get the client request, instead of the previous
//! `fastly::downstream_request()` function.
//!
//! Other functions and methods that used "downstream" to refer to the client that makes the initial
//! HTTP request now also use "client". For example, `Response::send_downstream()` is now
//! [`Response::send_to_client()`], and `downstream_client_ip_addr()` is now
//! [`Request::get_client_ip_addr()`].
//!
//! ### Header methods instead of `HeaderMap`
//!
//! Access headers directly through [`Request`] and [`Response`], rather than through
//! [`http::header::HeaderMap`][`::http::header::HeaderMap`]. For example, code that previously
//! looked like:
//!
//! ```no_compile
//! let my_val = req.headers().get(header_name);
//! req.headers_mut().insert(other_header_name, header_value);
//! ```
//!
//! Should now look like:
//!
//! ```no_run
//! # let mut req = fastly::Request::get("/");
//! # let header_name = "";
//! # let other_header_name = "";
//! # let header_value = "";
//! let my_val = req.get_header(header_name);
//! req.set_header(other_header_name, header_value);
//! ```
//!
//! ### Automatic argument conversion
//!
//! Pass trusted string literals and other similar types to functions like [`Request::get_header()`]
//! directly, rather than converting them explicitly.
//!
//! In previous Compute@Edge programs, it was very common to see code like:
//!
//! ```no_compile
//! HeaderName::try_from("my-header").unwrap()
//! ```
//!
//! This has an explicit type conversion and error handling, despite the fact that we know the
//! string `"my-header"` will always be a valid header name.
//!
//! Many method arguments now have types like `impl ToHeaderName` rather than `HeaderName`, allowing
//! you to mix and match strings, byte vectors, and other types into your argument types with
//! conversions performed automatically. See the documentation of the [`convert`] module's traits
//! like [`ToHeaderName`][`convert::ToHeaderName`] for details about which types can be converted,
//! and when to watch out for panics.
//!
//! ### Builder-style methods on `Request` and `Response`
//!
//! Remove uses of `http::request::Builder` and `http::response::Builder`, and use the methods of
//! [`Request`] and [`Response`] prefixed by `with_` to use builder-style method chaining. For example:
//!
//! ```no_run
//! # use fastly::{Error, Request};
//! # fn f() -> Result<(), Error> {
//! Request::get("https://example.com")
//!     .with_header("my-header", "hello!")
//!     .with_header("my-other-header", "Здравствуйте!")
//!     .send("example_backend")?;
//! # Ok(()) }
//! ```
//!
//! There are still non-builder-style getter and setter methods on [`Request`] and [`Response`], so
//! you can mix and match styles. For example:
//!
//! ```no_run
//! # use fastly::{Error, Request};
//! # fn f(needs_translation: bool) -> Result<(), Error> {
//! let mut req = Request::get("https://example.com").with_header("my-header", "hello!");
//! if needs_translation {
//!     req.set_header("my-other-header", "Здравствуйте!");
//! }
//! req.send("example_backend")?;
//! # Ok(()) }
//! ```
//!
//! ### Methods to read and modify prefixes of HTTP bodies
//!
//! Rather than buffering entire bodies with methods like [`Body::into_bytes()`] or
//! [`Body::into_string()`], you can use a new set of methods to inspect and modify a certain number
//! of bytes from the beginning of the body:
//!
//! - [`Body::get_prefix_mut()`]
//! - [`Body::get_prefix_str_mut()`]
//! - [`Body::try_get_prefix_str_mut()`]
//!
//! These methods automatically write the modified prefix back to the front of the body, making them
//! ideal for situations where you want to inspect and possibly change some metadata at the
//! beginning of a file. See the methods' documentation for examples.
mod abi;

mod backend;
pub mod convert;
mod dictionary;
pub mod error;
pub mod experimental;
pub mod geo;
pub mod handle;
pub mod http;
pub mod limits;
pub mod log;
pub mod mime;

pub use crate::backend::Backend;
pub use crate::dictionary::Dictionary;
#[doc(inline)]
pub use crate::error::Error;
#[doc(inline)]
pub use crate::http::{Body, Request, Response};
pub use fastly_macros::main;

/// Tell the runtime what ABI version this program is using.
///
// TODO ACF 2020-12-02: figure out what we want to do with this function, probably when we switch
// away from using the `fastly-sys` semver for the ABI versioning. For now, hide its documentation
// to avoid confusion for users, but still allow the `#[fastly::main]` macro to see it.
#[doc(hidden)]
pub fn init() {
    unsafe { abi::fastly_abi::init(abi::FASTLY_ABI_VERSION) };
}