diff options
| -rw-r--r-- | binnit.go | 79 | ||||
| -rw-r--r-- | templ.go | 34 | 
2 files changed, 53 insertions, 60 deletions
| @@ -9,51 +9,46 @@   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   *  General Public License for more details.   * - *  You should have received a copy of the GNU Affero General Public  + *  You should have received a copy of the GNU Affero General Public   *  License along with this program.  If not, see   *  <http://www.gnu.org/licenses/>.   *   *  (c) Vincenzo "KatolaZ" Nicosia 2017 -- <katolaz@freaknet.org> - *  - *  - *  This file is part of "binnit", a minimal no-fuss pastebin-like  + * + * + *  This file is part of "binnit", a minimal no-fuss pastebin-like   *  server written in golang   *   */ -  package main  import ( +	"binnit/paste" +	"flag"  	"fmt" +	"html" +	"io"  	"log"  	"net/http"  	"os"  	"path/filepath"  	"time" -	"io" -	"binnit/paste" -	"flag"  ) -  var conf_file = flag.String("c", "./binnit.cfg", "Configuration file for binnit") - -  var p_conf = Config{  	server_name: "localhost", -	bind_addr: "0.0.0.0", -	bind_port: "8000", -	paste_dir: "./pastes", -	templ_dir: "./tmpl", -	max_size: 4096, -	log_file: "./binnit.log", +	bind_addr:   "0.0.0.0", +	bind_port:   "8000", +	paste_dir:   "./pastes", +	templ_dir:   "./tmpl", +	max_size:    4096, +	log_file:    "./binnit.log",  } - - -func min (a, b int) int { +func min(a, b int) int {  	if a > b {  		return b @@ -71,16 +66,20 @@ func handle_get_paste(w http.ResponseWriter, r *http.Request) {  	paste_name = p_conf.paste_dir + "/" + orig_name  	orig_IP := r.RemoteAddr -	 +  	log.Printf("Received GET from %s for  '%s'\n", orig_IP, orig_name)  	// The default is to serve index.html  	if (orig_name == "/") || (orig_name == "/index.html") { -		http.ServeFile(w, r, p_conf.templ_dir + "/index.html") +		http.ServeFile(w, r, p_conf.templ_dir+"/index.html")  	} else {  		// otherwise, if the requested paste exists, we serve it...  		title, date, content, err := paste.Retrieve(paste_name) + +		title = html.EscapeString(title) +		date = html.EscapeString(date) +		content = html.EscapeString(content)  		if err == nil {  			s, err := prepare_paste_page(title, date, content, p_conf.templ_dir) @@ -101,34 +100,37 @@ func handle_get_paste(w http.ResponseWriter, r *http.Request) {  func handle_put_paste(w http.ResponseWriter, r *http.Request) { -	 -	if err := r.ParseForm(); err != nil { +	err1 := r.ParseForm() +	err2 := r.ParseMultipartForm(int64(2 * p_conf.max_size)) + +	if err1 != nil && err2 != nil {  		// Invalid POST -- let's serve the default file -		http.ServeFile(w, r, p_conf.templ_dir + "/index.html") +		http.ServeFile(w, r, p_conf.templ_dir+"/index.html")  	} else {  		req_body := r.PostForm  		orig_IP := r.RemoteAddr  		log.Printf("Received new POST from %s\n", orig_IP) -		 +  		// get title, body, and time  		title := req_body.Get("title")  		date := time.Now().String()  		content := req_body.Get("paste") -		 +  		content = content[0:min(len(content), int(p_conf.max_size))]  		ID, err := paste.Store(title, date, content, p_conf.paste_dir) -		 + +		log.Printf("   title: %s\npaste: %s\n", title, content)  		log.Printf("   ID: %s; err: %s\n", ID, err) -		if  err == nil { +		if err == nil {  			hostname := p_conf.server_name  			if show := req_body.Get("show"); show != "1" { -				fmt.Fprintf(w, "http://%s/%s", hostname, ID) +				fmt.Fprintf(w, "http://%s/%s\n", hostname, ID)  				return -			} else{ +			} else {  				fmt.Fprintf(w, "<html><body>Link: <a href='http://%s/%s'>http://%s/%s</a></body></html>",  					hostname, ID, hostname, ID)  				return @@ -139,7 +141,6 @@ func handle_put_paste(w http.ResponseWriter, r *http.Request) {  	}  } -  func req_handler(w http.ResponseWriter, r *http.Request) {  	switch r.Method { @@ -152,23 +153,19 @@ func req_handler(w http.ResponseWriter, r *http.Request) {  	}  } - -  func main() { -	  	flag.Parse()  	parse_config(*conf_file, &p_conf) -	 -	f, err := os.OpenFile(p_conf.log_file, os.O_APPEND | os.O_CREATE | os.O_RDWR, 0600) + +	f, err := os.OpenFile(p_conf.log_file, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0600)  	if err != nil {  		fmt.Fprintf(os.Stderr, "Error opening log_file: %s. Exiting\n", p_conf.log_file)  		os.Exit(1)  	}  	defer f.Close() -	  	log.SetOutput(io.Writer(f))  	log.SetPrefix("[binnit]: ")  	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) @@ -176,13 +173,13 @@ func main() {  	log.Println("Binnit version 0.1 -- Starting ")  	log.Printf("  + Config file: %s\n", *conf_file)  	log.Printf("  + Serving pastes on: %s\n", p_conf.server_name) -	log.Printf("  + listening on: %s:%s\n", p_conf.bind_addr, p_conf.bind_port ) +	log.Printf("  + listening on: %s:%s\n", p_conf.bind_addr, p_conf.bind_port)  	log.Printf("  + paste_dir: %s\n", p_conf.paste_dir)  	log.Printf("  + templ_dir: %s\n", p_conf.templ_dir)  	log.Printf("  + max_size: %d\n", p_conf.max_size)  	// FIXME: create paste_dir if it does not exist -	 +  	http.HandleFunc("/", req_handler) -	log.Fatal(http.ListenAndServe(p_conf.bind_addr + ":" +  p_conf.bind_port, nil)) +	log.Fatal(http.ListenAndServe(p_conf.bind_addr+":"+p_conf.bind_port, nil))  } @@ -9,19 +9,18 @@   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   *  General Public License for more details.   * - *  You should have received a copy of the GNU Affero General Public  + *  You should have received a copy of the GNU Affero General Public   *  License along with this program.  If not, see   *  <http://www.gnu.org/licenses/>.   *   *  (c) Vincenzo "KatolaZ" Nicosia 2017 -- <katolaz@freaknet.org> - *  - *  - *  This file is part of "binnit", a minimal no-fuss pastebin-like  + * + * + *  This file is part of "binnit", a minimal no-fuss pastebin-like   *  server written in golang   *   */ -  /*   *   * minimal Templating support for binnit @@ -35,29 +34,28 @@ import (  	"io/ioutil"  	"os"  	"regexp" -	"strings"  	"strconv" +	"strings"  ) -func format_rows(content string) (string) { +func format_rows(content string) string {  	var ret string  	lines := strings.Split(content, "\n")  	ret += "<table class='content'>" -	 +  	for l_num, l := range lines {  		ret += "<tr>\n" -		ret += "<td class='lineno'><pre>"+ strconv.Itoa(l_num+1) + "</pre></td>" -		ret += "<td class='line'><pre>"+ l +"</pre></td>" +		ret += "<td class='lineno'><pre>" + strconv.Itoa(l_num+1) + "</pre></td>" +		ret += "<td class='line'><pre>" + l + "</pre></td>"  		ret += "</tr>"  	}  	ret += "</table>"  	return ret  } -  func prepare_paste_page(title, date, content, templ_dir string) (string, error) {  	s := "" @@ -83,28 +81,26 @@ func prepare_paste_page(title, date, content, templ_dir string) (string, error)  	f_templ, err := os.Open(templ_file)  	defer f_templ.Close() -	  	if cont, err := ioutil.ReadFile(templ_file); err == nil {  		tmpl := string(cont) -		// ...and replace  {{CONTENT}} with the paste itself!  		re, _ := regexp.Compile("{{TITLE}}") -		tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(title))) +		tmpl = string(re.ReplaceAllLiteralString(tmpl, title))  		re, _ = regexp.Compile("{{DATE}}") -		tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(date))) +		tmpl = string(re.ReplaceAllLiteralString(tmpl, date))  		re, _ = regexp.Compile("{{CONTENT}}") -		tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(format_rows(content)))) +		tmpl = string(re.ReplaceAllLiteralString(tmpl, format_rows(content)))  		re, _ = regexp.Compile("{{RAW_CONTENT}}") -		tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(content))) +		tmpl = string(re.ReplaceAllLiteralString(tmpl, content))  		s += tmpl -		 +  	} else {  		return "", errors.New("Error opening template file")  	} -	 +  	// insert footer  	foot_file := templ_dir + "/footer.html"  	f_foot, err := os.Open(foot_file) | 
