child.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. Framework for testing with a server process
  3. Copyright (C) 2001-2024, 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. #include <sys/types.h>
  18. #include <sys/wait.h>
  19. #include <sys/socket.h>
  20. #include <netinet/in.h>
  21. #include <arpa/inet.h>
  22. #include <sys/stat.h>
  23. #ifdef HAVE_ERRNO_H
  24. #include <errno.h>
  25. #endif
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #ifdef HAVE_STDLIB_H
  30. #include <stdlib.h>
  31. #endif
  32. #ifdef HAVE_STRING_H
  33. #include <string.h>
  34. #endif
  35. #include <fcntl.h>
  36. #include <netdb.h>
  37. #include <signal.h>
  38. #include "ne_socket.h"
  39. #include "ne_utils.h"
  40. #include "ne_string.h"
  41. #include "tests.h"
  42. #include "child.h"
  43. #ifndef NEON_NO_TEST_CHILD
  44. #ifndef NI_MAXHOST
  45. #define NI_MAXHOST 1025
  46. #endif
  47. static pid_t child = 0;
  48. unsigned long clength;
  49. struct server_addr {
  50. int family;
  51. union {
  52. struct sockaddr_in in;
  53. struct sockaddr_in6 in6;
  54. } sockaddr;
  55. char name[NI_MAXHOST];
  56. };
  57. struct server_addr lh;
  58. const char *want_header = NULL;
  59. got_header_fn got_header = NULL;
  60. /* If we have pipe(), then use a pipe between the parent and child to
  61. * know when the child is ready to accept incoming connections.
  62. * Otherwise use boring sleep()s trying to avoid the race condition
  63. * between listen() and connect() in the two processes. */
  64. #ifdef HAVE_PIPE
  65. #define USE_PIPE 1
  66. #endif
  67. int lookup_localhost(void)
  68. {
  69. #ifdef USE_GETADDRINFO
  70. struct addrinfo hints = {}, *results, *rp;
  71. #endif
  72. if (lh.family != AF_UNSPEC)
  73. return OK;
  74. #ifdef USE_GETADDRINFO
  75. #ifdef USE_GAI_ADDRCONFIG
  76. hints.ai_flags = AI_ADDRCONFIG;
  77. #endif
  78. hints.ai_family = AF_UNSPEC;
  79. hints.ai_socktype = SOCK_STREAM;
  80. if (getaddrinfo("localhost", NULL, &hints, &results) != 0)
  81. goto err_use_ipv4;
  82. for (rp = results; rp != NULL; rp = rp->ai_next) {
  83. int sock, rv;
  84. if (rp->ai_family != AF_INET &&
  85. rp->ai_family != AF_INET6)
  86. continue;
  87. sock = socket(rp->ai_family, rp->ai_socktype, 0);
  88. if (sock < 0)
  89. continue;
  90. rv = bind(sock, rp->ai_addr, rp->ai_addrlen);
  91. close(sock);
  92. if (rv < 0)
  93. continue;
  94. if (getnameinfo(rp->ai_addr, rp->ai_addrlen,
  95. lh.name, sizeof lh.name, NULL, 0,
  96. NI_NUMERICHOST))
  97. continue;
  98. lh.family = rp->ai_family;
  99. memcpy(&lh.sockaddr, rp->ai_addr, rp->ai_addrlen);
  100. break;
  101. }
  102. freeaddrinfo(results);
  103. err_use_ipv4:
  104. #endif
  105. if (lh.family == AF_UNSPEC) {
  106. /* this will break if a system is set up so that `localhost' does
  107. * not resolve to 127.0.0.1, but... */
  108. lh.family = AF_INET;
  109. strcpy(lh.name, "127.0.0.1");
  110. lh.sockaddr.in.sin_family = lh.family;
  111. lh.sockaddr.in.sin_addr.s_addr = inet_addr(lh.name);
  112. }
  113. return OK;
  114. }
  115. int
  116. get_lh_family(void)
  117. {
  118. if (lh.family == AF_UNSPEC)
  119. lookup_localhost();
  120. return lh.family;
  121. }
  122. const char *
  123. get_lh_addr(void)
  124. {
  125. if (lh.family == AF_UNSPEC)
  126. lookup_localhost();
  127. return lh.name;
  128. }
  129. ne_inet_addr *
  130. get_lh_inet_addr(void)
  131. {
  132. ne_iaddr_type type;
  133. unsigned char *raw;
  134. if (lh.family == AF_UNSPEC)
  135. lookup_localhost();
  136. if (lh.family == AF_INET) {
  137. type = ne_iaddr_ipv4;
  138. raw = (unsigned char *) &lh.sockaddr.in.sin_addr.s_addr;
  139. } else {
  140. type = ne_iaddr_ipv6;
  141. raw = lh.sockaddr.in6.sin6_addr.s6_addr;
  142. }
  143. return ne_iaddr_make(type, raw);
  144. }
  145. static int do_listen(int port)
  146. {
  147. int ls = socket(lh.family, SOCK_STREAM, 0);
  148. struct sockaddr *saddr;
  149. socklen_t saddrlen;
  150. int val = 1;
  151. setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
  152. if (lh.family == AF_INET) {
  153. lh.sockaddr.in.sin_port = htons(port);
  154. saddr = (struct sockaddr *) &lh.sockaddr.in;
  155. saddrlen = sizeof lh.sockaddr.in;
  156. } else {
  157. lh.sockaddr.in6.sin6_port = htons(port);
  158. saddr = (struct sockaddr *) &lh.sockaddr.in6;
  159. saddrlen = sizeof lh.sockaddr.in6;
  160. }
  161. if (bind(ls, saddr, saddrlen)) {
  162. printf("bind failed: %s\n", strerror(errno));
  163. return -1;
  164. }
  165. if (listen(ls, 5)) {
  166. printf("listen failed: %s\n", strerror(errno));
  167. return -1;
  168. }
  169. return ls;
  170. }
  171. void minisleep(void)
  172. {
  173. #ifdef HAVE_USLEEP
  174. usleep(500);
  175. #else
  176. sleep(1);
  177. #endif
  178. }
  179. int reset_socket(ne_socket *sock)
  180. {
  181. #ifdef SO_LINGER
  182. /* Stevens' magic trick to send an RST on close(). */
  183. struct linger l = {1, 0};
  184. return setsockopt(ne_sock_fd(sock), SOL_SOCKET, SO_LINGER, &l, sizeof l);
  185. #else
  186. return 1;
  187. #endif
  188. }
  189. /* close 'sock', performing lingering close to avoid premature RST. */
  190. static int close_socket(ne_socket *sock)
  191. {
  192. int ret;
  193. char buf[20];
  194. ret = ne_sock_shutdown(sock, NE_SOCK_SEND);
  195. if (ret == 0) {
  196. NE_DEBUG(NE_DBG_SOCKET, "ssl: Socket cleanly closed.\n");
  197. }
  198. else {
  199. NE_DEBUG(NE_DBG_SOCKET, "sock: Socket closed uncleanly: %s\n",
  200. ne_sock_error(sock));
  201. }
  202. NE_DEBUG(NE_DBG_SSL, "sock: Lingering close...\n");
  203. ne_sock_read_timeout(sock, 5);
  204. while (ne_sock_read(sock, buf, sizeof buf) > 0);
  205. NE_DEBUG(NE_DBG_SSL, "sock: Closing socket.\n");
  206. ret = ne_sock_close(sock);
  207. NE_DEBUG(NE_DBG_SSL, "sock: Socket closed (%d).\n", ret);
  208. return ret;
  209. }
  210. /* This runs as the child process. */
  211. static int server_child(int readyfd, int port,
  212. server_fn callback, void *userdata)
  213. {
  214. ne_socket *s = ne_sock_create();
  215. int ret, listener;
  216. in_child();
  217. listener = do_listen(port);
  218. if (listener < 0)
  219. return FAIL;
  220. #ifdef USE_PIPE
  221. /* Tell the parent we're ready for the request. */
  222. if (write(readyfd, "a", 1) != 1) abort();
  223. #endif
  224. ONN("accept failed", ne_sock_accept(s, listener));
  225. ret = callback(s, userdata);
  226. close_socket(s);
  227. return ret;
  228. }
  229. int spawn_server(int port, server_fn fn, void *ud)
  230. {
  231. int fds[2];
  232. #ifdef USE_PIPE
  233. if (pipe(fds)) {
  234. perror("spawn_server: pipe");
  235. return FAIL;
  236. }
  237. #else
  238. /* avoid using uninitialized variable. */
  239. fds[0] = fds[1] = 0;
  240. #endif
  241. child = fork();
  242. ONN("fork server", child == -1);
  243. if (child == 0) {
  244. /* this is the child. */
  245. int ret;
  246. ret = server_child(fds[1], port, fn, ud);
  247. #ifdef USE_PIPE
  248. close(fds[0]);
  249. close(fds[1]);
  250. #endif
  251. /* print the error out otherwise it gets lost. */
  252. if (ret) {
  253. printf("server child failed (%s): %s\n",
  254. tests[test_num].name, test_context);
  255. }
  256. /* and quit the child. */
  257. NE_DEBUG(NE_DBG_HTTP, "child exiting with %d\n", ret);
  258. exit(ret);
  259. } else {
  260. char ch;
  261. #ifdef USE_PIPE
  262. if (read(fds[0], &ch, 1) < 0)
  263. perror("parent read");
  264. close(fds[0]);
  265. close(fds[1]);
  266. #else
  267. minisleep();
  268. #endif
  269. return OK;
  270. }
  271. }
  272. int new_spawn_server(int count, server_fn fn, void *userdata,
  273. unsigned int *port)
  274. {
  275. ne_inet_addr *addr = NULL;
  276. int ret;
  277. ret = new_spawn_server2(count, fn, userdata, &addr, port);
  278. if (addr)
  279. ne_iaddr_free(addr);
  280. return ret;
  281. }
  282. int new_spawn_server2(int count, server_fn fn, void *userdata,
  283. ne_inet_addr **addr, unsigned int *port)
  284. {
  285. union {
  286. struct sockaddr_in in;
  287. struct sockaddr_in6 in6;
  288. } sa;
  289. socklen_t salen = sizeof sa;
  290. int ls;
  291. if (lh.family == AF_UNSPEC)
  292. lookup_localhost();
  293. ls = do_listen(0);
  294. ONN("could not bind/listen fd for server", ls < 0);
  295. ONV(getsockname(ls, (struct sockaddr *) &sa, &salen) != 0,
  296. ("could not get socket name for listening fd: %s",
  297. strerror(errno)));
  298. if (salen == sizeof sa.in) {
  299. *port = ntohs(sa.in.sin_port);
  300. *addr = ne_iaddr_make(ne_iaddr_ipv4,
  301. (unsigned char *) &sa.in.sin_addr.s_addr);
  302. } else {
  303. *port = ntohs(sa.in6.sin6_port);
  304. *addr = ne_iaddr_make(ne_iaddr_ipv6, sa.in6.sin6_addr.s6_addr);
  305. }
  306. NE_DEBUG(NE_DBG_SOCKET, "child: using port %u\n", *port);
  307. NE_DEBUG(NE_DBG_SOCKET, "child: forking now...\n");
  308. child = fork();
  309. ONN("failed to fork server", child == -1);
  310. if (child == 0) {
  311. int ret, iter = 1;
  312. in_child();
  313. NE_DEBUG(NE_DBG_SOCKET, ">>> child spawned, port %u, %d iterations.\n",
  314. *port, count);
  315. do {
  316. ne_socket *sock = ne_sock_create();
  317. char errbuf[256];
  318. int cret;
  319. NE_DEBUG(NE_DBG_HTTP, "child: iteration #%d (of %d), "
  320. "awaiting connection...\n", iter, count);
  321. if (ne_sock_accept(sock, ls)) {
  322. t_context("Server child could not accept connection: %s",
  323. ne_sock_error(sock));
  324. exit(FAIL);
  325. }
  326. NE_DEBUG(NE_DBG_HTTP, "child: got connection, invoking server\n");
  327. if (iter == count) {
  328. close(ls);
  329. NE_DEBUG(NE_DBG_HTTP, "child: closed listening socket.\n");
  330. }
  331. ret = fn(sock, userdata);
  332. NE_DEBUG(NE_DBG_HTTP, "child: iteration #%d returns %d\n",
  333. iter, ret);
  334. cret = close_socket(sock);
  335. NE_DEBUG(NE_DBG_HTTP, "child: closed connection, %d: %s.\n", cret,
  336. cret ? ne_strerror(cret, errbuf, sizeof errbuf)
  337. : "no error");
  338. } while (ret == 0 && ++iter <= count);
  339. NE_DEBUG(NE_DBG_HTTP, "child: terminating with %d\n", ret);
  340. exit(ret);
  341. }
  342. close(ls);
  343. return OK;
  344. }
  345. int dead_server(void)
  346. {
  347. int status;
  348. if (waitpid(child, &status, WNOHANG)) {
  349. /* child quit already! */
  350. return FAIL;
  351. }
  352. NE_DEBUG(NE_DBG_HTTP, "child has not quit.\n");
  353. return OK;
  354. }
  355. int destroy_and_wait(ne_session *sess)
  356. {
  357. ne_session_destroy(sess);
  358. return await_server();
  359. }
  360. int await_server(void)
  361. {
  362. int status, code;
  363. (void) wait(&status);
  364. /* so that we aren't reaped by mistake. */
  365. child = 0;
  366. if (WIFEXITED(status)) {
  367. code = WEXITSTATUS(status);
  368. ONV(code,
  369. ("server process terminated abnormally: %s (%d)",
  370. code == FAIL ? "FAIL" : "error", code));
  371. }
  372. else {
  373. ONV(WIFSIGNALED(status),
  374. ("server process terminated by signal %d", WTERMSIG(status)));
  375. }
  376. return OK;
  377. }
  378. int reap_server(void)
  379. {
  380. int status;
  381. if (child != 0) {
  382. (void) kill(child, SIGTERM);
  383. minisleep();
  384. (void) wait(&status);
  385. child = 0;
  386. }
  387. return OK;
  388. }
  389. ssize_t server_send(ne_socket *sock, const char *str, size_t len)
  390. {
  391. NE_DEBUG(NE_DBG_HTTP, "Sending: %.*s\n", (int)len, str);
  392. return ne_sock_fullwrite(sock, str, len);
  393. }
  394. int discard_request(ne_socket *sock)
  395. {
  396. char buffer[1024];
  397. size_t offset = want_header?strlen(want_header):0;
  398. clength = 0;
  399. NE_DEBUG(NE_DBG_HTTP, "Discarding request...\n");
  400. do {
  401. ONV(ne_sock_readline(sock, buffer, 1024) < 0,
  402. ("error reading line: %s", ne_sock_error(sock)));
  403. NE_DEBUG(NE_DBG_HTTP, "[req] %s", buffer);
  404. if (strncasecmp(buffer, "content-length: ", 16) == 0) {
  405. char *ptr = NULL;
  406. errno = 0;
  407. clength = strtoul(buffer + 16, &ptr, 10);
  408. ONV(errno || *ptr != '\r',
  409. ("invalid Content-Length request header: %s", buffer));
  410. }
  411. if (got_header != NULL && want_header != NULL &&
  412. strncasecmp(buffer, want_header, offset) == 0 &&
  413. buffer[offset] == ':') {
  414. char *value = buffer + offset + 1;
  415. if (*value == ' ') value++;
  416. got_header(ne_shave(value, "\r\n"));
  417. }
  418. } while (strcmp(buffer, "\r\n") != 0);
  419. return OK;
  420. }
  421. int error_response(ne_socket *sock, int ret)
  422. {
  423. char resp[1024];
  424. ne_snprintf(resp, sizeof resp,
  425. "HTTP/1.1 500 Server Test Failed\r\n"
  426. "X-Neon-Context: %s\r\n"
  427. "Content-Length: 0\r\n"
  428. "Connection: close\r\n"
  429. "\r\n",
  430. test_context);
  431. SEND_STRING(sock, resp);
  432. return ret;
  433. }
  434. int discard_body(ne_socket *sock)
  435. {
  436. while (clength > 0) {
  437. char buf[BUFSIZ];
  438. size_t bytes = clength;
  439. ssize_t ret;
  440. if (bytes > sizeof(buf)) bytes = sizeof(buf);
  441. NE_DEBUG(NE_DBG_HTTP, "Discarding %" NE_FMT_SIZE_T " bytes.\n",
  442. bytes);
  443. ret = ne_sock_read(sock, buf, bytes);
  444. ONV(ret < 0, ("socket read failed (%" NE_FMT_SSIZE_T "): %s",
  445. ret, ne_sock_error(sock)));
  446. clength -= ret;
  447. NE_DEBUG(NE_DBG_HTTP, "Got %" NE_FMT_SSIZE_T " bytes.\n", ret);
  448. }
  449. NE_DEBUG(NE_DBG_HTTP, "Discard successful.\n");
  450. return OK;
  451. }
  452. int serve_file(ne_socket *sock, void *ud)
  453. {
  454. char buffer[BUFSIZ];
  455. struct stat st;
  456. struct serve_file_args *args = ud;
  457. ssize_t ret;
  458. int fd;
  459. CALL(discard_request(sock));
  460. ne_sock_fullread(sock, buffer, clength);
  461. fd = open(args->fname, O_RDONLY);
  462. if (fd < 0) {
  463. SEND_STRING(sock,
  464. "HTTP/1.0 404 File Not Found\r\n"
  465. "Content-Length: 0\r\n\r\n");
  466. return 0;
  467. }
  468. ONN("fstat fd", fstat(fd, &st));
  469. SEND_STRING(sock, "HTTP/1.0 200 OK\r\n");
  470. if (args->chunks) {
  471. sprintf(buffer, "Transfer-Encoding: chunked\r\n");
  472. } else {
  473. sprintf(buffer, "Content-Length: %" NE_FMT_OFF_T "\r\n",
  474. st.st_size);
  475. }
  476. if (args->headers) {
  477. strcat(buffer, args->headers);
  478. }
  479. strcat(buffer, "\r\n");
  480. SEND_STRING(sock, buffer);
  481. NE_DEBUG(NE_DBG_HTTP, "Serving %s (%" NE_FMT_OFF_T " bytes).\n",
  482. args->fname, st.st_size);
  483. if (args->chunks) {
  484. char buf[1024];
  485. while ((ret = read(fd, &buf, args->chunks)) > 0) {
  486. /* this is a small integer, cast it explicitly to avoid
  487. * warnings with printing an ssize_t. */
  488. sprintf(buffer, "%x\r\n", (unsigned int)ret);
  489. SEND_STRING(sock, buffer);
  490. ONN("writing body", ne_sock_fullwrite(sock, buf, ret));
  491. SEND_STRING(sock, "\r\n");
  492. }
  493. SEND_STRING(sock, "0\r\n\r\n");
  494. } else {
  495. while ((ret = read(fd, buffer, BUFSIZ)) > 0) {
  496. ONN("writing body", ne_sock_fullwrite(sock, buffer, ret));
  497. }
  498. }
  499. ONN("error reading from file", ret < 0);
  500. (void) close(fd);
  501. return OK;
  502. }
  503. #endif /* NEON_NO_TEST_CHILD */