Add missing application/json headers to RPC requests (#4215)

This enables compatibility with `zcash-cli`.
This commit is contained in:
teor 2022-04-28 10:57:13 +10:00 committed by GitHub
parent 5a94a09292
commit 1f2837c86e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 2 deletions

View File

@ -9,13 +9,23 @@ use jsonrpc_http_server::RequestMiddleware;
/// ///
/// This middleware makes the following changes to requests: /// This middleware makes the following changes to requests:
/// ///
/// ## JSON RPC 1.0 `jsonrpc` field /// ## Remove `jsonrpc` field in JSON RPC 1.0
/// ///
/// Removes "jsonrpc: 1.0" fields from requests, /// Removes "jsonrpc: 1.0" fields from requests,
/// because the "jsonrpc" field was only added in JSON-RPC 2.0. /// because the "jsonrpc" field was only added in JSON-RPC 2.0.
/// ///
/// <http://www.simple-is-better.org/rpc/#differences-between-1-0-and-2-0> /// <http://www.simple-is-better.org/rpc/#differences-between-1-0-and-2-0>
/// ///
/// ## Add missing `content-type` HTTP header
///
/// Some RPC clients don't include a `content-type` HTTP header.
/// But unlike web browsers, [`jsonrpc_http_server`] does not do content sniffing.
///
/// If there is no `content-type` header, we assume the content is JSON,
/// and let the parser error if we are incorrect.
///
/// This enables compatibility with `zcash-cli`.
///
/// ## Security /// ## Security
/// ///
/// Any user-specified data in RPC requests is hex or base58check encoded. /// Any user-specified data in RPC requests is hex or base58check encoded.
@ -27,8 +37,14 @@ pub struct FixHttpRequestMiddleware;
impl RequestMiddleware for FixHttpRequestMiddleware { impl RequestMiddleware for FixHttpRequestMiddleware {
fn on_request( fn on_request(
&self, &self,
request: hyper::Request<hyper::Body>, mut request: hyper::Request<hyper::Body>,
) -> jsonrpc_http_server::RequestMiddlewareAction { ) -> jsonrpc_http_server::RequestMiddlewareAction {
tracing::trace!(?request, "original HTTP request");
// Fix the request headers
FixHttpRequestMiddleware::add_missing_content_type_header(request.headers_mut());
// Fix the request body
let request = request.map(|body| { let request = request.map(|body| {
let body = body.map_ok(|data| { let body = body.map_ok(|data| {
// To simplify data handling, we assume that any search strings won't be split // To simplify data handling, we assume that any search strings won't be split
@ -54,6 +70,8 @@ impl RequestMiddleware for FixHttpRequestMiddleware {
Body::wrap_stream(body) Body::wrap_stream(body)
}); });
tracing::trace!(?request, "modified HTTP request");
jsonrpc_http_server::RequestMiddlewareAction::Proceed { jsonrpc_http_server::RequestMiddlewareAction::Proceed {
// TODO: disable this security check if we see errors from lightwalletd. // TODO: disable this security check if we see errors from lightwalletd.
should_continue_on_invalid_cors: false, should_continue_on_invalid_cors: false,
@ -82,4 +100,12 @@ impl FixHttpRequestMiddleware {
.replace(",\"jsonrpc\":\"1.0\"", "") .replace(",\"jsonrpc\":\"1.0\"", "")
.replace(", \"jsonrpc\": \"1.0\"", "") .replace(", \"jsonrpc\": \"1.0\"", "")
} }
/// If the `content-type` HTTP header is not present,
/// add an `application/json` content type header.
pub fn add_missing_content_type_header(headers: &mut hyper::header::HeaderMap) {
headers
.entry(hyper::header::CONTENT_TYPE)
.or_insert(hyper::header::HeaderValue::from_static("application/json"));
}
} }