/*
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);
}