| /* |
| This file is part of libmicrospdy |
| Copyright Copyright (C) 2013 Andrey Uzunov |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| /** |
| * @file test_proxies.c |
| * @brief test curl > mhd2spdylay > microspdy2http > mhd |
| * @author Andrey Uzunov |
| */ |
| |
| #include "platform.h" |
| #include "microspdy.h" |
| #include "common.h" |
| #include <sys/wait.h> |
| #include <stdio.h> /* printf, stderr, fprintf */ |
| #include <sys/types.h> /* pid_t */ |
| #include <unistd.h> /* _exit, fork */ |
| #include <stdlib.h> /* exit */ |
| #include <errno.h> /* errno */ |
| #include <sys/wait.h> /* pid_t */ |
| #include "common.h" |
| |
| #ifdef _WIN32 |
| #ifndef WIN32_LEAN_AND_MEAN |
| #define WIN32_LEAN_AND_MEAN 1 |
| #endif /* !WIN32_LEAN_AND_MEAN */ |
| #include <windows.h> |
| #endif |
| |
| #define EXPECTED_BODY "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>" |
| |
| |
| pid_t parent; |
| pid_t child_mhd; |
| pid_t child_spdy2http; |
| pid_t child_mhd2spdy; |
| pid_t child_curl; |
| |
| uint16_t mhd_port; |
| uint16_t spdy2http_port; |
| uint16_t mhd2spdy_port; |
| |
| void |
| killproc(int pid, const char *message) |
| { |
| printf("%s\nkilling %i\n",message,pid); |
| kill(pid, SIGKILL); |
| } |
| |
| |
| void killchildren() |
| { |
| if(0 != child_mhd) |
| killproc(child_mhd,"kill mhd\n"); |
| if(0 != child_spdy2http) |
| killproc(child_spdy2http,"kill spdy2http\n"); |
| if(0 != child_mhd2spdy) |
| killproc(child_mhd2spdy,"kill mhd2spdy\n"); |
| if(0 != child_curl) |
| killproc(child_curl,"kill curl\n"); |
| } |
| |
| pid_t au_fork() |
| { |
| pid_t child = fork(); |
| if (child == -1) |
| { |
| killchildren(); |
| |
| killproc(parent,"fork failed\n"); |
| } |
| |
| return child; |
| } |
| |
| |
| int main() |
| { |
| //pid_t child; |
| int childstatus; |
| pid_t wpid; |
| |
| parent = getpid(); |
| mhd_port = get_port(4000); |
| spdy2http_port = get_port(4100); |
| mhd2spdy_port = get_port(4200); |
| |
| child_mhd = au_fork(); |
| if (child_mhd == 0) |
| { |
| //run MHD |
| pid_t devnull; |
| char *port_s; |
| |
| close(1); |
| devnull = open("/dev/null", O_WRONLY); |
| if (-1 == devnull) |
| abort(); |
| if (1 != devnull) |
| { |
| dup2(devnull, 1); |
| close(devnull); |
| } |
| asprintf(&port_s, "%i", mhd_port); |
| execlp ("../examples/minimal_example", "minimal_example", port_s, NULL); |
| fprintf(stderr, "executing mhd failed\nFor this test 'make' must be run before 'make check'!\n"); |
| //killchildren(); |
| _exit(1); |
| } |
| |
| |
| child_spdy2http = au_fork(); |
| if (child_spdy2http == 0) |
| { |
| //run spdy2http |
| pid_t devnull; |
| char *port_s; |
| //char *url; |
| |
| close(1); |
| devnull = open("/dev/null", O_WRONLY); |
| if (-1 == devnull) |
| abort(); |
| if (1 != devnull) |
| { |
| dup2(devnull, 1); |
| close(devnull); |
| } |
| //asprintf(&url, "127.0.0.1:%i", mhd_port); |
| asprintf(&port_s, "%i", spdy2http_port); |
| sleep(1); |
| execlp ("../spdy2http/microspdy2http", "microspdy2http", "-v4rtT", "10", "-p", port_s, NULL); |
| fprintf(stderr, "executing microspdy2http failed\n"); |
| //killchildren(); |
| _exit(1); |
| } |
| |
| child_mhd2spdy = au_fork(); |
| if (child_mhd2spdy == 0) |
| { |
| //run MHD2sdpy |
| pid_t devnull; |
| char *port_s; |
| char *url; |
| |
| close(1); |
| devnull = open("/dev/null", O_WRONLY); |
| if (-1 == devnull) |
| abort(); |
| if (1 != devnull) |
| { |
| dup2(devnull, 1); |
| close(devnull); |
| } |
| asprintf(&url, "http://127.0.0.1:%i", spdy2http_port); |
| asprintf(&port_s, "%i", mhd2spdy_port); |
| sleep(2); |
| execlp ("../examples/mhd2spdy", "mhd2spdy", "-vosb", url, "-p", port_s, NULL); |
| fprintf(stderr, "executing mhd2spdy failed\n"); |
| //killchildren(); |
| _exit(1); |
| } |
| |
| child_curl = au_fork(); |
| if (child_curl == 0) |
| { |
| //run curl |
| FILE *p; |
| pid_t devnull; |
| char *cmd; |
| unsigned int i; |
| int retc; |
| char buf[strlen(EXPECTED_BODY) + 1]; |
| |
| close(1); |
| devnull = open("/dev/null", O_WRONLY); |
| if (-1 == devnull) |
| abort (); |
| if (1 != devnull) |
| { |
| dup2(devnull, 1); |
| close(devnull); |
| } |
| |
| asprintf (&cmd, "curl --proxy http://127.0.0.1:%i http://127.0.0.1:%i/", mhd2spdy_port, mhd_port); |
| sleep(3); |
| p = popen(cmd, "r"); |
| if (p != NULL) |
| { |
| for (i = 0; i < strlen(EXPECTED_BODY) && !feof(p); i++) |
| { |
| retc = fgetc (p); |
| if (EOF == retc) |
| abort (); /* what did feof(p) do there!? */ |
| buf[i] = (char) retc; |
| } |
| |
| pclose(p); |
| buf[i] = 0; |
| _exit(strcmp(EXPECTED_BODY, buf)); |
| } |
| fprintf(stderr, "executing curl failed\n"); |
| //killchildren(); |
| _exit(1); |
| } |
| |
| do |
| { |
| wpid = waitpid(child_mhd,&childstatus,WNOHANG); |
| if(wpid == child_mhd) |
| { |
| fprintf(stderr, "mhd died unexpectedly\n"); |
| killchildren(); |
| return 1; |
| } |
| |
| wpid = waitpid(child_spdy2http,&childstatus,WNOHANG); |
| if(wpid == child_spdy2http) |
| { |
| fprintf(stderr, "spdy2http died unexpectedly\n"); |
| killchildren(); |
| return 1; |
| } |
| |
| wpid = waitpid(child_mhd2spdy,&childstatus,WNOHANG); |
| if(wpid == child_mhd2spdy) |
| { |
| fprintf(stderr, "mhd2spdy died unexpectedly\n"); |
| killchildren(); |
| return 1; |
| } |
| |
| if(waitpid(child_curl,&childstatus,WNOHANG) == child_curl) |
| { |
| killchildren(); |
| return WEXITSTATUS(childstatus); |
| } |
| sleep(1); |
| } |
| while(true); |
| } |