Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to allow access methods from default url #1214

Merged
merged 3 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/brpc/policy/http_rpc_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ FindMethodPropertyByURI(const std::string& uri_path, const Server* server,
const Server::MethodProperty* mp =
FindMethodPropertyByURIImpl(uri_path, server, unresolved_path);
if (mp != NULL) {
if (mp->http_url != NULL) {
if (mp->http_url != NULL && !mp->params.allow_default_url) {
// the restful method is accessed from its
// default url (SERVICE/METHOD) which should be rejected.
return NULL;
Expand Down
9 changes: 8 additions & 1 deletion src/brpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ServerSSLOptions* ServerOptions::mutable_ssl_options() {

Server::MethodProperty::OpaqueParams::OpaqueParams()
: is_tabbed(false)
, allow_default_url(false)
, allow_http_body_to_pb(true)
, pb_bytes_to_base64(false) {
}
Expand Down Expand Up @@ -1207,6 +1208,7 @@ int Server::AddServiceInternal(google::protobuf::Service* service,
mp.is_builtin_service = is_builtin_service;
mp.own_method_status = true;
mp.params.is_tabbed = !!tabbed;
mp.params.allow_default_url = svc_opt.allow_default_url;
mp.params.allow_http_body_to_pb = svc_opt.allow_http_body_to_pb;
mp.params.pb_bytes_to_base64 = svc_opt.pb_bytes_to_base64;
mp.service = service;
Expand Down Expand Up @@ -1293,6 +1295,7 @@ int Server::AddServiceInternal(google::protobuf::Service* service,
}
MethodProperty::OpaqueParams params;
params.is_tabbed = !!tabbed;
params.allow_default_url = svc_opt.allow_default_url;
params.allow_http_body_to_pb = svc_opt.allow_http_body_to_pb;
params.pb_bytes_to_base64 = svc_opt.pb_bytes_to_base64;
if (!_global_restful_map->AddMethod(
Expand Down Expand Up @@ -1330,6 +1333,7 @@ int Server::AddServiceInternal(google::protobuf::Service* service,
}
MethodProperty::OpaqueParams params;
params.is_tabbed = !!tabbed;
params.allow_default_url = svc_opt.allow_default_url;
params.allow_http_body_to_pb = svc_opt.allow_http_body_to_pb;
params.pb_bytes_to_base64 = svc_opt.pb_bytes_to_base64;
if (!m->AddMethod(mappings[i].path, service, params,
Expand Down Expand Up @@ -1384,6 +1388,7 @@ int Server::AddServiceInternal(google::protobuf::Service* service,

ServiceOptions::ServiceOptions()
: ownership(SERVER_DOESNT_OWN_SERVICE)
, allow_default_url(false)
, allow_http_body_to_pb(true)
#ifdef BAIDU_INTERNAL
, pb_bytes_to_base64(false)
Expand All @@ -1401,11 +1406,13 @@ int Server::AddService(google::protobuf::Service* service,

int Server::AddService(google::protobuf::Service* service,
ServiceOwnership ownership,
const butil::StringPiece& restful_mappings) {
const butil::StringPiece& restful_mappings,
bool allow_default_url) {
ServiceOptions options;
options.ownership = ownership;
// TODO: This is weird
options.restful_mappings = restful_mappings.as_string();
options.allow_default_url = allow_default_url;
return AddServiceInternal(service, false, options);
}

Expand Down
9 changes: 8 additions & 1 deletion src/brpc/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ struct ServiceOptions {
// Default: empty
std::string restful_mappings;

// Work with restful_mappings, if this flag is false, reject methods accessed
// from default urls (SERVICE/METHOD).
// Default: false
bool allow_default_url;

// [ Not recommended to change this option ]
// If this flag is true, the service will convert http body to protobuf
// when the pb schema is non-empty in http servings. The body must be
Expand Down Expand Up @@ -338,6 +343,7 @@ class Server {
// will be used when the service is queried.
struct OpaqueParams {
bool is_tabbed;
bool allow_default_url;
bool allow_http_body_to_pb;
bool pb_bytes_to_base64;
OpaqueParams();
Expand Down Expand Up @@ -414,7 +420,8 @@ class Server {
ServiceOwnership ownership);
int AddService(google::protobuf::Service* service,
ServiceOwnership ownership,
const butil::StringPiece& restful_mappings);
const butil::StringPiece& restful_mappings,
bool allow_default_url = false);
int AddService(google::protobuf::Service* service,
const ServiceOptions& options);

Expand Down
35 changes: 35 additions & 0 deletions test/brpc_server_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,16 @@ TEST_F(ServerTest, restful_mapping) {
" /v1/*/* => Echo"));
ASSERT_EQ(0u, server9.service_count());

// default url access
brpc::Server server10;
ASSERT_EQ(0, server10.AddService(
&service_v1,
brpc::SERVER_DOESNT_OWN_SERVICE,
"/v1/echo => Echo",
true));
ASSERT_EQ(1u, server10.service_count());
ASSERT_FALSE(server10._global_restful_map);

// Access services
ASSERT_EQ(0, server1.Start(port, NULL));
brpc::Channel http_channel;
Expand Down Expand Up @@ -867,6 +877,31 @@ TEST_F(ServerTest, restful_mapping) {
server1.Stop(0);
server1.Join();

ASSERT_EQ(0, server10.Start(port, NULL));

// access v1.Echo via /v1/echo.
cntl.Reset();
cntl.http_request().uri() = "/v1/echo";
cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
cntl.request_attachment().append("{\"message\":\"foo\"}");
http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
ASSERT_EQ(12, service_v1.ncalled.load());
ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());

// access v1.Echo via default url
cntl.Reset();
cntl.http_request().uri() = "/EchoService/Echo";
cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
cntl.request_attachment().append("{\"message\":\"foo\"}");
http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
ASSERT_EQ(13, service_v1.ncalled.load());
ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());

server10.Stop(0);
server10.Join();

// Removing the service should update _global_restful_map.
ASSERT_EQ(0, server1.RemoveService(&service_v1));
ASSERT_EQ(0u, server1.service_count());
Expand Down