brpc_server_unittest.cpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // brpc - A framework to host and access services throughout Baidu.
  18. // Date: Sun Jul 13 15:04:18 CST 2014
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <fstream>
  22. #include <gtest/gtest.h>
  23. #include <google/protobuf/descriptor.h>
  24. #include "butil/time.h"
  25. #include "butil/macros.h"
  26. #include "butil/fd_guard.h"
  27. #include "butil/files/scoped_file.h"
  28. #include "brpc/socket.h"
  29. #include "brpc/builtin/version_service.h"
  30. #include "brpc/builtin/health_service.h"
  31. #include "brpc/builtin/list_service.h"
  32. #include "brpc/builtin/status_service.h"
  33. #include "brpc/builtin/threads_service.h"
  34. #include "brpc/builtin/vlog_service.h"
  35. #include "brpc/builtin/index_service.h" // IndexService
  36. #include "brpc/builtin/connections_service.h" // ConnectionsService
  37. #include "brpc/builtin/flags_service.h" // FlagsService
  38. #include "brpc/builtin/vars_service.h" // VarsService
  39. #include "brpc/builtin/rpcz_service.h" // RpczService
  40. #include "brpc/builtin/dir_service.h" // DirService
  41. #include "brpc/builtin/pprof_service.h" // PProfService
  42. #include "brpc/builtin/bthreads_service.h" // BthreadsService
  43. #include "brpc/builtin/ids_service.h" // IdsService
  44. #include "brpc/builtin/sockets_service.h" // SocketsService
  45. #include "brpc/builtin/bad_method_service.h"
  46. #include "brpc/server.h"
  47. #include "brpc/restful.h"
  48. #include "brpc/channel.h"
  49. #include "brpc/socket_map.h"
  50. #include "brpc/controller.h"
  51. #include "echo.pb.h"
  52. #include "v1.pb.h"
  53. #include "v2.pb.h"
  54. int main(int argc, char* argv[]) {
  55. testing::InitGoogleTest(&argc, argv);
  56. GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);
  57. return RUN_ALL_TESTS();
  58. }
  59. namespace brpc {
  60. DECLARE_bool(enable_threads_service);
  61. DECLARE_bool(enable_dir_service);
  62. }
  63. namespace {
  64. void* RunClosure(void* arg) {
  65. google::protobuf::Closure* done = (google::protobuf::Closure*)arg;
  66. done->Run();
  67. return NULL;
  68. }
  69. class MyAuthenticator : public brpc::Authenticator {
  70. public:
  71. MyAuthenticator() {}
  72. virtual ~MyAuthenticator() {}
  73. int GenerateCredential(std::string*) const {
  74. return 0;
  75. }
  76. int VerifyCredential(const std::string&,
  77. const butil::EndPoint&,
  78. brpc::AuthContext*) const {
  79. return 0;
  80. }
  81. };
  82. bool g_delete = false;
  83. const std::string EXP_REQUEST = "hello";
  84. const std::string EXP_RESPONSE = "world";
  85. const std::string EXP_REQUEST_BASE64 = "aGVsbG8=";
  86. class EchoServiceImpl : public test::EchoService {
  87. public:
  88. EchoServiceImpl() : count(0) {}
  89. virtual ~EchoServiceImpl() { g_delete = true; }
  90. virtual void Echo(google::protobuf::RpcController* cntl_base,
  91. const test::EchoRequest* request,
  92. test::EchoResponse* response,
  93. google::protobuf::Closure* done) {
  94. brpc::ClosureGuard done_guard(done);
  95. brpc::Controller* cntl = (brpc::Controller*)cntl_base;
  96. count.fetch_add(1, butil::memory_order_relaxed);
  97. EXPECT_EQ(EXP_REQUEST, request->message());
  98. response->set_message(EXP_RESPONSE);
  99. if (request->sleep_us() > 0) {
  100. LOG(INFO) << "Sleep " << request->sleep_us() << " us, protocol="
  101. << cntl->request_protocol();
  102. bthread_usleep(request->sleep_us());
  103. } else {
  104. LOG(INFO) << "No sleep, protocol=" << cntl->request_protocol();
  105. }
  106. }
  107. virtual void BytesEcho1(google::protobuf::RpcController*,
  108. const test::BytesRequest* request,
  109. test::BytesResponse* response,
  110. google::protobuf::Closure* done) {
  111. brpc::ClosureGuard done_guard(done);
  112. EXPECT_EQ(EXP_REQUEST, request->databytes());
  113. response->set_databytes(request->databytes());
  114. }
  115. virtual void BytesEcho2(google::protobuf::RpcController*,
  116. const test::BytesRequest* request,
  117. test::BytesResponse* response,
  118. google::protobuf::Closure* done) {
  119. brpc::ClosureGuard done_guard(done);
  120. EXPECT_EQ(EXP_REQUEST_BASE64, request->databytes());
  121. response->set_databytes(request->databytes());
  122. }
  123. butil::atomic<int64_t> count;
  124. };
  125. // An evil service that fakes its `ServiceDescriptor'
  126. class EvilService : public test::EchoService {
  127. public:
  128. explicit EvilService(const google::protobuf::ServiceDescriptor* sd)
  129. : _sd(sd) {}
  130. const google::protobuf::ServiceDescriptor* GetDescriptor() {
  131. return _sd;
  132. }
  133. private:
  134. const google::protobuf::ServiceDescriptor* _sd;
  135. };
  136. class ServerTest : public ::testing::Test{
  137. protected:
  138. ServerTest() {};
  139. virtual ~ServerTest(){};
  140. virtual void SetUp() {};
  141. virtual void TearDown() {};
  142. void TestAddBuiltinService(
  143. const google::protobuf::ServiceDescriptor* conflict_sd) {
  144. brpc::Server server;
  145. EvilService evil(conflict_sd);
  146. EXPECT_EQ(0, server.AddServiceInternal(
  147. &evil, false, brpc::ServiceOptions()));
  148. EXPECT_EQ(-1, server.AddBuiltinServices());
  149. }
  150. };
  151. TEST_F(ServerTest, sanity) {
  152. {
  153. brpc::Server server;
  154. ASSERT_EQ(-1, server.Start("127.0.0.1:12345:asdf", NULL));
  155. ASSERT_EQ(-1, server.Start("127.0.0.1:99999", NULL));
  156. ASSERT_EQ(0, server.Start("127.0.0.1:8613", NULL));
  157. }
  158. {
  159. brpc::Server server;
  160. // accept hostname as well.
  161. ASSERT_EQ(0, server.Start("localhost:8613", NULL));
  162. }
  163. {
  164. brpc::Server server;
  165. ASSERT_EQ(0, server.Start("localhost:0", NULL));
  166. // port should be replaced with the actually used one.
  167. ASSERT_NE(0, server.listen_address().port);
  168. }
  169. {
  170. brpc::Server server;
  171. ASSERT_EQ(-1, server.Start(99999, NULL));
  172. ASSERT_EQ(0, server.Start(8613, NULL));
  173. }
  174. {
  175. brpc::Server server;
  176. brpc::ServerOptions options;
  177. options.internal_port = 8613; // The same as service port
  178. ASSERT_EQ(-1, server.Start("127.0.0.1:8613", &options));
  179. ASSERT_FALSE(server.IsRunning()); // Revert server's status
  180. // And release the listen port
  181. ASSERT_EQ(0, server.Start("127.0.0.1:8613", NULL));
  182. }
  183. butil::EndPoint ep;
  184. MyAuthenticator auth;
  185. brpc::Server server;
  186. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  187. brpc::ServerOptions opt;
  188. opt.auth = &auth;
  189. ASSERT_EQ(0, server.Start(ep, &opt));
  190. ASSERT_TRUE(server.IsRunning());
  191. ASSERT_EQ(&auth, server.options().auth);
  192. ASSERT_EQ(0ul, server.service_count());
  193. ASSERT_TRUE(NULL == server.first_service());
  194. std::vector<google::protobuf::Service*> services;
  195. server.ListServices(&services);
  196. ASSERT_TRUE(services.empty());
  197. ASSERT_EQ(0UL, server.service_count());
  198. for (brpc::Server::ServiceMap::const_iterator it
  199. = server._service_map.begin();
  200. it != server._service_map.end(); ++it) {
  201. ASSERT_TRUE(it->second.is_builtin_service);
  202. }
  203. ASSERT_EQ(0, server.Stop(0));
  204. ASSERT_EQ(0, server.Join());
  205. }
  206. TEST_F(ServerTest, invalid_protocol_in_enabled_protocols) {
  207. butil::EndPoint ep;
  208. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  209. brpc::Server server;
  210. brpc::ServerOptions opt;
  211. opt.enabled_protocols = "hehe baidu_std";
  212. ASSERT_EQ(-1, server.Start(ep, &opt));
  213. }
  214. class EchoServiceV1 : public v1::EchoService {
  215. public:
  216. EchoServiceV1() : ncalled(0)
  217. , ncalled_echo2(0)
  218. , ncalled_echo3(0)
  219. , ncalled_echo4(0)
  220. , ncalled_echo5(0)
  221. {}
  222. virtual ~EchoServiceV1() {}
  223. virtual void Echo(google::protobuf::RpcController* cntl_base,
  224. const v1::EchoRequest* request,
  225. v1::EchoResponse* response,
  226. google::protobuf::Closure* done) {
  227. brpc::Controller* cntl = static_cast<brpc::Controller*>(cntl_base);
  228. brpc::ClosureGuard done_guard(done);
  229. if (request->has_message()) {
  230. response->set_message(request->message() + "_v1");
  231. } else {
  232. CHECK_EQ(brpc::PROTOCOL_HTTP, cntl->request_protocol());
  233. cntl->response_attachment() = cntl->request_attachment();
  234. }
  235. ncalled.fetch_add(1);
  236. }
  237. virtual void Echo2(google::protobuf::RpcController*,
  238. const v1::EchoRequest* request,
  239. v1::EchoResponse* response,
  240. google::protobuf::Closure* done) {
  241. brpc::ClosureGuard done_guard(done);
  242. response->set_message(request->message() + "_v1_Echo2");
  243. ncalled_echo2.fetch_add(1);
  244. }
  245. virtual void Echo3(google::protobuf::RpcController*,
  246. const v1::EchoRequest* request,
  247. v1::EchoResponse* response,
  248. google::protobuf::Closure* done) {
  249. brpc::ClosureGuard done_guard(done);
  250. response->set_message(request->message() + "_v1_Echo3");
  251. ncalled_echo3.fetch_add(1);
  252. }
  253. virtual void Echo4(google::protobuf::RpcController*,
  254. const v1::EchoRequest* request,
  255. v1::EchoResponse* response,
  256. google::protobuf::Closure* done) {
  257. brpc::ClosureGuard done_guard(done);
  258. response->set_message(request->message() + "_v1_Echo4");
  259. ncalled_echo4.fetch_add(1);
  260. }
  261. virtual void Echo5(google::protobuf::RpcController*,
  262. const v1::EchoRequest* request,
  263. v1::EchoResponse* response,
  264. google::protobuf::Closure* done) {
  265. brpc::ClosureGuard done_guard(done);
  266. response->set_message(request->message() + "_v1_Echo5");
  267. ncalled_echo5.fetch_add(1);
  268. }
  269. butil::atomic<int> ncalled;
  270. butil::atomic<int> ncalled_echo2;
  271. butil::atomic<int> ncalled_echo3;
  272. butil::atomic<int> ncalled_echo4;
  273. butil::atomic<int> ncalled_echo5;
  274. };
  275. class EchoServiceV2 : public v2::EchoService {
  276. public:
  277. EchoServiceV2() : ncalled(0) {}
  278. virtual ~EchoServiceV2() {}
  279. virtual void Echo(google::protobuf::RpcController*,
  280. const v2::EchoRequest* request,
  281. v2::EchoResponse* response,
  282. google::protobuf::Closure* done) {
  283. brpc::ClosureGuard done_guard(done);
  284. response->set_value(request->value() + 1);
  285. ncalled.fetch_add(1);
  286. }
  287. butil::atomic<int> ncalled;
  288. };
  289. TEST_F(ServerTest, empty_enabled_protocols) {
  290. butil::EndPoint ep;
  291. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  292. brpc::Server server;
  293. EchoServiceImpl echo_svc;
  294. ASSERT_EQ(0, server.AddService(
  295. &echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  296. brpc::ServerOptions opt;
  297. opt.enabled_protocols = " ";
  298. ASSERT_EQ(0, server.Start(ep, &opt));
  299. brpc::Channel chan;
  300. brpc::ChannelOptions copt;
  301. copt.protocol = "baidu_std";
  302. ASSERT_EQ(0, chan.Init(ep, &copt));
  303. brpc::Controller cntl;
  304. test::EchoRequest req;
  305. test::EchoResponse res;
  306. req.set_message(EXP_REQUEST);
  307. test::EchoService_Stub stub(&chan);
  308. stub.Echo(&cntl, &req, &res, NULL);
  309. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  310. ASSERT_EQ(0, server.Stop(0));
  311. ASSERT_EQ(0, server.Join());
  312. }
  313. TEST_F(ServerTest, only_allow_protocols_in_enabled_protocols) {
  314. butil::EndPoint ep;
  315. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  316. brpc::Server server;
  317. EchoServiceImpl echo_svc;
  318. ASSERT_EQ(0, server.AddService(
  319. &echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  320. brpc::ServerOptions opt;
  321. opt.enabled_protocols = "hulu_pbrpc";
  322. ASSERT_EQ(0, server.Start(ep, &opt));
  323. brpc::ChannelOptions copt;
  324. brpc::Controller cntl;
  325. // http is always allowed.
  326. brpc::Channel http_channel;
  327. copt.protocol = "http";
  328. ASSERT_EQ(0, http_channel.Init(ep, &copt));
  329. cntl.Reset();
  330. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  331. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  332. // Unmatched protocols are not allowed.
  333. brpc::Channel chan;
  334. copt.protocol = "baidu_std";
  335. ASSERT_EQ(0, chan.Init(ep, &copt));
  336. test::EchoRequest req;
  337. test::EchoResponse res;
  338. cntl.Reset();
  339. req.set_message(EXP_REQUEST);
  340. test::EchoService_Stub stub(&chan);
  341. stub.Echo(&cntl, &req, &res, NULL);
  342. ASSERT_TRUE(cntl.Failed());
  343. ASSERT_TRUE(cntl.ErrorText().find("Got EOF of ") != std::string::npos);
  344. ASSERT_EQ(0, server.Stop(0));
  345. ASSERT_EQ(0, server.Join());
  346. }
  347. TEST_F(ServerTest, services_in_different_ns) {
  348. const int port = 9200;
  349. brpc::Server server1;
  350. EchoServiceV1 service_v1;
  351. ASSERT_EQ(0, server1.AddService(&service_v1, brpc::SERVER_DOESNT_OWN_SERVICE));
  352. ASSERT_EQ(0, server1.Start(port, NULL));
  353. brpc::Channel http_channel;
  354. brpc::ChannelOptions chan_options;
  355. chan_options.protocol = "http";
  356. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  357. brpc::Controller cntl;
  358. cntl.http_request().uri() = "/EchoService/Echo";
  359. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  360. cntl.request_attachment().append("{\"message\":\"foo\"}");
  361. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  362. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  363. ASSERT_EQ(1, service_v1.ncalled.load());
  364. cntl.Reset();
  365. cntl.http_request().uri() = "/v1.EchoService/Echo";
  366. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  367. cntl.request_attachment().append("{\"message\":\"foo\"}");
  368. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  369. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  370. ASSERT_EQ(2, service_v1.ncalled.load());
  371. //Stop the server to add another service.
  372. server1.Stop(0);
  373. server1.Join();
  374. // NOTICE: stopping server now does not trigger HC of the client because
  375. // the main socket is only SetFailed in RPC route, however the RPC already
  376. // ends at this point.
  377. EchoServiceV2 service_v2;
  378. #ifndef ALLOW_SAME_NAMED_SERVICE_IN_DIFFERENT_NAMESPACE
  379. ASSERT_EQ(-1, server1.AddService(&service_v2, brpc::SERVER_DOESNT_OWN_SERVICE));
  380. #else
  381. ASSERT_EQ(0, server1.AddService(&service_v2, brpc::SERVER_DOESNT_OWN_SERVICE));
  382. ASSERT_EQ(0, server1.Start(port, NULL));
  383. //sleep(3); // wait for HC
  384. cntl.Reset();
  385. cntl.http_request().uri() = "/v2.EchoService/Echo";
  386. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  387. cntl.request_attachment().append("{\"value\":33}");
  388. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  389. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  390. ASSERT_EQ(1, service_v2.ncalled.load());
  391. cntl.Reset();
  392. cntl.http_request().uri() = "/EchoService/Echo";
  393. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  394. cntl.request_attachment().append("{\"value\":33}");
  395. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  396. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  397. ASSERT_EQ(2, service_v2.ncalled.load());
  398. server1.Stop(0);
  399. server1.Join();
  400. #endif
  401. }
  402. TEST_F(ServerTest, various_forms_of_uri_paths) {
  403. const int port = 9200;
  404. brpc::Server server1;
  405. EchoServiceV1 service_v1;
  406. ASSERT_EQ(0, server1.AddService(&service_v1, brpc::SERVER_DOESNT_OWN_SERVICE));
  407. ASSERT_EQ(0, server1.Start(port, NULL));
  408. brpc::Channel http_channel;
  409. brpc::ChannelOptions chan_options;
  410. chan_options.protocol = "http";
  411. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  412. brpc::Controller cntl;
  413. cntl.http_request().uri() = "/EchoService/Echo";
  414. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  415. cntl.request_attachment().append("{\"message\":\"foo\"}");
  416. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  417. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  418. ASSERT_EQ(1, service_v1.ncalled.load());
  419. cntl.Reset();
  420. cntl.http_request().uri() = "/EchoService///Echo//";
  421. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  422. cntl.request_attachment().append("{\"message\":\"foo\"}");
  423. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  424. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText() << cntl.response_attachment();
  425. ASSERT_EQ(2, service_v1.ncalled.load());
  426. cntl.Reset();
  427. cntl.http_request().uri() = "/EchoService /Echo/";
  428. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  429. cntl.request_attachment().append("{\"message\":\"foo\"}");
  430. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  431. ASSERT_TRUE(cntl.Failed());
  432. ASSERT_EQ(brpc::EREQUEST, cntl.ErrorCode());
  433. LOG(INFO) << "Expected error: " << cntl.ErrorText();
  434. ASSERT_EQ(2, service_v1.ncalled.load());
  435. // Additional path(stored in unresolved_path) after method is acceptible
  436. cntl.Reset();
  437. cntl.http_request().uri() = "/EchoService/Echo/Foo";
  438. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  439. cntl.request_attachment().append("{\"message\":\"foo\"}");
  440. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  441. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  442. ASSERT_EQ(3, service_v1.ncalled.load());
  443. //Stop the server.
  444. server1.Stop(0);
  445. server1.Join();
  446. }
  447. TEST_F(ServerTest, missing_required_fields) {
  448. const int port = 9200;
  449. brpc::Server server1;
  450. EchoServiceV1 service_v1;
  451. ASSERT_EQ(0, server1.AddService(&service_v1, brpc::SERVER_DOESNT_OWN_SERVICE));
  452. ASSERT_EQ(0, server1.Start(port, NULL));
  453. brpc::Channel http_channel;
  454. brpc::ChannelOptions chan_options;
  455. chan_options.protocol = "http";
  456. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  457. brpc::Controller cntl;
  458. cntl.http_request().uri() = "/EchoService/Echo";
  459. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  460. ASSERT_TRUE(cntl.Failed());
  461. ASSERT_EQ(brpc::EHTTP, cntl.ErrorCode());
  462. LOG(INFO) << cntl.ErrorText();
  463. ASSERT_EQ(brpc::HTTP_STATUS_BAD_REQUEST, cntl.http_response().status_code());
  464. ASSERT_EQ(0, service_v1.ncalled.load());
  465. cntl.Reset();
  466. cntl.http_request().uri() = "/EchoService/Echo";
  467. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  468. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  469. ASSERT_TRUE(cntl.Failed());
  470. ASSERT_EQ(brpc::EHTTP, cntl.ErrorCode());
  471. ASSERT_EQ(brpc::HTTP_STATUS_BAD_REQUEST, cntl.http_response().status_code());
  472. ASSERT_EQ(0, service_v1.ncalled.load());
  473. cntl.Reset();
  474. cntl.http_request().uri() = "/EchoService/Echo";
  475. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  476. cntl.request_attachment().append("{\"message2\":\"foo\"}");
  477. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  478. ASSERT_TRUE(cntl.Failed());
  479. ASSERT_EQ(brpc::EHTTP, cntl.ErrorCode());
  480. ASSERT_EQ(brpc::HTTP_STATUS_BAD_REQUEST, cntl.http_response().status_code());
  481. ASSERT_EQ(0, service_v1.ncalled.load());
  482. }
  483. TEST_F(ServerTest, disallow_http_body_to_pb) {
  484. const int port = 9200;
  485. brpc::Server server1;
  486. EchoServiceV1 service_v1;
  487. brpc::ServiceOptions svc_opt;
  488. svc_opt.allow_http_body_to_pb = false;
  489. svc_opt.restful_mappings = "/access_echo1=>Echo";
  490. ASSERT_EQ(0, server1.AddService(&service_v1, svc_opt));
  491. ASSERT_EQ(0, server1.Start(port, NULL));
  492. brpc::Channel http_channel;
  493. brpc::ChannelOptions chan_options;
  494. chan_options.protocol = "http";
  495. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  496. brpc::Controller cntl;
  497. cntl.http_request().uri() = "/access_echo1";
  498. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  499. ASSERT_TRUE(cntl.Failed());
  500. ASSERT_EQ(brpc::EHTTP, cntl.ErrorCode());
  501. ASSERT_EQ(brpc::HTTP_STATUS_INTERNAL_SERVER_ERROR,
  502. cntl.http_response().status_code());
  503. ASSERT_EQ(1, service_v1.ncalled.load());
  504. cntl.Reset();
  505. cntl.http_request().uri() = "/access_echo1";
  506. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  507. cntl.request_attachment().append("heheda");
  508. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  509. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  510. ASSERT_EQ("heheda", cntl.response_attachment());
  511. ASSERT_EQ(2, service_v1.ncalled.load());
  512. }
  513. TEST_F(ServerTest, restful_mapping) {
  514. const int port = 9200;
  515. EchoServiceV1 service_v1;
  516. EchoServiceV2 service_v2;
  517. brpc::Server server1;
  518. ASSERT_EQ(0u, server1.service_count());
  519. ASSERT_EQ(0, server1.AddService(
  520. &service_v1,
  521. brpc::SERVER_DOESNT_OWN_SERVICE,
  522. "/v1/echo/ => Echo,"
  523. // Map another path to the same method is ok.
  524. "/v3/echo => Echo,"
  525. // end with wildcard
  526. "/v2/echo/* => Echo,"
  527. // single-component path should be OK
  528. "/v4_echo => Echo,"
  529. // heading slash can be ignored
  530. " v5/echo => Echo,"
  531. // with or without wildcard can coexist.
  532. " /v6/echo => Echo,"
  533. " /v6/echo/* => Echo2,"
  534. " /v6/abc/*/def => Echo3,"
  535. " /v6/echo/*.flv => Echo4,"
  536. " /v6/*.flv => Echo5,"
  537. " *.flv => Echo,"
  538. ));
  539. ASSERT_EQ(1u, server1.service_count());
  540. ASSERT_TRUE(server1._global_restful_map);
  541. ASSERT_EQ(1UL, server1._global_restful_map->size());
  542. // Disallow duplicated path
  543. brpc::Server server2;
  544. ASSERT_EQ(-1, server2.AddService(
  545. &service_v1,
  546. brpc::SERVER_DOESNT_OWN_SERVICE,
  547. "/v1/echo => Echo,"
  548. "/v1/echo => Echo"));
  549. ASSERT_EQ(0u, server2.service_count());
  550. // NOTE: PATH/* and PATH cannot coexist in previous versions, now it's OK.
  551. brpc::Server server3;
  552. ASSERT_EQ(0, server3.AddService(
  553. &service_v1,
  554. brpc::SERVER_DOESNT_OWN_SERVICE,
  555. "/v1/echo/* => Echo,"
  556. "/v1/echo => Echo"));
  557. ASSERT_EQ(1u, server3.service_count());
  558. // Same named services can't be added even with restful mapping
  559. brpc::Server server4;
  560. ASSERT_EQ(0, server4.AddService(
  561. &service_v1,
  562. brpc::SERVER_DOESNT_OWN_SERVICE,
  563. "/v1/echo => Echo"));
  564. ASSERT_EQ(1u, server4.service_count());
  565. ASSERT_EQ(-1, server4.AddService(
  566. &service_v2,
  567. brpc::SERVER_DOESNT_OWN_SERVICE,
  568. "/v2/echo => Echo"));
  569. ASSERT_EQ(1u, server4.service_count());
  570. // Invalid method name.
  571. brpc::Server server5;
  572. ASSERT_EQ(-1, server5.AddService(
  573. &service_v1,
  574. brpc::SERVER_DOESNT_OWN_SERVICE,
  575. "/v1/echo => UnexistMethod"));
  576. ASSERT_EQ(0u, server5.service_count());
  577. // Invalid path.
  578. brpc::Server server6;
  579. ASSERT_EQ(-1, server6.AddService(
  580. &service_v1,
  581. brpc::SERVER_DOESNT_OWN_SERVICE,
  582. "/v1/ echo => Echo"));
  583. ASSERT_EQ(0u, server6.service_count());
  584. // Empty path
  585. brpc::Server server7;
  586. ASSERT_EQ(-1, server7.AddService(
  587. &service_v1,
  588. brpc::SERVER_DOESNT_OWN_SERVICE,
  589. " => Echo"));
  590. ASSERT_EQ(0u, server7.service_count());
  591. // Disabled pattern "/A*/B => M"
  592. brpc::Server server8;
  593. ASSERT_EQ(-1, server8.AddService(
  594. &service_v1,
  595. brpc::SERVER_DOESNT_OWN_SERVICE,
  596. " abc* => Echo"));
  597. ASSERT_EQ(0u, server8.service_count());
  598. ASSERT_EQ(-1, server8.AddService(
  599. &service_v1,
  600. brpc::SERVER_DOESNT_OWN_SERVICE,
  601. " abc/def* => Echo"));
  602. ASSERT_EQ(0u, server8.service_count());
  603. // More than one wildcard
  604. brpc::Server server9;
  605. ASSERT_EQ(-1, server9.AddService(
  606. &service_v1,
  607. brpc::SERVER_DOESNT_OWN_SERVICE,
  608. " /v1/*/* => Echo"));
  609. ASSERT_EQ(0u, server9.service_count());
  610. // default url access
  611. brpc::Server server10;
  612. ASSERT_EQ(0, server10.AddService(
  613. &service_v1,
  614. brpc::SERVER_DOESNT_OWN_SERVICE,
  615. "/v1/echo => Echo",
  616. true));
  617. ASSERT_EQ(1u, server10.service_count());
  618. ASSERT_FALSE(server10._global_restful_map);
  619. // Access services
  620. ASSERT_EQ(0, server1.Start(port, NULL));
  621. brpc::Channel http_channel;
  622. brpc::ChannelOptions chan_options;
  623. chan_options.protocol = "http";
  624. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  625. // reject /EchoService/Echo
  626. brpc::Controller cntl;
  627. cntl.http_request().uri() = "/EchoService/Echo";
  628. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  629. cntl.request_attachment().append("{\"message\":\"foo\"}");
  630. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  631. ASSERT_TRUE(cntl.Failed());
  632. ASSERT_EQ(0, service_v1.ncalled.load());
  633. // access v1.Echo via /v1/echo.
  634. cntl.Reset();
  635. cntl.http_request().uri() = "/v1/echo";
  636. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  637. cntl.request_attachment().append("{\"message\":\"foo\"}");
  638. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  639. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  640. ASSERT_EQ(1, service_v1.ncalled.load());
  641. ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());
  642. // access v1.Echo via /v3/echo.
  643. cntl.Reset();
  644. cntl.http_request().uri() = "/v3/echo";
  645. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  646. cntl.request_attachment().append("{\"message\":\"bar\"}");
  647. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  648. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  649. ASSERT_EQ(2, service_v1.ncalled.load());
  650. ASSERT_EQ("{\"message\":\"bar_v1\"}", cntl.response_attachment());
  651. // Adding extra slashes (and heading/trailing spaces) is OK.
  652. cntl.Reset();
  653. cntl.http_request().uri() = " //v1///echo//// ";
  654. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  655. cntl.request_attachment().append("{\"message\":\"hello\"}");
  656. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  657. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  658. ASSERT_EQ(3, service_v1.ncalled.load());
  659. ASSERT_EQ("{\"message\":\"hello_v1\"}", cntl.response_attachment());
  660. // /v3/echo must be exactly matched.
  661. cntl.Reset();
  662. cntl.http_request().uri() = "/v3/echo/anything";
  663. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  664. cntl.request_attachment().append("{\"message\":\"foo\"}");
  665. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  666. ASSERT_TRUE(cntl.Failed());
  667. ASSERT_EQ(brpc::EHTTP, cntl.ErrorCode());
  668. LOG(INFO) << "Expected error: " << cntl.ErrorText();
  669. ASSERT_EQ(3, service_v1.ncalled.load());
  670. // Access v1.Echo via /v2/echo
  671. cntl.Reset();
  672. cntl.http_request().uri() = "/v2/echo";
  673. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  674. cntl.request_attachment().append("{\"message\":\"hehe\"}");
  675. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  676. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  677. ASSERT_EQ(4, service_v1.ncalled.load());
  678. ASSERT_EQ("{\"message\":\"hehe_v1\"}", cntl.response_attachment());
  679. // Access v1.Echo via /v2/echo/anything
  680. cntl.Reset();
  681. cntl.http_request().uri() = "/v2/echo/anything";
  682. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  683. cntl.request_attachment().append("{\"message\":\"good\"}");
  684. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  685. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  686. ASSERT_EQ(5, service_v1.ncalled.load());
  687. ASSERT_EQ("{\"message\":\"good_v1\"}", cntl.response_attachment());
  688. cntl.Reset();
  689. cntl.http_request().uri() = "/v4_echo";
  690. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  691. cntl.request_attachment().append("{\"message\":\"hoho\"}");
  692. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  693. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  694. ASSERT_EQ(6, service_v1.ncalled.load());
  695. ASSERT_EQ("{\"message\":\"hoho_v1\"}", cntl.response_attachment());
  696. cntl.Reset();
  697. cntl.http_request().uri() = "/v5/echo";
  698. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  699. cntl.request_attachment().append("{\"message\":\"xyz\"}");
  700. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  701. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  702. ASSERT_EQ(7, service_v1.ncalled.load());
  703. ASSERT_EQ("{\"message\":\"xyz_v1\"}", cntl.response_attachment());
  704. cntl.Reset();
  705. cntl.http_request().uri() = "/v6/echo";
  706. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  707. cntl.request_attachment().append("{\"message\":\"xyz\"}");
  708. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  709. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  710. ASSERT_EQ(8, service_v1.ncalled.load());
  711. ASSERT_EQ("{\"message\":\"xyz_v1\"}", cntl.response_attachment());
  712. cntl.Reset();
  713. cntl.http_request().uri() = "/v6/echo/test";
  714. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  715. cntl.request_attachment().append("{\"message\":\"xyz\"}");
  716. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  717. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  718. ASSERT_EQ(1, service_v1.ncalled_echo2.load());
  719. ASSERT_EQ("{\"message\":\"xyz_v1_Echo2\"}", cntl.response_attachment());
  720. cntl.Reset();
  721. cntl.http_request().uri() = "/v6/abc/heheda/def";
  722. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  723. cntl.request_attachment().append("{\"message\":\"abc_heheda\"}");
  724. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  725. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  726. ASSERT_EQ(1, service_v1.ncalled_echo3.load());
  727. ASSERT_EQ("{\"message\":\"abc_heheda_v1_Echo3\"}", cntl.response_attachment());
  728. cntl.Reset();
  729. cntl.http_request().uri() = "/v6/abc/def";
  730. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  731. cntl.request_attachment().append("{\"message\":\"abc\"}");
  732. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  733. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  734. ASSERT_EQ(2, service_v1.ncalled_echo3.load());
  735. ASSERT_EQ("{\"message\":\"abc_v1_Echo3\"}", cntl.response_attachment());
  736. // Incorrect suffix
  737. cntl.Reset();
  738. cntl.http_request().uri() = "/v6/abc/heheda/def2";
  739. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  740. cntl.request_attachment().append("{\"message\":\"xyz\"}");
  741. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  742. ASSERT_TRUE(cntl.Failed());
  743. ASSERT_EQ(2, service_v1.ncalled_echo3.load());
  744. cntl.Reset();
  745. cntl.http_request().uri() = "/v6/echo/1.flv";
  746. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  747. cntl.request_attachment().append("{\"message\":\"1.flv\"}");
  748. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  749. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  750. ASSERT_EQ("{\"message\":\"1.flv_v1_Echo4\"}", cntl.response_attachment());
  751. ASSERT_EQ(1, service_v1.ncalled_echo4.load());
  752. cntl.Reset();
  753. cntl.http_request().uri() = "//v6//d.flv//";
  754. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  755. cntl.request_attachment().append("{\"message\":\"d.flv\"}");
  756. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  757. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  758. ASSERT_EQ("{\"message\":\"d.flv_v1_Echo5\"}", cntl.response_attachment());
  759. ASSERT_EQ(1, service_v1.ncalled_echo5.load());
  760. // matched the global restful map.
  761. cntl.Reset();
  762. cntl.http_request().uri() = "//d.flv//";
  763. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  764. cntl.request_attachment().append("{\"message\":\"d.flv\"}");
  765. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  766. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  767. ASSERT_EQ("{\"message\":\"d.flv_v1\"}", cntl.response_attachment());
  768. ASSERT_EQ(9, service_v1.ncalled.load());
  769. cntl.Reset();
  770. cntl.http_request().uri() = "/v7/e.flv";
  771. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  772. cntl.request_attachment().append("{\"message\":\"e.flv\"}");
  773. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  774. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  775. ASSERT_EQ("{\"message\":\"e.flv_v1\"}", cntl.response_attachment());
  776. ASSERT_EQ(10, service_v1.ncalled.load());
  777. cntl.Reset();
  778. cntl.http_request().uri() = "/v0/f.flv";
  779. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  780. cntl.request_attachment().append("{\"message\":\"f.flv\"}");
  781. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  782. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  783. ASSERT_EQ("{\"message\":\"f.flv_v1\"}", cntl.response_attachment());
  784. ASSERT_EQ(11, service_v1.ncalled.load());
  785. // matched nothing
  786. cntl.Reset();
  787. cntl.http_request().uri() = "/v6/ech/1.ts";
  788. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  789. cntl.request_attachment().append("{\"message\":\"1.ts\"}");
  790. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  791. ASSERT_TRUE(cntl.Failed());
  792. //Stop the server.
  793. server1.Stop(0);
  794. server1.Join();
  795. ASSERT_EQ(0, server10.Start(port, NULL));
  796. // access v1.Echo via /v1/echo.
  797. cntl.Reset();
  798. cntl.http_request().uri() = "/v1/echo";
  799. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  800. cntl.request_attachment().append("{\"message\":\"foo\"}");
  801. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  802. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  803. ASSERT_EQ(12, service_v1.ncalled.load());
  804. ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());
  805. // access v1.Echo via default url
  806. cntl.Reset();
  807. cntl.http_request().uri() = "/EchoService/Echo";
  808. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  809. cntl.request_attachment().append("{\"message\":\"foo\"}");
  810. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  811. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  812. ASSERT_EQ(13, service_v1.ncalled.load());
  813. ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());
  814. server10.Stop(0);
  815. server10.Join();
  816. // Removing the service should update _global_restful_map.
  817. ASSERT_EQ(0, server1.RemoveService(&service_v1));
  818. ASSERT_EQ(0u, server1.service_count());
  819. ASSERT_TRUE(server1._global_restful_map); // deleted in dtor.
  820. ASSERT_EQ(0u, server1._global_restful_map->size());
  821. }
  822. TEST_F(ServerTest, conflict_name_between_restful_mapping_and_builtin) {
  823. const int port = 9200;
  824. EchoServiceV1 service_v1;
  825. brpc::Server server1;
  826. ASSERT_EQ(0u, server1.service_count());
  827. ASSERT_EQ(0, server1.AddService(
  828. &service_v1,
  829. brpc::SERVER_DOESNT_OWN_SERVICE,
  830. "/status/hello => Echo"));
  831. ASSERT_EQ(1u, server1.service_count());
  832. ASSERT_TRUE(server1._global_restful_map == NULL);
  833. ASSERT_EQ(-1, server1.Start(port, NULL));
  834. }
  835. TEST_F(ServerTest, restful_mapping_is_tried_after_others) {
  836. const int port = 9200;
  837. EchoServiceV1 service_v1;
  838. brpc::Server server1;
  839. ASSERT_EQ(0u, server1.service_count());
  840. ASSERT_EQ(0, server1.AddService(
  841. &service_v1,
  842. brpc::SERVER_DOESNT_OWN_SERVICE,
  843. "* => Echo"));
  844. ASSERT_EQ(1u, server1.service_count());
  845. ASSERT_TRUE(server1._global_restful_map);
  846. ASSERT_EQ(1UL, server1._global_restful_map->size());
  847. ASSERT_EQ(0, server1.Start(port, NULL));
  848. brpc::Channel http_channel;
  849. brpc::ChannelOptions chan_options;
  850. chan_options.protocol = "http";
  851. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  852. // accessing /status should be OK.
  853. brpc::Controller cntl;
  854. cntl.http_request().uri() = "/status";
  855. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  856. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  857. ASSERT_TRUE(cntl.response_attachment().to_string().find(
  858. service_v1.GetDescriptor()->full_name()) != std::string::npos)
  859. << "body=" << cntl.response_attachment();
  860. // reject /EchoService/Echo
  861. cntl.Reset();
  862. cntl.http_request().uri() = "/EchoService/Echo";
  863. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  864. cntl.request_attachment().append("{\"message\":\"foo\"}");
  865. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  866. ASSERT_TRUE(cntl.Failed());
  867. ASSERT_EQ(0, service_v1.ncalled.load());
  868. // Hit restful map
  869. cntl.Reset();
  870. cntl.http_request().uri() = "/non_exist";
  871. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  872. cntl.request_attachment().append("{\"message\":\"foo\"}");
  873. http_channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  874. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  875. ASSERT_EQ(1, service_v1.ncalled.load());
  876. ASSERT_EQ("{\"message\":\"foo_v1\"}", cntl.response_attachment());
  877. ;
  878. //Stop the server.
  879. server1.Stop(0);
  880. server1.Join();
  881. // Removing the service should update _global_restful_map.
  882. ASSERT_EQ(0, server1.RemoveService(&service_v1));
  883. ASSERT_EQ(0u, server1.service_count());
  884. ASSERT_TRUE(server1._global_restful_map); // deleted in dtor.
  885. ASSERT_EQ(0u, server1._global_restful_map->size());
  886. }
  887. TEST_F(ServerTest, add_remove_service) {
  888. brpc::Server server;
  889. EchoServiceImpl echo_svc;
  890. ASSERT_EQ(0, server.AddService(
  891. &echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  892. // Duplicate
  893. ASSERT_EQ(-1, server.AddService(
  894. &echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  895. ASSERT_TRUE(server.FindServiceByName(
  896. test::EchoService::descriptor()->name()) == &echo_svc);
  897. ASSERT_TRUE(server.FindServiceByFullName(
  898. test::EchoService::descriptor()->full_name()) == &echo_svc);
  899. ASSERT_TRUE(NULL == server.FindServiceByFullName(
  900. test::EchoService::descriptor()->name()));
  901. butil::EndPoint ep;
  902. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  903. ASSERT_EQ(0, server.Start(ep, NULL));
  904. ASSERT_EQ(1ul, server.service_count());
  905. ASSERT_TRUE(server.first_service() == &echo_svc);
  906. ASSERT_TRUE(server.FindServiceByName(
  907. test::EchoService::descriptor()->name()) == &echo_svc);
  908. // Can't add/remove service while running
  909. ASSERT_EQ(-1, server.AddService(
  910. &echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  911. ASSERT_EQ(-1, server.RemoveService(&echo_svc));
  912. ASSERT_EQ(0, server.Stop(0));
  913. ASSERT_EQ(0, server.Join());
  914. ASSERT_EQ(0, server.RemoveService(&echo_svc));
  915. ASSERT_EQ(0ul, server.service_count());
  916. EchoServiceImpl* svc_on_heap = new EchoServiceImpl();
  917. ASSERT_EQ(0, server.AddService(svc_on_heap,
  918. brpc::SERVER_OWNS_SERVICE));
  919. ASSERT_EQ(0, server.RemoveService(svc_on_heap));
  920. ASSERT_TRUE(g_delete);
  921. server.ClearServices();
  922. ASSERT_EQ(0ul, server.service_count());
  923. }
  924. void SendSleepRPC(butil::EndPoint ep, int sleep_ms, bool succ) {
  925. brpc::Channel channel;
  926. ASSERT_EQ(0, channel.Init(ep, NULL));
  927. brpc::Controller cntl;
  928. test::EchoRequest req;
  929. test::EchoResponse res;
  930. req.set_message(EXP_REQUEST);
  931. if (sleep_ms > 0) {
  932. req.set_sleep_us(sleep_ms * 1000);
  933. }
  934. test::EchoService_Stub stub(&channel);
  935. stub.Echo(&cntl, &req, &res, NULL);
  936. if (succ) {
  937. EXPECT_FALSE(cntl.Failed()) << cntl.ErrorText()
  938. << " latency=" << cntl.latency_us();
  939. } else {
  940. EXPECT_TRUE(cntl.Failed());
  941. }
  942. }
  943. TEST_F(ServerTest, close_idle_connections) {
  944. butil::EndPoint ep;
  945. brpc::Server server;
  946. brpc::ServerOptions opt;
  947. opt.idle_timeout_sec = 1;
  948. ASSERT_EQ(0, str2endpoint("127.0.0.1:9776", &ep));
  949. ASSERT_EQ(0, server.Start(ep, &opt));
  950. const int cfd = tcp_connect(ep, NULL);
  951. ASSERT_GT(cfd, 0);
  952. usleep(10000);
  953. brpc::ServerStatistics stat;
  954. server.GetStat(&stat);
  955. ASSERT_EQ(1ul, stat.connection_count);
  956. usleep(2500000);
  957. server.GetStat(&stat);
  958. ASSERT_EQ(0ul, stat.connection_count);
  959. }
  960. TEST_F(ServerTest, logoff_and_multiple_start) {
  961. butil::Timer timer;
  962. butil::EndPoint ep;
  963. EchoServiceImpl echo_svc;
  964. brpc::Server server;
  965. ASSERT_EQ(0, server.AddService(&echo_svc,
  966. brpc::SERVER_DOESNT_OWN_SERVICE));
  967. ASSERT_EQ(0, str2endpoint("127.0.0.1:9876", &ep));
  968. // Server::Stop(-1)
  969. {
  970. ASSERT_EQ(0, server.Start(ep, NULL));
  971. bthread_t tid;
  972. const int64_t old_count = echo_svc.count.load(butil::memory_order_relaxed);
  973. google::protobuf::Closure* thrd_func =
  974. brpc::NewCallback(SendSleepRPC, ep, 100, true);
  975. EXPECT_EQ(0, bthread_start_background(&tid, NULL, RunClosure, thrd_func));
  976. while (echo_svc.count.load(butil::memory_order_relaxed) == old_count) {
  977. bthread_usleep(1000);
  978. }
  979. timer.start();
  980. ASSERT_EQ(0, server.Stop(-1));
  981. ASSERT_EQ(0, server.Join());
  982. timer.stop();
  983. EXPECT_TRUE(labs(timer.m_elapsed() - 100) < 15) << timer.m_elapsed();
  984. bthread_join(tid, NULL);
  985. }
  986. // Server::Stop(0)
  987. {
  988. ++ep.port;
  989. ASSERT_EQ(0, server.Start(ep, NULL));
  990. bthread_t tid;
  991. const int64_t old_count = echo_svc.count.load(butil::memory_order_relaxed);
  992. google::protobuf::Closure* thrd_func =
  993. brpc::NewCallback(SendSleepRPC, ep, 100, true);
  994. EXPECT_EQ(0, bthread_start_background(&tid, NULL, RunClosure, thrd_func));
  995. while (echo_svc.count.load(butil::memory_order_relaxed) == old_count) {
  996. bthread_usleep(1000);
  997. }
  998. timer.start();
  999. ASSERT_EQ(0, server.Stop(0));
  1000. ASSERT_EQ(0, server.Join());
  1001. timer.stop();
  1002. // Assertion will fail since EchoServiceImpl::Echo is holding
  1003. // additional reference to the `Socket'
  1004. // EXPECT_TRUE(timer.m_elapsed() < 15) << timer.m_elapsed();
  1005. bthread_join(tid, NULL);
  1006. }
  1007. // Server::Stop(timeout) where timeout < g_sleep_ms
  1008. {
  1009. ++ep.port;
  1010. ASSERT_EQ(0, server.Start(ep, NULL));
  1011. bthread_t tid;
  1012. const int64_t old_count = echo_svc.count.load(butil::memory_order_relaxed);
  1013. google::protobuf::Closure* thrd_func =
  1014. brpc::NewCallback(SendSleepRPC, ep, 100, true);
  1015. EXPECT_EQ(0, bthread_start_background(&tid, NULL, RunClosure, thrd_func));
  1016. while (echo_svc.count.load(butil::memory_order_relaxed) == old_count) {
  1017. bthread_usleep(1000);
  1018. }
  1019. timer.start();
  1020. ASSERT_EQ(0, server.Stop(50));
  1021. ASSERT_EQ(0, server.Join());
  1022. timer.stop();
  1023. // Assertion will fail since EchoServiceImpl::Echo is holding
  1024. // additional reference to the `Socket'
  1025. // EXPECT_TRUE(labs(timer.m_elapsed() - 50) < 15) << timer.m_elapsed();
  1026. bthread_join(tid, NULL);
  1027. }
  1028. // Server::Stop(timeout) where timeout > g_sleep_ms
  1029. {
  1030. ++ep.port;
  1031. ASSERT_EQ(0, server.Start(ep, NULL));
  1032. bthread_t tid;
  1033. const int64_t old_count = echo_svc.count.load(butil::memory_order_relaxed);
  1034. google::protobuf::Closure* thrd_func =
  1035. brpc::NewCallback(SendSleepRPC, ep, 100, true);
  1036. EXPECT_EQ(0, bthread_start_background(&tid, NULL, RunClosure, thrd_func));
  1037. while (echo_svc.count.load(butil::memory_order_relaxed) == old_count) {
  1038. bthread_usleep(1000);
  1039. }
  1040. timer.start();
  1041. ASSERT_EQ(0, server.Stop(1000));
  1042. ASSERT_EQ(0, server.Join());
  1043. timer.stop();
  1044. EXPECT_TRUE(labs(timer.m_elapsed() - 100) < 15) << timer.m_elapsed();
  1045. bthread_join(tid, NULL);
  1046. }
  1047. }
  1048. void SendMultipleRPC(butil::EndPoint ep, int count) {
  1049. brpc::Channel channel;
  1050. EXPECT_EQ(0, channel.Init(ep, NULL));
  1051. for (int i = 0; i < count; ++i) {
  1052. brpc::Controller cntl;
  1053. test::EchoRequest req;
  1054. test::EchoResponse res;
  1055. req.set_message(EXP_REQUEST);
  1056. test::EchoService_Stub stub(&channel);
  1057. stub.Echo(&cntl, &req, &res, NULL);
  1058. EXPECT_EQ(EXP_RESPONSE, res.message()) << cntl.ErrorText();
  1059. }
  1060. }
  1061. TEST_F(ServerTest, serving_requests) {
  1062. EchoServiceImpl echo_svc;
  1063. brpc::Server server;
  1064. ASSERT_EQ(0, server.AddService(&echo_svc,
  1065. brpc::SERVER_DOESNT_OWN_SERVICE));
  1066. butil::EndPoint ep;
  1067. ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
  1068. ASSERT_EQ(0, server.Start(ep, NULL));
  1069. const int NUM = 1;
  1070. const int COUNT = 1;
  1071. pthread_t tids[NUM];
  1072. for (int i = 0; i < NUM; ++i) {
  1073. google::protobuf::Closure* thrd_func =
  1074. brpc::NewCallback(SendMultipleRPC, ep, COUNT);
  1075. EXPECT_EQ(0, pthread_create(&tids[i], NULL, RunClosure, thrd_func));
  1076. }
  1077. for (int i = 0; i < NUM; ++i) {
  1078. pthread_join(tids[i], NULL);
  1079. }
  1080. ASSERT_EQ(NUM * COUNT, echo_svc.count.load());
  1081. ASSERT_EQ(0, server.Stop(0));
  1082. ASSERT_EQ(0, server.Join());
  1083. }
  1084. TEST_F(ServerTest, create_pid_file) {
  1085. {
  1086. brpc::Server server;
  1087. server._options.pid_file = "./pid_dir/sub_dir/./.server.pid";
  1088. server.PutPidFileIfNeeded();
  1089. pid_t pid = getpid();
  1090. std::ifstream fin("./pid_dir/sub_dir/.server.pid");
  1091. ASSERT_TRUE(fin.is_open());
  1092. pid_t pid_from_file;
  1093. fin >> pid_from_file;
  1094. ASSERT_EQ(pid, pid_from_file);
  1095. }
  1096. std::ifstream fin("./pid_dir/sub_dir/.server.pid");
  1097. ASSERT_FALSE(fin.is_open());
  1098. }
  1099. TEST_F(ServerTest, range_start) {
  1100. const int START_PORT = 8713;
  1101. const int END_PORT = 8719;
  1102. butil::fd_guard listen_fds[END_PORT - START_PORT];
  1103. butil::EndPoint point;
  1104. for (int i = START_PORT; i < END_PORT; ++i) {
  1105. point.port = i;
  1106. listen_fds[i - START_PORT].reset(butil::tcp_listen(point));
  1107. }
  1108. brpc::Server server;
  1109. EXPECT_EQ(-1, server.Start("0.0.0.0", brpc::PortRange(START_PORT, END_PORT - 1), NULL));
  1110. // note: add an extra port after END_PORT to detect the bug that the
  1111. // probing does not stop at the first valid port(END_PORT).
  1112. EXPECT_EQ(0, server.Start("0.0.0.0", brpc::PortRange(START_PORT, END_PORT + 1/*note*/), NULL));
  1113. EXPECT_EQ(END_PORT, server.listen_address().port);
  1114. }
  1115. TEST_F(ServerTest, add_builtin_service) {
  1116. TestAddBuiltinService(brpc::IndexService::descriptor());
  1117. TestAddBuiltinService(brpc::VersionService::descriptor());
  1118. TestAddBuiltinService(brpc::HealthService::descriptor());
  1119. TestAddBuiltinService(brpc::StatusService::descriptor());
  1120. TestAddBuiltinService(brpc::ConnectionsService::descriptor());
  1121. TestAddBuiltinService(brpc::BadMethodService::descriptor());
  1122. TestAddBuiltinService(brpc::ListService::descriptor());
  1123. if (brpc::FLAGS_enable_threads_service) {
  1124. TestAddBuiltinService(brpc::ThreadsService::descriptor());
  1125. }
  1126. #if !BRPC_WITH_GLOG
  1127. TestAddBuiltinService(brpc::VLogService::descriptor());
  1128. #endif
  1129. TestAddBuiltinService(brpc::FlagsService::descriptor());
  1130. TestAddBuiltinService(brpc::VarsService::descriptor());
  1131. TestAddBuiltinService(brpc::RpczService::descriptor());
  1132. TestAddBuiltinService(brpc::PProfService::descriptor());
  1133. if (brpc::FLAGS_enable_dir_service) {
  1134. TestAddBuiltinService(brpc::DirService::descriptor());
  1135. }
  1136. }
  1137. TEST_F(ServerTest, base64_to_string) {
  1138. // We test two cases as following. If these two tests can be passed, we
  1139. // can prove that the pb_bytes_to_base64 flag is working in both client side
  1140. // and server side.
  1141. // 1. Client sets pb_bytes_to_base64 and server also sets pb_bytes_to_base64
  1142. // 2. Client sets pb_bytes_to_base64, but server doesn't set pb_bytes_to_base64
  1143. for (int i = 0; i < 2; ++i) {
  1144. brpc::Server server;
  1145. EchoServiceImpl echo_svc;
  1146. brpc::ServiceOptions service_opt;
  1147. service_opt.pb_bytes_to_base64 = (i == 0);
  1148. ASSERT_EQ(0, server.AddService(&echo_svc,
  1149. service_opt));
  1150. ASSERT_EQ(0, server.Start(8613, NULL));
  1151. brpc::Channel chan;
  1152. brpc::ChannelOptions opt;
  1153. opt.protocol = brpc::PROTOCOL_HTTP;
  1154. ASSERT_EQ(0, chan.Init("localhost:8613", &opt));
  1155. brpc::Controller cntl;
  1156. cntl.http_request().uri() = "/EchoService/BytesEcho" +
  1157. butil::string_printf("%d", i + 1);
  1158. cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
  1159. cntl.http_request().set_content_type("application/json");
  1160. cntl.set_pb_bytes_to_base64(true);
  1161. test::BytesRequest req;
  1162. test::BytesResponse res;
  1163. req.set_databytes(EXP_REQUEST);
  1164. chan.CallMethod(NULL, &cntl, &req, &res, NULL);
  1165. EXPECT_FALSE(cntl.Failed());
  1166. EXPECT_EQ(EXP_REQUEST, res.databytes());
  1167. server.Stop(0);
  1168. server.Join();
  1169. }
  1170. }
  1171. TEST_F(ServerTest, too_big_message) {
  1172. EchoServiceImpl echo_svc;
  1173. brpc::Server server;
  1174. ASSERT_EQ(0, server.AddService(&echo_svc,
  1175. brpc::SERVER_DOESNT_OWN_SERVICE));
  1176. ASSERT_EQ(0, server.Start(8613, NULL));
  1177. #if !BRPC_WITH_GLOG
  1178. logging::StringSink log_str;
  1179. logging::LogSink* old_sink = logging::SetLogSink(&log_str);
  1180. #endif
  1181. brpc::Channel chan;
  1182. ASSERT_EQ(0, chan.Init("localhost:8613", NULL));
  1183. brpc::Controller cntl;
  1184. test::EchoRequest req;
  1185. test::EchoResponse res;
  1186. req.mutable_message()->resize(brpc::FLAGS_max_body_size + 1);
  1187. test::EchoService_Stub stub(&chan);
  1188. stub.Echo(&cntl, &req, &res, NULL);
  1189. EXPECT_TRUE(cntl.Failed());
  1190. #if !BRPC_WITH_GLOG
  1191. ASSERT_EQ(&log_str, logging::SetLogSink(old_sink));
  1192. std::ostringstream expected_log;
  1193. expected_log << " is bigger than " << brpc::FLAGS_max_body_size
  1194. << " bytes, the connection will be closed."
  1195. " Set max_body_size to allow bigger messages";
  1196. ASSERT_NE(std::string::npos, log_str.find(expected_log.str()));
  1197. #endif
  1198. server.Stop(0);
  1199. server.Join();
  1200. }
  1201. TEST_F(ServerTest, max_concurrency) {
  1202. const int port = 9200;
  1203. brpc::Server server1;
  1204. EchoServiceImpl service1;
  1205. ASSERT_EQ(0, server1.AddService(&service1, brpc::SERVER_DOESNT_OWN_SERVICE));
  1206. server1.MaxConcurrencyOf("test.EchoService.Echo") = 1;
  1207. ASSERT_EQ(1, server1.MaxConcurrencyOf("test.EchoService.Echo"));
  1208. server1.MaxConcurrencyOf(&service1, "Echo") = 2;
  1209. ASSERT_EQ(2, server1.MaxConcurrencyOf(&service1, "Echo"));
  1210. ASSERT_EQ(0, server1.Start(port, NULL));
  1211. brpc::Channel http_channel;
  1212. brpc::ChannelOptions chan_options;
  1213. chan_options.protocol = "http";
  1214. ASSERT_EQ(0, http_channel.Init("0.0.0.0", port, &chan_options));
  1215. brpc::Channel normal_channel;
  1216. ASSERT_EQ(0, normal_channel.Init("0.0.0.0", port, NULL));
  1217. test::EchoService_Stub stub(&normal_channel);
  1218. brpc::Controller cntl1;
  1219. cntl1.http_request().uri() = "/EchoService/Echo";
  1220. cntl1.http_request().set_method(brpc::HTTP_METHOD_POST);
  1221. cntl1.request_attachment().append("{\"message\":\"hello\",\"sleep_us\":100000}");
  1222. http_channel.CallMethod(NULL, &cntl1, NULL, NULL, brpc::DoNothing());
  1223. brpc::Controller cntl2;
  1224. test::EchoRequest req;
  1225. test::EchoResponse res;
  1226. req.set_message("hello");
  1227. req.set_sleep_us(100000);
  1228. stub.Echo(&cntl2, &req, &res, brpc::DoNothing());
  1229. bthread_usleep(20000);
  1230. LOG(INFO) << "Send other requests";
  1231. brpc::Controller cntl3;
  1232. cntl3.http_request().uri() = "/EchoService/Echo";
  1233. cntl3.http_request().set_method(brpc::HTTP_METHOD_POST);
  1234. cntl3.request_attachment().append("{\"message\":\"hello\"}");
  1235. http_channel.CallMethod(NULL, &cntl3, NULL, NULL, NULL);
  1236. ASSERT_TRUE(cntl3.Failed());
  1237. ASSERT_EQ(brpc::EHTTP, cntl3.ErrorCode());
  1238. ASSERT_EQ(brpc::HTTP_STATUS_SERVICE_UNAVAILABLE, cntl3.http_response().status_code());
  1239. brpc::Controller cntl4;
  1240. req.clear_sleep_us();
  1241. stub.Echo(&cntl4, &req, NULL, NULL);
  1242. ASSERT_TRUE(cntl4.Failed());
  1243. ASSERT_EQ(brpc::ELIMIT, cntl4.ErrorCode());
  1244. brpc::Join(cntl1.call_id());
  1245. brpc::Join(cntl2.call_id());
  1246. ASSERT_FALSE(cntl1.Failed()) << cntl1.ErrorText();
  1247. ASSERT_FALSE(cntl2.Failed()) << cntl2.ErrorText();
  1248. cntl3.Reset();
  1249. cntl3.http_request().uri() = "/EchoService/Echo";
  1250. cntl3.http_request().set_method(brpc::HTTP_METHOD_POST);
  1251. cntl3.request_attachment().append("{\"message\":\"hello\"}");
  1252. http_channel.CallMethod(NULL, &cntl3, NULL, NULL, NULL);
  1253. ASSERT_FALSE(cntl3.Failed()) << cntl3.ErrorText();
  1254. cntl4.Reset();
  1255. stub.Echo(&cntl4, &req, NULL, NULL);
  1256. ASSERT_FALSE(cntl4.Failed()) << cntl4.ErrorText();
  1257. }
  1258. } //namespace