The simpleEgi sample demonstrates
how to create and use the Embedded Gateway Interface (EGI) in your application to respond to posted HTTP forms.
The sample is a main program that
listens on port 8888 for HTTP requests and responds to the "/myEgi" URL
when used with the POST method. The supplied index.esp page displays a
form and prompts for user input. This is sent to the form when the user
presses OK. The EGI handler echos back the input data values.
The sample is multithreaded and is configured to use a pool of
4 threads. By changing the
value
of the
ThreadLimit
directive in the configuration file to zero you can run single-threaded.
See also
the equivalent
C simpleEgi sample.
Files
index.esp
simpleEgi.conf
Makefile
simpleEgi.cpp
index.html Web Page
<HTML>
<HEAD>
<TITLE>Embedded Gateway Interface (EGI) Sample</TITLE>
</HEAD>
<BODY>
<h1>Embedded Gateway Interface (EGI) Sample</h1>
<FORM action=/myEgi.egi method=POST>
<TABLE>
<TR>
<TD>Name:</TD><TD><input type=text name=name size=50 value=""></TD>
</TR>
<TR>
<TD>Address:</TD><TD><input type=text name=address size=50 value=""></TD>
</TR>
<TR>
<TD ALIGN="CENTER">
<input type=submit name=ok value="OK">
<input type=submit name=ok value="Cancel">
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
Configuration File
simpleEgi.conf
DocumentRoot "."
Listen 8888
ThreadLimit 4
AddHandler egiHandler .egi
AddHandler copyHandler
This file is an AppWeb configuration file.
It is configured to run single-threaded and assumes that
the sample is being run from the current directory.
You should modify the
DocumentRoot and
Listen directives to suit your application's needs.
Makefile
The Makefile will build on Windows or Linux. A Windows VS 6.0 project
file is also supplied.
Typical output from the Makefile build is listed below. This is the
output on a Windows system:
cl -o simpleEgi.exe simpleEgi.cpp -Zi -Od -D_NDEBUG -W3 -nologo -MDd -FD -DWIN -D_DLL -D_MT \
-D_WINDOWS -DWIN32 -D_WIN32_WINNT=0x500 -D_X86_=1 -D_CRT_SECURE_NO_DEPRECATE -D_USRDLL \
-I../../../include ../../../bin/libappWebStatic.lib ws2_32.lib advapi32.lib user32.lib
Source
Code
simpleEgi.cpp
///
/// @file simpleEgi.cpp
/// @brief Demonstrate the use of Embedded Server Pages (EGI) in a
/// simple multi-threaded application.
//
// Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
//
/////////////////////////////// Includes ///////////////////////////////
#include "appWeb/appWeb.h"
//////////////////////////////// Defines ///////////////////////////////
#if BLD_FEATURE_EGI_MODULE
//
// Define the our EGI object to be called when the web form is posted.
//
class MyEgi : public MaEgiForm {
public:
MyEgi(char *egiName);
~MyEgi();
void run(MaRequest *rq, char *script, char *path, char *query,
char *postData, int postLen);
};
/////////////////////////////////// Code ///////////////////////////////
int main(int argc, char** argv)
{
MaHttp *http; // Http service inside our app
MaServer *server; // For the HTTP server
Mpr mpr("simpleEgi"); // Initialize the run time
#if BLD_FEATURE_LOG
//
// Do the following two statements only if you want debug trace
//
mpr.addListener(new MprLogToFile());
mpr.setLogSpec("stdout:4");
#endif
//
// Start the Mbedthis Portable Runtime
//
mpr.start(0);
//
// Create Http and Server objects for this application. We set the
// ServerName to be "default" and the initial serverRoot to be ".".
// This will be overridden in simpleEgi.conf.
//
http = new MaHttp();
server = new MaServer(http, "default", ".");
//
// Activate the copy module and handler
//
new MaCopyModule(0);
new MaEgiModule(0);
//
// Configure the server with the configuration directive file
//
if (server->configure("simpleEgi.conf") < 0) {
mprFprintf(MPR_STDERR,
"Can't configure the server. Error on line %d\n",
server->getLine());
exit(2);
}
//
// Define our EGI procedures
//
new MyEgi("/myEgi.egi");
//
// Start the server
//
if (http->start() < 0) {
mprFprintf(MPR_STDERR, "Can't start the server\n");
exit(2);
}
//
// Tell the MPR to loop servicing incoming requests. We can
// replace this call with a variety of event servicing
// mechanisms offered by AppWeb.
//
mpr.serviceEvents(0, -1);
//
// Orderly shutdown
//
http->stop();
delete server;
delete http;
//
// MPR run-time will automatically stop and be cleaned up
//
return 0;
}
////////////////////////////////////////////////////////////////////////
MyEgi::MyEgi(char *name) : MaEgiForm(name)
{
// Put required initialization (if any) here
}
////////////////////////////////////////////////////////////////////////
MyEgi::~MyEgi()
{
// Put cleanup herre
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//
// Method that is run when the EGI form is called from the web
// page. Rq is the request context. URI is the bare URL minus query.
// Query is the string after a "?" in the URL. Post data is posted
// HTTP form data.
//
void MyEgi::run(MaRequest *rq, char *script, char *uri, char *query,
char *postData, int postLen)
{
#if TEST_MULTI_THREADED_ACCESS
mprPrintf("In MyEgi::run, thread %s\n", mprGetCurrentThreadName());
//
// To test multithreaded access, this will sleep now
//
mprPrintf("Sleeping for 15 seconds\n");
mprSleep(15 * 1000);
#else
mprPrintf("In MyEgi::run, single threaded\n");
#endif
#if TEST || 1
MaClient *client;
int code,contentLen;
char* content;
client = new MaClient();
if (client->getRequest("http://www.mbedthis.com/index.html") < 0) {
rq->requestError(500, "Can't get client URL");
return;
}
//
// Examine the HTTP response HTTP code. 200 is success.
//
code = client->getResponseCode();
if (code != 200) {
rq->requestError(500, "Bad status code %d", code);
return;
}
//
// Get the actual response content
//
content = client->getResponseContent(&contentLen);
if (content) {
mprPrintf("Server responded with:\n%s\n", content);
}
rq->setResponseCode(200);
rq->write(content);
delete client;
#endif
rq->write("<HTML><TITLE>simpleEgi</TITLE><BODY>\r\n");
rq->writeFmt("<p>Name: %s</p>\n",
rq->getVar(MA_FORM_OBJ, "name", "-"));
rq->writeFmt("<p>Address: %s</p>\n",
rq->getVar(MA_FORM_OBJ, "address", "-"));
rq->write("</BODY></HTML>\r\n");
#if TEST_MULTI_THREADED_ACCESS
mprPrintf("Exiting thread %s\n", mprGetCurrentThreadName());
#endif
#if UNUSED
//
// Possible useful things to do in egi forms
//
rq->setResponseCode(200);
rq->setContentType("text/html");
rq->setHeaderFlags(MPR_HTTP_DONT_CACHE);
rq->requestError(409, "My message : %d", 5);
rq->redirect(302, "/myURl");
rq->flushOutput(MPR_HTTP_FOREGROUND_FLUSH, MPR_HTTP_FINISH_REQUEST);
#endif
}
////////////////////////////////////////////////////////////////////////
#else
int main()
{
fprintf(stderr, "BLD_FEATURE_EGI_MODULE is not defined in config.h\n");
exit(2);
}
#endif /* BLD_FEATURE_EGI_MODULE */