#include <ehs.h>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include "common.h"
using namespace std;
class tester :
public EHS
{
protected:
public:
tester(string file, int delay = 0):
EHS(), m_nDelay(delay), m_oInfile(file.c_str())
{
cout << "loading file '" << file << "'" << endl;
if (m_oInfile.fail()) {
throw runtime_error("Could not open file");
}
}
private:
int m_nDelay;
ifstream m_oInfile;
};
static int nRequests = 0;
static pthread_mutex_t oRequestMutex = PTHREAD_MUTEX_INITIALIZER;
{
pthread_mutex_lock(&oRequestMutex);
int nMyRequest = ++nRequests;
pthread_mutex_unlock(&oRequestMutex);
if (0 == (nMyRequest % 1000)) {
cerr << "[" << nMyRequest << "]" << endl;
}
char buf[5000];
sleep (m_nDelay);
m_oInfile.getline(buf, 4999);
if (m_oInfile.eof()) {
m_oInfile.seekg(0);
}
string sCopy(buf);
string sBody(buf);
sBody.append(
"<br>previous line: ").append(request->
Cookies(
"ehs_test_cookie"));
response->
SetBody(sBody.c_str(), sBody.length());
CookieParameters oCP;
string sCookieName("ehs_test_cookie_");
oCP["name"] = sCookieName.append(m_sRegisteredAs);
oCP["value"] = sCopy;
return HTTPRESPONSECODE_200_OK;
}
int main(int argc, char **argv)
{
cout << getEHSconfig() << endl;
if (argc < 4) {
string cmd = basename(argv[0]);
cerr << "Usage: " << cmd << " [mode] [port] [file] <delay> <threadcount> <norouterequest>)" << endl;
cerr << "\tModes: 1 - Single Threaded (last parameter ignored)" << endl;
cerr << "\tModes: 2 - Multithreaded, fixed number of threads" << endl;
cerr << "\tModes: 3 - Multithreaded, one thread per request (last parameter ignored)" << endl;
cerr << "\tnorouterequest: if anything is specified, requests will not be routed" << endl;
return 0;
}
int nDelay = 0;
int nThreadCount = 1;
int nMode = atoi(argv[1]);
if (argc >= 5) {
nDelay = atoi(argv[4]);
}
if (argc >= 6) {
nThreadCount = atoi(argv[5]);
}
EHSServerParameters oSP;
oSP["port"] = argv[2];
if (argc >= 7) {
oSP["norouterequest"] = 1;
}
switch (nMode) {
case 1:
cout << "Running in single threaded mode" << endl;
oSP["mode"] = "singlethreaded";
break;
case 2:
cout << "Running with a thread pool of " << nThreadCount << " threads" << endl;
oSP["mode"] = "threadpool";
oSP["threadcount"] = nThreadCount;
break;
case 3:
cout << "Running with one thread per request" << endl;
oSP["mode"] = "onethreadperrequest";
break;
default:
cerr << "Invalid mode specified: must be 1, 2, or 3" << endl;
return 0;
}
cout << "binding to " << argv[2] << endl;
cout << "Delay set to " << nDelay << " seconds" << endl;
tester srv(argv[3], nDelay);
try {
srv.StartServer(oSP);
tester a(argv[3]);
srv.RegisterEHS(&a, "a");
tester b(argv[3]);
srv.RegisterEHS(&b, "b");
tester aa(argv[3]);
a.RegisterEHS(&aa, "a");
tester ab(argv[3]);
a.RegisterEHS(&ab, "b");
kbdio kbd;
cout << "Press q to terminate ..." << endl;
while (!(srv.ShouldTerminate() || kbd.qpressed())) {
if (1 == nMode) {
srv.HandleData(1000);
} else {
usleep(300000);
}
}
srv.StopServer();
} catch (exception &e) {
cerr << "ERROR: " << e.what() << endl;
}
return 0;
}