http_client-test.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* libanode: the Anode C reference implementation
  2. * Copyright (C) 2009-2010 Adam Ierymenko <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>. */
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <openssl/sha.h>
  20. #include "../anode.h"
  21. #include "../misc.h"
  22. #include "../http_client.h"
  23. #include "../dictionary.h"
  24. struct TestCase
  25. {
  26. int method;
  27. AnodeURI uri;
  28. const void *client_data;
  29. unsigned int client_data_len;
  30. const char *expected_sha1;
  31. char actual_sha1[64];
  32. int got_it;
  33. int keepalive;
  34. struct TestCase *next;
  35. };
  36. #define NUM_TEST_CASES 7
  37. static struct TestCase test_cases[NUM_TEST_CASES];
  38. static void init_test_cases(int keepalive)
  39. {
  40. AnodeURI_parse(&(test_cases[0].uri),"http://zerotier.com/for_unit_tests/test1.txt");
  41. test_cases[0].method = ANODE_HTTP_GET;
  42. test_cases[0].client_data_len = 0;
  43. test_cases[0].expected_sha1 = "0828324174b10cc867b7255a84a8155cf89e1b8b";
  44. test_cases[0].actual_sha1[0] = (char)0;
  45. test_cases[0].got_it = 0;
  46. test_cases[0].keepalive = keepalive;
  47. test_cases[0].next = &(test_cases[1]);
  48. AnodeURI_parse(&(test_cases[1].uri),"http://zerotier.com/for_unit_tests/test2.bin");
  49. test_cases[1].method = ANODE_HTTP_GET;
  50. test_cases[1].client_data_len = 0;
  51. test_cases[1].expected_sha1 = "6b67c635786ab52666211d02412c0d0f0372980d";
  52. test_cases[1].actual_sha1[0] = (char)0;
  53. test_cases[1].got_it = 0;
  54. test_cases[1].keepalive = keepalive;
  55. test_cases[1].next = &(test_cases[2]);
  56. AnodeURI_parse(&(test_cases[2].uri),"http://zerotier.com/for_unit_tests/test3.bin");
  57. test_cases[2].method = ANODE_HTTP_GET;
  58. test_cases[2].client_data_len = 0;
  59. test_cases[2].expected_sha1 = "efa7722029fdbb6abd0e3ed32a0b44bfb982cff0";
  60. test_cases[2].actual_sha1[0] = (char)0;
  61. test_cases[2].got_it = 0;
  62. test_cases[2].keepalive = keepalive;
  63. test_cases[2].next = &(test_cases[3]);
  64. AnodeURI_parse(&(test_cases[3].uri),"http://zerotier.com/for_unit_tests/test4.bin");
  65. test_cases[3].method = ANODE_HTTP_GET;
  66. test_cases[3].client_data_len = 0;
  67. test_cases[3].expected_sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
  68. test_cases[3].actual_sha1[0] = (char)0;
  69. test_cases[3].got_it = 0;
  70. test_cases[3].keepalive = keepalive;
  71. test_cases[3].next = &(test_cases[4]);
  72. AnodeURI_parse(&(test_cases[4].uri),"http://zerotier.com/for_unit_tests/echo.php?echo=foobar");
  73. test_cases[4].method = ANODE_HTTP_GET;
  74. test_cases[4].client_data_len = 0;
  75. test_cases[4].expected_sha1 = "8843d7f92416211de9ebb963ff4ce28125932878";
  76. test_cases[4].actual_sha1[0] = (char)0;
  77. test_cases[4].got_it = 0;
  78. test_cases[4].keepalive = keepalive;
  79. test_cases[4].next = &(test_cases[5]);
  80. AnodeURI_parse(&(test_cases[5].uri),"http://zerotier.com/for_unit_tests/echo.php");
  81. test_cases[5].method = ANODE_HTTP_POST;
  82. test_cases[5].client_data = "echo=foobar";
  83. test_cases[5].client_data_len = strlen((char *)test_cases[5].client_data);
  84. test_cases[5].expected_sha1 = "8843d7f92416211de9ebb963ff4ce28125932878";
  85. test_cases[5].actual_sha1[0] = (char)0;
  86. test_cases[5].got_it = 0;
  87. test_cases[5].keepalive = keepalive;
  88. test_cases[5].next = &(test_cases[6]);
  89. AnodeURI_parse(&(test_cases[6].uri),"http://zerotier.com/for_unit_tests/test3.bin");
  90. test_cases[6].method = ANODE_HTTP_HEAD;
  91. test_cases[6].client_data_len = 0;
  92. test_cases[6].expected_sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
  93. test_cases[6].actual_sha1[0] = (char)0;
  94. test_cases[6].got_it = 0;
  95. test_cases[6].keepalive = keepalive;
  96. test_cases[6].next = 0;
  97. }
  98. static int http_handler_dump_headers(void *arg,const char *key,const char *value)
  99. {
  100. printf(" H %s: %s\n",key,value);
  101. return 1;
  102. }
  103. static void http_handler(struct AnodeHttpClient *client)
  104. {
  105. const char *method = "???";
  106. char buf[1024];
  107. unsigned char sha[20];
  108. struct TestCase *test = (struct TestCase *)client->ptr[0];
  109. switch(client->method) {
  110. case ANODE_HTTP_GET:
  111. method = "GET";
  112. break;
  113. case ANODE_HTTP_HEAD:
  114. method = "HEAD";
  115. break;
  116. case ANODE_HTTP_POST:
  117. method = "POST";
  118. break;
  119. }
  120. if (client->response.code == 200) {
  121. SHA1((unsigned char *)client->response.data,client->response.data_length,sha);
  122. Anode_to_hex(sha,20,test->actual_sha1,sizeof(test->actual_sha1));
  123. printf("%s %s\n * SHA1: %s exp: %s\n",method,AnodeURI_to_string(&(test->uri),buf,sizeof(buf)),test->actual_sha1,test->expected_sha1);
  124. if (strcmp(test->actual_sha1,test->expected_sha1))
  125. printf(" ! SHA1 MISMATCH!\n");
  126. AnodeDictionary_iterate(&(client->response.headers),0,&http_handler_dump_headers);
  127. } else printf("%s %s: ERROR: %d\n",method,AnodeURI_to_string(&(test->uri),buf,sizeof(buf)),client->response.code);
  128. test->got_it = 1;
  129. if (!test->keepalive)
  130. AnodeHttpClient_free(client);
  131. else {
  132. test = test->next;
  133. if (test) {
  134. memcpy((void *)&(client->uri),(const void *)&(test->uri),sizeof(AnodeURI));
  135. client->data = test->client_data;
  136. client->data_length = test->client_data_len;
  137. client->ptr[0] = test;
  138. client->keepalive = test->keepalive;
  139. client->method = test->method;
  140. client->handler = &http_handler;
  141. AnodeHttpClient_send(client);
  142. } else {
  143. AnodeHttpClient_free(client);
  144. }
  145. }
  146. }
  147. int main(int argc,char **argv)
  148. {
  149. struct AnodeHttpClient *client;
  150. AnodeTransportEngine transport_engine;
  151. int i;
  152. if (Anode_init_ip_transport_engine(&transport_engine)) {
  153. printf("Failed (transport engine init)\n");
  154. return 1;
  155. }
  156. printf("Testing without keepalive...\n\n");
  157. init_test_cases(0);
  158. for(i=0;i<NUM_TEST_CASES;++i) {
  159. client = AnodeHttpClient_new(&transport_engine);
  160. memcpy((void *)&(client->uri),(const void *)&(test_cases[i].uri),sizeof(AnodeURI));
  161. client->data = test_cases[i].client_data;
  162. client->data_length = test_cases[i].client_data_len;
  163. client->ptr[0] = &test_cases[i];
  164. client->keepalive = test_cases[i].keepalive;
  165. client->method = test_cases[i].method;
  166. client->handler = &http_handler;
  167. AnodeHttpClient_send(client);
  168. }
  169. for(;;) {
  170. for(i=0;i<NUM_TEST_CASES;++i) {
  171. if (!test_cases[i].got_it)
  172. break;
  173. }
  174. if (i == NUM_TEST_CASES)
  175. break;
  176. transport_engine.poll(&transport_engine);
  177. }
  178. printf("\n\n");
  179. printf("Testing with keepalive...\n\n");
  180. init_test_cases(1);
  181. client = AnodeHttpClient_new(&transport_engine);
  182. i = 0;
  183. memcpy((void *)&(client->uri),(const void *)&(test_cases[i].uri),sizeof(AnodeURI));
  184. client->data = test_cases[i].client_data;
  185. client->data_length = test_cases[i].client_data_len;
  186. client->ptr[0] = &test_cases[i];
  187. client->keepalive = test_cases[i].keepalive;
  188. client->method = test_cases[i].method;
  189. client->handler = &http_handler;
  190. AnodeHttpClient_send(client);
  191. for(;;) {
  192. for(i=0;i<NUM_TEST_CASES;++i) {
  193. if (!test_cases[i].got_it)
  194. break;
  195. }
  196. if (i == NUM_TEST_CASES)
  197. break;
  198. transport_engine.poll(&transport_engine);
  199. }
  200. transport_engine.destroy(&transport_engine);
  201. return 0;
  202. }