jsonrpsee_http_server/
response.rs

1// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27//! Contains common builders for hyper responses.
28
29use jsonrpsee_types::error::reject_too_big_request;
30
31use crate::types::error::{ErrorCode, ErrorResponse};
32use crate::types::Id;
33
34const JSON: &str = "application/json; charset=utf-8";
35const TEXT: &str = "text/plain";
36
37/// Create a response for json internal error.
38pub fn internal_error() -> hyper::Response<hyper::Body> {
39	let error = serde_json::to_string(&ErrorResponse::borrowed(ErrorCode::InternalError.into(), Id::Null))
40		.expect("built from known-good data; qed");
41
42	from_template(hyper::StatusCode::INTERNAL_SERVER_ERROR, error, JSON)
43}
44
45/// Create a text/plain response for not allowed hosts.
46pub fn host_not_allowed() -> hyper::Response<hyper::Body> {
47	from_template(hyper::StatusCode::FORBIDDEN, "Provided Host header is not whitelisted.\n".to_owned(), TEXT)
48}
49
50/// Create a text/plain response for disallowed method used.
51pub fn method_not_allowed() -> hyper::Response<hyper::Body> {
52	from_template(
53		hyper::StatusCode::METHOD_NOT_ALLOWED,
54		"Used HTTP Method is not allowed. POST or OPTIONS is required\n".to_owned(),
55		TEXT,
56	)
57}
58
59/// Create a text/plain response for invalid CORS "Origin" headers.
60pub fn invalid_allow_origin() -> hyper::Response<hyper::Body> {
61	from_template(
62        hyper::StatusCode::FORBIDDEN,
63        "Origin of the request is not whitelisted. CORS headers would not be sent and any side-effects were cancelled as well.\n".to_owned(),
64		TEXT,
65    )
66}
67
68/// Create a text/plain response for invalid CORS "Allow-*" headers.
69pub fn invalid_allow_headers() -> hyper::Response<hyper::Body> {
70	from_template(
71        hyper::StatusCode::FORBIDDEN,
72        "Requested headers are not allowed for CORS. CORS headers would not be sent and any side-effects were cancelled as well.\n".to_owned(),
73		TEXT,
74    )
75}
76
77/// Create a json response for oversized requests (413)
78pub fn too_large(limit: u32) -> hyper::Response<hyper::Body> {
79	let error = serde_json::to_string(&ErrorResponse::borrowed(reject_too_big_request(limit), Id::Null))
80		.expect("built from known-good data; qed");
81
82	from_template(hyper::StatusCode::PAYLOAD_TOO_LARGE, error, JSON)
83}
84
85/// Create a json response for empty or malformed requests (400)
86pub fn malformed() -> hyper::Response<hyper::Body> {
87	let error = serde_json::to_string(&ErrorResponse::borrowed(ErrorCode::ParseError.into(), Id::Null))
88		.expect("built from known-good data; qed");
89
90	from_template(hyper::StatusCode::BAD_REQUEST, error, JSON)
91}
92
93/// Create a response body.
94fn from_template<S: Into<hyper::Body>>(
95	status: hyper::StatusCode,
96	body: S,
97	content_type: &'static str,
98) -> hyper::Response<hyper::Body> {
99	hyper::Response::builder()
100		.status(status)
101		.header("content-type", hyper::header::HeaderValue::from_static(content_type))
102		.body(body.into())
103		// Parsing `StatusCode` and `HeaderValue` is infalliable but
104		// parsing body content is not.
105		.expect("Unable to parse response body for type conversion")
106}
107
108/// Create a valid JSON response.
109pub fn ok_response(body: String) -> hyper::Response<hyper::Body> {
110	from_template(hyper::StatusCode::OK, body, JSON)
111}
112
113/// Create a response for unsupported content type.
114pub fn unsupported_content_type() -> hyper::Response<hyper::Body> {
115	from_template(
116		hyper::StatusCode::UNSUPPORTED_MEDIA_TYPE,
117		"Supplied content type is not allowed. Content-Type: application/json is required\n".to_owned(),
118		TEXT,
119	)
120}