forked from lulivi/mattata
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mattata-https.lua
98 lines (91 loc) · 3.04 KB
/
mattata-https.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
local socket = require('socket')
local ssl = require('ssl')
local ltn12 = require('ltn12')
local http = require('socket.http')
local url = require('socket.url')
local https = {
['try'] = socket.try,
['configuration'] = {
['protocol'] = 'any',
['options'] = {
'all',
'no_sslv2',
'no_sslv3'
},
['verify'] = 'none'
}
}
function https.build_url(request)
local parsed = url.parse(request, { ['port'] = 443 })
return url.build(parsed)
end
function https.build_table(request, body, result, method)
request = {
['url'] = https.build_url(request),
['method'] = method or (body and 'POST' or 'GET'),
['sink'] = ltn12.sink.table(result)
}
if body then
request.source = ltn12.source.string(body)
request.headers = {
['Content-Length'] = #body,
['Content-Type'] = 'application/x-www-form-urlencoded'
}
end
return request
end
function https.register(connection)
for name, method in pairs(getmetatable(connection.socket).__index) do
if type(method) == 'function' then
connection[name] = function(self, ...)
return method(self.socket, ...)
end
end
end
end
function https.tcp(parameters, timeout)
parameters = type(parameters) == 'table' and parameters or {}
for k, v in pairs(https.configuration) do
parameters[k] = parameters[k] or v
end
parameters.mode = 'client'
return function()
local connection = {}
connection.socket = https.try(socket.tcp())
https.settimeout = getmetatable(connection.socket).__index.settimeout
function connection:settimeout(...)
return https.settimeout(self.socket, ...)
end
function connection:connect(host, port)
https.try(self.socket:connect(host, port))
self.socket = https.try(ssl.wrap(self.socket, parameters))
self.socket:sni(host)
if timeout and tonumber(timeout) ~= nil then
self.socket:settimeout(tonumber(timeout))
end
https.try(self.socket:dohandshake())
https.register(self, getmetatable(self.socket))
return 1
end
return connection
end
end
function https.request(request, body, timeout)
local result = {}
request = type(request) == 'string' and https.build_table(request, body, result) or https.build_url(request.url)
timeout = https.timeout or request.timeout or timeout or nil
if http.PROXY or request.proxy then
return nil, 'Proxies are not supported!'
elseif request.redirect then
return nil, 'Redirects are not supported!'
elseif request.create then
return nil, 'The create function is not supported!'
end
request.create = https.tcp(request, timeout)
local res, code, headers, status = http.request(request)
if res and type(result) == 'table' then
res = table.concat(result)
end
return res, code, headers, status
end
return https