Skip to content

Instantly share code, notes, and snippets.

@oberhamsi
Last active August 29, 2015 14:04
Show Gist options
  • Save oberhamsi/e092ecc838c8db70d9c4 to your computer and use it in GitHub Desktop.
Save oberhamsi/e092ecc838c8db70d9c4 to your computer and use it in GitHub Desktop.
self-hosted pastebin
#!/bin/bash
## This is vpaste.net minus most features.
##
## * Uploaded text is stored as plain-text files in ${DBFOLDER}
## * Automatic syntax highlight detection powered by highlight.js
##
## Copyright 2009-2013 Andy Spencer <[email protected]>
## Modified 2014 Simon Oberhammer <[email protected]>
DBFOLDER=/tmp
LATESTCOUNT=10
# stop script on first statement returning an error
set -e
# Extract upload file from stdinput
function cut_file {
bnd="${CONTENT_TYPE/*boundary\=/}"
awk -v "want=$1" -v "bnd=$bnd" '
BEGIN { RS="\r\n" }
# reset based on boundaries
$0 == "--"bnd"" { st=1; next; }
$0 == "--"bnd"--" { st=0; next; }
$0 == "--"bnd"--\r" { st=0; next; }
# search for wanted file
st == 1 && $0 ~ "^Content-Disposition:.* name=\""want"\"" { st=2; next; }
st == 1 && $0 == "" { st=9; next; }
# wait for newline, then start printing
st == 2 && $0 == "" { st=3; next; }
st == 3 { print $0 }
' | head -c $((128*1024)) # Limit size to 128K
}
# write file to disk and redirect to view
function do_upload {
body=$(cat -)
text=$(echo -n "$body" | cut_file "(text|x)")
echo "Content-Type:text/html; charset=UTF-8"
if [ -z "$text" ]; then
echo
echo "No text pasted."
return
fi
output=$(mktemp ${DBFOLDER}/XXXXXXX)
echo "$text" > $output
uri="$url?$(basename "$output")"
echo "Status: 302 Found"
echo "Location: $uri"
echo
echo "$uri"
}
# upload form
function do_index {
latest=`ls -t $DBFOLDER | head -n $LATESTCOUNT`
echo "Content-Type:text/html; charset=UTF-8"
echo
cat <<-EOF
<h1>CopyPaster</h1>
<form id="form" method="post" action="" enctype="multipart/form-data">
<div>
<textarea name="text" cols="80" rows="25"></textarea>
</div>
<div class="buttons">
<input type="submit" value="Paste" />
</div>
</form>
Latest uploads:
<ul>
$(for upload in ${latest[@]}; do
echo -n "<li>"
echo -n "<a href='./?$upload'>$upload</a> "
echo "</li>"
done)
</ul>
EOF
}
function do_view {
inputfile="$DBFOLDER/$1"
# security: do not break out of $DBFOLDER
inputfile=`readlink -m $inputfile`
if [ `dirname $inputfile` != "$DBFOLDER" ]; then
echo "Content-Type:text/html; charset=UTF-8"
echo
echo "Nope"
return
fi
if [ ! -f $inputfile ]; then
echo "Content-Type:text/html; charset=UTF-8"
echo
echo "File $inputfile not found"
else
input=`cat $inputfile`
# HTML escape &, < and >
input=${input//\&/&amp;}
input=${input//</&lt;}
input=${input//>/&gt;}
echo "Content-Type:text/html; charset=utf-8"
echo
echo '<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/styles/default.min.css">'
echo '<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js"></script>'
echo '<script>hljs.initHighlightingOnLoad();</script>'
echo '<pre><code>'
echo "$input"
echo "</code></pre>"
fi
}
# Main
fullurl="http://$HTTP_HOST${REQUEST_URI}"
url="http://$HTTP_HOST${REQUEST_URI/\?*}"
queryparams="${fullurl#${url}}"
filename="${queryparams#?}"
if [ "$CONTENT_TYPE" ]; then
do_upload
elif [ -n "$filename" ]; then
do_view $filename
else
do_index
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment