On Sat, 16 Feb 2008 13:31:17 -0800 (PST), happytoday
<ehabaziz2001@[EMAIL PROTECTED]
> wrote:
>On Feb 16, 9:18 pm, Kees Nuyt <k.n...@[EMAIL PROTECTED]
> wrote:
>> On Sat, 16 Feb 2008 10:55:43 -0600, Ted Davis
>>
>> Yes, it's hard to find a gawk with 2way pipes for
>> MSWindows, but there is a cygwin gawk version that does.
>>
>> It is called gawki.exe :
>> $ gawki --version
>> GNU Awk 3.1.1
>> Copyright (C) 1989, 1991-2002 Free Software Foundation.
>>
>> It also supports 2way pipes to TCP / UDP ports.
>>
>> Just for fun, here is the core of an awk script for gawki
>> that implements a webserver ("Lakota"):
>>
>> ===
>> dtsvcstart = strftime("%Y-%m-%d %H:%M:%S")
>> LakotaVersion = "2.2"
>>
>> RC["200"] = "Ok"
[snip code]
>> } # while (KeepRunning)
>> ===
>>
>> I use it as an "emergency" webserver, when Apache is down
>> for maintenance.
>If you run this script under windows . What are the step did
>you take to run them under windows ?
Some zealots consider that off-topic in comp.lang.awk,
but I'll bite the bullet for the sake of awk promotion ;)
The code in my previous article is just the core.
Here is some more code.
It sure isn't the prettiest awk code around,
but it's legible and it works for me.
All stuff below assumes a directory tree like:
dir (files)
------------ ----------------------
%serverroot% (lakota.cmd, lakota.awk)
bin (
2002-10-16 23:00 240.640 gawki.exe
2003-08-09 23:00 37.888 cygintl-2.dll
2004-07-05 23:00 1.015.128 cygiconv-2.dll
2005-07-02 23:00 1.295.582 cygwin1.dll )
conf (lakota.conf)
htdocs (index.html server*.html ....)
logs
Scripts:
- lakota.cmd
start script
- conf/lakota.conf
Contains server parameters, like DocumentRoot etc.
- lakota.awk
The server itself, basically:
BEGIN{
init
serverloop
exit 0
}
function getpage(){
} and a few more functions.
getpage supports a few Server Side Includes (SSI)
The SSI substitution is a little ugly :-)
- htdocs/index.html
- htdocs/server-status.html
- htdocs/server-stop.html
(Of course I use something else than **some_magic**)
Notes:
All .html pages should conform w3c XHTML 1.0 Strict
This post has extra long line length, but
some lines may still be wrapped by usenet
========
lakota.cmd
========
if not exist logs mkdir logs
pushd logs
for %%v in (request.log) do if exist %%v del %%v
popd
bin\gawki.exe "{gsub(/\t/,\"
\");gsub(/**the_magic**/,\"**some_magic**\");print}" lakota.awk
>htdocs\lakota.awk
bin\gawki.exe -f conf/httpd.conf -f lakota.awk
type lakota.hit
sleep 5
:Z
========
conf/httpd.conf
========
#
## Lakota configuration file
## syntax is awk
#
BEGIN{
Listen = 80
DocumentRoot = "htdocs"
DirectoryIndex = "index.html"
CustomLog = "logs/access.log"
ErrorLog = "logs/error.log"
RequestLog = "logs/request.log"
ServerAdmin = "webmaster@[EMAIL PROTECTED]
"
}
========
lakota.awk
========
#
# %ServerRoot%/lakota.awk Microscopic Webserver
# uses gawki.exe (gnu awk with IP protocol extensions)
#
# Copyright (C) 2007,2008 by Kees Nuyt
#
# version history:
# [snipped]
#
#% is for debugging
#
BEGIN{
dtsvcstart = strftime("%Y-%m-%d %H:%M:%S")
LakotaVersion = "2.2"
fSetHit = "lakota.hit"
RS = "\x0D"
ORS = "\x0D\x0A"
if (!Listen) Listen = 80
if (!DocumentRoot) DocumentRoot = "htdocs"
if (!DirectoryIndex) DirectoryIndex = "index.html"
if (!CustomLog) CustomLog = "logs/access.log"
if (!ErrorLog) ErrorLog = "logs/error.log"
if (!RequestLog) RequestLog = "logs/request.log"
if (!ServerAdmin) ServerAdmin = "webmaster@[EMAIL PROTECTED]
"
doctype = \
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
ORS ORS
hits = 0
if ((getline <fSetHit) >0){ # LakotaSessionsHitsBytes
sessions = $1 + 1
hits = $2 + 0
servedbytes = $3 + 0
}
close(fSetHit)
RC["200"] = "Ok"
RC["203"] = "Not found"
httpd = "/inet/tcp/" Listen "/0/0"
printf("%s Lakota started\n",dtsvcstart)
printf("%s Lakota started\n",dtsvcstart) >>CustomLog
printf("%s port:%s; RS:%s; ORS:%s;\n",dtsvcstart,Listen,RS,ORS)
>>CustomLog
headers = \
"HTTP/1.1 %s %s" ORS \
"Server: Lakota/" LakotaVersion ORS \
"Set-Cookie: salutation=\"Lakota Webserver Says Hello\";
Max-Age=\"3600\"; Version=\"1\"" ORS \
"Set-Cookie: onbehalfof=\"" ServerAdmin "\"; Max-Age=\"3600\";
Version=\"1\"" ORS \
"Connection: close" ORS \
"Cache-control: no-cache, no-store" ORS \
"MIME-version: 1.0" ORS \
"Content-type: text/html" ORS
KeepRunning = (1 == 1) # true
while (KeepRunning){
print strftime("%Y-%m-%d %H:%M:%S Listen ") Listen
rqlines = 0
while ((httpd |& getline) > 0){
request = $0
gsub(/[[:cntrl:]]+/,"",request) # strip all control chars (0x0D
0x0A leftovers etc.)
gsub(/^[[:blank:]]+/,"",request) # strip leading whitespace
gsub(/[[:blank:]]+$/,"",request) # strip trailing whitespace
if (request ~ /^GET /){
delete rq # gawk specific
datetime = strftime("%Y-%m-%d %H:%M:%S")
URL = substr(request,5,index(request," HTTP/") - 5)
html = getpage(URL) # sets status 200
or 203, may also change KeepRunning
contlen = length(html)
loghit(URL,hits,status,contlen)
} else if ((pc = index(request,":")) > 2){ # eval request
header, hit counts
hdrnm = substr(request,1,pc - 1) # header name
hdrvl = substr(request,pc + 1) # header values
rq[hdrnm] = hdrvl # for later use in
pagebuilder
if (hdrnm in hit_hnm){
hit_hnm[hdrnm]++
} else {
hit_hnm[hdrnm] = 1
}
if ((hdrnm,hdrvl) in hit_hnm_hvl){
hit_hnm_hvl[hdrnm,hdrvl]++
} else {
hit_hnm_hvl[hdrnm,hdrvl] = 1
}
}
printf("%s#%05d#%03d %s\n",datetime,hits,++rqlines,request)
>>RequestLog
if ($0 ~ /^[[:cntrl:][:blank:]]*$/){ # empty line is end of
request
printf("%s %s URL:%s:",datetime,status,URL)
printf(headers,status,RC[status]) |& httpd
printf("Content-Length: %d%s%s",\
contlen,ORS,ORS) |& httpd
printf("%s",html) |& httpd
break
}
}
printf("-- \n") >>RequestLog
printf("\n")
fflush("") # flush ALL output buffers
close(httpd) # keep-alive not honored
printf( "%d %d %d
LakotaSessionsHitsBytes\n",sessions,hits,servedbytes) >fSetHit
close(fSetHit)
}
datetime = strftime("%Y-%m-%d %H:%M:%S")
print datetime " stopped"
print datetime " Lakota stopped" >>CustomLog
print getstat() >>CustomLog
close(CustomLog)
close(RequestLog)
exit 0
}
#
##
#
function loghit(_URL,_hits,_stat,_len){
printf("%s %05d %s %5d %s\n",datetime,_hits,_stat,_len,_URL)
>>CustomLog
if (!(_stat in resp)){
resp[_stat] = 0
fstresp[_stat] = datetime
}
resp[_stat]++
lstresp[_stat] = datetime
if (!(_URL in hit)){
hit[_URL] = 0
fsthit[_URL] = datetime
}
hit[_URL]++
lsthit[_URL] = datetime
hits++
servedbytes += _len
}
#
##
#
function getstat( _resp,_hits,_idx,_idy){
_resp = ""
for (_idx in resp){
_resp = _resp \
sprintf("<tr><td>%s </td><td align=\"right\">%d </td><td>%s
</td><td>%s </td></tr>",\
_idx,resp[_idx],fstresp[_idx],lstresp[_idx])
}
_hits = ""
for (_idx in hit){
_hits = _hits \
sprintf("<tr><td>%s </td><td align=\"right\">%d </td><td>%s
</td><td>%s </td></tr>",\
_idx,hit[_idx],fsthit[_idx],lsthit[_idx])
}
_hdrs = ""
for (_idx in hit_hnm){
for (_idy in hit_hnm_hvl){
split (_idy,tmp,SUBSEP)
#% print _idy "\n"
if (tmp[1] == _idx){
_hdrs = _hdrs \
sprintf("<tr><td>%s </td><td align=\"right\">%d </td><td>%s
</td></tr>",\
_idx,hit_hnm_hvl[_idy],tmp[2])
}
}
}
return \
"<table border=\"1\" summary=\" URL
statistics\"><tr><th>URL</th><th>hits</th><th>first</th><th>last</th></tr>"\
_hits "</table><br />" ORS \
"<table border=\"1\" summary=\"Response
statistics\"><tr><th>response</th><th>hits</th><th>first</th><th>last</th></tr>"\
_resp "</table><br />" ORS \
"<table border=\"1\" summary=\"Header
statistics\"><tr><th>header</th><th>hits</th><th>value</th></tr>"\
_hdrs "</table><br />" ORS
}
#
##
#
function getpage( _fHTML,_html,_lines,_line){
_fHTML = URL
sub(/^\//,"",_fHTML)
if (_fHTML == ""){
_fHTML = DirectoryIndex
URL = "/" _fHTML
}
_fHTML = DocumentRoot "/" _fHTML
_lines = 0
while (_lines < 1){
_html = ""
#% printf("read:%s:",_fHTML)
ext = tolower(substr(_fHTML,length(_fHTML)-3,4))
while ((getline _line <_fHTML) >0){
_lines++
_html = _html _line ORS
}
close(_fHTML)
if (_lines < 1){
_html = "<html><head><title>Not found</title></head>" ORS \
"<body><h1>Page " URL " not found on the server.</h1>" ORS \
"<p><a href=\"/index.html\">back home</a> "\
"<a href=\"mailto:<!--#server_admin -->\">info</a></p>" ORS \
"</body></html>"
_lines = 2
status = "203"
} else {
status = "200"
}
}
if ((ext == "html") || (status != "200")){ # substitutions
while (match(_html, /<!--#[^->]*-->/)){ # SSI format
<!--#expression -->
rawexp = substr(_html,RSTART, RLENGTH)
#% print "%%%" rawexp "%%%"
express = tolower(substr(_html,RSTART + 5, RLENGTH - 8))
gsub(/[[:blank:]]+/," ",express) # multiple spaces
to single, tabs to space
gsub(/^[[:blank:]]+/,"",express) # strip leading
whitespace
gsub(/[[:blank:]]+$/,"",express) # strip trailing
whitespace
if (express == "server_status"){
gsub(rawexp,getstat(),_html)
} else if (express == "**some_magic**"){
KeepRunning = (1 == 0) # false
print datetime " Stop command processed."
gsub(rawexp,"Stop command processed.",_html)
} else if (express == "server_start"){
gsub(rawexp,dtsvcstart,_html)
} else if (express == "server_version"){
gsub(rawexp,LakotaVersion,_html)
} else if (express == "server_admin"){
gsub(rawexp,ServerAdmin,_html)
} else if (express == "current_time"){
gsub(rawexp,datetime,_html)
} else if (express == "hit_count"){
gsub(rawexp,sprintf("%05d",hits + 1),_html)
} else if (express == "url"){
gsub(rawexp,URL,_html)
} else {
gsub(rawexp,"Unknow SSI expression: " express,_html)
}
}
} else {
#% printf("add tags:")
gsub(/^&/,"\\&",_html) # replace ampersand with ampersand a m p
semicolon
gsub(/</,"\\<",_html) # replace less with ampersand l t
semicolon
gsub(/>/,"\\>",_html) # replace greater with ampersand g t
semicolon
_html = "<html>" ORS \
"<head><title>" _fHTML \
"</title></head>" ORS \
"<body>" ORS \
"<p><a href=\"/index.html\">home</a> <a
href=\"mailto:<!--#server_admin -->\">info</a></p>" ORS \
"<pre>" _html "</pre></body></html>"
}
return doctype _html
}
========
htdocs/index.html
========
<html>
<head>
<title>Lakota webserver</title>
</head>
<body>
<h1>I'm sorry,</h1>
<h2>the website is unavailable</h2>
<p>This is a <a title="Lakota is a microscopic webserver implemented in
GNU awk. Click to show the source."
href="lakota.awk">Lakota</a> smoke signal to tell you that<br />
<b>Apache is down for maintenance</b> since <small><!--#server_start
--></small>.</p>
<p><small><a href="mailto:<!--#server_admin -->">info</a></small></p>
<p>
<small>
<!--#current_time -->
<span style="color: yellow; background-color: black; font-weight:
bold">
<!--#hit_count -->
</span> (<!--#url -->)
</small>
</p>
</body>
</html>
========
htdocs/server-status.html
========
<html>
<head>
<title>Lakota v<!--#server_version --> webserver</title>
</head>
<body>
<h1>Lakota v<!--#server_version --> webserver status</h1>
<a href="/index.html">home</a> <a
href="/server-stop.html">stop</a>
<div><!--#server_status --></div>
<p>
<small>Running <!--#server_start --> thru <!--#current_time -->
<span style="color: yellow; background-color: black; font-weight:
bold">
<!--#hit_count -->
</span> (<!--#url -->)
</small>
</p>
</body>
</html>
========
htdocs/server-stop.html
========
<html>
<head>
<title>Lakota webserver terminating</title>
</head>
<body>
<h1><a title="Lakota is a microscopic webserver implemented in GNU awk"
href="mailto:<!--#server_admin -->">LAKOTA</a>will terminate.</h1>
<div><!--#server_status --></div>
<div><!--#**some_magic** --></div>
<p><small><!--#server_start --></small></p>
<p><small><!--#current_time --> <span style="color: yellow;
background-color: black; font-weight:
bold"><!--#hit_count --></span> (<!--#url -->)</small></p>
</body>
</html>
==================
Well, there it is. Good luck cutting 'n pasting.
I'm not sure the pages validate :D
--
( Kees
)
c[_] Oliver's Law: Experience is something you don't get until just after
you need it. (#514)


|