Embedded Binary Web Server


Small, light web server that can use C++ compiled shared object libraries to serve dynamic web content. Can also server content form static HTML or dynamically by running any valid system command, this includes dynamic generation of content using bash scripts.

Advantages to using EBWS and C++ generated web pages.

















Installing EBWS


EBWS is supported to compile on most Linux systems i386 and ARM.

Downloading: ebws
Dependancies: libSiliconTao.so
To compile EBWS extract the tar file and run make then sudo make install.
















Creating content using C++


All content served from C++ code must be compiled to a shared object. This makes it much easier to protect your code and increases speed while reducing system resources needed.

All C++ files must have a common entry point for the EBWS to use the file. This is managed by the common file and members. There are six common files to all C++ content libraries.

PageObject.cpp
PageObject.h
All custom code goes in here. The common entry point PageObject::Main is the member that will execute when the page is called to load by EBWS. The member function PageObject::Close is the exiting cleanup function that will be called when EBWS is about to shutdown or unload the page library.
More member functions can be added and other objects included but the Main and Close functions are required. Typically Close does not need any code added to it unless a Static Object was created.
WebObjects.cpp
WebObjects.h
These files are provided by EBWS and provide a connection between your custom code in PageObject and the EBWS. Do not modify these file. They must be compiled in to your code. They include the PageObject files and make calls to the common entry point PageObject::Main and PageObject::Close
It is a good idea to make these files available to your compiler in this directory as a symbolic link to the original files in the EBWS source directory.
A unique binary .o file will be compiled from these that will have structural map of the custom changes made to PageObject.
exporter.cpp
exporter.h
These files are provided by EBWS and provide a connection between C++ objects and C exports to be used to invoke the loading of shared object libraries.
It is a good idea to make these files available to your compiler in this directory as a symbolic link to the original files in the EBWS source directory.

















Functionality


The EBWS server provides many services to the developer of custom PageObject code.
Function Calls
Post
void Post(const char *DataString);
void Post(STString DataString);
Post normal text as HTML body. Format is set to HTML.
HPost
void HPost(STString DataString);
void HPost(const char *DataString);
Post normal text as HTML header such as META tags. Format is set to HTML.
IPost
void IPost(const char *DataString);
void IPost(STString DataString);
Post normal text as included. Sets format to included so no formating data is sent. The is needed for special text that should be posted as is like JavaScript and CSS code.
EPost
void EPost(const char *DataString);
void EPost(STString DataString);
Post extra information about the error after an error has happened in the same page load event. See also Error Codes and SetError.
PostBinaryFile
void PostBinaryFile(char *FileName);
void PostBinaryFile(STString FileName);
Sends the contents of a binary file like an image or download as a raw binary to the client viewer.
PostFromFile
void PostFromFile(STString FileName);
Displays the content of static text file as an HTML formated page to the viewing client.
IPostFromFile
void IPostFromFile(STString FileName);
Included Posting. Displays the content of static text file as HTML formated sub page content to the viewing client. Does not try to generate any standard HTML headers. Assumes that has already been done. Use this to include CSS or JavaScript file in the HTML page.
PostFromFilePre
void PostFromFilePre(STString FileName);
Works like PostFromFile but wraps the contents in HTML PRE tags and formats special symbols for original viewing. For example the < symbol is replaced by &lt; Use this to show HTML and other source code.
SetCookie
void SetCookie(const char *CookieString);
void SetCookie(STString CookieString);
Used to set a cookie on the client browser. This function has no smarts to help with proper cookie formating. You must give it a complete cookie string that is well formated.
Log
void Log(const char*NewLogMessage);
Log messages to the syslogd server. If in EBWS is run in debug mode text is also output to STDOUT.
GetDataLink
STDynamicDataLink* GetDataLink();
Returns a pointer the STDynamicDataLink that is running in EBWS. The link object will be created the very first time GetDataLink is called. Only one instance of STDynamicDataLink is able to run in EBWS. EBWS provides this service to enable inter application and system communication. EBWS cannot service this connection constantly so it is run with HSC dissabled and should only be used for asking questions to other programs, not for listening.
SetError
void SetError(int NewError);
Generate an error for display to the viewing client. Any data currently in the post buffer waiting to be sent to the the viewing client will be lost. The viewing client will only receive the error page. See also Error Codes and EPost.

ShowVars
void ShowVars();
Displays the content of the global variables as an HTML formated page to the viewing client.
ListDirectory
void ListDirectory(const char *DirPath);
void ListDirectory(STString DirPath);
Displays the content of a directory as an HTML formated page to the viewing client.
EvalFile
void EvalFile(STString FileName);
Works like PostFromFile but parses the file for known global variables that have bean Endorsd and replaces them with known values.
Endorse
void Endorse(STHash *HashPointer, const char *HashName);
void Endorse(STHash *HashPointer, STString HashName);
Required to create and use custom STHash variables globally. STHash variables must be Endorsed before they will be identified by EvalFile.
FileUploaded
bool FileUploaded();
EBWS currently supports the FORM uploading of one file at a time. This function returns true if a file was uploaded by the viewing client. Look to the values stored in the global variable _FILE to find details about the uploaded file.
SaveUploadedFile
bool SaveUploadedFile(STString NewFilePathName);
Saves the uploaded file to the giving file name and clears memory used by the global variable _FILE.
ExecuteLibrary
void ExecuteLibrary(STString LibName);
Load another Page Library and begin execution of it's PageObject::Main.

















