Decompress and read gzipped responses

When you need to work on API and text responses from backends that support gzip.

Compute@Edge

Use this solution in your Compute@Edge service:

  1. Rust
  2. JavaScript
  3. Go
Cargo.toml
Rust
[dependencies]
fastly = "0.7.1"
libflate = "1.1.0"
main.rs
Rust
// This function prevents responses on other compression formats
// so the content-encoding response header must be "gzip"
// and we can focus on gzip
#[fastly::main]
fn main(mut req: Request) -> Result<Response, Error> {
let accept_encoding = match req.get_header(header::ACCEPT_ENCODING) {
Some(accept_encoding_value) if accept_encoding_value.to_str().unwrap().contains("gzip") => {
req.set_header(header::ACCEPT_ENCODING, "gzip");
true
}
_ => false,
};
let mut response = req.send(BACKEND_NAME)?;
let body = response.take_body();
let body_orig = match response.get_header(header::CONTENT_ENCODING) {
Some(_) => {
let mut decoder = Decoder::new(body).unwrap();
let mut decoded_data = Vec::new();
decoder.read_to_end(&mut decoded_data).unwrap();
String::from_utf8(decoded_data).unwrap()
}
None => body.into_string(),
};
// The following line is just a placeholder to your code.
// Now it is a string, work on the response body and modify it at will
let body_transformed = str::replace(&body_orig, "dog", "cat");
// Return a response with the new body
if accept_encoding {
response.remove_header(header::CONTENT_ENCODING);
// The next header tells Fastly to compress your modified response
// so you do not need to spend C@E CPU for this
response.set_header("x-compress-hint", "on");
}
response.set_body(body_transformed);
Ok(response)
}