]> git.plutz.net Git - shellwiki/commitdiff
basic multipaart handler
authorPaul Hänsch <paul@plutz.net>
Tue, 12 Apr 2022 18:45:37 +0000 (20:45 +0200)
committerPaul Hänsch <paul@plutz.net>
Tue, 12 Apr 2022 18:45:37 +0000 (20:45 +0200)
multipart.sh [new file with mode: 0644]

diff --git a/multipart.sh b/multipart.sh
new file mode 100644 (file)
index 0000000..2c38a37
--- /dev/null
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+[ "$include_multipart" ] && return 0
+inlude_multipart="$0"
+
+if [ "${CONTENT_TYPE}" -a ! "${CONTENT_TYPE##multipart/form-data;*}" ]; then
+  multipart_boundary="${CONTENT_TYPE#*; boundary=}"
+  multipart_boundary="${multipart_boundary%%;*}"
+  multipart_boundary="${multipart_boundary%${CR}}"
+fi
+multipart_cachefile="/tmp/multipart.$$"
+
+readbytes(){
+  # read n bytes, like `head -c` but do not consume input
+  local size="$1" block
+
+  for block in 65536 32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1; do
+    if [ $size -ge $block ]; then
+      dd status=none bs="$block" count="$((size / block))"
+      size="$((size % block))"
+    fi
+  done
+}
+
+multipart_cache() {
+  multipart_cachefile="${1:-${multipart_cachefile}}"  # global
+
+  if [ "${multipart_boundary}" ]; then
+    # readbytes "$(( CONTENT_LENGTH ))" >"${multipart_cachefile}"
+    head -c "$(( CONTENT_LENGTH ))" >"${multipart_cachefile}"
+  else
+    return 1
+  fi
+}
+
+multipart(){
+  local name="$1"
+  local formdata state=begin
+
+  debug "Boundary: $multipart_boundary"
+  debug "File: $multipart_cachefile"
+
+  while read -r formdata; do case "$formdata" in
+    "--${multipart_boundary}--${CR}")
+      [ $state = data ] && return 0 \
+                        || return 1
+      ;;
+    "--${multipart_boundary}${CR}")
+      [ $state = data ] && return 0 \
+                        || state=header
+      ;;
+    "Content-Disposition: form-data; name=\"${name}\""*"${CR}")
+      [ $state = header ] && state=dheader
+      [ $state = data ] && printf "%s\n" "$formdata"
+      ;;
+    "${CR}")
+      [ $state = dheader ] && state=data
+      [ $state = header ] && state=junk
+      ;;
+    *)
+      [ $state = data ] && printf "%s\n" "$formdata"
+      ;;
+  esac; done <"${multipart_cachefile}"
+}