test-http.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*************************************************************************
  2. *
  3. * Copyright (C) 2018-2025 Ruilin Peng (Nick) <[email protected]>.
  4. *
  5. * smartdns is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * smartdns is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "client.h"
  19. #include "include/utils.h"
  20. #include "server.h"
  21. #include "smartdns/dns.h"
  22. #include "smartdns/http_parse.h"
  23. #include "smartdns/util.h"
  24. #include "gtest/gtest.h"
  25. #include <fstream>
  26. class HTTP : public ::testing::Test
  27. {
  28. protected:
  29. virtual void SetUp() {}
  30. virtual void TearDown() {}
  31. };
  32. TEST_F(HTTP, http1_1_request_parse)
  33. {
  34. const char *data = "GET /?q=question&lang=cn HTTP/1.1\r\n"
  35. "Host: www.example.com\r\n"
  36. "User-Agent: smartdns/46\r\n"
  37. "Accept: */*\r\n"
  38. "\r\n"
  39. "hello world";
  40. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_1_1);
  41. ASSERT_NE(http_head, nullptr);
  42. int ret = http_head_parse(http_head, (const unsigned char *)data, strlen(data));
  43. ASSERT_GT(ret, 0);
  44. EXPECT_STREQ(http_head_get_httpversion(http_head), "HTTP/1.1");
  45. EXPECT_EQ(http_head_get_method(http_head), HTTP_METHOD_GET);
  46. EXPECT_STREQ(http_head_get_url(http_head), "/");
  47. EXPECT_STREQ(http_head_get_fields_value(http_head, "Host"), "www.example.com");
  48. EXPECT_STREQ(http_head_get_fields_value(http_head, "User-Agent"), "smartdns/46");
  49. EXPECT_STREQ(http_head_get_fields_value(http_head, "Accept"), "*/*");
  50. EXPECT_STREQ((const char *)http_head_get_data(http_head), "hello world");
  51. EXPECT_STREQ(http_head_get_params_value(http_head, "q"), "question");
  52. EXPECT_STREQ(http_head_get_params_value(http_head, "lang"), "cn");
  53. http_head_destroy(http_head);
  54. }
  55. TEST_F(HTTP, http1_1_request_serialize)
  56. {
  57. const char *data = "GET /?q=question&lang=cn HTTP/1.1\r\n"
  58. "Host: www.example.com\r\n"
  59. "User-Agent: smartdns/46\r\n"
  60. "Accept: */*\r\n"
  61. "\r\n"
  62. "hello world";
  63. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_1_1);
  64. ASSERT_NE(http_head, nullptr);
  65. http_head_set_httpversion(http_head, "HTTP/1.1");
  66. http_head_set_method(http_head, HTTP_METHOD_GET);
  67. http_head_set_url(http_head, "/");
  68. http_head_add_fields(http_head, "Host", "www.example.com");
  69. http_head_add_fields(http_head, "User-Agent", "smartdns/46");
  70. http_head_add_fields(http_head, "Accept", "*/*");
  71. http_head_set_data(http_head, "hello world", strlen("hello world") + 1);
  72. http_head_set_head_type(http_head, HTTP_HEAD_REQUEST);
  73. http_head_add_param(http_head, "q", "question");
  74. http_head_add_param(http_head, "lang", "cn");
  75. char buffer[1024];
  76. int ret = http_head_serialize(http_head, buffer, 1024);
  77. ASSERT_GT(ret, 0);
  78. EXPECT_STREQ(buffer, data);
  79. http_head_destroy(http_head);
  80. }
  81. TEST_F(HTTP, http1_1_response_parse)
  82. {
  83. const char *data = "HTTP/1.1 200 OK\r\n"
  84. "Server: smartdns\r\n"
  85. "Content-Type: text/html\r\n"
  86. "Content-Length: 11\r\n"
  87. "\r\n"
  88. "hello world";
  89. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_1_1);
  90. ASSERT_NE(http_head, nullptr);
  91. int ret = http_head_parse(http_head, (const unsigned char *)data, strlen(data));
  92. ASSERT_GT(ret, 0);
  93. EXPECT_STREQ(http_head_get_httpversion(http_head), "HTTP/1.1");
  94. EXPECT_EQ(http_head_get_httpcode(http_head), 200);
  95. EXPECT_STREQ(http_head_get_httpcode_msg(http_head), "OK");
  96. EXPECT_STREQ(http_head_get_fields_value(http_head, "Server"), "smartdns");
  97. EXPECT_STREQ(http_head_get_fields_value(http_head, "Content-Type"), "text/html");
  98. EXPECT_STREQ(http_head_get_fields_value(http_head, "Content-Length"), "11");
  99. EXPECT_STREQ((const char *)http_head_get_data(http_head), "hello world");
  100. http_head_destroy(http_head);
  101. }
  102. TEST_F(HTTP, http1_1_response_serialize)
  103. {
  104. const char *data = "HTTP/1.1 200 OK\r\n"
  105. "Server: smartdns\r\n"
  106. "Content-Type: text/html\r\n"
  107. "Content-Length: 11\r\n"
  108. "\r\n"
  109. "hello world";
  110. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_1_1);
  111. ASSERT_NE(http_head, nullptr);
  112. http_head_set_httpversion(http_head, "HTTP/1.1");
  113. http_head_set_httpcode(http_head, 200, "OK");
  114. http_head_add_fields(http_head, "Server", "smartdns");
  115. http_head_add_fields(http_head, "Content-Type", "text/html");
  116. http_head_add_fields(http_head, "Content-Length", "11");
  117. http_head_set_data(http_head, "hello world", strlen("hello world") + 1);
  118. http_head_set_head_type(http_head, HTTP_HEAD_RESPONSE);
  119. char buffer[1024];
  120. int ret = http_head_serialize(http_head, buffer, 1024);
  121. ASSERT_GT(ret, 0);
  122. EXPECT_STREQ(buffer, data);
  123. http_head_destroy(http_head);
  124. }
  125. TEST_F(HTTP, http3_0_parse)
  126. {
  127. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_3_0);
  128. ASSERT_NE(http_head, nullptr);
  129. http_head_set_httpversion(http_head, "HTTP/3");
  130. http_head_set_method(http_head, HTTP_METHOD_GET);
  131. http_head_set_url(http_head, "/");
  132. http_head_add_fields(http_head, "Host", "www.example.com");
  133. http_head_add_fields(http_head, "User-Agent", "smartdns/46");
  134. http_head_add_fields(http_head, "Accept", "*/*");
  135. http_head_set_data(http_head, "hello world", strlen("hello world") + 1);
  136. http_head_set_head_type(http_head, HTTP_HEAD_REQUEST);
  137. http_head_add_param(http_head, "q", "question");
  138. http_head_add_param(http_head, "lang", "cn");
  139. unsigned char buffer[1024];
  140. int ret = http_head_serialize(http_head, buffer, 1024);
  141. ASSERT_EQ(ret, 149);
  142. http_head_destroy(http_head);
  143. http_head = http_head_init(1024, HTTP_VERSION_3_0);
  144. ASSERT_NE(http_head, nullptr);
  145. ret = http_head_parse(http_head, buffer, ret);
  146. ASSERT_EQ(ret, 149);
  147. EXPECT_STREQ(http_head_get_httpversion(http_head), "HTTP/3.0");
  148. EXPECT_EQ(http_head_get_method(http_head), HTTP_METHOD_GET);
  149. EXPECT_STREQ(http_head_get_url(http_head), "/");
  150. EXPECT_STREQ(http_head_get_fields_value(http_head, "Host"), "www.example.com");
  151. EXPECT_STREQ(http_head_get_fields_value(http_head, "User-Agent"), "smartdns/46");
  152. EXPECT_STREQ(http_head_get_fields_value(http_head, "Accept"), "*/*");
  153. EXPECT_STREQ((const char *)http_head_get_data(http_head), "hello world");
  154. EXPECT_STREQ(http_head_get_params_value(http_head, "q"), "question");
  155. EXPECT_STREQ(http_head_get_params_value(http_head, "lang"), "cn");
  156. http_head_destroy(http_head);
  157. }
  158. TEST_F(HTTP, http1_1_small_buffer)
  159. {
  160. const char *data = "HTTP/1.1 200 OK\r\n"
  161. "Server: smartdns\r\n"
  162. "Content-Type: text/html\r\n"
  163. "Content-Length: 11\r\n"
  164. "\r\n"
  165. "hello world";
  166. struct http_head *http_head = http_head_init(5, HTTP_VERSION_1_1);
  167. ASSERT_NE(http_head, nullptr);
  168. int ret = http_head_parse(http_head, (const unsigned char *)data, strlen(data));
  169. EXPECT_EQ(ret, -3);
  170. http_head_destroy(http_head);
  171. }
  172. TEST_F(HTTP, http3_small_buffer)
  173. {
  174. struct http_head *http_head = http_head_init(1024, HTTP_VERSION_3_0);
  175. ASSERT_NE(http_head, nullptr);
  176. http_head_set_httpversion(http_head, "HTTP/3");
  177. http_head_set_method(http_head, HTTP_METHOD_GET);
  178. http_head_set_url(http_head, "/");
  179. http_head_add_fields(http_head, "Host", "www.example.com");
  180. http_head_add_fields(http_head, "User-Agent", "smartdns/46");
  181. http_head_add_fields(http_head, "Accept", "*/*");
  182. http_head_set_data(http_head, "hello world", strlen("hello world") + 1);
  183. http_head_set_head_type(http_head, HTTP_HEAD_REQUEST);
  184. http_head_add_param(http_head, "q", "question");
  185. http_head_add_param(http_head, "lang", "cn");
  186. unsigned char buffer[1024];
  187. int buffer_len = http_head_serialize(http_head, buffer, 1024);
  188. ASSERT_EQ(buffer_len, 149);
  189. http_head_destroy(http_head);
  190. http_head = http_head_init(5, HTTP_VERSION_3_0);
  191. ASSERT_NE(http_head, nullptr);
  192. int ret = http_head_parse(http_head, (const unsigned char *)buffer, buffer_len);
  193. EXPECT_EQ(ret, -3);
  194. http_head_destroy(http_head);
  195. http_head = http_head_init(100, HTTP_VERSION_3_0);
  196. ASSERT_NE(http_head, nullptr);
  197. ret = http_head_parse(http_head, (const unsigned char *)buffer, buffer_len);
  198. EXPECT_EQ(ret, -3);
  199. http_head_destroy(http_head);
  200. http_head = http_head_init(1024, HTTP_VERSION_3_0);
  201. ASSERT_NE(http_head, nullptr);
  202. ret = http_head_parse(http_head, (const unsigned char *)buffer, buffer_len);
  203. EXPECT_GT(ret, 0);
  204. http_head_destroy(http_head);
  205. }