]> git.plutz.net Git - rawnet/blob - upload.sh
For progress frame use chunked encoding instead of long poll
[rawnet] / upload.sh
1 #!/bin/sh
2
3 [ "$include_upload" ] && return 0
4 include_upload="$0"
5
6 UPLOAD(){
7   local file="$1"
8   local boundary line length=0
9
10   [ ! "${CONTENT_TYPE}" -o "${CONTENT_TYPE##multipart/form-data;*}" ] && return 1
11
12   boundary="${CONTENT_TYPE#*; boundary=}"
13   boundary="${boundary%%;*}"
14
15   while read -r line; do
16     length="$(( length + ${#line} + 1))"
17     [ "${line%${CR}}" = "--$boundary" ] && break
18   done
19   while read -r line; do
20     length="$(( length + ${#line} + 1))"
21     [ ! "${line%${CR}}" ] && break \
22     || debug "$line"
23   done
24
25   printf "%i\n" "$(( CONTENT_LENGTH - length ))" >"${file}.upload"
26   head -c "$(( CONTENT_LENGTH - length ))" \
27   | sed -nE '
28     # print lines until boundary ( = actual file upload)
29     :FILE; p; n;
30     /^--'"${boundary}"'(--)?\r?$/!bFILE;
31     # discard remaining lines
32     :END; $q; n; bEND;
33   ' >"$file"
34   truncate -s $(( $(stat -c %s -- "$file") -2 )) -- "$file"
35   rm -- "${file}.upload"
36 }
37
38 base16(){
39   local num="$1"
40   case $num in
41     [0-9]) printf %i "$num";;
42     10) printf a;;
43     11) printf b;;
44     12) printf c;;
45     13) printf d;;
46     14) printf e;;
47     15) printf f;;
48     *) printf '%s%s' "$(base16 $((num / 16)))" "$(base16 $((num % 16)))"
49   esac
50 }
51
52 HTTP_CHUNK(){
53   local chunk="$*"
54   printf '%s\r\n%s\r\n' "$(base16 "${#chunk}")" "$chunk"
55 }
56
57 frame_uploadprogress() {
58   printf '%s: %s\r\n' "Content-Type" "text/html" "Transfer-Encoding" "chunked"
59   printf '\r\n'
60
61   HTTP_CHUNK "<!DOCTYPE HTML>
62   " "<html><head>
63   <title>Upload Progress</title>
64   <!-- <link rel=\"stylesheet\" type=\"text/css\" href=\"$_BASE/rawnet.css\" /> -->
65   <style type=\"text/css\"><!--
66     #uploadprogress {
67       text-align: center;
68       background: transparent;
69       margin: 0;
70     }
71     #uploadprogress .progress {
72       display: block;
73       position: absolute;
74       top: 0;
75       width: 99%; width: calc(100% - 2pt);
76       background-color: #FFF;
77       border: 1pt solid;
78       border-radius: 4pt;
79       height: 1.25em;
80     }
81     #uploadprogress .progress .bar {
82       display: block;
83       position: absolute;
84       left: 0; top: 0; bottom: 0;
85       background-color: #666;
86     }
87     #uploadprogress .progress .count {
88       display: block;
89       position: absolute;
90       left: 0; top: 0; right: 0; bottom: 0;
91       line-height: 1.375em;
92     }
93   --></style>
94   " "</head><body id=uploadprogress>
95   "
96   HTTP_CHUNK '  <div class=progress><div class=bar style="width: 0%;"></div><div class=count>0 / 0</div></div>'
97   while [  ! -f "${VIDEO_FILE}" -a ! -f "${VIDEO_FILE}.upload" ]; do
98     sleep 1
99   done
100   read size <"${VIDEO_FILE}.upload" 2>&-
101   while [ -f "${VIDEO_FILE}.upload" ]; do
102     stat="$(stat -c %s "$VIDEO_FILE" 2>&-)"
103     HTTP_CHUNK "  <div class=progress><div class=bar style=\"width:$(( stat * 100 / size))%;\">" \
104                "</div><div class=count>$((stat / 1048576))MB / $((size / 1048576))MB</div></div>" "$BR"
105     sleep 1
106   done
107   HTTP_CHUNK '  <div class=progress><div class=bar style="width:100%%;"></div><div class=count>Ready!</div></div>' "$BR" \
108              '</body></html>'
109   HTTP_CHUNK ''
110 }