Global Variables


The global variables in EBWS are STHash string hash objects from the SiliconTaoCppLibs library. They are well suited for use in dynamic web page creation because of the ability to safely test for a non existent value. Many of the global variables are intended for read actions only and will not submit data back to the viewing client. The global variables for _SERVER and _FILE contain pre-defined values, more can be added my the developer of custom PageObject content.

_GLOBAL Parent STHash object that keeps track of all STHash global variables.
_SERVER
(*_SERVER)["DOCUMENT_ROOT"]
(*_SERVER)["HOST"]
(*_SERVER)["PORT"]
(*_SERVER)["REMOTE_ADDR"]
(*_SERVER)["REQUEST_URI"]
(*_SERVER)["REQUEST_METHOD"]
(*_SERVER)["SCRIPT_NAME"]
(*_SERVER)["SCRIPT_DIR"]
(*_SERVER)["SERVER_SOFTWARE"]
Standard information about server and client connection.
_FILE
(*_FILE)["BUFFER_LIST_POINTER"]
(*_FILE)["FILE_NAME"]
(*_FILE)["FORM_NAME"]
(*_FILE)["MAX_FILE_SIZE"]
(*_FILE)["SIZE"]
(*_FILE)["TEMP_FILE_NAME"]
Information about the file that was uploaded.
MAX_FILE_SIZE limits the size of the file upload on the server side but does not prevent the user from trying to upload larger files. You should write JavaScript to check the file size on the client side before upload.
SIZE contains the actual size in bytes of the file that was uploaded. BUFFER_LIST_POINTER is an internal memory block where the file data is kept while it is being uploaded.
TEMP_FILE_NAME is the location of the file on the server after is has been successfully been uploaded.
_GET Values submitted to the server as a get request. These appear on the URL request line.
_POST Values submitted to the server as a data post.
_COOKIE Values saved in the viewing client as cookies.

















Internal Server Page Requests


The viewing client can request internal operations of the server to be displayed to the viewing client as an HTML page.
/server: Show some information about the EBWS server.

















Page Library


A Page Library is what is created by the PageObject.cpp being compiled. It will compile to a .so as a Shared Object library. In this format the EBWS can load the library and execute it by calling PageObject::Main to generate some page data to send to the client browser.

















Static Objects


Often it is helpful to load an external library or create a new object instance. These pointers can be loaded or created once when a Page Library is executed and then used again in future page library events. These pointer can be stored in the _GLOBAL variable and then loaded again when needed.

int PageObject::Main()
{
   DataLink = GetDataLink();
   Db = (ClientDB*)(*_GLOBAL)["DB_POINTER"].ToInt();
   if(Db == 0)
   {
      Db = new ClientDB(DataLink, (STXlog*)(*_GLOBAL)["XLOG_POINTER"].ToInt());
      (*_GLOBAL)["DB_POINTER"] = IntToStr.Sprintf("%d", (unsigned int)Db);
   }
}

int PageObject::Close
{
   Log("index.so PageObject::Close()\n");
   Db = (ClientDB*)(*_GLOBAL)["DB_POINTER"].ToInt();
   if(Db != 0)
   {
      delete Db;
      (*_GLOBAL)["DB_POINTER"] = "0";
   }
}

















Interactive Example


This is an example of how HTML, JavaScript, C++ and an SQL server work together. Pass your mouse over the red text to see what roll that identifier has.
 


in the web browser on the client side viewing index.so in the server program index.so
<HTML>
   <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="check.js"></SCRIPT>
   <FORM NAME="likesForm" ACTION="index.so? do=save_text">
      <INPUT TYPE="text" NAME="my_new_text" VALUE="I like candy">
      <INPUT onClick="checkItOver()" TYPE="button" VALUE="Save">
   </FORM>
</HTML>
int PageObject::Main()
{
   Db = (ClientDB*)(*_GLOBAL)["DB_POINTER"].ToInt();
   if(Db == 0)
   {
      Db = new DbConnect("localhost", "dbuser", "dbpassword");
      (*_GLOBAL)["DB_POINTER"] = IntToStr.Sprintf("%d", (unsigned int)Db);
   }
   if((*_GET)["do"] == "save_text")
   {
      Db->exec("UPDATE mydata SET like='"+(*_POST)["my_new_text"]+"' WHERE id=1");

      return(0);
   } else
   {
      PostFromFile("main.html");
   }
}

int PageObject::Close
{
   Db = (ClientDB*)(*_GLOBAL)["DB_POINTER"].ToInt();
   if(Db != 0)
   {       delete Db;
      (*_GLOBAL)["DB_POINTER"] = "0";
   }
}








  in the server template file main.html




<HTML>
   <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript" SRC="check.js"></SCRIPT>
   <FORM NAME="likesForm" ACTION="index.so? do=save_text">
      <INPUT TYPE="text" NAME="my_new_text" VALUE="I like candy">
      <INPUT onClick="checkItOver()" TYPE="button" VALUE="Save">
   </FORM>
</HTML>








in the script check.js
in the database ourstuff in the table mydata
function checkItOver()
{
    textBox = getElementByName("my_new_text");
    if(textBox.length > 0)
    {
       document.likesForm.submit();
    }
}
     id        |             like
------------------------------------------------
      1        |      I like candy
      2        |      I like pizza