post_target.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package ui
  2. //go:generate gotext -srclang=en update -out=catalog.go -lang=fr,en
  3. import (
  4. "fmt"
  5. "io"
  6. "log"
  7. "net/http"
  8. "strings"
  9. "code.osinet.fr/fgm/kurz/domain"
  10. "code.osinet.fr/fgm/kurz/web/i18n"
  11. "github.com/gorilla/mux"
  12. "github.com/gorilla/sessions"
  13. _ "golang.org/x/text/message"
  14. )
  15. // handlePostTarget handles form POST requests to /
  16. func handlePostTarget(w http.ResponseWriter, r *http.Request, router *mux.Router) {
  17. var sess *sessions.Session
  18. sess, storeErr := store.Get(r, globals.SessionName)
  19. if storeErr != nil {
  20. log.Fatal()
  21. w.WriteHeader(http.StatusInternalServerError)
  22. return
  23. }
  24. r.ParseForm()
  25. defer r.Body.Close()
  26. p := i18n.Printer(r)
  27. rawTarget := r.PostForm.Get(rootInputName)
  28. target, err := validateTarget(rawTarget)
  29. if err != nil {
  30. sess.AddFlash(p.Sprintf(err.Error()))
  31. sess.Save(r, w)
  32. location, err := URLFromRoute(router, RouteGetRoot, nil)
  33. if err != nil {
  34. w.WriteHeader(http.StatusInternalServerError)
  35. return
  36. }
  37. w.Header().Set("Location", location)
  38. w.WriteHeader(http.StatusSeeOther)
  39. return
  40. }
  41. short, isNew, err := domain.GetShortURL(target)
  42. if err != nil {
  43. w.WriteHeader(http.StatusInternalServerError)
  44. return
  45. }
  46. fqsu, err := URLFromRoute(router, RouteGetShort, map[string]string{"short": short})
  47. if err != nil {
  48. w.WriteHeader(http.StatusInternalServerError)
  49. return
  50. }
  51. sw := &strings.Builder{}
  52. var templateName string
  53. if isNew {
  54. templateName = "201"
  55. } else {
  56. templateName = "409"
  57. }
  58. defer sess.Save(r, w)
  59. data := struct {
  60. Flashes []interface{}
  61. FullyQualifiedShortURL string
  62. FullyQualifiedTargetURL string
  63. Globals
  64. }{
  65. sess.Flashes(),
  66. fqsu,
  67. target,
  68. globals,
  69. }
  70. err = tmpl.ExecuteTemplate(sw, templateName, data)
  71. if err != nil {
  72. fmt.Println(err)
  73. w.WriteHeader(http.StatusInternalServerError)
  74. return
  75. }
  76. if isNew {
  77. w.WriteHeader(http.StatusCreated)
  78. } else {
  79. w.WriteHeader(http.StatusConflict)
  80. }
  81. io.Copy(w, strings.NewReader(sw.String()))
  82. }
  83. func validateTarget(raw string) (string, error) {
  84. if raw == "" {
  85. return "", domain.MakeError(domain.TargetInvalidError, "empty target")
  86. }
  87. // BUG(fgm): needs much more validation, starting with XSS.
  88. return raw, nil
  89. }