a simple url shortener in Go (check it out at qurl.org)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
1.6 KiB

  1. package pages
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "git.binarythought.com/cdramey/qurl/obj"
  7. "net"
  8. "net/http"
  9. "time"
  10. )
  11. type apijson struct {
  12. URL string `json:"url,omitempty"`
  13. Exists bool `json:"exists,omitempty"`
  14. Error string `json:"error,omitempty"`
  15. }
  16. func (ctx *RootHandler) ServeAPI(w http.ResponseWriter, r *http.Request) {
  17. var (
  18. j apijson
  19. q *obj.QURL
  20. err error
  21. )
  22. u := r.FormValue("url")
  23. if u == "" {
  24. j.Error = "Not a valid URL."
  25. goto complete
  26. }
  27. q, err = ctx.Storage.GetQURLByURL(u)
  28. if err != nil {
  29. j.Error = err.Error()
  30. goto complete
  31. }
  32. // Deal with URLs that already exist in the database
  33. if q != nil {
  34. j.Exists = true
  35. j.URL = fmt.Sprintf("https://qurl.org/%s", obj.ToString(q.ID))
  36. goto complete
  37. }
  38. q = &obj.QURL{
  39. URL: u,
  40. Created: time.Now(),
  41. }
  42. if h, _, err := net.SplitHostPort(r.RemoteAddr); err == nil && h != "" {
  43. q.IP = net.ParseIP(h)
  44. }
  45. if b := r.Header.Get("User-Agent"); b != "" {
  46. q.Browser = b
  47. }
  48. // Check if the URL we're adding is valid
  49. err = q.CheckValid()
  50. if err != nil {
  51. j.Error = err.Error()
  52. goto complete
  53. }
  54. // Add the URL
  55. err = ctx.Storage.AddQURL(q)
  56. if err != nil {
  57. j.Error = err.Error()
  58. goto complete
  59. }
  60. j.URL = fmt.Sprintf("https://qurl.org/%s", obj.ToString(q.ID))
  61. complete:
  62. var buf bytes.Buffer
  63. encoder := json.NewEncoder(&buf)
  64. err = encoder.Encode(j)
  65. if err != nil {
  66. http.Error(w, fmt.Sprintf("JSON encoding error: %s", err.Error()),
  67. http.StatusInternalServerError)
  68. return
  69. }
  70. w.Header().Set("Content-Type", "application/json")
  71. w.Header().Set("Content-Length", fmt.Sprintf("%d", buf.Len()))
  72. w.Write(buf.Bytes())
  73. }