pub fn complement(&mut self) {
        // build the canonical request
        self.canonical_uri = self.canonical_path();
        self.canonical_query_string = build_canonical_query_string(&self.params);
        // Gotta remove and re-add headers since by default they append the value.  If we're following
        // a 307 redirect we end up with Three Stooges in the headers with duplicate values.
        self.remove_header("host");
        self.add_header("host", &self.hostname());
        // if there's no content-type header set, set it to the default value
        if let Entry::Vacant(entry) = self.headers.entry("content-type".to_owned()) {
            let mut values = Vec::new();
            values.push(b"application/octet-stream".to_vec());
            entry.insert(values);
        }
        let len = match self.payload {
            None => Some(0),
            Some(SignedRequestPayload::Buffer(ref payload)) => Some(payload.len()),
            Some(SignedRequestPayload::Stream(ref stream)) => stream.size_hint(),
        };
        if let Some(len) = len {
            self.remove_header("content-length");
            self.add_header("content-length", &format!("{}", len));
        }
    }
Complement SignedRequest by ensuring the following HTTP headers are set accordingly:
- host
- content-type
- content-length (if applicable)
rusoto/signature/src/signature.rs