test_proxy.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include <future>
  2. #include <gtest/gtest.h>
  3. #include <httplib.h>
  4. using namespace std;
  5. using namespace httplib;
  6. template <typename T> void ProxyTest(T &cli, bool basic) {
  7. cli.set_proxy("localhost", basic ? 3128 : 3129);
  8. auto res = cli.Get("/httpbin/get");
  9. ASSERT_TRUE(res != nullptr);
  10. EXPECT_EQ(StatusCode::ProxyAuthenticationRequired_407, res->status);
  11. }
  12. TEST(ProxyTest, NoSSLBasic) {
  13. Client cli("nghttp2.org");
  14. ProxyTest(cli, true);
  15. }
  16. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  17. TEST(ProxyTest, SSLBasic) {
  18. SSLClient cli("nghttp2.org");
  19. ProxyTest(cli, true);
  20. }
  21. TEST(ProxyTest, NoSSLDigest) {
  22. Client cli("nghttp2.org");
  23. ProxyTest(cli, false);
  24. }
  25. TEST(ProxyTest, SSLDigest) {
  26. SSLClient cli("nghttp2.org");
  27. ProxyTest(cli, false);
  28. }
  29. #endif
  30. // ----------------------------------------------------------------------------
  31. template <typename T>
  32. void RedirectProxyText(T &cli, const char *path, bool basic) {
  33. cli.set_proxy("localhost", basic ? 3128 : 3129);
  34. if (basic) {
  35. cli.set_proxy_basic_auth("hello", "world");
  36. } else {
  37. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  38. cli.set_proxy_digest_auth("hello", "world");
  39. #endif
  40. }
  41. cli.set_follow_location(true);
  42. auto res = cli.Get(path);
  43. ASSERT_TRUE(res != nullptr);
  44. EXPECT_EQ(StatusCode::OK_200, res->status);
  45. }
  46. TEST(RedirectTest, HTTPBinNoSSLBasic) {
  47. Client cli("nghttp2.org");
  48. RedirectProxyText(cli, "/httpbin/redirect/2", true);
  49. }
  50. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  51. TEST(RedirectTest, HTTPBinNoSSLDigest) {
  52. Client cli("nghttp2.org");
  53. RedirectProxyText(cli, "/httpbin/redirect/2", false);
  54. }
  55. TEST(RedirectTest, HTTPBinSSLBasic) {
  56. SSLClient cli("nghttp2.org");
  57. RedirectProxyText(cli, "/httpbin/redirect/2", true);
  58. }
  59. TEST(RedirectTest, HTTPBinSSLDigest) {
  60. SSLClient cli("nghttp2.org");
  61. RedirectProxyText(cli, "/httpbin/redirect/2", false);
  62. }
  63. #endif
  64. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  65. TEST(RedirectTest, YouTubeNoSSLBasic) {
  66. Client cli("youtube.com");
  67. RedirectProxyText(cli, "/", true);
  68. }
  69. TEST(RedirectTest, DISABLED_YouTubeNoSSLDigest) {
  70. Client cli("youtube.com");
  71. RedirectProxyText(cli, "/", false);
  72. }
  73. TEST(RedirectTest, YouTubeSSLBasic) {
  74. SSLClient cli("youtube.com");
  75. RedirectProxyText(cli, "/", true);
  76. }
  77. TEST(RedirectTest, YouTubeSSLDigest) {
  78. SSLClient cli("youtube.com");
  79. RedirectProxyText(cli, "/", false);
  80. }
  81. #endif
  82. // ----------------------------------------------------------------------------
  83. template <typename T> void BaseAuthTestFromHTTPWatch(T &cli) {
  84. cli.set_proxy("localhost", 3128);
  85. cli.set_proxy_basic_auth("hello", "world");
  86. {
  87. auto res = cli.Get("/basic-auth/hello/world");
  88. ASSERT_TRUE(res != nullptr);
  89. EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  90. }
  91. {
  92. auto res = cli.Get("/basic-auth/hello/world",
  93. {make_basic_authentication_header("hello", "world")});
  94. ASSERT_TRUE(res != nullptr);
  95. EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
  96. res->body);
  97. EXPECT_EQ(StatusCode::OK_200, res->status);
  98. }
  99. {
  100. cli.set_basic_auth("hello", "world");
  101. auto res = cli.Get("/basic-auth/hello/world");
  102. ASSERT_TRUE(res != nullptr);
  103. EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
  104. res->body);
  105. EXPECT_EQ(StatusCode::OK_200, res->status);
  106. }
  107. {
  108. cli.set_basic_auth("hello", "bad");
  109. auto res = cli.Get("/basic-auth/hello/world");
  110. ASSERT_TRUE(res != nullptr);
  111. EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  112. }
  113. {
  114. cli.set_basic_auth("bad", "world");
  115. auto res = cli.Get("/basic-auth/hello/world");
  116. ASSERT_TRUE(res != nullptr);
  117. EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  118. }
  119. }
  120. TEST(BaseAuthTest, NoSSL) {
  121. Client cli("httpbin.org");
  122. BaseAuthTestFromHTTPWatch(cli);
  123. }
  124. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  125. TEST(BaseAuthTest, SSL) {
  126. SSLClient cli("httpbin.org");
  127. BaseAuthTestFromHTTPWatch(cli);
  128. }
  129. #endif
  130. // ----------------------------------------------------------------------------
  131. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  132. template <typename T> void DigestAuthTestFromHTTPWatch(T &cli) {
  133. cli.set_proxy("localhost", 3129);
  134. cli.set_proxy_digest_auth("hello", "world");
  135. {
  136. auto res = cli.Get("/digest-auth/auth/hello/world");
  137. ASSERT_TRUE(res != nullptr);
  138. EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  139. }
  140. {
  141. std::vector<std::string> paths = {
  142. "/digest-auth/auth/hello/world/MD5",
  143. "/digest-auth/auth/hello/world/SHA-256",
  144. "/digest-auth/auth/hello/world/SHA-512",
  145. "/digest-auth/auth-int/hello/world/MD5",
  146. };
  147. cli.set_digest_auth("hello", "world");
  148. for (auto path : paths) {
  149. auto res = cli.Get(path.c_str());
  150. ASSERT_TRUE(res != nullptr);
  151. EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
  152. res->body);
  153. EXPECT_EQ(StatusCode::OK_200, res->status);
  154. }
  155. cli.set_digest_auth("hello", "bad");
  156. for (auto path : paths) {
  157. auto res = cli.Get(path.c_str());
  158. ASSERT_TRUE(res != nullptr);
  159. EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  160. }
  161. // NOTE: Until httpbin.org fixes issue #46, the following test is commented
  162. // out. Please see https://httpbin.org/digest-auth/auth/hello/world
  163. // cli.set_digest_auth("bad", "world");
  164. // for (auto path : paths) {
  165. // auto res = cli.Get(path.c_str());
  166. // ASSERT_TRUE(res != nullptr);
  167. // EXPECT_EQ(StatusCode::Unauthorized_401, res->status);
  168. // }
  169. }
  170. }
  171. TEST(DigestAuthTest, SSL) {
  172. SSLClient cli("httpbin.org");
  173. DigestAuthTestFromHTTPWatch(cli);
  174. }
  175. TEST(DigestAuthTest, NoSSL) {
  176. Client cli("httpbin.org");
  177. DigestAuthTestFromHTTPWatch(cli);
  178. }
  179. #endif
  180. // ----------------------------------------------------------------------------
  181. template <typename T> void KeepAliveTest(T &cli, bool basic) {
  182. cli.set_proxy("localhost", basic ? 3128 : 3129);
  183. if (basic) {
  184. cli.set_proxy_basic_auth("hello", "world");
  185. } else {
  186. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  187. cli.set_proxy_digest_auth("hello", "world");
  188. #endif
  189. }
  190. cli.set_follow_location(true);
  191. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  192. cli.set_digest_auth("hello", "world");
  193. #endif
  194. {
  195. auto res = cli.Get("/httpbin/get");
  196. EXPECT_EQ(StatusCode::OK_200, res->status);
  197. }
  198. {
  199. auto res = cli.Get("/httpbin/redirect/2");
  200. EXPECT_EQ(StatusCode::OK_200, res->status);
  201. }
  202. {
  203. std::vector<std::string> paths = {
  204. "/httpbin/digest-auth/auth/hello/world/MD5",
  205. "/httpbin/digest-auth/auth/hello/world/SHA-256",
  206. "/httpbin/digest-auth/auth/hello/world/SHA-512",
  207. "/httpbin/digest-auth/auth-int/hello/world/MD5",
  208. };
  209. for (auto path : paths) {
  210. auto res = cli.Get(path.c_str());
  211. EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n",
  212. res->body);
  213. EXPECT_EQ(StatusCode::OK_200, res->status);
  214. }
  215. }
  216. {
  217. int count = 10;
  218. while (count--) {
  219. auto res = cli.Get("/httpbin/get");
  220. EXPECT_EQ(StatusCode::OK_200, res->status);
  221. }
  222. }
  223. }
  224. #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
  225. TEST(KeepAliveTest, NoSSLWithBasic) {
  226. Client cli("nghttp2.org");
  227. KeepAliveTest(cli, true);
  228. }
  229. TEST(KeepAliveTest, SSLWithBasic) {
  230. SSLClient cli("nghttp2.org");
  231. KeepAliveTest(cli, true);
  232. }
  233. TEST(KeepAliveTest, NoSSLWithDigest) {
  234. Client cli("nghttp2.org");
  235. KeepAliveTest(cli, false);
  236. }
  237. TEST(KeepAliveTest, SSLWithDigest) {
  238. SSLClient cli("nghttp2.org");
  239. KeepAliveTest(cli, false);
  240. }
  241. #endif