shi/http_backend.sh

148 lines
3.7 KiB
Bash
Executable File

#!/bin/sh
. ./globals.sh
echo "Using http backend." >> "$log_file"
gen_post_data_from_file() {
# TODO: if variables are unset by the end, set them to "error"
local file="$1"
local board=""
local parent=""
local user=""
local title=""
local content=""
local image_name=""
local image_content=""
# find the form boundary
local boundary="$(grep -am1 \
"Content-Type: multipart/form-data; boundary=" \
$file | cut -f 2- -d "=")"
local in_boundary="0"
local data_type=""
local file_upload_start="" # the line at which binary file data starts (if any)
local iterator="0"
echo "New post"
while read -r line
do
iterator="$(( iterator + 1 ))"
# dont read the binary data contained in files,
# as it will break the script
if echo "$line" | grep -q 'Content-Disposition: form-data; name="fileupload";'
then
file_upload_start="$iterator"
break
fi
# if a boundary is seen
if echo "$line" | grep -q -- "$boundary"
then
# and we are not already in a boundary
if [ "$in_boundary" -eq 0 ]
then
# then we are now in a boundary
in_boundary="1"
else
# otherwise, we are in a new boundary,
# so reset data_type
data_type=""
fi
fi
# if we are in a boundary, the beginning of form data is seen,
# and we are not already reading form data
if [ "$in_boundary" -eq "1" ] \
&& echo "$line" \
| grep -q "Content-Disposition: form-data; name=" \
&& [ -z "$data_type" ]
then
data_type=$(echo "$line" | cut -f 2 -d '"')
fi
case "$data_type" in "post_to")
# remove LFs from line
line="$(echo "$line" | tr -d '\r')"
# if our post is a reply
if echo "$line" | grep -qE "[0-9]$"
then
# set parent to the post it is replying to
parent="$(find $board_dir \
-maxdepth 3 \
-name "$line" \
-not -path '*/\.*')"
# make sure the parent post exists
if [ -z "$parent" ]; then return 1; fi
# and set the board value to the board it is to be posted to
board="$(basename `dirname "$parent"`)"
# then change the parent value from adirectory path to a plain string
parent="$(basename `realpath "$parent"`)"
else # otherwise the post is a oppost
# set the board value appropriately
board="$line"
fi
;;
"name")
user="$(echo "$line" | tr -d '\r')"
;;
"title")
title="$(echo "$line" | tr -d '\r')"
;;
"content")
# carrige returns need to be removed from multiline content
content="$content$(printf "\n%s\n" "$line" | tr -d '\r')"
;;
"fileupload")
echo "read line of fileupload"
;;
esac
done < "$file"
# remove the first line from content, which is html form junk
content="$(echo "$content" | sed -e '1,2d' | tr '\n' '\a')"
image_name="$(sed -n "$file_upload_start"p $file \
| grep -oE 'filename=".*' \
| cut -f 2 -d '"' \
| tr -d '"' )"
image_content="$(sed -e "1,$(( file_upload_start + 2 ))d" "$file" | base64 -w 0)"
echo "board:$board"
echo "parent:$parent"
echo "user:$user"
echo "title:$title"
echo "content:$content"
echo "image_name:$image_name"
echo "image_content:$image_content"
echo "End new post"
rm "$file"
}
get_request() {
submission_id="$(date '+%s%N')" # unique id of the submission
printf "HTTP/1.1 200 OK\r
Date: %s\r
Server: BSD Netcat/lmao\r
Connection: close\r
Content-Type: text/html\r\n\r\n
<script>window.close();</script>\n" "$(date -Ru | sed -e 's/\+0000/GMT/')" \
| nc -lp "$port" -w 3 | head -c 1000000000 > "$inbox/$submission_id"
mv "$inbox/$submission_id" "$inbox/$submission_id.submission"
}
listen() {
while true
do
# TODO: scale to allow for posting in rapid succession
get_request
for post in $(find "$inbox" -iname "*.submission")
do
gen_post_data_from_file "$post"
done
done
}
trap break EXIT INT TERM