X-Git-Url: http://pileus.org/git/?p=vpaste;a=blobdiff_plain;f=index.cgi;h=09e5c985d394b6307e4dc22c5c8350195e3aa603;hp=4b587dc4541966806409feb004e5eecd2da9f297;hb=HEAD;hpb=8ea90e3037f45638d9edf7e9934cc1d2446016b6 diff --git a/index.cgi b/index.cgi index 4b587dc..09e5c98 100755 --- a/index.cgi +++ b/index.cgi @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (C) 2009-2012 Andy Spencer +# Copyright (C) 2009-2013 Andy Spencer # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the Free @@ -15,7 +15,8 @@ # Remove url codings from stdin function get_modeline { echo "$QUERY_STRING" | - sed -e 's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g; s/[,&?]/ /g' | + sed -e 's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' \ + -e 's/[^a-zA-Z0-9.:=_\-]/ /g' | xargs echo -e } function get_param { @@ -44,31 +45,115 @@ function cut_file { ' | head -c $((128*1024)) # Limit size to 128K } -# Print out a generic header -function header { - echo "Content-Type: $1; charset=UTF-8" +# Respond to a request +function respond { + local allow ctype heads files texts gzip h f + while [ "$1" ]; do + case $1 in + -y) allow="true"; ;; + -c) ctype="$2"; shift ;; + -h) heads=("${heads[@]}" "$2"); shift ;; + -f) files=("${files[@]}" "$2"); shift ;; + *) texts=("${texts[@]}" "$1"); ;; + esac + shift + done + + # Check if the browser supports gzip if [[ "$HTTP_ACCEPT_ENCODING" == *'gzip'* ]]; then + gzip=true + fi + + # Output header + if [ "$ctype" ]; then + echo "Content-Type: $ctype; charset=UTF-8" + else + echo "Content-Type: text/plain; charset=UTF-8" + fi + if [ "$gzip" ]; then echo "Content-Encoding: gzip" - echo + fi + if [ "$allow" ]; then + echo "Access-Control-Allow-Origin: *" + echo "Access-Control-Allow-Headers: Content-Type" + fi + for h in "${heads[@]}"; do + echo "$h" + done + echo + + # Output text messages + if [ "$texts" ]; then + if [ "$gzip" ]; then + echo "${texts[@]}" | gzip + else + echo "${texts[@]}" + fi + exit + fi + + # Output body files + if [ "$files" ]; then + for f in "${files[@]}"; do + if [[ "$gzip" && "$f" != *'.gz' ]]; then + gzip < "$f" + elif [[ ! "$gzip" && "$f" == *'.gz' ]]; then + zcat < "$f" + else + cat "$f" + fi + done + exit + fi + + # Gzip remaining stream + if [ "$gzip" ]; then exec 1> >(gzip) - else - echo fi } -# Print plain message and exit -function message { - while [ "$1" == '-h' ]; do - shift; echo "$1"; shift - done - header text/plain - echo "$*" - exit +# Format and output a file +function format { + # Create a temp file with the provided modeline + tmp="$(mktemp)" + sed -e "1ivim: $(get_modeline)" \ + -e "\$avim: $(get_modeline)" "$1" > "$tmp" + + # Determine cache name + md5="$(cat index.cgi vimrc "$tmp" /usr/bin/ex | md5sum -b)" + out="cache/${md5% *}.htm" + zip="$out.gz" + + # Cache the file, if needed + if [ ! -f "$zip" ]; then + # - I have some plugins in ~/.vim + # - Run ex in pty to trick it into thinking that it + # has a real terminal, note that we also have to set + # term=xterm-256color in vimrc + HOME=/home/andy \ + /home/vpaste/bin/pty \ + /usr/bin/ex -nXZ -i NONE -u vimrc \ + '+sil! set fde= fdt= fex= inde= inex= key= pa= pexpr=' \ + '+sil! set iconstring= ruf= stl= tal=' \ + "+sil! set titlestring=$1\ -\ vpaste.net" \ + '+sil! set noml' \ + '+sil! 1d|$d|'$2 \ + '+sil! %s/\r//g' \ + '+sil! TOhtml' \ + "+sav! $out" \ + '+qall!' \ + "$tmp" >/dev/null 2>&1 + gzip "$out" + fi + rm "$tmp" + + # Output the file + respond -y -c "text/html" -f "$zip" } # List previous pastes function do_cmd { - header text/plain + respond case "$1" in ls) ls -t db | column @@ -106,47 +191,34 @@ function do_print { input="db/$1" trim='1,/^$/d' # sed command to remove cruft else - message -h 'Status: 404 Not Found' \ + respond -h 'Status: 404 Not Found' \ "File '$1' not found" fi + # Check for javascript + if [[ "$input" == 'embed.js' && + "$HTTP_ACCEPT" != *'html'* ]]; then + respond -c text/javascript -f "$input" + fi + # Check for raw paste if [[ "$QUERY_STRING" == 'raw'* || "$REQUEST_URI" != *'?'* && ( "$input" != 'db/'* || "$HTTP_ACCEPT" != *'html'* ) ]]; then - header text/plain + respond sed "$trim" "$input" exit fi - # Create a temp file with the provided modeline - output="$(mktemp)" - tmp="$(mktemp)" - sed "\$avim: $(get_modeline)" "$input" > "$tmp" - - # - I have some plugins in ~/.vim - # - Run ex in screen to trick it into thinking that it - # has a real terminal, note that we also have to set - # term=xterm-256color in vimrc - HOME=/home/andy \ - screen -D -m ex -nXZ -i NONE -u vimrc \ - '+sil! set fde= fdt= fex= inde= inex= key= pa= pexpr=' \ - '+sil! set iconstring= ruf= stl= tal=' \ - "+sil! set titlestring=$1\ -\ vpaste.net" \ - '+sil! set noml' \ - '+sil! $d|'$trim \ - '+sil! %s/\r//g' \ - '+sil! TOhtml' \ - "+sav! $output" \ - '+qall!' \ - "$tmp" - - header text/html - cat "$output" - rm "$tmp" "$output" + # Output the file + format "$input" "$trim" } +# Format a file for viewing +function do_view { + format - +} # Upload handler function do_upload { @@ -154,9 +226,10 @@ function do_upload { spam=$(echo -n "$body" | cut_file "ignoreme") text=$(echo -n "$body" | cut_file "(text|x)") bans=$(echo -n "$REMOTE_ADDR" | grep -f blacklist) - [ ! -z "$spam" ] && message "Spam check.." - [ ! -z "$bans" ] && message "You have been banned" - [ -z "$text" ] && message "No text pasted" + + [ ! -z "$spam" ] && respond -h "Status: 403 Forbidden" "Spam check.." + [ ! -z "$bans" ] && respond -h "Status: 403 Forbidden" "You have been banned" + [ -z "$text" ] && respond "No text pasted" # Format and save message output="$(mktemp db/XXXXX)" @@ -171,7 +244,7 @@ function do_upload { # Redirect user uri="$url$(basename "$output")" - message -h 'Status: 302 Found' \ + respond -h 'Status: 302 Found' \ -h "Location: $uri" \ "$uri" } @@ -183,12 +256,15 @@ function do_help { sed -n '/^\(syntax\|manual\|synload\|2html\|colortest\|hitest\).vim$/d; s/.vim$//p' | sort | uniq ) - uploads=$(ls -t db | head -n 5) + uploads=$(ls -t db 2>/dev/null | head -n 5) filetype=$(get_param '^(ft|filet(y(pe?)?)?)$') vpaste='vpaste' - repo='https://lug.rose-hulman.edu/svn/misc/trunk/htdocs/vpaste/' + pileus='http://pileus.org/tools/vpaste' + gitweb='http://pileus.org/git/?p=vpaste' + mailman='http://pileus.org/mailman/listinfo/dev' + repo='git://pileus.org/vpaste' - header text/html + respond -c text/html cat <<-EOF @@ -199,22 +275,16 @@ function do_help { + + +