185 185 | let cfg = cfg_with_metadata("MyService", "DoThing");
|
186 186 | let request = AwsJsonRpcProtocol::aws_json_1_0("MyService")
|
187 187 | .serialize_request(&EmptyStruct, &TEST_SCHEMA, "https://example.com", &cfg)
|
188 188 | .unwrap();
|
189 189 | assert_eq!(
|
190 190 | request.headers().get("X-Amz-Target").unwrap(),
|
191 191 | "MyService.DoThing"
|
192 192 | );
|
193 193 | }
|
194 194 |
|
195 + | /// The body deserializer handed out by `deserialize_response` must reject malformed JSON
|
196 + | /// bodies end to end, not only inside containers. These are the bodies of Smithy protocol
|
197 + | /// tests `RestJsonInvalidJsonBody_case1` and `RestJsonInvalidJsonBody_case7`.
|
198 + | #[test]
|
199 + | fn malformed_response_bodies_are_rejected() {
|
200 + | use aws_smithy_runtime_api::http::Response;
|
201 + | use aws_smithy_types::body::SdkBody;
|
202 + |
|
203 + | for body in [r#"{ "int": 10 }abc"#, r#"{"int": 10,}"#] {
|
204 + | let response = Response::new(200u16.try_into().unwrap(), SdkBody::from(body));
|
205 + | let mut deser = AwsJsonRpcProtocol::aws_json_1_0("TestService")
|
206 + | .deserialize_response(&response, &TEST_SCHEMA, &ConfigBag::base())
|
207 + | .unwrap();
|
208 + | let result = deser.read_struct(&TEST_SCHEMA, &mut |_, _| Ok(()));
|
209 + | assert!(result.is_err(), "body {body:?} must be rejected");
|
210 + | }
|
211 + |
|
212 + | let response = Response::new(
|
213 + | 200u16.try_into().unwrap(),
|
214 + | SdkBody::from(r#"{ "int": 10 }"#),
|
215 + | );
|
216 + | let mut deser = AwsJsonRpcProtocol::aws_json_1_0("TestService")
|
217 + | .deserialize_response(&response, &TEST_SCHEMA, &ConfigBag::base())
|
218 + | .unwrap();
|
219 + | deser
|
220 + | .read_struct(&TEST_SCHEMA, &mut |_, _| Ok(()))
|
221 + | .expect("well-formed body is accepted");
|
222 + | }
|
223 + |
|
224 + | /// A quoted number for a double member must be rejected through the real response path.
|
225 + | /// This is the body of Smithy protocol test `RestJsonBodyDoubleMalformedValueRejected_case0`.
|
226 + | #[test]
|
227 + | fn quoted_number_for_double_member_is_rejected() {
|
228 + | use aws_smithy_runtime_api::http::Response;
|
229 + | use aws_smithy_types::body::SdkBody;
|
230 + |
|
231 + | static DOUBLE: aws_smithy_schema::Schema = aws_smithy_schema::Schema::new_member(
|
232 + | shape_id!("test", "Output", "doubleInBody"),
|
233 + | ShapeType::Double,
|
234 + | "doubleInBody",
|
235 + | 0,
|
236 + | );
|
237 + | static OUTPUT: aws_smithy_schema::Schema = aws_smithy_schema::Schema::new_struct(
|
238 + | shape_id!("test", "Output"),
|
239 + | ShapeType::Structure,
|
240 + | &[&DOUBLE],
|
241 + | );
|
242 + | let read = |body: &str| {
|
243 + | let response = Response::new(200u16.try_into().unwrap(), SdkBody::from(body));
|
244 + | let mut deser = AwsJsonRpcProtocol::aws_json_1_0("TestService")
|
245 + | .deserialize_response(&response, &OUTPUT, &ConfigBag::base())
|
246 + | .unwrap();
|
247 + | let mut value = None;
|
248 + | deser
|
249 + | .read_struct(&OUTPUT, &mut |member, d| {
|
250 + | value = Some(d.read_double(member)?);
|
251 + | Ok(())
|
252 + | })
|
253 + | .map(|()| value)
|
254 + | };
|
255 + | assert_eq!(read(r#"{ "doubleInBody" : 123 }"#).unwrap(), Some(123.0));
|
256 + | assert!(read(r#"{ "doubleInBody" : "123" }"#).is_err());
|
257 + | }
|
258 + |
|
195 259 | #[test]
|
196 260 | fn json_1_0_protocol_id() {
|
197 261 | assert_eq!(
|
198 262 | AwsJsonRpcProtocol::aws_json_1_0("Svc")
|
199 263 | .protocol_id()
|
200 264 | .as_str(),
|
201 265 | "aws.protocols#awsJson1_0"
|
202 266 | );
|
203 267 | }
|
204 268 |
|