diff options
-rw-r--r-- | binit.cfg | 8 | ||||
-rw-r--r-- | config.go | 83 | ||||
-rw-r--r-- | main.go | 117 |
3 files changed, 172 insertions, 36 deletions
diff --git a/binit.cfg b/binit.cfg new file mode 100644 index 0000000..df17e2d --- /dev/null +++ b/binit.cfg @@ -0,0 +1,8 @@ +## +## These are comments +## + +host=localhost +port=8080 +paste_dir=./pastes +templ_dir=./html diff --git a/config.go b/config.go new file mode 100644 index 0000000..729815f --- /dev/null +++ b/config.go @@ -0,0 +1,83 @@ +package main + + +import ( + "fmt" + "os" + "bufio" + "regexp" + "strings" + "log" +) + + +type Config struct { + host string + port string + paste_dir string + templ_dir string + log_fname string + logger *log.Logger +} + + +func (c Config) String() string { + + var s string + + s+= "Host: " + c.host + "\n" + s+= "Port: " + c.port + "\n" + s+= "paste_dir: " + c.paste_dir + "\n" + s+= "templ_dir: " + c.templ_dir + "\n" + + return s + +} + +func parse_config (fname string, c *Config) error { + + + f, err := os.Open(fname); + if err != nil { + return err + } + + r := bufio.NewScanner(f) + + line := 0 + for r.Scan (){ + s := r.Text() + line += 1 + if matched, _ := regexp.MatchString("^([ \t]*)$", s); matched != true { + // it's not a blank line + if matched, _ := regexp.MatchString("^#", s); matched != true { + // This is not a comment... + if matched, _ := regexp.MatchString("^([a-z_]+)=.*", s); matched == true { + // and contains an assignment + fields := strings.Split(s, "=") + switch fields[0]{ + case "host": + c.host = fields[1] + case "port": + c.port = fields[1] + case "paste_dir": + c.paste_dir = fields[1] + case "templ_dir": + c.templ_dir = fields[1] + case "log_fname": + c.log_fname = fields[1] + default: + fmt.Fprintf(os.Stderr, "Error reading config file %s at line %d: unknown variable '%s'\n", + fname, line, fields[0]) + } + } else { + fmt.Fprintf(os.Stderr, "Error reading config file %s at line %d: unknown statement '%s'\n", + fname, line, s) + } + } + } + } + return nil +} + + @@ -1,88 +1,111 @@ package main import ( - "fmt" - "net/http" "crypto/sha256" + "fmt" + "io/ioutil" "log" - "path/filepath" + "net/http" "os" + "path/filepath" "time" - "io/ioutil" + "io" ) -func handle_get_paste(w http.ResponseWriter, r *http.Request){ - +var p_conf = Config{ + host: "localhost", + port: "8000", + paste_dir: "./pastes", + templ_dir: "./tmpl", + log_fname: "./binit.log", +} + + + + +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 = "./pastes/" + orig_name + paste_name = p_conf.paste_dir + "/" + orig_name - fmt.Printf("orig_name: '%s'\npaste_name: '%s'\n", orig_name, paste_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, "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) - } else { - // otherwise, we give say we didn't find it + } 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) { - -func handle_put_paste(w http.ResponseWriter, r *http.Request){ - - - fmt.Printf("We are inside handle_put_paste\n"); - if err := r.ParseForm(); err != nil{ + if err := r.ParseForm(); err != nil { // Invalid POST -- let's serve the default file - http.ServeFile(w, r, "index.html") + http.ServeFile(w, r, p_conf.templ_dir + "/index.html") } else { h := sha256.New() 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") paste := req_body.Get("paste") now := time.Now().String() - // format content + // format content 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)) + h.Write([]byte(content)) paste_hash := fmt.Sprintf("%x", h.Sum(nil)) - fmt.Printf("hash: %s fname: %s\n", paste_hash, paste_hash[:16]) - paste_dir := "./pastes/" - - // Now we save the file - for i := 0; i < len(paste_hash) - 16; i ++ { + log.Printf(" `-- hash: %s\n", paste_hash) + paste_dir := p_conf.paste_dir + "/" - if _, err := os.Stat(paste_dir + paste_hash[i:i+16]); os.IsNotExist(err) { + // 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_hash[i:i+16], []byte (content), 0644); err == nil{ + if err := ioutil.WriteFile(paste_dir+ paste_name, []byte(content), 0644); err == nil { // and then we return the URL: - fmt.Fprintf(w, "<html><body>Link: <a href='%s'>%s</a></body></html>", - paste_hash[i:i+16], paste_hash[i:i+16]) - return + log.Printf(" `-- saving paste to : %s", paste_dir + paste_name) + hostname := r.Host + if show := req_body.Get("show"); show != "" { + fmt.Fprintf(w, "%s/%s", hostname, paste_name) + return + } else{ + fmt.Fprintf(w, "<html><body>Link: <a href='%s'>%s</a></body></html>", + paste_hash[i:i+16], paste_hash[i:i+16]) + return + } } else { - fmt.Fprintf(w, "Cannot create the paste!!!\n") + fmt.Fprintf(w, "Cannot create the paste.. Sorry!\n") + return } } } } } -func req_handler(w http.ResponseWriter, r *http.Request){ +func req_handler(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": @@ -94,7 +117,29 @@ func req_handler(w http.ResponseWriter, r *http.Request){ } } -func main(){ +func main() { + + + + parse_config("binit.cfg", &p_conf) + + + f, err := os.OpenFile(p_conf.log_fname, os.O_APPEND | os.O_CREATE | os.O_RDWR, 0600) + if err != nil { + fmt.Fprintf(os.Stderr, "Error opening logfile: %s. Exiting\n", p_conf.log_fname) + os.Exit(1) + } + + log.SetOutput(io.Writer(f)) + log.SetPrefix("[binit]: ") + log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) + + log.Println("Binit version 0.1 -- Starting ") + log.Printf(" + listening on: %s:%s\n", p_conf.host, p_conf.port ) + log.Printf(" + paste_dir: %s\n", p_conf.paste_dir) + log.Printf(" + templ_dir: %s\n", p_conf.templ_dir) + + http.HandleFunc("/", req_handler) - log.Fatal(http.ListenAndServe("localhost:8000", nil)) + log.Fatal(http.ListenAndServe(p_conf.host + ":" + p_conf.port, nil)) } |