Skip to content

Commit 1d647e4

Browse files
committed
Add https transport via luasec or ngx.socket
1 parent e691212 commit 1d647e4

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

raven.lua

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,17 @@ local table_insert = table.insert
4343
local debug = false
4444

4545
local socket
46+
local ssl
4647
local catcher_trace_level = 4
4748
if not ngx then
4849
local ok, luasocket = pcall(require, "socket")
4950
if not ok then
5051
error("No socket library found, you need ngx.socket or luasocket.")
5152
end
53+
local ok, luassl = pcall(require, "ssl")
54+
if ok then
55+
ssl = luassl
56+
end
5257
socket = luasocket
5358
else
5459
socket = ngx.socket
@@ -161,7 +166,7 @@ local function _parse_host_port(protocol, host)
161166
local i = string_find(host, ":")
162167
if not i then
163168
-- TODO
164-
return host, 80
169+
return host, nil
165170
end
166171

167172
local port_str = string_sub(host, i + 1)
@@ -193,7 +198,7 @@ local function _parse_dsn(dsn, obj)
193198

194199
local host, port, err = _parse_host_port(obj.protocol, obj.long_host)
195200

196-
if not host or not port then
201+
if not host then
197202
return nil, err
198203
end
199204

@@ -388,8 +393,10 @@ function _M.send_report(self, json, conf)
388393

389394
local json_str = json_encode(json)
390395
local ok, err
391-
if self.protocol == "http" then
392-
ok, err = self:http_send(json_str)
396+
if self.protocol == "https" then
397+
ok, err = self:http_send(json_str, true)
398+
elseif self.protocol == "http" then
399+
ok, err = self:http_send(json_str, false)
393400
else
394401
error("protocol not implemented yet: " .. self.protocol)
395402
end
@@ -521,23 +528,84 @@ function _M.http_send_core(self, json_str)
521528
return string_sub(res, s2 + 1)
522529
end
523530

531+
-- lua_wrap_tls: Enables TLS for luasocket. Requires luasec.
532+
function _M.lua_wrap_tls(self, sock)
533+
if not ssl then
534+
error("no ssl library found, please install luasec")
535+
end
536+
537+
local ok, err
538+
539+
sock, err = ssl.wrap(sock, {
540+
mode = "client",
541+
protocol = "tlsv1",
542+
verify = "peer",
543+
options = "all",
544+
})
545+
if not sock then
546+
return nil, err
547+
end
548+
549+
ok, err = sock:dohandshake()
550+
if not ok then
551+
return nil, err
552+
end
553+
554+
return sock
555+
end
556+
557+
-- ngx_wrap_tls: Enables TLS for ngx.socket
558+
function _M.ngx_wrap_tls(self, sock)
559+
local session, err = sock:sslhandshake(false, self.host, true)
560+
if not session then
561+
return nil, err
562+
end
563+
return sock
564+
end
565+
566+
-- wrap_tls: Wraps a connected socket with TLS
567+
function _M.wrap_tls(self, sock)
568+
if ngx then
569+
return self:ngx_wrap_tls(sock)
570+
end
571+
return self:lua_wrap_tls(sock)
572+
end
573+
524574
-- http_send: actually sends the structured data to the Sentry server using
525-
-- HTTP
526-
function _M.http_send(self, json_str)
575+
-- HTTP or HTTPS
576+
function _M.http_send(self, json_str, secure)
527577
local ok, err
528578
local sock
579+
local port = self.port
529580

530581
sock, err = socket.tcp()
531582
if not sock then
532583
return nil, err
533584
end
534-
self.sock = sock
535585

536-
ok, err = sock:connect(self.host, self.port)
586+
-- Rely on default port values for http and https
587+
if not port then
588+
port = secure and 443 or 80
589+
end
590+
591+
ok, err = sock:connect(self.host, port)
537592
if not ok then
538593
return nil, err
539594
end
540595

596+
if secure then
597+
-- Sprinkle on some TLS juice
598+
local tlssock, err = self:wrap_tls(sock)
599+
if not tlssock then
600+
-- Need to close the tcp connection yet before bailing
601+
sock:close()
602+
return nil, err
603+
end
604+
sock = tlssock
605+
end
606+
607+
self.sock = sock
608+
541609
ok, err = self:http_send_core(json_str)
542610

543611
sock:close()

tests/test_sanity.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function test_parse_dsn()
1414
assert_equal("public", obj.public_key)
1515
assert_equal("secret", obj.secret_key)
1616
assert_equal("example.com", obj.host)
17-
assert_equal(80, obj.port)
17+
assert_equal(nil, obj.port)
1818
assert_equal("/sentry/", obj.path)
1919
assert_equal("project-id", obj.project_id)
2020
assert_equal("/sentry/api/project-id/store/", obj.request_uri)
@@ -64,7 +64,7 @@ end
6464
function test_parse_host_port1()
6565
local host, port = raven._parse_host_port("http", "somehost.com")
6666
assert_equal("somehost.com", host)
67-
assert_equal(80, port)
67+
assert_equal(nil, port)
6868
end
6969

7070
function test_parse_host_port2()

0 commit comments

Comments
 (0)