Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
parity
Mirrored projects
jsonrpsee
Commits
669a43be
Unverified
Commit
669a43be
authored
Jul 25, 2022
by
Alexandru Vasile
Browse files
http: Handle RPC messages
Signed-off-by:
Alexandru Vasile
<
alexandru.vasile@parity.io
>
parent
8b2189a3
Changes
1
Hide whitespace changes
Inline
Side-by-side
http-server/src/server.rs
View file @
669a43be
...
...
@@ -38,7 +38,7 @@ use hyper::header::{HeaderMap, HeaderValue};
use
hyper
::
server
::
conn
::
AddrStream
;
use
hyper
::
server
::{
conn
::
AddrIncoming
,
Builder
as
HyperBuilder
};
use
hyper
::
service
::{
make_service_fn
,
service_fn
};
use
hyper
::{
Error
as
HyperError
,
Method
};
use
hyper
::{
Body
,
Error
as
HyperError
,
Method
};
use
jsonrpsee_core
::
error
::{
Error
,
GenericTransportError
};
use
jsonrpsee_core
::
http_helpers
::{
self
,
read_body
};
use
jsonrpsee_core
::
middleware
::{
self
,
HttpMiddleware
as
Middleware
};
...
...
@@ -410,6 +410,123 @@ struct RPSeeSvcData<M> {
batch_requests_supported
:
bool
,
}
impl
<
M
:
Middleware
>
RPSeeSvcData
<
M
>
{
/// Default behavior for RPSee handling of requests.
pub
async
fn
handle_request
(
self
,
request
:
hyper
::
Request
<
hyper
::
Body
>
)
->
Result
<
hyper
::
Response
<
hyper
::
Body
>
,
HyperError
>
{
let
RPSeeSvcData
{
remote_addr
,
methods
,
acl
,
resources
,
middleware
,
health_api
,
max_request_body_size
,
max_response_body_size
,
max_log_length
,
batch_requests_supported
,
}
=
self
;
let
remote_addr
=
match
remote_addr
{
Some
(
addr
)
=>
addr
,
// Default RPC port
None
=>
SocketAddr
::
from
(([
127
,
0
,
0
,
1
],
9944
)),
};
let
request_start
=
middleware
.on_request
(
remote_addr
,
request
.headers
());
let
keys
=
request
.headers
()
.keys
()
.map
(|
k
|
k
.as_str
());
let
cors_request_headers
=
http_helpers
::
get_cors_request_headers
(
request
.headers
());
let
host
=
match
http_helpers
::
read_header_value
(
request
.headers
(),
"host"
)
{
Some
(
origin
)
=>
origin
,
None
=>
return
Ok
(
malformed
()),
};
let
maybe_origin
=
http_helpers
::
read_header_value
(
request
.headers
(),
"origin"
);
if
let
Err
(
e
)
=
acl
.verify_host
(
host
)
{
tracing
::
warn!
(
"Denied request: {:?}"
,
e
);
return
Ok
(
response
::
host_not_allowed
());
}
if
let
Err
(
e
)
=
acl
.verify_origin
(
maybe_origin
,
host
)
{
tracing
::
warn!
(
"Denied request: {:?}"
,
e
);
return
Ok
(
response
::
invalid_allow_origin
());
}
if
let
Err
(
e
)
=
acl
.verify_headers
(
keys
,
cors_request_headers
)
{
tracing
::
warn!
(
"Denied request: {:?}"
,
e
);
return
Ok
(
response
::
invalid_allow_headers
());
}
// Only `POST` and `OPTIONS` methods are allowed.
match
*
request
.method
()
{
// An OPTIONS request is a CORS preflight request. We've done our access check
// above so we just need to tell the browser that the request is OK.
Method
::
OPTIONS
=>
{
let
origin
=
match
maybe_origin
{
Some
(
origin
)
=>
origin
,
None
=>
return
Ok
(
malformed
()),
};
let
allowed_headers
=
acl
.allowed_headers
()
.to_cors_header_value
();
let
allowed_header_bytes
=
allowed_headers
.as_bytes
();
let
res
=
hyper
::
Response
::
builder
()
.header
(
"access-control-allow-origin"
,
origin
)
.header
(
"access-control-allow-methods"
,
"POST"
)
.header
(
"access-control-allow-headers"
,
allowed_header_bytes
)
.body
(
hyper
::
Body
::
empty
())
.unwrap_or_else
(|
e
|
{
tracing
::
error!
(
"Error forming preflight response: {}"
,
e
);
internal_error
()
});
Ok
(
res
)
}
// The actual request. If it's a CORS request we need to remember to add
// the access-control-allow-origin header (despite preflight) to allow it
// to be read in a browser.
Method
::
POST
if
content_type_is_json
(
&
request
)
=>
{
let
origin
=
return_origin_if_different_from_host
(
request
.headers
())
.cloned
();
let
mut
res
=
process_validated_request
(
ProcessValidatedRequest
{
request
,
middleware
,
methods
,
resources
,
max_request_body_size
,
max_response_body_size
,
max_log_length
,
batch_requests_supported
,
request_start
,
})
.await
?
;
if
let
Some
(
origin
)
=
origin
{
res
.headers_mut
()
.insert
(
"access-control-allow-origin"
,
origin
);
}
Ok
(
res
)
}
Method
::
GET
=>
match
health_api
.as_ref
()
{
Some
(
health
)
if
health
.path
.as_str
()
==
request
.uri
()
.path
()
=>
{
process_health_request
(
health
,
middleware
,
methods
,
max_response_body_size
,
request_start
,
max_log_length
,
)
.await
}
_
=>
Ok
(
response
::
method_not_allowed
()),
},
// Error scenarios:
Method
::
POST
=>
Ok
(
response
::
unsupported_content_type
()),
_
=>
Ok
(
response
::
method_not_allowed
()),
}
}
}
/// An HTTP JSON RPC server.
#[derive(Debug)]
pub
struct
Server
<
M
=
()
>
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment