Skip to content

Commit

Permalink
Allow wildcard CORS (#2568)
Browse files Browse the repository at this point in the history
* Allow wildcard CORS

* Add test

* Omit Allow-Credentials when not required
  • Loading branch information
shohamc1 authored Oct 11, 2023
1 parent 6a4cab5 commit 99aa229
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 7 deletions.
10 changes: 4 additions & 6 deletions lib/ain-grpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,13 @@ pub fn init_network_json_rpc_service(runtime: &Services, addr: &str) -> Result<(
let max_connections = ain_cpp_imports::get_max_connections();

let middleware = if !ain_cpp_imports::get_cors_allowed_origin().is_empty() {
info!(
"Allowed origins: {}",
ain_cpp_imports::get_cors_allowed_origin()
);
let origin = ain_cpp_imports::get_cors_allowed_origin();
info!("Allowed origins: {}", origin);
let cors = CorsLayer::new()
.allow_methods([Method::POST, Method::GET, Method::OPTIONS])
.allow_origin(ain_cpp_imports::get_cors_allowed_origin().parse::<HeaderValue>()?)
.allow_origin(origin.parse::<HeaderValue>()?)
.allow_headers([hyper::header::CONTENT_TYPE, hyper::header::AUTHORIZATION])
.allow_credentials(true);
.allow_credentials(origin != "*");

tower::ServiceBuilder::new().layer(cors)
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/httprpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ static bool CorsHandler(HTTPRequest *req) {
return false;

req->WriteHeader("Access-Control-Allow-Origin", host);
req->WriteHeader("Access-Control-Allow-Credentials", "true");
if (host != "*")
req->WriteHeader("Access-Control-Allow-Credentials", "true");
req->WriteHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
req->WriteHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

Expand Down
91 changes: 91 additions & 0 deletions test/functional/interface_http_cors_wildcard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
"""Test the RPC HTTP CORS."""

from test_framework.test_framework import DefiTestFramework
from test_framework.util import assert_equal, str_to_b64str

import http.client
import urllib.parse


class HTTPCorsWildcardTest(DefiTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.cors_origin = "*"
self.extra_args = [["-rpcallowcors=" + self.cors_origin]]

def run_test(self):
print("LETSGO")
self.test_json_rpc_port()
self.test_eth_json_rpc_port()

def test_json_rpc_port(self):
url = urllib.parse.urlparse(self.nodes[0].url)
authpair = url.username + ":" + url.password

# same should be if we add keep-alive because this should be the std. behaviour
headers = {
"Authorization": "Basic " + str_to_b64str(authpair),
"Connection": "keep-alive",
}

conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request("POST", "/", '{"method": "getbestblockhash"}', headers)
res = conn.getresponse()
self.check_cors_headers(res)
assert_equal(res.status, http.client.OK)
res.close()

conn.request("OPTIONS", "/", '{"method": "getbestblockhash"}', headers)
res = conn.getresponse()
self.check_cors_headers(res)
assert_equal(res.status, http.client.NO_CONTENT)
res.close()

def test_eth_json_rpc_port(self):
url = urllib.parse.urlparse(self.nodes[0].evm_rpc.url)

# same should be if we add keep-alive because this should be the std. behaviour
headers = {
"Connection": "keep-alive",
"Content-Type": "application/json",
}

conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request("POST", "/", '{"method": "eth_syncing"}', headers)
res = conn.getresponse()
print(res.status)
print(res.headers)
self.check_cors_headers(res, False, False)
assert_equal(res.status, http.client.OK)
res.close()

conn.request("OPTIONS", "/", '{"method": "eth_syncing"}', headers)
res = conn.getresponse()
self.check_cors_headers(res, False, False)
assert_equal(res.status, http.client.OK)
res.close()

def check_cors_headers(
self, res, check_allow_methods=True, check_allow_headers=True
):
assert_equal(res.getheader("Access-Control-Allow-Origin"), self.cors_origin)
assert_equal(res.getheader("Access-Control-Allow-Credentials"), None)
if check_allow_methods:
assert_equal(
res.getheader("Access-Control-Allow-Methods"), "POST, GET, OPTIONS"
)
if check_allow_headers:
assert_equal(
res.getheader("Access-Control-Allow-Headers"),
"Content-Type, Authorization",
)


if __name__ == "__main__":
HTTPCorsWildcardTest().main()
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
"feature_consortium.py",
"interface_http.py",
"interface_http_cors.py",
"interface_http_cors_wildcard.py",
"interface_rpc.py",
"rpc_psbt.py",
"rpc_users.py",
Expand Down

0 comments on commit 99aa229

Please sign in to comment.