moved paste operations into paste/paste.go. Using paste.Store()

master
KatolaZ 8 years ago
parent dece484ef7
commit 8f5b41695d
  1. 4
      binnit.cfg
  2. 179
      binnit.go
  3. 59
      main.go
  4. 52
      paste/paste.go

@ -12,7 +12,7 @@ bind_addr = 127.0.0.1
bind_port=8080
## Directory where all pastes are kept
paste_dir=./pastes
paste_dir="./rubbish"
## Directory where HTML files and templates are kept
templ_dir=./html
@ -21,4 +21,4 @@ templ_dir=./html
max_size=16384
## logfile
log_file="./binnit.log"
log_file="./binnit.log"

@ -0,0 +1,179 @@
/*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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 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
* server written in golang
*
*/
package main
import (
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"time"
"io"
"binnit/paste"
)
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",
}
func min (a, b int) int {
if a > b {
return b
} else {
return a
}
}
func handle_get_paste(w http.ResponseWriter, r *http.Request) {
var paste_name, orig_name string
var err error
orig_name = filepath.Clean(r.URL.Path)
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")
} else {
// otherwise, if the requested paste exists, we serve it...
if _, err = os.Stat(paste_name); err == nil && orig_name != "./" {
//http.ServeFile(w, r, paste_name)
s, err := prepare_paste_page(&p_conf, orig_name)
if err == nil {
fmt.Fprintf(w, "%s", s)
return
} else {
fmt.Fprintf(w, "Error recovering paste '%s'\n", orig_name)
return
}
} else {
// otherwise, we give say we didn't find it
fmt.Fprintf(w, "Paste '%s' not found\n", orig_name)
return
}
}
}
func handle_put_paste(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
// Invalid POST -- let's serve the default file
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(" ID: %s; err: %s\n", ID, err)
if err == nil {
hostname := p_conf.server_name
if show := req_body.Get("show"); show != "1" {
fmt.Fprintf(w, "http://%s/%s", hostname, ID)
return
} else{
fmt.Fprintf(w, "<html><body>Link: <a href='http://%s/%s'>http://%s/%s</a></body></html>",
hostname, ID, hostname, ID)
return
}
} else {
fmt.Fprintf(w, "%s\n", err)
}
}
}
func req_handler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
handle_get_paste(w, r)
case "POST":
handle_put_paste(w, r)
default:
http.NotFound(w, r)
}
}
func main() {
parse_config("binnit.cfg", &p_conf)
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)
log.Println("Binnit version 0.1 -- Starting ")
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(" + 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))
}

@ -25,15 +25,14 @@
package main
import (
"crypto/sha256"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"time"
"io"
"binnit/paste"
)
@ -101,7 +100,6 @@ func handle_put_paste(w http.ResponseWriter, r *http.Request) {
// Invalid POST -- let's serve the default file
http.ServeFile(w, r, p_conf.templ_dir + "/index.html")
} else {
h := sha256.New()
req_body := r.PostForm
orig_IP := r.RemoteAddr
@ -110,48 +108,30 @@ func handle_put_paste(w http.ResponseWriter, r *http.Request) {
// get title, body, and time
title := req_body.Get("title")
paste := req_body.Get("paste")
now := time.Now().String()
// format content
date := time.Now().String()
content := req_body.Get("paste")
content = content[0:min(len(content), int(p_conf.max_size))]
paste = paste[0:min(len(paste), int(p_conf.max_size))]
ID, err := paste.Store(title, date, content, p_conf.paste_dir)
content := fmt.Sprintf("# Title: %s\n# Pasted: %s\n------------\n%s", title, now, paste)
// ccompute the sha256 hash using title, body, and time
h.Write([]byte(content))
paste_hash := fmt.Sprintf("%x", h.Sum(nil))
log.Printf(" `-- hash: %s\n", paste_hash)
paste_dir := p_conf.paste_dir + "/"
// Now we save the file
for i := 0; i < len(paste_hash)-16; i++ {
paste_name := paste_hash[i:i+16]
if _, err := os.Stat(paste_dir + paste_name); os.IsNotExist(err) {
// The file does not exist, so we can create it
if err := ioutil.WriteFile(paste_dir+ paste_name, []byte(content), 0644); err == nil {
// and then we return the URL:
log.Printf(" `-- saving paste to : %s", paste_dir + paste_name)
//hostname := r.Host
hostname := p_conf.server_name
if show := req_body.Get("show"); show != "1" {
fmt.Fprintf(w, "%s/%s", hostname, paste_name)
return
} else{
fmt.Fprintf(w, "<html><body>Link: <a href='http://%s/%s'>http://%s/%s</a></body></html>",
hostname, paste_hash[i:i+16], hostname, paste_hash[i:i+16])
return
}
} else {
fmt.Fprintf(w, "Cannot create the paste.. Sorry!\n")
return
}
log.Printf(" ID: %s; err: %s\n", ID, err)
if err == nil {
hostname := p_conf.server_name
if show := req_body.Get("show"); show != "1" {
fmt.Fprintf(w, "%s/%s", hostname, ID)
return
} else{
fmt.Fprintf(w, "<html><body>Link: <a href='http://%s/%s'>http://%s/%s</a></body></html>",
hostname, ID, hostname, ID)
return
}
} else {
fmt.Fprintf(w, "%s\n", err)
}
}
}
func req_handler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
@ -190,6 +170,7 @@ func main() {
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))

@ -0,0 +1,52 @@
package paste
import(
"crypto/sha256"
"fmt"
"log"
"os"
"io/ioutil"
"errors"
)
func Store(title, date, content, dest_dir string) (string, error) {
h := sha256.New()
h.Write([]byte(title))
h.Write([]byte(date))
h.Write([]byte(content))
paste := fmt.Sprintf("# Title: %s\n# Date: %s\n%s", title, date, content)
paste_hash := fmt.Sprintf("%x", h.Sum(nil))
log.Printf(" `-- hash: %s\n", paste_hash)
paste_dir := dest_dir + "/"
// Now we save the file
for i := 0; i < len(paste_hash)-16; i++ {
paste_name := paste_hash[i:i+16]
if _, err := os.Stat(paste_dir + paste_name); os.IsNotExist(err) {
// The file does not exist, so we can create it
if err := ioutil.WriteFile(paste_dir + paste_name, []byte(paste), 0644); err == nil {
// and then we return the URL:
log.Printf(" `-- saving new paste to : %s", paste_dir + paste_name)
return paste_name, nil
} else {
log.Printf("Cannot create the paste: %s!\n", paste_dir + paste_name)
}
}
}
return "", errors.New("Cannot store the paste...Sorry!")
}
//func Retrieve(URI string) (title, date, content string) {
//}
Loading…
Cancel
Save