a simple url shortening service, in the same vein as bit.ly and tinyurl.com, written in Go and using BoltDB as a backend
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.

90 lines
1.5KB

  1. package obj
  2. import (
  3. "fmt"
  4. "net/url"
  5. "strings"
  6. "time"
  7. )
  8. type QURL struct {
  9. ID uint64
  10. URL string
  11. Created time.Time
  12. IP []byte
  13. Browser string
  14. }
  15. func (q *QURL) CheckValid() error {
  16. if q == nil {
  17. return fmt.Errorf("QURL is nil")
  18. }
  19. if q.URL == "" {
  20. return fmt.Errorf("URL may not be empty")
  21. }
  22. u, err := url.Parse(q.URL)
  23. if err != nil {
  24. return err
  25. }
  26. if u.Scheme == "" {
  27. return fmt.Errorf("URLs must begin with a scheme (e.g. https:)")
  28. }
  29. if u.Host == "" && u.RawQuery == "" && u.RawPath == "" && u.Fragment == "" {
  30. return fmt.Errorf("URLs must contain a path, host, query or fragment element")
  31. }
  32. if !u.IsAbs() {
  33. return fmt.Errorf("Relative URLs are not allowed")
  34. }
  35. return nil
  36. }
  37. const alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  38. const alphalen = uint64(len(alpha))
  39. func ToString(v uint64) string {
  40. var r strings.Builder
  41. var i uint64
  42. for i = v; i >= alphalen; i = (i / alphalen) - 1 {
  43. r.WriteByte(alpha[i%alphalen])
  44. }
  45. r.WriteByte(alpha[i])
  46. return r.String()
  47. }
  48. func FromString(s string) (uint64, error) {
  49. var r uint64
  50. vlen := uint64(len(s))
  51. for i := uint64(0); i < vlen; i++ {
  52. x := strings.IndexByte(alpha, s[i])
  53. if x == -1 {
  54. return 0, fmt.Errorf("Invalid character [%s]", s[i])
  55. }
  56. if i == 0 {
  57. r += uint64(x)
  58. } else {
  59. r += (uint64(x+1) * pow(alphalen, i))
  60. }
  61. }
  62. return r, nil
  63. }
  64. func pow(a, b uint64) uint64 {
  65. p := uint64(1)
  66. for b > 0 {
  67. if b&1 != 0 {
  68. p *= a
  69. }
  70. b >>= 1
  71. a *= a
  72. }
  73. return p
  74. }