server.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package main
  2. import (
  3. "flag"
  4. "html/template"
  5. "log"
  6. "net/http"
  7. "strings"
  8. )
  9. const (
  10. shortenPath = "/s/"
  11. decodePath = "/d/"
  12. indexHTML = "./html/index.html"
  13. )
  14. var host = flag.String("h", "localhost", "Host on which to serve")
  15. var port = flag.String("p", "9090", "Port on which to serve")
  16. var file = flag.String("f", "links.txt", "File to which save links")
  17. var domain = flag.String("d", "", "Domain of shorty, preferably add schema")
  18. var toSave chan string
  19. func init() {
  20. toSave = make(chan string, 100)
  21. }
  22. func returnErorr(w http.ResponseWriter, err string) {
  23. w.WriteHeader(http.StatusBadRequest)
  24. t := template.Must(template.ParseFiles("./html/error.html"))
  25. t.Execute(w, err)
  26. }
  27. func shorten(w http.ResponseWriter, r *http.Request) {
  28. link := r.URL.Query().Get("link")
  29. if link == "" {
  30. link = strings.TrimPrefix(r.URL.Path, shortenPath)
  31. }
  32. addStatus, linkID := addLink(link, toSave)
  33. if !addStatus {
  34. returnErorr(w, linkID)
  35. return
  36. }
  37. t := template.Must(template.ParseFiles("./html/result.html"))
  38. shortened := r.Host + "/" + linkID
  39. if *domain != "" {
  40. shortened = *domain + "/" + linkID
  41. }
  42. t.Execute(w, shortened)
  43. }
  44. func decode(w http.ResponseWriter, r *http.Request) {
  45. link := r.URL.Query().Get("link")
  46. if link == "" {
  47. link = strings.TrimPrefix(r.URL.Path, shortenPath)
  48. }
  49. t := template.Must(template.ParseFiles("./html/result.html"))
  50. parts := strings.Split(link, "/")
  51. linkID := parts[len(parts)-1]
  52. if linkID != "" {
  53. fullLink := getLink(linkID)
  54. if fullLink != "" {
  55. t.Execute(w, fullLink)
  56. return
  57. }
  58. }
  59. t.Execute(w, "Not found!")
  60. }
  61. func redirectOrServe(w http.ResponseWriter, r *http.Request) {
  62. linkID := strings.TrimPrefix(r.URL.Path, "/")
  63. if linkID != "" {
  64. link := getLink(linkID)
  65. if link != "" {
  66. http.Redirect(w, r, link, http.StatusMovedPermanently)
  67. return
  68. }
  69. }
  70. http.ServeFile(w, r, indexHTML)
  71. }
  72. func main() {
  73. flag.Parse()
  74. readLinks(*file)
  75. go saveLink(*file, toSave)
  76. hostname := *host + ":" + *port
  77. http.HandleFunc(shortenPath, shorten)
  78. http.HandleFunc(decodePath, decode)
  79. http.HandleFunc("/", redirectOrServe)
  80. log.Fatal(http.ListenAndServe(hostname, nil))
  81. }