diff --git a/src/server/message.rs b/src/server/message.rs index cf366dbf40a..0773864a85f 100644 --- a/src/server/message.rs +++ b/src/server/message.rs @@ -269,10 +269,18 @@ impl RawMessage { Id::Null => None, }; - let params = R::Params::deserialize(&self.params).map_err(|e| { - debug!("error when parsing as request: {}", e); - jsonrpc::Error::invalid_params(format!("{}", e)) - })?; + let params = R::Params::deserialize(&self.params) + .or_else(|e| { + // Avoid tedious type errors trying to deserialize `()` + if std::mem::size_of::() == 0 { + R::Params::deserialize(&serde_json::Value::Null).map_err(|_| e) + } else { + Err(e) + } + }).map_err(|e| { + debug!("error when parsing as request: {}", e); + jsonrpc::Error::invalid_params(format!("{}", e)) + })?; match parsed_id { Some(id) => Ok(Request { diff --git a/src/server/mod.rs b/src/server/mod.rs index c24a95c06d3..f1aa6227f81 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -465,4 +465,18 @@ mod test { assert_eq!(get_root_path(¶ms), root_path); } + + /// Some clients send empty object params for void params requests (see #1038) + #[test] + fn parse_shutdown_object_params() { + let raw = RawMessage::try_parse( + r#"{"jsonrpc": "2.0", "id": 2, "method": "shutdown", "params": {}}"#, + ).ok() + .and_then(|x| x) + .expect("raw parse failed"); + + let _request: Request = raw + .parse_as_request() + .expect("Boring validation is happening"); + } }