interceptor_tests.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include <gtest/gtest.h>
  2. #include <iostream>
  3. #include "cpr/cpr.h"
  4. #include "httpServer.hpp"
  5. using namespace cpr;
  6. static HttpServer* server = new HttpServer();
  7. class HiddenHelloWorldRedirectInterceptor : public Interceptor {
  8. public:
  9. Response intercept(Session& session) override {
  10. // Save original url
  11. Url old_url = session.GetFullRequestUrl();
  12. // Rewrite the url
  13. Url url{server->GetBaseUrl() + "/hello.html"};
  14. session.SetUrl(url);
  15. // Procceed the chain
  16. Response response = proceed(session);
  17. // Restore the url again
  18. response.url = old_url;
  19. return response;
  20. }
  21. };
  22. class ChangeStatusCodeInterceptor : public Interceptor {
  23. public:
  24. Response intercept(Session& session) override {
  25. // Procceed the chain
  26. Response response = proceed(session);
  27. // Change the status code
  28. response.status_code = 12345;
  29. return response;
  30. }
  31. };
  32. class SetBasicAuthInterceptor : public Interceptor {
  33. public:
  34. Response intercept(Session& session) override {
  35. // Set authentication
  36. session.SetAuth(Authentication{"user", "password", AuthMode::BASIC});
  37. // Procceed the chain
  38. return proceed(session);
  39. }
  40. };
  41. class SetUnsupportedProtocolErrorInterceptor : public Interceptor {
  42. public:
  43. Response intercept(Session& session) override {
  44. // Procceed the chain
  45. Response response = proceed(session);
  46. // Set unsupported protocol error
  47. response.error = Error{CURLE_UNSUPPORTED_PROTOCOL, "SetErrorInterceptor"};
  48. // Return response
  49. return response;
  50. }
  51. };
  52. class ChangeRequestMethodToGetInterceptor : public Interceptor {
  53. public:
  54. Response intercept(Session& session) override {
  55. return proceed(session, Interceptor::ProceedHttpMethod::GET_REQUEST);
  56. }
  57. };
  58. class ChangeRequestMethodToPostInterceptor : public Interceptor {
  59. public:
  60. Response intercept(Session& session) override {
  61. session.SetOption(Payload{{"x", "5"}});
  62. return proceed(session, Interceptor::ProceedHttpMethod::POST_REQUEST);
  63. }
  64. };
  65. class ChangeRequestMethodToPutInterceptor : public Interceptor {
  66. public:
  67. Response intercept(Session& session) override {
  68. session.SetOption(Payload{{"x", "5"}});
  69. return proceed(session, Interceptor::ProceedHttpMethod::PUT_REQUEST);
  70. }
  71. };
  72. class ChangeRequestMethodToDeleteInterceptor : public Interceptor {
  73. public:
  74. Response intercept(Session& session) override {
  75. return proceed(session, Interceptor::ProceedHttpMethod::DELETE_REQUEST);
  76. }
  77. };
  78. bool write_data(std::string /*data*/, intptr_t /*userdata*/) {
  79. return true;
  80. }
  81. class ChangeRequestMethodToDownloadCallbackInterceptor : public Interceptor {
  82. public:
  83. Response intercept(Session& session) override {
  84. return proceed(session, Interceptor::ProceedHttpMethod::DOWNLOAD_CALLBACK_REQUEST, WriteCallback{write_data, 0});
  85. }
  86. };
  87. class ChangeRequestMethodToHeadInterceptor : public Interceptor {
  88. public:
  89. Response intercept(Session& session) override {
  90. return proceed(session, Interceptor::ProceedHttpMethod::HEAD_REQUEST);
  91. }
  92. };
  93. class ChangeRequestMethodToOptionsInterceptor : public Interceptor {
  94. public:
  95. Response intercept(Session& session) override {
  96. return proceed(session, Interceptor::ProceedHttpMethod::OPTIONS_REQUEST);
  97. }
  98. };
  99. class ChangeRequestMethodToPatchInterceptor : public Interceptor {
  100. public:
  101. Response intercept(Session& session) override {
  102. session.SetOption(Payload{{"x", "5"}});
  103. return proceed(session, Interceptor::ProceedHttpMethod::PATCH_REQUEST);
  104. }
  105. };
  106. TEST(InterceptorTest, HiddenUrlRewriteInterceptorTest) {
  107. Url url{server->GetBaseUrl() + "/basic.json"};
  108. Session session;
  109. session.SetUrl(url);
  110. session.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptor>());
  111. Response response = session.Get();
  112. std::string expected_text{"Hello world!"};
  113. EXPECT_EQ(expected_text, response.text);
  114. EXPECT_EQ(url, response.url);
  115. EXPECT_EQ(ErrorCode::OK, response.error.code);
  116. }
  117. TEST(InterceptorTest, ChangeStatusCodeInterceptorTest) {
  118. Url url{server->GetBaseUrl() + "/hello.html"};
  119. Session session;
  120. session.SetUrl(url);
  121. session.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptor>());
  122. Response response = session.Get();
  123. long expected_status_code{12345};
  124. EXPECT_EQ(url, response.url);
  125. EXPECT_EQ(expected_status_code, response.status_code);
  126. EXPECT_EQ(ErrorCode::OK, response.error.code);
  127. }
  128. TEST(InterceptorTest, DownloadChangeStatusCodeInterceptorTest) {
  129. cpr::Url url{server->GetBaseUrl() + "/download_gzip.html"};
  130. cpr::Session session;
  131. session.SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}});
  132. session.SetUrl(url);
  133. session.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptor>());
  134. Response response = session.Download(cpr::WriteCallback{write_data, 0});
  135. long expected_status_code{12345};
  136. EXPECT_EQ(url, response.url);
  137. EXPECT_EQ(expected_status_code, response.status_code);
  138. EXPECT_EQ(cpr::ErrorCode::OK, response.error.code);
  139. }
  140. TEST(InterceptorTest, SetBasicAuthInterceptorTest) {
  141. Url url{server->GetBaseUrl() + "/basic_auth.html"};
  142. Session session;
  143. session.SetUrl(url);
  144. session.AddInterceptor(std::make_shared<SetBasicAuthInterceptor>());
  145. Response response = session.Get();
  146. std::string expected_text{"Header reflect GET"};
  147. EXPECT_EQ(expected_text, response.text);
  148. EXPECT_EQ(url, response.url);
  149. EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
  150. EXPECT_EQ(200, response.status_code);
  151. EXPECT_EQ(ErrorCode::OK, response.error.code);
  152. }
  153. TEST(InterceptorTest, SetUnsupportedProtocolErrorInterceptorTest) {
  154. Url url{server->GetBaseUrl() + "/hello.html"};
  155. Session session;
  156. session.SetUrl(url);
  157. session.AddInterceptor(std::make_shared<SetUnsupportedProtocolErrorInterceptor>());
  158. Response response = session.Get();
  159. std::string expected_error_message{"SetErrorInterceptor"};
  160. ErrorCode expected_error_code{ErrorCode::UNSUPPORTED_PROTOCOL};
  161. EXPECT_EQ(url, response.url);
  162. EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
  163. EXPECT_EQ(200, response.status_code);
  164. EXPECT_EQ(expected_error_message, response.error.message);
  165. EXPECT_EQ(expected_error_code, response.error.code);
  166. }
  167. TEST(InterceptorTest, ChangeRequestMethodToGetInterceptorTest) {
  168. Url url{server->GetBaseUrl() + "/hello.html"};
  169. Session session;
  170. session.SetUrl(url);
  171. session.AddInterceptor(std::make_shared<ChangeRequestMethodToGetInterceptor>());
  172. Response response = session.Head();
  173. std::string expected_text{"Hello world!"};
  174. EXPECT_EQ(expected_text, response.text);
  175. EXPECT_EQ(url, response.url);
  176. EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
  177. EXPECT_EQ(200, response.status_code);
  178. EXPECT_EQ(ErrorCode::OK, response.error.code);
  179. }
  180. TEST(InterceptorTest, ChangeRequestMethodToPostInterceptorTest) {
  181. Url url{server->GetBaseUrl() + "/url_post.html"};
  182. Session session;
  183. session.SetUrl(url);
  184. session.AddInterceptor(std::make_shared<ChangeRequestMethodToPostInterceptor>());
  185. Response response = session.Head();
  186. std::string expected_text{
  187. "{\n"
  188. " \"x\": 5\n"
  189. "}"};
  190. EXPECT_EQ(expected_text, response.text);
  191. EXPECT_EQ(url, response.url);
  192. EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]);
  193. EXPECT_EQ(201, response.status_code);
  194. EXPECT_EQ(ErrorCode::OK, response.error.code);
  195. }
  196. TEST(InterceptorTest, ChangeRequestMethodToPutInterceptorTest) {
  197. Url url{server->GetBaseUrl() + "/put.html"};
  198. Session session;
  199. session.SetUrl(url);
  200. session.AddInterceptor(std::make_shared<ChangeRequestMethodToPutInterceptor>());
  201. Response response = session.Get();
  202. std::string expected_text{
  203. "{\n"
  204. " \"x\": 5\n"
  205. "}"};
  206. EXPECT_EQ(expected_text, response.text);
  207. EXPECT_EQ(url, response.url);
  208. EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]);
  209. EXPECT_EQ(200, response.status_code);
  210. EXPECT_EQ(ErrorCode::OK, response.error.code);
  211. }
  212. TEST(InterceptorTest, ChangeRequestMethodToPatchInterceptorTest) {
  213. Url url{server->GetBaseUrl() + "/patch.html"};
  214. Session session;
  215. session.SetUrl(url);
  216. session.AddInterceptor(std::make_shared<ChangeRequestMethodToPatchInterceptor>());
  217. Response response = session.Get();
  218. std::string expected_text{
  219. "{\n"
  220. " \"x\": 5\n"
  221. "}"};
  222. EXPECT_EQ(expected_text, response.text);
  223. EXPECT_EQ(url, response.url);
  224. EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]);
  225. EXPECT_EQ(200, response.status_code);
  226. EXPECT_EQ(ErrorCode::OK, response.error.code);
  227. }
  228. TEST(InterceptorTest, ChangeRequestMethodToOptionsInterceptorTest) {
  229. Url url{server->GetBaseUrl() + "/"};
  230. Session session;
  231. session.SetUrl(url);
  232. session.AddInterceptor(std::make_shared<ChangeRequestMethodToOptionsInterceptor>());
  233. Response response = session.Get();
  234. std::string expected_text{""};
  235. EXPECT_EQ(expected_text, response.text);
  236. EXPECT_EQ(url, response.url);
  237. EXPECT_EQ(std::string{"GET, POST, PUT, DELETE, PATCH, OPTIONS"}, response.header["Access-Control-Allow-Methods"]);
  238. EXPECT_EQ(200, response.status_code);
  239. EXPECT_EQ(ErrorCode::OK, response.error.code);
  240. }
  241. TEST(InterceptorTest, ChangeRequestMethodToHeadInterceptorTest) {
  242. Url url{server->GetBaseUrl() + "/hello.html"};
  243. Session session;
  244. session.SetUrl(url);
  245. session.AddInterceptor(std::make_shared<ChangeRequestMethodToHeadInterceptor>());
  246. Response response = session.Get();
  247. EXPECT_EQ(std::string{}, response.text);
  248. EXPECT_EQ(url, response.url);
  249. EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
  250. EXPECT_EQ(200, response.status_code);
  251. EXPECT_EQ(ErrorCode::OK, response.error.code);
  252. }
  253. TEST(InterceptorTest, ChangeRequestMethodToDownloadCallbackInterceptorTest) {
  254. Url url{server->GetBaseUrl() + "/download_gzip.html"};
  255. Session session;
  256. session.SetUrl(url);
  257. session.SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}});
  258. session.SetTimeout(Timeout{2000});
  259. session.AddInterceptor(std::make_shared<ChangeRequestMethodToDownloadCallbackInterceptor>());
  260. Response response = session.Put();
  261. EXPECT_EQ(url, response.url);
  262. EXPECT_EQ(200, response.status_code);
  263. EXPECT_EQ(cpr::ErrorCode::OK, response.error.code);
  264. }
  265. TEST(InterceptorTest, ChangeRequestMethodToDeleteInterceptorTest) {
  266. Url url{server->GetBaseUrl() + "/delete.html"};
  267. Session session;
  268. session.SetUrl(url);
  269. session.AddInterceptor(std::make_shared<ChangeRequestMethodToDeleteInterceptor>());
  270. Response response = session.Get();
  271. std::string expected_text{"Delete success"};
  272. EXPECT_EQ(expected_text, response.text);
  273. EXPECT_EQ(url, response.url);
  274. EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
  275. EXPECT_EQ(200, response.status_code);
  276. EXPECT_EQ(ErrorCode::OK, response.error.code);
  277. }
  278. TEST(InterceptorTest, TwoInterceptorsTest) {
  279. Url url{server->GetBaseUrl() + "/basic.json"};
  280. Session session;
  281. session.SetUrl(url);
  282. session.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptor>());
  283. session.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptor>());
  284. Response response = session.Get();
  285. std::string expected_text{"Hello world!"};
  286. long expected_status_code{12345};
  287. EXPECT_EQ(expected_text, response.text);
  288. EXPECT_EQ(url, response.url);
  289. EXPECT_EQ(expected_status_code, response.status_code);
  290. EXPECT_EQ(ErrorCode::OK, response.error.code);
  291. }
  292. TEST(InterceptorTest, ThreeInterceptorsTest) {
  293. Url url{server->GetBaseUrl() + "/basic.json"};
  294. Session session;
  295. session.SetUrl(url);
  296. session.AddInterceptor(std::make_shared<HiddenHelloWorldRedirectInterceptor>());
  297. session.AddInterceptor(std::make_shared<ChangeStatusCodeInterceptor>());
  298. session.AddInterceptor(std::make_shared<SetUnsupportedProtocolErrorInterceptor>());
  299. Response response = session.Get();
  300. std::string expected_text{"Hello world!"};
  301. long expected_status_code{12345};
  302. std::string expected_error_message{"SetErrorInterceptor"};
  303. ErrorCode expected_error_code{ErrorCode::UNSUPPORTED_PROTOCOL};
  304. EXPECT_EQ(expected_text, response.text);
  305. EXPECT_EQ(url, response.url);
  306. EXPECT_EQ(expected_status_code, response.status_code);
  307. EXPECT_EQ(expected_error_message, response.error.message);
  308. EXPECT_EQ(expected_error_code, response.error.code);
  309. }
  310. int main(int argc, char** argv) {
  311. ::testing::InitGoogleTest(&argc, argv);
  312. ::testing::AddGlobalTestEnvironment(server);
  313. return RUN_ALL_TESTS();
  314. }