In CEHTTP, a dynamic page can be distributed by creating DLL. It resembles
page performed by PHP or Perl running on Apache Web server.
In the current version of CEHTTP, Three kinds of extension was supported that
is ".MOD" ".CHX" ".DLL".
Moreover, a log files extension can be customized by creating DLL.
Tow small class libraries are used for communication between CEHTTP and the extensions files.
WindowsCE has not environment variable and stdin/stdout.
A HTTP request header is usually set to environment variable. these variable can be obtain by using ::getenv(). but WindowsCE doesn't support. For this reason, CEHTTP pass the environment variables through dynamically allocated memory.
The browser send the body data to the web server by using POST command. Usually, this body data can be read from pipe which was connected to stdin And CGI response the data by using stdout. The web server send this data to browser. In CEHTTP, these data is also passed through allocated memory.
Operation of CHX extension and DLL extension is almost the same. It is just
DLL. When CHX/DLL called by the demand from browser, CEHTTP create the
environment and loads CHX/DLL on the memory.
CHX/DLL create response dynamically and return it to browser through CEHTTP.
CHX/DLL can create response any type of content such as GIF, bitmap, or HTML
document.
MOD type extension can create response according to the MIME type of
requested file. If the file which was registered extension is called, CEHTTP
will scan a MIME type list, and will determine MOD extension to execute.
The called file name and path goes into the environment variable. MOD
extension can create a response dynamically according to this information.
MyVarMem is the memory buffer elongated dynamically. Binary data and text data can be added.
Refer to "MyVarMem specifications"
MyHash is inherited class from MyVarMem. It held a key and value. Addition, reference, and acquisition are possible.
Refer to "MyHash specifications"
It is possible to create dynamic page. This extension is more simply than DLL
extension by using class library.
In WindowsCE. in order not to support PIPE and environment variables, those
information is passed via a memory.
Create Windows DLL, and change the extension to ".CHX", and export the following function by using def file.
int fnChx(MyHash* pEnv, MyVarMem* pBody, MyVarMem* pRes)
in | MyHash* pEnv | The environment variable entries. |
in | MyVarMem* pBody | If the HTTP request comannd is POST,
a request body entries. |
out | MyVarMem* pRes | The contents to return to a client. |
The length of pRes. It is possible to obtain by using pRes->GetLength() function.
none.
It is possible to obtain all reciving data from a client browser. And it is
possible to send all response data to client browser. But treatment is a little
difficult. It is like a ISAPI extension.
In WindowsCE. in order not to support PIPE and environment variables, those
information is passed via a memory.
The environment variable is contained in the form of the following.
|key1|\0|value1|\0|key2|\0|value2|...|keyN|\0|valueN|\0|\0|
・Terminate is like "|\0|\0|".
・The value is possible to be "\0" like "|key1|\0|\0|key2|...".
・The kye does not permited "\0".
What is actually inputted is not different from CHX forms.
Create Windows DLL, and export the following function by using def file.
int fnCAPI(const void* pEnv, int nEnvLen,const void* pHead, int nHeadLen,const void* pBody, int nBodyLen,void** ppResponce)
in | const void* pEnv | The environment variable. |
in | int nEnvLen | The length of the environment variable. |
in | const void* pHead | The request header block. |
in | int nHeadLen | The length of the request header block. |
in | const void* pBody | The request body. |
in | int nBodyLen | The length of body block. |
out | void** ppResponce | The content of response which is allocated by ::malloc(). |
From version 2.30, use
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size ) instead of ::malloc( size
).
HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, p, size ) instead of ::realloc(
size ).
The data length (byte unit) which transmits to be browser.
It is an extension module for a MIME type. The form of function is same as CHX extension.
It is determined by the file name which MIME type is extended. For example, When the file which has the extension ".txt" is requested by client browser, the extension named "text.mod" is invoked by CEHTTP.
The following code indicate to obtain the filename path.
strcpy( szFile, pEnv->GetValueI("DOCUMENT_ROOT") );
strcat( szFile, pEnv->GetValueI("SCRIPT_NAME") );
// '/' ->'\'
char* p = szFile;
while( *p != '\0' ) {
if(*p == '/' ) {
*p++ = '\\';
}
MOD extension can change the called file.
CEHTTP enumerates the ".mod" files which exist in a current directory. A MIME type list will be changed if a ".mod" file is dsicoverd here.
For example, if there is "txt.mod", MIME type list is added following record.
.txt \program files\cehttp\txt.mod
The same thing is possible if MIME type list file is written as mentioned above. This file is explained by "CEHTTP users manual".
The log file is provided by DLL extension. It is possible to change the output of a log file.
The file name is "cehttplog.dll" and the function name is "fnCehttpLog".
Although an environment variable is given to a log file function, some information is added as follows.
remote_addr | The IP address of remote host. |
request_line | Request line which remote host has sent. |
send_bytes | Byte count of response. It is not set when HTTP status is except 200. |
typedef int (*CEHTTPLOGAPI)(WCHAR* pwszLogFile, int nLogSize, int nHttpStatus, MyHash* hashRequest);
in | WCHAR* pwszLogFile | The log file name specified by CEHTTP. |
in | int nLogSize | Max size of log files |
in | int nHttpStatus | The status code of CEHTTP. |
in | MyHash* pHashHeaders | The environment variables |
0 indicate failure. otherwise success.
All source code was compiled with Microsoft eMbedded Visual Tools 3.0. It is gratuitously compiler of Windows CE provided by Microsoft Corp.
It is possible to download of English version. Refer to the following URL.
http://www.microsoft.com/japan/windows/embedded/ce/techinfo/default.asp
The DLL cannot debug alone. It must be debugged with CEHTTP.
If the project of CEHTTP and the project of extension DLL is added to one workspace, it is possible to debug. And step debugging can be available.
It becomes possible to debug both of code.
As a point which it must be careful of in case DLL is dealt with on WindowsCE, once DLL is load on memory of CEHTTP process, is is never released. This point becomes the difference with a Windows.
The extended module loaded from CEHTTP needs to be multithread safe. It must be careful of in case of a global variable are used. The writing of a global variable affects operation of the extended module which is operated by other threads.
Initialization and release of a system object are performed in the function of ::DllMain(). For example, in case CriticalSection is used, it describe as follows.
CRITICAL_SECTION cs; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: { InitializeCriticalSection(&cs); break; } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: { DeleteCriticalSection( &cs ); break; } } return TRUE; } int fnChx(MyHash* pEnv, MyVarMem* pBody, MyVarMem* pRes) { EnterCriticalSection( &cs ); // critical section code here... LeaveCriticalSection( &cs ); }
By this way, while other threads perform this DLL, it can prevend opening a system object carelessly.
As for WindowsCE, UNICODE is default character set. But HTTP protocol request and response is written by ASCII character. Cautions are required.
In CEHTTP, it has shifted to the programming style which uses WSTR clearly, without using TEXT macro.
Although it is the best way which is actually seen by the browser, it is also effective to check the raw data by using telnet. Windows has useful telnet to use a test.
It can use with the command line as follows.
>telnet <server name> <port number>
>telnet localhost 80 GET / HTTP/1.0
HTTP/1.0 200 OK Server: CEHTTP/2.2 Content-Length: 127 Last-Modified: Mon, 10 Feb 2003 04:28:49 GMT Connection: Keep-Alive Content-Type: text/html <HTML><BODY><H1>Can you see me?</H1><BR><HR>CEHTTP2 by<A HREF="http://www001.upp.so-net.ne.jp/ishi/">IshiSoft</A></BODY></HTML>
The tool for seeing the protocol between a Web server and a browser is provided on IshiSoft.
WAS is convenient for multithread test or durability test. This is the gratuitously tool from Microsoft Corp. It operates by the multithread and can describe with macro.
It can download from the following URL.
// sample.chx #include "stdafx.h" #include "stdio.h" #include "chx.h" //***************************************************************************** // fhChx //***************************************************************************** int fnChx(MyHash* pEnv, MyVarMem* pBody, MyVarMem* pRes) { char work[2048]; if((char*)pBody) { sprintf(work, "Content-Type: text/html\r\n\r\n" "<html>" "<head><title>CECGI</title></head>" "<u><b>BODY</b></u><br>" "%s<br>" "<u><b>environment</b></u><br>" , pBody->GetBuffer() ); } else { pRes->Add("(null)"); } pRes->Add(work); pEnv->SeekToFirst(); do{ sprintf(work, "%s=%s<br>\n" ,pEnv->GetCurrentKey() ,pEnv->GetCurrentValue() ); pRes->Add(work); }while(pEnv->SeekNext()); pRes->Add("</html>"); return pRes->GetLength(); } //***************************************************************************** // DllMain //***************************************************************************** BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
CEHTTP sets the following environment variables. It will not be set if there is information which is not acquired.
parameters description SCRIPT_NAME The extended file name currently performed PATH_INFO Path information attached behind URI PATH_TRANSLATED The position on the local file system of path information CONTENT_LENGTH Body length at the time of POST command QUERY_STRING The parameter of the URI REMOTE_ADDR The IP address of a client REMOTE_HOST The host name (need dnslookup option at registry) REMOTE_PORT The port of a client REQUEST_METHOD The method of client request SERVER_NAME The address of the WEB server specified by the client SERVER_PORT A server's port specified by the client SERVER_PROTOCOL The HTTP protocol version specified by the client SERVER_SOFTWARE Server soft name HTTP_ACCEPT The receivable MIME type specified by the client HTTP_USER_AGENT Client soft name HTTP_COOKIE The Cookie name which the client transmitted HTTP_REFERER The page by which the client came DOCUMENT_ROOT The document route position on a local file system GATEWAY_INTERFACE Extended gateway name
All request header by client is upper cased, '-' is translated and added
'HTTP_'.
e.g. "Accept-Encoding" is translated to "HTTP_ACCEPT_ENCORDING".