1 /* 2 This file is part of libmicrospdy 3 Copyright Copyright (C) 2013 Andrey Uzunov 4 5 This program 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 This program 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 19 /** 20 * @file test_proxies.c 21 * @brief test curl > mhd2spdylay > microspdy2http > mhd 22 * @author Andrey Uzunov 23 */ 24 25 #include "platform.h" 26 #include "microspdy.h" 27 #include "common.h" 28 #include <sys/wait.h> 29 #include <stdio.h> /* printf, stderr, fprintf */ 30 #include <sys/types.h> /* pid_t */ 31 #include <unistd.h> /* _exit, fork */ 32 #include <stdlib.h> /* exit */ 33 #include <errno.h> /* errno */ 34 #include <sys/wait.h> /* pid_t */ 35 #include "common.h" 36 37 #ifdef _WIN32 38 #ifndef WIN32_LEAN_AND_MEAN 39 #define WIN32_LEAN_AND_MEAN 1 40 #endif /* !WIN32_LEAN_AND_MEAN */ 41 #include <windows.h> 42 #endif 43 44 #define EXPECTED_BODY "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>" 45 46 47 pid_t parent; 48 pid_t child_mhd; 49 pid_t child_spdy2http; 50 pid_t child_mhd2spdy; 51 pid_t child_curl; 52 53 uint16_t mhd_port; 54 uint16_t spdy2http_port; 55 uint16_t mhd2spdy_port; 56 57 void 58 killproc(int pid, const char *message) 59 { 60 printf("%s\nkilling %i\n",message,pid); 61 kill(pid, SIGKILL); 62 } 63 64 65 void killchildren() 66 { 67 if(0 != child_mhd) 68 killproc(child_mhd,"kill mhd\n"); 69 if(0 != child_spdy2http) 70 killproc(child_spdy2http,"kill spdy2http\n"); 71 if(0 != child_mhd2spdy) 72 killproc(child_mhd2spdy,"kill mhd2spdy\n"); 73 if(0 != child_curl) 74 killproc(child_curl,"kill curl\n"); 75 } 76 77 pid_t au_fork() 78 { 79 pid_t child = fork(); 80 if (child == -1) 81 { 82 killchildren(); 83 84 killproc(parent,"fork failed\n"); 85 } 86 87 return child; 88 } 89 90 91 int main() 92 { 93 //pid_t child; 94 int childstatus; 95 pid_t wpid; 96 97 parent = getpid(); 98 mhd_port = get_port(4000); 99 spdy2http_port = get_port(4100); 100 mhd2spdy_port = get_port(4200); 101 102 child_mhd = au_fork(); 103 if (child_mhd == 0) 104 { 105 //run MHD 106 pid_t devnull; 107 char *port_s; 108 109 close(1); 110 devnull = open("/dev/null", O_WRONLY); 111 if (-1 == devnull) 112 abort(); 113 if (1 != devnull) 114 { 115 dup2(devnull, 1); 116 close(devnull); 117 } 118 asprintf(&port_s, "%i", mhd_port); 119 execlp ("../examples/minimal_example", "minimal_example", port_s, NULL); 120 fprintf(stderr, "executing mhd failed\nFor this test 'make' must be run before 'make check'!\n"); 121 //killchildren(); 122 _exit(1); 123 } 124 125 126 child_spdy2http = au_fork(); 127 if (child_spdy2http == 0) 128 { 129 //run spdy2http 130 pid_t devnull; 131 char *port_s; 132 //char *url; 133 134 close(1); 135 devnull = open("/dev/null", O_WRONLY); 136 if (-1 == devnull) 137 abort(); 138 if (1 != devnull) 139 { 140 dup2(devnull, 1); 141 close(devnull); 142 } 143 //asprintf(&url, "127.0.0.1:%i", mhd_port); 144 asprintf(&port_s, "%i", spdy2http_port); 145 sleep(1); 146 execlp ("../spdy2http/microspdy2http", "microspdy2http", "-v4rtT", "10", "-p", port_s, NULL); 147 fprintf(stderr, "executing microspdy2http failed\n"); 148 //killchildren(); 149 _exit(1); 150 } 151 152 child_mhd2spdy = au_fork(); 153 if (child_mhd2spdy == 0) 154 { 155 //run MHD2sdpy 156 pid_t devnull; 157 char *port_s; 158 char *url; 159 160 close(1); 161 devnull = open("/dev/null", O_WRONLY); 162 if (-1 == devnull) 163 abort(); 164 if (1 != devnull) 165 { 166 dup2(devnull, 1); 167 close(devnull); 168 } 169 asprintf(&url, "http://127.0.0.1:%i", spdy2http_port); 170 asprintf(&port_s, "%i", mhd2spdy_port); 171 sleep(2); 172 execlp ("../examples/mhd2spdy", "mhd2spdy", "-vosb", url, "-p", port_s, NULL); 173 fprintf(stderr, "executing mhd2spdy failed\n"); 174 //killchildren(); 175 _exit(1); 176 } 177 178 child_curl = au_fork(); 179 if (child_curl == 0) 180 { 181 //run curl 182 FILE *p; 183 pid_t devnull; 184 char *cmd; 185 unsigned int i; 186 int retc; 187 char buf[strlen(EXPECTED_BODY) + 1]; 188 189 close(1); 190 devnull = open("/dev/null", O_WRONLY); 191 if (-1 == devnull) 192 abort (); 193 if (1 != devnull) 194 { 195 dup2(devnull, 1); 196 close(devnull); 197 } 198 199 asprintf (&cmd, "curl --proxy http://127.0.0.1:%i http://127.0.0.1:%i/", mhd2spdy_port, mhd_port); 200 sleep(3); 201 p = popen(cmd, "r"); 202 if (p != NULL) 203 { 204 for (i = 0; i < strlen(EXPECTED_BODY) && !feof(p); i++) 205 { 206 retc = fgetc (p); 207 if (EOF == retc) 208 abort (); /* what did feof(p) do there!? */ 209 buf[i] = (char) retc; 210 } 211 212 pclose(p); 213 buf[i] = 0; 214 _exit(strcmp(EXPECTED_BODY, buf)); 215 } 216 fprintf(stderr, "executing curl failed\n"); 217 //killchildren(); 218 _exit(1); 219 } 220 221 do 222 { 223 wpid = waitpid(child_mhd,&childstatus,WNOHANG); 224 if(wpid == child_mhd) 225 { 226 fprintf(stderr, "mhd died unexpectedly\n"); 227 killchildren(); 228 return 1; 229 } 230 231 wpid = waitpid(child_spdy2http,&childstatus,WNOHANG); 232 if(wpid == child_spdy2http) 233 { 234 fprintf(stderr, "spdy2http died unexpectedly\n"); 235 killchildren(); 236 return 1; 237 } 238 239 wpid = waitpid(child_mhd2spdy,&childstatus,WNOHANG); 240 if(wpid == child_mhd2spdy) 241 { 242 fprintf(stderr, "mhd2spdy died unexpectedly\n"); 243 killchildren(); 244 return 1; 245 } 246 247 if(waitpid(child_curl,&childstatus,WNOHANG) == child_curl) 248 { 249 killchildren(); 250 return WEXITSTATUS(childstatus); 251 } 252 sleep(1); 253 } 254 while(true); 255 } 256