werc-1.5.0-tweaks

Tweaks for the werc website builder created by the mad architect Uriel
Log | Files | Refs | README

cgilib.rc (5870B)


      1 # Useful CGI stuff
      2 
      3 fn dprint { echo $* >[1=2] }
      4 fn dprintv { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; '  }; echo } >[1=2] }
      5 fn echo {if(! ~ $1 -n || ! ~ $2 '') /bin/echo $*}
      6 fn escape_html { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' $* }
      7 
      8 fn http_redirect {
      9     if(~ $1 http://* https://*)
     10         t=$1
     11     if not if(~ $1 /*)
     12         t=$"base_url^$1
     13     if not
     14         t=$"base_url^$"req_path^$1
     15     exec /bin/echo 'Status: '^$2^'
     16 Location: '^$t^'
     17 
     18 '
     19     exit
     20 }
     21 fn perm_redirect { http_redirect $1 '301 Moved Permanantly' }
     22 fn post_redirect { http_redirect $1 '303 See Other' }
     23 
     24 
     25 # Note: should check if content type is application/x-www-form-urlencoded?
     26 # Should compare with http://www.shelldorado.com/scripts/cmds/urlgetopt.txt
     27 fn load_post_args {
     28     if(~ $REQUEST_METHOD POST && ~ $#post_args 0) {
     29         ifs='&
     30 '       for(pair in `{cat}) {
     31             ifs='=' { pair=`{echo -n $pair} }
     32             n='post_arg_'^`{echo $pair(1)|nurldecode|tr -cd 'a-zA-Z0-9_'}
     33             post_args=( $post_args $n )
     34             ifs=() { $n=`{echo -n $pair(2)|nurldecode|tr -d ''} }
     35         }
     36         pair=()
     37     }
     38     if not
     39         status='No POST or post args already loaded'
     40 }
     41 # Status is () if at least one arg is found. DEPRECATED: access vars directly.
     42 fn get_post_args {
     43     load_post_args
     44     _status='No post arg matches'
     45     for(n in $*) {
     46         v=post_arg_$n
     47         if(! ~ $#$v 0) {
     48             $n=$$v
     49             _status=()
     50         }
     51     }
     52     status=$_status
     53 }
     54 
     55 # This seems slightly improve performance, but might depend on httpd buffering behavior.
     56 fn awk_buffer {
     57     awk '{
     58         buf = buf $0"\n"
     59         if(length(buf) > 1400) {
     60             printf "%s", buf
     61             buf = ""
     62         }
     63     }
     64     END { printf "%s", buf }'
     65 }
     66 
     67 fn nurldecode { urlencode -d || url_decode}	# GROSS
     68 
     69 fn url_decode {
     70 awk '
     71 BEGIN {
     72     hextab ["0"] = 0; hextab ["8"] = 8;
     73     hextab ["1"] = 1; hextab ["9"] = 9;
     74     hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
     75     hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
     76     hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
     77     hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
     78     hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
     79     hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
     80 }
     81 {
     82     decoded = ""
     83     i = 1
     84     len = length ($0)
     85     while ( i <= len ) {
     86         c = substr ($0, i, 1)
     87         if ( c == "%" ) {
     88             if ( i+2 <= len ) {
     89                 c1 = substr ($0, i+1, 1)
     90                 c2 = substr ($0, i+2, 1)
     91                 if ( hextab [c1] == "" || hextab [c2] == "" ) {
     92                     print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
     93                 } else {
     94                     code = 0 + hextab [c1] * 16 + hextab [c2] + 0
     95                     c = sprintf ("%c", code)
     96                     i = i + 2
     97                 }
     98             } else {
     99                 print "WARNING: invalid % encoding: " substr ($0, i, len - i)
    100             }
    101         } else if ( c == "+" ) {
    102             c = " "
    103         }
    104         decoded = decoded c
    105         ++i
    106     }
    107     printf "%s", decoded
    108 }
    109 '
    110 }
    111 
    112 fn nurlencode { urlencode || url_encode }	# GROSS
    113 
    114 fn url_encode {
    115     awk '
    116     BEGIN {
    117     # We assume an awk implementation that is just plain dumb.
    118     # We will convert an character to its ASCII value with the
    119     # table ord[], and produce two-digit hexadecimal output
    120     # without the printf("%02X") feature.
    121 
    122     EOL = "%0A"     # "end of line" string (encoded)
    123     split ("1 2 3 4 5 6 7 8 9 A B C D E F", hextab, " ")
    124     hextab [0] = 0
    125     for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0
    126     if ("'^$"EncodeEOL^'" == "yes") EncodeEOL = 1; else EncodeEOL = 0
    127     }
    128     {
    129     encoded = ""
    130     for ( i=1; i<=length ($0); ++i ) {
    131         c = substr ($0, i, 1)
    132         if ( c ~ /[a-zA-Z0-9.-]/ ) {
    133         encoded = encoded c     # safe character
    134         } else if ( c == " " ) {
    135         encoded = encoded "+"   # special handling
    136         } else {
    137         # unsafe character, encode it as a two-digit hex-number
    138         lo = ord [c] % 16
    139         hi = int (ord [c] / 16);
    140         encoded = encoded "%" hextab [hi] hextab [lo]
    141         }
    142     }
    143     if ( EncodeEOL ) {
    144         printf ("%s", encoded EOL)
    145     } else {
    146         print encoded
    147     }
    148     }
    149     END {
    150         #if ( EncodeEOL ) print ""
    151     }
    152 ' $* 
    153 }
    154 
    155 # Cookies
    156 fn set_cookie {
    157     # TODO: should check input values more carefully
    158     name=$1
    159     val=$2
    160     extraHttpHeaders=( $extraHttpHeaders 'Set-cookie: '^$"name^'='^$"val^'; path=/;' )
    161 }
    162 fn get_cookie {
    163     ifs=';' { co=`{echo $HTTP_COOKIE} }
    164 
    165     # XXX: we might be adding a trailing new line?
    166     # The ' ?' is needed to deal with '; ' inter-cookie delimiter
    167     { for(c in $co) echo $c } | sed -n 's/^ ?'$1'=//p' 
    168 }
    169 
    170 
    171 fn static_file {
    172     echo -n 'Content-Type: '
    173     select_mime $1
    174     echo
    175     exec cat $1
    176 }
    177 
    178 fn select_mime {
    179     m='text/plain'
    180     if(~ $1 *.css)
    181         m='text/css'
    182     if not if(~ $1 *.ico)
    183         m='image/x-icon'
    184     if not if(~ $1 *.png)
    185         m='image/png'
    186     if not if(~ $1 *.jpg *.jpeg)
    187         m='image/jpeg'
    188     if not if(~ $1 *.gif)
    189         m='image/gif'
    190     if not if(~ $1 *.pdf)
    191         m='application/pdf'
    192     echo $m
    193 }
    194 
    195 ##############################################
    196 # Generic rc programming helpers
    197 
    198 # Manage nested lists
    199 fn ll_add {
    200     _l=$1^_^$#$1
    201     $_l=$*(2-)
    202     $1=( $$1 $_l )
    203 }
    204 # Add to the head: dangerous if you shrink list by hand!
    205 fn ll_addh {
    206     _l=$1^_^$#$1
    207     $_l=$*(2-)
    208     $1=( $_l $$1 )
    209 }
    210 
    211 
    212 NEW_LINE='
    213 '
    214 
    215 # crop_text [max_lenght [ellipsis]] 
    216 # TODO: Option to crop only at word-delimiters.
    217 fn crop_text {
    218     m=512
    219     e='...'
    220     if(! ~ $#1 0)
    221         m=$1
    222     if(! ~ $#2 0)
    223         e=$2
    224 
    225     awk -v 'max='^$"m -v 'ellipsis='$e '
    226     {
    227         nc += 1 + length;
    228         if(nc > max) {
    229             print substr($0, 1, nc - max) " " ellipsis
    230             exit
    231         }
    232         print
    233     }' 
    234 }
    235 
    236