pin-httpd 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/bin/bash
  2. function fetch() {
  3. dd of=/dev/null bs=1 count=$2 2>/dev/null
  4. if ! [ -f "$1" -a -f "$1.ct" ]; then
  5. echo -e "HTTP/1.1 404 Not Found\r"
  6. echo -e "Content-Length: 0\r"
  7. echo -e "\r"
  8. return 0
  9. fi
  10. echo -e "HTTP/1.1 200 OK\r"
  11. echo -e "Content-Type: `cat $1.ct`\r"
  12. echo -e "Content-Length: `stat -c%s $1`\r"
  13. echo -e "\r"
  14. cat $1
  15. }
  16. function store() {
  17. if [ -z "$3" ]; then
  18. dd of=/dev/null bs=1 count=$2 2>/dev/null
  19. echo -e "HTTP/1.1 400 Bad Request\r"
  20. echo -e "Content-Length: 0\r"
  21. echo -e "\r"
  22. fi
  23. dd of=$1 bs=1 count=$2 2>/dev/null
  24. echo "$3" > $1.ct
  25. echo -e "HTTP/1.1 200 OK\r"
  26. echo -e "Content-Length: 0\r"
  27. echo -e "\r"
  28. }
  29. function methd() {
  30. dd of=/dev/null bs=1 count=$2 2>/dev/null
  31. echo -e "HTTP/1.1 405 Method Not Allowed\r"
  32. echo -e "Content-Length: 0\r"
  33. echo -e "\r"
  34. }
  35. if [ $# -ne 1 ]; then
  36. echo "Usage: `basename $0` STATEDIR" >&2
  37. exit 1
  38. fi
  39. shopt -s nocasematch
  40. while true; do
  41. read meth path vers
  42. [ -z "$meth" -a -z "$path" -a -z "$vers" ] && exit 0
  43. [[ "$vers" =~ ^HTTP/1\.[01]$'\r'?$ ]] || exit 1
  44. cl=0
  45. while read h && [ "$h" != $'\r' ]; do
  46. [[ "$h" =~ ^Content-Length:[[:blank:]]*([[:digit:]]+)[[:space:]]*$ ]] \
  47. && cl=${BASH_REMATCH[1]}
  48. [[ "$h" =~ ^Content-Type:[[:blank:]]*(.+)[[:blank:]]*$ ]] \
  49. && ct=${BASH_REMATCH[1]}
  50. done
  51. echo "$meth $path" >&2
  52. read path discard < <(echo "$path" | sha224sum)
  53. case "$meth" in
  54. GET) fetch "$1/$path" "$cl";;
  55. PUT) store "$1/$path" "$cl" "$ct";;
  56. POST) store "$1/$path" "$cl" "$ct";;
  57. *) methd "$1/$path" "$cl";;
  58. esac
  59. done