utils.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. Utility functions for HTTP client tests
  3. Copyright (C) 2001-2009, Joe Orton <[email protected]>
  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 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #ifdef HAVE_UNISTD_H
  18. #include <unistd.h> /* for sleep() */
  19. #endif
  20. #ifdef HAVE_STDLIB_H
  21. #include <stdlib.h>
  22. #endif
  23. #include <fcntl.h>
  24. #include <netinet/in.h>
  25. #include <arpa/inet.h>
  26. #include "ne_session.h"
  27. #include "child.h"
  28. #include "tests.h"
  29. #include "utils.h"
  30. static char session_host[128];
  31. int serve_response(ne_socket *s, const char *response)
  32. {
  33. CALL(discard_request(s));
  34. CALL(discard_body(s));
  35. ONN("failed to send response", SEND_STRING(s, response));
  36. return OK;
  37. }
  38. int single_serve_string(ne_socket *s, void *userdata)
  39. {
  40. const char *str = userdata;
  41. return serve_response(s, str);
  42. }
  43. int double_serve_sstring(ne_socket *s, void *userdata)
  44. {
  45. struct double_serve_args *args = userdata;
  46. struct string *str;
  47. CALL(discard_request(s));
  48. CALL(discard_body(s));
  49. str = &args->first;
  50. NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
  51. (int)str->len, str->data);
  52. ONN("write failed", ne_sock_fullwrite(s, str->data, str->len));
  53. CALL(discard_request(s));
  54. CALL(discard_body(s));
  55. str = &args->second;
  56. NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
  57. (int)str->len, str->data);
  58. ONN("write failed", ne_sock_fullwrite(s, str->data, str->len));
  59. return OK;
  60. }
  61. int sleepy_server(ne_socket *sock, void *userdata)
  62. {
  63. sleep(10);
  64. return 0;
  65. }
  66. int many_serve_string(ne_socket *s, void *userdata)
  67. {
  68. int n;
  69. struct many_serve_args *args = userdata;
  70. for (n = 0; n < args->count; n++) {
  71. NE_DEBUG(NE_DBG_HTTP, "Serving response %d\n", n);
  72. CALL(serve_response(s, args->str));
  73. }
  74. return OK;
  75. }
  76. int any_request(ne_session *sess, const char *uri)
  77. {
  78. ne_request *req = ne_request_create(sess, "GET", uri);
  79. int ret = ne_request_dispatch(req);
  80. ne_request_destroy(req);
  81. return ret;
  82. }
  83. int any_2xx_request_method(ne_session *sess, const char *method, const char *uri)
  84. {
  85. ne_request *req = ne_request_create(sess, method, uri);
  86. int ret = ne_request_dispatch(req);
  87. int klass = ne_get_status(req)->klass;
  88. const char *context = ne_get_response_header(req, "X-Neon-Context");
  89. if (ret != NE_OK || klass != 2) {
  90. if (context)
  91. t_context("request failed, server error: %s", context);
  92. else
  93. t_context("request failed: %s", ne_get_error(sess));
  94. ret = FAIL;
  95. }
  96. else {
  97. ret = OK;
  98. }
  99. ne_request_destroy(req);
  100. return ret;
  101. }
  102. int any_2xx_request(ne_session *sess, const char *uri)
  103. {
  104. return any_2xx_request_method(sess, "GET", uri);
  105. }
  106. int any_2xx_request_body(ne_session *sess, const char *uri)
  107. {
  108. ne_request *req = ne_request_create(sess, "GET", uri);
  109. #define BSIZE 5000
  110. char *body = memset(ne_malloc(BSIZE), 'A', BSIZE);
  111. int ret;
  112. ne_set_request_body_buffer(req, body, BSIZE);
  113. ret = ne_request_dispatch(req);
  114. ne_free(body);
  115. ONV(ret != NE_OK || ne_get_status(req)->klass != 2,
  116. ("request failed: %s", ne_get_error(sess)));
  117. ne_request_destroy(req);
  118. return ret;
  119. }
  120. int serve_sstring(ne_socket *sock, void *ud)
  121. {
  122. struct string *str = ud;
  123. NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
  124. (int)str->len, str->data);
  125. ONN("write failed", ne_sock_fullwrite(sock, str->data, str->len));
  126. return 0;
  127. }
  128. int serve_sstring_slowly(ne_socket *sock, void *ud)
  129. {
  130. struct string *str = ud;
  131. size_t n;
  132. NE_DEBUG(NE_DBG_SOCKET, "Slowly serving string: [[[%.*s]]]\n",
  133. (int)str->len, str->data);
  134. for (n = 0; n < str->len; n++) {
  135. ONN("write failed", ne_sock_fullwrite(sock, &str->data[n], 1));
  136. minisleep();
  137. }
  138. return 0;
  139. }
  140. int serve_infinite(ne_socket *sock, void *ud)
  141. {
  142. struct infinite *i = ud;
  143. CALL(discard_request(sock));
  144. SEND_STRING(sock, i->header);
  145. while (server_send(sock, i->repeat, strlen(i->repeat)) == 0)
  146. /* nullop */;
  147. return OK;
  148. }
  149. int full_write(ne_socket *sock, const char *data, size_t len)
  150. {
  151. int ret = ne_sock_fullwrite(sock, data, len);
  152. NE_DEBUG(NE_DBG_SOCKET, "wrote: [%.*s]\n", (int)len, data);
  153. ONV(ret, ("write failed (%d): %s", ret, ne_sock_error(sock)));
  154. return OK;
  155. }
  156. int multi_session_server(ne_session **sess,
  157. const char *scheme, const char *hostname,
  158. int count, server_fn fn, void *userdata)
  159. {
  160. unsigned int port;
  161. CALL(new_spawn_server(count, fn, userdata, &port));
  162. *sess = ne_session_create(scheme, hostname, port);
  163. return OK;
  164. }
  165. const char *get_session_host(void)
  166. {
  167. return session_host;
  168. }
  169. int session_server(ne_session **sess, server_fn fn, void *userdata)
  170. {
  171. if (get_lh_family() == AF_INET6) {
  172. ne_snprintf(session_host, sizeof session_host, "[%s]", get_lh_addr());
  173. }
  174. else {
  175. ne_strnzcpy(session_host, get_lh_addr(), sizeof session_host);
  176. }
  177. return multi_session_server(sess, "http", session_host, 1, fn, userdata);
  178. }
  179. int proxied_multi_session_server(int count, ne_session **sess,
  180. const char *scheme, const char *host,
  181. unsigned int fakeport,
  182. server_fn fn, void *userdata)
  183. {
  184. unsigned int port;
  185. CALL(new_spawn_server(count, fn, userdata, &port));
  186. *sess = ne_session_create(scheme, host, fakeport);
  187. NE_DEBUG(NE_DBG_HTTP, "test: Using proxied session to port %u.\n", port);
  188. ne_session_proxy(*sess, get_lh_addr(), port);
  189. return OK;
  190. }
  191. int proxied_session_server(ne_session **sess, const char *scheme,
  192. const char *host, unsigned int fakeport,
  193. server_fn fn, void *userdata)
  194. {
  195. return proxied_multi_session_server(1, sess, scheme, host, fakeport,
  196. fn, userdata);
  197. }
  198. static void fakesess_destroy(void *userdata)
  199. {
  200. ne_inet_addr *addr = userdata;
  201. ne_iaddr_free(addr);
  202. }
  203. int fakeproxied_session_server(ne_session **sess, const char *scheme,
  204. const char *host, unsigned int fakeport,
  205. server_fn fn, void *userdata)
  206. {
  207. return fakeproxied_multi_session_server(1, sess, scheme, host, fakeport,
  208. fn, userdata);
  209. }
  210. int fakeproxied_multi_session_server(int count,
  211. ne_session **sess, const char *scheme,
  212. const char *host, unsigned int fakeport,
  213. server_fn fn, void *userdata)
  214. {
  215. unsigned int port;
  216. ne_inet_addr *addr;
  217. const ne_inet_addr *alist[1];
  218. CALL(new_spawn_server2(count, fn, userdata, &addr, &port));
  219. NE_DEBUG(NE_DBG_HTTP, "test: Using fake proxied '%s' session for %s using port %u.\n",
  220. scheme, host, port);
  221. alist[0] = addr;
  222. *sess = ne_session_create(scheme, host, fakeport);
  223. ne_set_addrlist2(*sess, port, alist, 1);
  224. ne_hook_destroy_session(*sess, fakesess_destroy, addr);
  225. return OK;
  226. }
  227. int make_session(ne_session **sess, server_fn fn, void *ud)
  228. {
  229. return session_server(sess, fn, ud);
  230. }
  231. int file_to_buffer(const char *filename, ne_buffer *buf)
  232. {
  233. char buffer[BUFSIZ];
  234. int fd;
  235. ssize_t n;
  236. fd = open(filename, O_RDONLY);
  237. ONV(fd < 0, ("could not open file %s", filename));
  238. while ((n = read(fd, buffer, BUFSIZ)) > 0) {
  239. ne_buffer_append(buf, buffer, n);
  240. }
  241. close(fd);
  242. return 0;
  243. }