diff --git a/pastebin.go b/pastebin.go index c1314e8..aa521da 100644 --- a/pastebin.go +++ b/pastebin.go @@ -68,26 +68,26 @@ type Page struct { } // check error handling function -func check(err error) { +func Check(err error) { if err != nil { log.Println(err) } } -// generateName uses uniuri to generate a random string that isn't in the +// GenerateName uses uniuri to generate a random string that isn't in the // database -func generateName() string { +func GenerateName() string { // use uniuri to generate random string id := uniuri.NewLen(LENGTH) db, err := sql.Open("mysql", DATABASE) - check(err) + Check(err) defer db.Close() // query database if id exists and if it does call generateName again query, err := db.Query("select id from pastebin where id=?", id) if err != sql.ErrNoRows { for query.Next() { - generateName() + GenerateName() } } @@ -95,8 +95,8 @@ func generateName() string { } -// hash hashes paste into a sha1 hash -func hash(paste string) string { +// Hash hashes paste into a sha1 hash +func Hash(paste string) string { hasher := sha1.New() hasher.Write([]byte(paste)) @@ -104,9 +104,9 @@ func hash(paste string) string { return sha } -// durationFromExpiry takes the expiry in string format and returns the duration +// DurationFromExpiry takes the expiry in string format and returns the duration // that the paste will exist for -func durationFromExpiry(expiry string) time.Duration { +func DurationFromExpiry(expiry string) time.Duration { switch expiry { case "5 minutes": return time.Minute * 5 @@ -126,70 +126,70 @@ func durationFromExpiry(expiry string) time.Duration { return time.Hour * 24 * (365 * 20) } -// save function handles the saving of each paste. +// Save function handles the saving of each paste. // raw string is the raw paste input // lang string is the user specified language for syntax highlighting // title string user customized title // expiry string duration that the paste will exist for // Returns Response struct -func save(raw string, lang string, title string, expiry string) Response { +func Save(raw string, lang string, title string, expiry string) Response { db, err := sql.Open("mysql", DATABASE) - check(err) + Check(err) defer db.Close() // hash paste data and query database to see if paste exists - sha := hash(raw) + sha := Hash(raw) query, err := db.Query("select id, title, hash, data, delkey from pastebin where hash=?", sha) if err != sql.ErrNoRows { for query.Next() { var id, title, hash, paste, delkey string err := query.Scan(&id, &title, &hash, &paste, &delkey) - check(err) + Check(err) url := ADDRESS + "/p/" + id return Response{id, title, hash, url, len(paste), delkey} } } - id := generateName() + id := GenerateName() url := ADDRESS + "/p/" + id if lang != "" { url += "/" + lang } const timeFormat = "2006-01-02 15:04:05" - expiryTime := time.Now().Add(durationFromExpiry(expiry)).Format(timeFormat) + expiryTime := time.Now().Add(DurationFromExpiry(expiry)).Format(timeFormat) delKey := uniuri.NewLen(40) dataEscaped := html.EscapeString(raw) stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey, expiry) values(?,?,?,?,?,?)") - check(err) + Check(err) if title == "" { title = id } _, err = stmt.Exec(id, html.EscapeString(title), sha, dataEscaped, delKey, expiryTime) - check(err) + Check(err) return Response{id, title, sha, url, len(dataEscaped), delKey} } -// delHandler checks to see if delkey and pasteid exist in the database. +// DelHandler checks to see if delkey and pasteid exist in the database. // if both exist and are correct the paste will be removed. -func delHandler(w http.ResponseWriter, r *http.Request) { +func DelHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["pasteId"] delkey := vars["delKey"] db, err := sql.Open("mysql", DATABASE) - check(err) + Check(err) defer db.Close() stmt, err := db.Prepare("delete from pastebin where delkey=? and id=?") - check(err) + Check(err) res, err := stmt.Exec(html.EscapeString(delkey), html.EscapeString(id)) - check(err) + Check(err) _, err = res.RowsAffected() if err != sql.ErrNoRows { @@ -197,8 +197,8 @@ func delHandler(w http.ResponseWriter, r *http.Request) { } } -// saveHandler -func saveHandler(w http.ResponseWriter, r *http.Request) { +// SaveHandler Handles saving pastes and outputing responses +func SaveHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) output := vars["output"] switch r.Method { @@ -211,7 +211,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Empty paste", 500) return } - b := save(paste, lang, title, expiry) + b := Save(paste, lang, title, expiry) switch output { case "json": @@ -249,9 +249,9 @@ func saveHandler(w http.ResponseWriter, r *http.Request) { } -// highlight uses user specified input to call pygments library to highlight the +// Highlight uses user specified input to call pygments library to highlight the // paste -func highlight(s string, lang string) (string, error) { +func Highlight(s string, lang string) (string, error) { highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8") if err != nil { @@ -261,22 +261,22 @@ func highlight(s string, lang string) (string, error) { } -// getPaste takes pasteid and language +// GetPaste takes pasteid and language // queries the database and returns paste data -func getPaste(paste string, lang string) (string, string) { +func GetPaste(paste string, lang string) (string, string) { param1 := html.EscapeString(paste) db, err := sql.Open("mysql", DATABASE) - check(err) + Check(err) defer db.Close() var title, s string var expiry string err = db.QueryRow("select title, data, expiry from pastebin where id=?", param1).Scan(&title, &s, &expiry) - check(err) + Check(err) if time.Now().Format("2006-01-02 15:04:05") > expiry { stmt, err := db.Prepare("delete from pastebin where id=?") - check(err) + Check(err) _, err = stmt.Exec(param1) - check(err) + Check(err) return "Error invalid paste", "" } @@ -284,19 +284,20 @@ func getPaste(paste string, lang string) (string, string) { return "Error invalid paste", "" } if lang != "" { - high, err := highlight(s, lang) - check(err) + high, err := Highlight(s, lang) + Check(err) return high, html.UnescapeString(title) } return html.UnescapeString(s), html.UnescapeString(title) } -func pasteHandler(w http.ResponseWriter, r *http.Request) { +// PasteHandler handles the generation of paste pages with the links +func PasteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) paste := vars["pasteId"] lang := vars["lang"] - s, title := getPaste(paste, lang) + s, title := GetPaste(paste, lang) // button links link := ADDRESS + "/raw/" + paste @@ -324,11 +325,12 @@ func pasteHandler(w http.ResponseWriter, r *http.Request) { } } -func cloneHandler(w http.ResponseWriter, r *http.Request) { +// CloneHandler handles generating the clone pages +func CloneHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) paste := vars["pasteId"] - s, title := getPaste(paste, "") + s, title := GetPaste(paste, "") // Page links link := ADDRESS + "/raw/" + paste @@ -350,10 +352,12 @@ func cloneHandler(w http.ResponseWriter, r *http.Request) { } } -func downloadHandler(w http.ResponseWriter, r *http.Request) { + +// DownloadHandler forces downloads of selected pastes +func DownloadHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) paste := vars["pasteId"] - s, _ := getPaste(paste, "") + s, _ := GetPaste(paste, "") // Set header to an attachment so browser will automatically download it w.Header().Set("Content-Disposition", "attachment; filename="+paste) @@ -361,10 +365,12 @@ func downloadHandler(w http.ResponseWriter, r *http.Request) { io.WriteString(w, s) } -func rawHandler(w http.ResponseWriter, r *http.Request) { + +// RawHandler displays the pastes in text/plain format +func RawHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) paste := vars["pasteId"] - s, _ := getPaste(paste, "") + s, _ := GetPaste(paste, "") w.Header().Set("Content-Type", "text/plain; charset=UTF-8; imeanit=yes") // simply write string to browser @@ -372,7 +378,8 @@ func rawHandler(w http.ResponseWriter, r *http.Request) { } -func rootHandler(w http.ResponseWriter, r *http.Request) { +// RootHandler handles generating the root page +func RootHandler(w http.ResponseWriter, r *http.Request) { err := templates.ExecuteTemplate(w, "index.html", &Page{}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -381,15 +388,15 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { func main() { router := mux.NewRouter() - router.HandleFunc("/p/{pasteId}", pasteHandler).Methods("GET") - router.HandleFunc("/raw/{pasteId}", rawHandler).Methods("GET") - router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler).Methods("GET") - router.HandleFunc("/clone/{pasteId}", cloneHandler).Methods("GET") - router.HandleFunc("/download/{pasteId}", downloadHandler).Methods("GET") - router.HandleFunc("/p", saveHandler).Methods("POST") - router.HandleFunc("/p/{output}", saveHandler).Methods("POST") - router.HandleFunc("/p/{pasteId}/{delKey}", delHandler).Methods("DELETE") - router.HandleFunc("/", rootHandler) + router.HandleFunc("/p/{pasteId}", PasteHandler).Methods("GET") + router.HandleFunc("/raw/{pasteId}", RawHandler).Methods("GET") + router.HandleFunc("/p/{pasteId}/{lang}", PasteHandler).Methods("GET") + router.HandleFunc("/clone/{pasteId}", CloneHandler).Methods("GET") + router.HandleFunc("/download/{pasteId}", DownloadHandler).Methods("GET") + router.HandleFunc("/p", SaveHandler).Methods("POST") + router.HandleFunc("/p/{output}", SaveHandler).Methods("POST") + router.HandleFunc("/p/{pasteId}/{delKey}", DelHandler).Methods("DELETE") + router.HandleFunc("/", RootHandler) err := http.ListenAndServe(PORT, router) if err != nil { log.Fatal(err)