-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
101 lines (93 loc) · 2.95 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package main
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"log"
"math/big"
"net/url"
"regexp"
"time"
)
// Regexp object to match valid characters in an alias.
var HasValidCustomLinkChars = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString
// Function to compute the SHA256 hash of the given string.
func sha256Of(input string) []byte {
var algo = sha256.New()
algo.Write([]byte(input))
return algo.Sum(nil)
}
// Utility function to encode a long URL into a short random
// alias.
func Encode(msg string) string {
urlHashBytes := sha256Of(msg)
generatedNumber := new(big.Int).SetBytes(urlHashBytes).Uint64()
encoded := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf("%d", generatedNumber)))
return encoded[:6]
}
// Utility to check is the given string is a valid URL.
func IsUrl(str string) bool {
u, err := url.ParseRequestURI(str)
return err == nil && u.Scheme != "" && u.Host != ""
}
// Utility function to check whether the custom alias given is
// acceptable or not. By convention, it may only contain upto 32
// letters, digits, underscore and hyphen symbols.
func IsAcceptableAlias(alias string) bool {
return HasValidCustomLinkChars(alias) && len(alias) <= 32
}
func SaveUrl(longUrl string, alias string, validity int) string {
var temp urlStruct
temp.ShortURL = alias
temp.LongURL = longUrl
// Expiry date period has to be at least one day
if validity < 1 {
return "ERROR: Validity cannot be less than 1 day."
} else {
tempTime := time.Now().AddDate(0, 0, validity)
temp.ExpDate = int(tempTime.Unix()) // Get the UNIX epoch timestamp
_, error := repo.Save(&temp)
if error != nil {
log.Println(error)
return "ERROR: Failed to save url to DB."
} else {
// New entry successful
return HOST_URL + alias
}
}
}
// Utility function to handle one item from a bulk shortening request.
// Returns a urlStruct object with necessary details.
func PostUrlUtil(longUrl string, alias string, validity int) (result urlStruct) {
result.LongURL = longUrl
result.ExpDate = validity
if alias != "" {
// custom shortURL
if !IsAcceptableAlias(alias) {
result.ShortURL = "ERROR: Bad custom URL. Custom URL may only contain upto 32 letters, digits, underscore and hyphen symbols."
} else {
// Check if the given custom URL is available
pair, error := repo.FindByID(alias)
if error != nil {
log.Println(error)
result.ShortURL = "ERROR: Query Failed."
} else {
switch pair.LongURL {
case "":
// If custom url is available create a new entry with it
go SaveUrl(longUrl, alias, validity)
result.ShortURL = HOST_URL + alias
default:
// If custom url is allocated to different long url
result.ShortURL = "ERROR: Requested Custom URL is not available"
}
}
}
} else {
// If no custom url provided then create a random short url using sha256 and then save to database
alias = Encode(longUrl)
go SaveUrl(longUrl, alias, validity)
result.ShortURL = HOST_URL + alias
}
return result
}