-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
http.lua
128 lines (121 loc) · 2.79 KB
/
http.lua
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
local http = {}
local fnutils = hs.fnutils
local knu = hs.loadSpoon("Knu")
local utils = knu.utils
-- This is a wrapperr of hs.http.urlParts() that adds a "params" table
-- and lowercases the "scheme" and "host" fields.
http.urlParts = function (url)
local uri = hs.http.urlParts(url)
if uri.scheme ~= nil then
uri.scheme = uri.scheme:lower()
end
if uri.host ~= nil then
uri.host = uri.host:lower()
end
local params = {}
if uri.queryItems ~= nil then
for _, t in ipairs(uri.queryItems) do
for k, v in pairs(t) do
params[k] = v
end
end
end
uri.params = params
return uri
end
http.shortenerHosts = {
"amzn.to",
"bit.ly",
"bl.ink",
"buff.ly",
"db.tt",
"dlvr.it",
"fb.me",
"g.co",
"gg.gg",
"goo.gl",
"ht.ly",
"ift.tt",
"is.gd",
"j.mp",
"m.me",
"ow.ly",
"rebrand.ly",
"t.co",
"t.ly",
"tiny.cc",
"tinyurl.com",
"url.ie",
"v.gd",
"wp.me",
"yhoo.it",
"zpr.io",
-- tracking links
"hubspotlinks.com",
"list-manage.com",
"r.mailjet.com",
"ct.sendgrid.net",
}
-- Unshortens the given URL. Returns the unshortened URL followed by
-- nil or an error message if it fails. Failures include too many
-- recursive redirects, HTTP errors, etc. http.shortenerHosts is a
-- table of known shortener hosts. This function does not try to
-- follow redirects of a URL with a host name that is not on this
-- list.
http.unshortenUrl = function(url)
local purl = url
local nurl = url
local count = 0
local logger = hs.logger.new("unshorten", "info")
while nurl ~= nil do
local uri = hs.http.urlParts(nurl)
if uri.scheme ~= "https" and uri.scheme ~= "http" then
return purl, "non-HTTP scheme"
elseif uri.host == nil then
return purl, "host is missing"
end
local host = uri.host:lower()
local isShortener = false
for _, domain in ipairs(http.shortenerHosts) do
if host == domain or utils.string.endsWith(host, "." .. domain) then
isShortener = true
break
end
end
if not isShortener then
return nurl, nil
end
logger.i(host)
if count >= 3 then
return nurl, "too many redirects"
end
count = count + 1
purl = nurl
local output, ok = hs.execute(
utils.shelljoin{
"curl",
"-s",
"-I",
"-o",
"/dev/null",
"-w",
"%{http_code} %header{location}",
nurl,
}
)
if not ok then
return nurl, "curl failed"
end
local status, location = table.unpack(fnutils.split(output, " ", 1))
if status >= "400" then
return nurl, "HTTP error " .. status
elseif status >= "300" and location and #location > 0 then
nurl = location
else
-- not a redirect
return nurl, nil
end
end
return purl, "invalid URL"
end
return http