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
killproc(int pid,const char * message)58 killproc(int pid, const char *message)
59 {
60 printf("%s\nkilling %i\n",message,pid);
61 kill(pid, SIGKILL);
62 }
63
64
killchildren()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
au_fork()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
main()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