server.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. var errorTemplate *template.Template = template.Must(template.ParseFiles("./html/error.html"))
  20. var resultTemplate *template.Template = template.Must(template.ParseFiles("./html/result.html"))
  21. func init() {
  22. toSave = make(chan string, 100)
  23. }
  24. func returnErorr(w http.ResponseWriter, err string) {
  25. w.WriteHeader(http.StatusBadRequest)
  26. errorTemplate.Execute(w, err)
  27. }
  28. func shorten(w http.ResponseWriter, r *http.Request) {
  29. link := r.URL.Query().Get("link")
  30. if link == "" {
  31. link = strings.TrimPrefix(r.URL.Path, shortenPath)
  32. }
  33. addStatus, linkID := addLink(link, toSave)
  34. if !addStatus {
  35. returnErorr(w, linkID)
  36. return
  37. }
  38. shortened := r.Host + "/" + linkID
  39. if *domain != "" {
  40. shortened = *domain + "/" + linkID
  41. }
  42. resultTemplate.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. parts := strings.Split(link, "/")
  50. linkID := parts[len(parts)-1]
  51. if linkID != "" {
  52. fullLink := getLink(linkID)
  53. if fullLink != "" {
  54. resultTemplate.Execute(w, fullLink)
  55. return
  56. }
  57. }
  58. returnErorr(w, "Not found!")
  59. }
  60. func redirectOrServe(w http.ResponseWriter, r *http.Request) {
  61. linkID := strings.TrimPrefix(r.URL.Path, "/")
  62. if linkID != "" {
  63. link := getLink(linkID)
  64. if link != "" {
  65. http.Redirect(w, r, link, http.StatusMovedPermanently)
  66. return
  67. }
  68. }
  69. http.ServeFile(w, r, indexHTML)
  70. }
  71. func main() {
  72. flag.Parse()
  73. readLinks(*file)
  74. go saveLink(*file, toSave)
  75. hostname := *host + ":" + *port
  76. http.HandleFunc(shortenPath, shorten)
  77. http.HandleFunc(decodePath, decode)
  78. http.HandleFunc("/", redirectOrServe)
  79. log.Fatal(http.ListenAndServe(hostname, nil))
  80. }