|
1 | 1 | use crate::{Config, Error};
|
2 |
| -use http::HeaderMap; |
| 2 | +use http::{HeaderMap, HeaderValue}; |
3 | 3 | use serde::{Deserialize, Serialize};
|
4 | 4 | use std::{collections::HashMap, convert::TryFrom};
|
5 | 5 |
|
@@ -120,28 +120,107 @@ impl TryFrom<HeaderMap> for Context {
|
120 | 120 | type Error = Error;
|
121 | 121 | fn try_from(headers: HeaderMap) -> Result<Self, Self::Error> {
|
122 | 122 | let ctx = Context {
|
123 |
| - request_id: headers["lambda-runtime-aws-request-id"] |
124 |
| - .to_str() |
125 |
| - .expect("Missing Request ID") |
| 123 | + request_id: headers |
| 124 | + .get("lambda-runtime-aws-request-id") |
| 125 | + .expect("missing lambda-runtime-aws-request-id header") |
| 126 | + .to_str()? |
126 | 127 | .to_owned(),
|
127 |
| - deadline: headers["lambda-runtime-deadline-ms"] |
| 128 | + deadline: headers |
| 129 | + .get("lambda-runtime-deadline-ms") |
| 130 | + .expect("missing lambda-runtime-deadline-ms header") |
| 131 | + .to_str()? |
| 132 | + .parse::<u64>()?, |
| 133 | + invoked_function_arn: headers |
| 134 | + .get("lambda-runtime-invoked-function-arn") |
| 135 | + .unwrap_or(&HeaderValue::from_static( |
| 136 | + "No header lambda-runtime-invoked-function-arn found.", |
| 137 | + )) |
128 | 138 | .to_str()?
|
129 |
| - .parse() |
130 |
| - .expect("Missing deadline"), |
131 |
| - invoked_function_arn: headers["lambda-runtime-invoked-function-arn"] |
132 |
| - .to_str() |
133 |
| - .expect("Missing arn; this is a bug") |
134 | 139 | .to_owned(),
|
135 |
| - xray_trace_id: headers["lambda-runtime-trace-id"] |
136 |
| - .to_str() |
137 |
| - .expect("Invalid XRayTraceID sent by Lambda; this is a bug") |
| 140 | + xray_trace_id: headers |
| 141 | + .get("lambda-runtime-trace-id") |
| 142 | + .unwrap_or(&HeaderValue::from_static("No header lambda-runtime-trace-id found.")) |
| 143 | + .to_str()? |
138 | 144 | .to_owned(),
|
139 | 145 | ..Default::default()
|
140 | 146 | };
|
141 | 147 | Ok(ctx)
|
142 | 148 | }
|
143 | 149 | }
|
144 | 150 |
|
| 151 | +#[cfg(test)] |
| 152 | +mod test { |
| 153 | + use super::*; |
| 154 | + |
| 155 | + #[test] |
| 156 | + fn context_with_expected_values_and_types_resolves() { |
| 157 | + let mut headers = HeaderMap::new(); |
| 158 | + headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); |
| 159 | + headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123")); |
| 160 | + headers.insert( |
| 161 | + "lambda-runtime-invoked-function-arn", |
| 162 | + HeaderValue::from_static("arn::myarn"), |
| 163 | + ); |
| 164 | + headers.insert("lambda-runtime-trace-id", HeaderValue::from_static("arn::myarn")); |
| 165 | + let tried = Context::try_from(headers); |
| 166 | + assert!(tried.is_ok()); |
| 167 | + } |
| 168 | + |
| 169 | + #[test] |
| 170 | + fn context_with_certain_missing_headers_still_resolves() { |
| 171 | + let mut headers = HeaderMap::new(); |
| 172 | + headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); |
| 173 | + headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123")); |
| 174 | + let tried = Context::try_from(headers); |
| 175 | + assert!(tried.is_ok()); |
| 176 | + } |
| 177 | + |
| 178 | + #[test] |
| 179 | + fn context_with_bad_deadline_type_is_err() { |
| 180 | + let mut headers = HeaderMap::new(); |
| 181 | + headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); |
| 182 | + headers.insert( |
| 183 | + "lambda-runtime-deadline-ms", |
| 184 | + HeaderValue::from_static("BAD-Type,not <u64>"), |
| 185 | + ); |
| 186 | + headers.insert( |
| 187 | + "lambda-runtime-invoked-function-arn", |
| 188 | + HeaderValue::from_static("arn::myarn"), |
| 189 | + ); |
| 190 | + headers.insert("lambda-runtime-trace-id", HeaderValue::from_static("arn::myarn")); |
| 191 | + let tried = Context::try_from(headers); |
| 192 | + assert!(tried.is_err()); |
| 193 | + } |
| 194 | + |
| 195 | + #[test] |
| 196 | + #[should_panic] |
| 197 | + #[allow(unused_must_use)] |
| 198 | + fn context_with_missing_request_id_should_panic() { |
| 199 | + let mut headers = HeaderMap::new(); |
| 200 | + headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id")); |
| 201 | + headers.insert( |
| 202 | + "lambda-runtime-invoked-function-arn", |
| 203 | + HeaderValue::from_static("arn::myarn"), |
| 204 | + ); |
| 205 | + headers.insert("lambda-runtime-trace-id", HeaderValue::from_static("arn::myarn")); |
| 206 | + Context::try_from(headers); |
| 207 | + } |
| 208 | + |
| 209 | + #[test] |
| 210 | + #[should_panic] |
| 211 | + #[allow(unused_must_use)] |
| 212 | + fn context_with_missing_deadline_should_panic() { |
| 213 | + let mut headers = HeaderMap::new(); |
| 214 | + headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123")); |
| 215 | + headers.insert( |
| 216 | + "lambda-runtime-invoked-function-arn", |
| 217 | + HeaderValue::from_static("arn::myarn"), |
| 218 | + ); |
| 219 | + headers.insert("lambda-runtime-trace-id", HeaderValue::from_static("arn::myarn")); |
| 220 | + Context::try_from(headers); |
| 221 | + } |
| 222 | +} |
| 223 | + |
145 | 224 | impl Context {
|
146 | 225 | /// Add environment details to the context by setting `env_config`.
|
147 | 226 | pub fn with_config(self, config: &Config) -> Self {
|
|
0 commit comments