brpc_server_unittest.cpp 54 KB

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