cgi-lib.ksh.txt 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. typeset -A COOKIE HEADER
  2. typeset Cgi _CGI_c _CGI_multipart
  3. function cgi_header
  4. {
  5. typeset h
  6. for h in "${!HEADER[@]}"
  7. do printf '%s: %s\n' "$h" "${HEADER[$h]}"
  8. done
  9. print
  10. }
  11. function cgi_url
  12. {
  13. if [[ $SERVER_PORT != 80 ]]
  14. then print "http://$SERVER_NAME:$SERVER_PORT$SCRIPT_NAME"
  15. else print "http://$SERVER_NAME$SCRIPT_NAME"
  16. fi
  17. }
  18. function cgi_parse
  19. {
  20. if [[ $REQUEST_METHOD == POST ]]
  21. then if [[ $CONTENT_TYPE == multipart/form-data* ]]
  22. then _CGI_multipart=${TMPDIR-/tmp}/cgi-form-$$
  23. trap 'rm -rf "$_CGI_multipart"' EXIT
  24. mkdir $_CGI_multipart
  25. unset -f Cgi.set
  26. typeset -A Cgi.file
  27. typeset i b v
  28. pax --nosummary --read --edit ",.*/,," --edit ",^,$_CGI_multipart/,"
  29. for i in $_CGI_multipart/*
  30. do b=${i##*/}
  31. if [[ $b == +([a-z]) ]]
  32. then v=$(<$i)
  33. eval Cgi.$b='$v'
  34. else Cgi.file[$b]=$i
  35. fi
  36. done
  37. else Cgi=$(<&0) # Read from stdin
  38. fi
  39. else Cgi="$QUERY_STRING"
  40. fi
  41. cgi_cookie "$HTTP_COOKIE"
  42. HEADER["Content-type"]="text/html"
  43. }
  44. function cgi_cookie
  45. {
  46. typeset cookie=$1 name val c IFS=';'
  47. set -- $cookie
  48. for c
  49. do
  50. IFS='='
  51. set -- $c
  52. name=${1##' '} val=${2##' '} # trim white space
  53. name=${name%%' '} val=${val%%' '}
  54. COOKIE[$name]=$val
  55. done
  56. }
  57. function cgi_setcookie # name value
  58. {
  59. HEADER["Set-Cookie"]="$1=$2; path=$SCRIPT_NAME"
  60. }
  61. ## Cgi variable disciplines
  62. function Cgi.set
  63. {
  64. set -f
  65. typeset i j n val IFS='&'
  66. set -- ${.sh.value}
  67. for i
  68. do n=${i%%=*}
  69. [[ $n == [[:alpha:]_]*([[:alnum:]_]) ]] || continue
  70. val=${i#$n=}
  71. val=${val//+/ }
  72. val=${val//@([\'\\])/'\'\1}
  73. eval j=\${#${.sh.name}.${n}[@]} \
  74. "${.sh.name}.${n}[j]=\$'${val//'%'@(??)/'\x'\1"'\$'"}'"
  75. done
  76. }
  77. function cgi_C_init
  78. {
  79. integer i
  80. for ((i=1; i < 256; i++))
  81. do if (( i!=16#22 && i!=16#27 && i!=16#5C && i!=16#5B && i!=16#5D ))
  82. then printf $'_CGI_c[$\'\\\\x%.2X\']=%%%.2X\n' $i $i
  83. fi
  84. done
  85. print
  86. }
  87. function cgi_encode
  88. {
  89. typeset v=$1
  90. var=${v//' '/+}
  91. cbrace='}'
  92. eval var=${var//@([!a-zA-Z0-9_+])/\${_CGI_c[\\\1]$cbrace}
  93. print -r -- "$var"
  94. }
  95. function Cgi.get
  96. {
  97. typeset i val name vname
  98. if [[ ! ${_CGI_c[\\]} ]]
  99. then val='"'
  100. _CGI_c[""]=%00
  101. _CGI_c[$var]=%22
  102. _CGI_c[\']=%27
  103. _CGI_c[\]]=%5B
  104. _CGI_c[\[]=%5D
  105. _CGI_c[\\]=%5C
  106. eval $(cgi_C_init)
  107. unset -f cgi_C_init
  108. fi
  109. vname=${.sh.name} # .sh.name contains variable name
  110. .sh.value= # .sh.value stores value
  111. for i in ${!Cgi.@}
  112. do
  113. name=${i#$vname.}
  114. nameref v=${i}
  115. val=$(cgi_encode "$v")
  116. .sh.value="${.sh.value}${.sh.value:+&}$name=$val"
  117. done
  118. }