Skip to content

Commit

Permalink
Merge pull request Kong#777 from Tieske/fix/reuseaddr
Browse files Browse the repository at this point in the history
Tests: Fix socket in use error, and move a 'missing' file
  • Loading branch information
Tieske committed Dec 7, 2015
2 parents 113dc06 + d792c16 commit 1a57aba
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .ci/setup_kong.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sudo apt-get update
sudo apt-get install wget curl tar make gcc unzip git liblua5.1-0-dev

# Installing dependencies required for Kong
sudo apt-get install sudo netcat lua5.1 openssl libpcre3 dnsmasq
sudo apt-get install sudo netcat lua5.1 openssl libpcre3 dnsmasq uuid-dev

# Installing Kong and its dependencies
sudo apt-get install lsb-release
Expand All @@ -18,4 +18,4 @@ curl -L -o $KONG_FILE https://github.com/Mashape/kong/releases/download/$KONG_VE
sudo dpkg -i $KONG_FILE

sudo luarocks remove kong --force
sudo rm -rf /etc/kong
sudo rm -rf /etc/kong
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ env:
matrix:
- LUA=lua5.1

branches:
only:
- master

before_install:
- "bash .ci/setup_kong.sh"
- "bash .ci/setup_cassandra.sh"
Expand Down
2 changes: 1 addition & 1 deletion kong-0.5.4-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ build = {

["kong.constants"] = "kong/constants.lua",

["kong.cli.utils"] = "kong/cli/utils/utils.lua",
["kong.cli.utils"] = "kong/cli/utils.lua",
["kong.cli.utils.dnsmasq"] = "kong/cli/utils/dnsmasq.lua",
["kong.cli.utils.ssl"] = "kong/cli/utils/ssl.lua",
["kong.cli.utils.signal"] = "kong/cli/utils/signal.lua",
Expand Down
19 changes: 13 additions & 6 deletions kong/cli/utils/utils.lua → kong/cli/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,19 @@ local function get_kong_config_path(args_config)
return config_path
end

-- Checks if a port is open on localhost
-- Checks if a port is available to bind a server to on localhost
-- @param `port` The port to check
-- @return `open` True if open, false otherwise
local function is_port_open(port)
local _, code = IO.os_execute("nc -w 5 -z 127.0.0.1 "..tostring(port))
return code == 0
-- @return `open` Truthy if available, falsy + error otherwise
local function is_port_bindable(port)
local server, success, err
server = require("socket").tcp()
server:setoption('reuseaddr', true)
success, err = server:bind("*", port)
if success then
success, err = server:listen()
end
server:close()
return success, err
end

return {
Expand All @@ -133,5 +140,5 @@ return {
get_kong_infos = get_kong_infos,
get_kong_config_path = get_kong_config_path,
get_luarocks_install_dir = get_luarocks_install_dir,
is_port_open = is_port_open
is_port_bindable = is_port_bindable
}
4 changes: 2 additions & 2 deletions kong/cli/utils/signal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ function _M.prepare_kong(args_config, signal)
end

local function check_port(port)
if cutils.is_port_open(port) then
cutils.logger:error_exit("Port "..tostring(port).." is already being used by another process.")
if not cutils.is_port_bindable(port) then
cutils.logger:error_exit("Port "..tostring(port).." is being blocked by another process.")
end
end

Expand Down
21 changes: 16 additions & 5 deletions spec/spec_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,22 @@ function _M.find_port(exclude)
return tonumber(result)
end

-- Starts a TCP server
-- Starts a TCP server, accepting a single connection and then closes
-- @param `port` The port where the server will be listening to
-- @return `thread` A thread object
function _M.start_tcp_server(port, ...)
local thread = Threads.new({
function(port)
local socket = require "socket"
local server = assert(socket.bind("*", port))
local server = assert(socket.tcp())
assert(server:setoption('reuseaddr', true))
assert(server:bind("*", port))
assert(server:listen())
local client = server:accept()
local line, err = client:receive()
if not err then client:send(line .. "\n") end
client:close()
server:close()
return line
end;
}, port)
Expand All @@ -130,14 +134,17 @@ function _M.start_tcp_server(port, ...)
end


-- Starts a HTTP server
-- Starts a HTTP server, accepting a single connection and then closes
-- @param `port` The port where the server will be listening to
-- @return `thread` A thread object
function _M.start_http_server(port, ...)
local thread = Threads.new({
function(port)
local socket = require "socket"
local server = assert(socket.bind("*", port))
local server = assert(socket.tcp())
assert(server:setoption('reuseaddr', true))
assert(server:bind("*", port))
assert(server:listen())
local client = server:accept()

local lines = {}
Expand All @@ -156,28 +163,32 @@ function _M.start_http_server(port, ...)
end

if err then
server:close()
error(err)
end

client:send("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n")
client:close()
server:close()
return lines
end;
}, port)

return thread:start(...)
end

-- Starts a UDP server
-- Starts a UDP server, accepting a single connection and then closes
-- @param `port` The port where the server will be listening to
-- @return `thread` A thread object
function _M.start_udp_server(port, ...)
local thread = Threads.new({
function(port)
local socket = require("socket")
local udp = socket.udp()
udp:setoption('reuseaddr', true)
udp:setsockname("*", port)
local data = udp:receivefrom()
udp:close()
return data
end;
}, port)
Expand Down
30 changes: 24 additions & 6 deletions spec/unit/cli/utils_spec.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
local cutils = require "kong.cli.utils"
local spec_helper = require "spec.spec_helpers"
local socket = require "socket"

describe("CLI Utils", function()
it("should check if a port is open", function()
pending("should check if a port is open", function()
local PORT = 30000
assert.falsy(cutils.is_port_open(PORT))
spec_helper.start_tcp_server(PORT, true, true)
os.execute("sleep 0") -- Wait for the server to start
assert.truthy(cutils.is_port_open(PORT))
local server, success, err

-- Check a currently closed port
assert.truthy(cutils.is_port_bindable(PORT))

-- Check an open port, with SO_REUSEADDR set
server = socket.tcp()
assert(server:setoption('reuseaddr', true))
assert(server:bind("*", PORT))
assert(server:listen())
success, err = cutils.is_port_bindable(PORT)
server:close()
assert.truthy(success, err)

-- Check an open port, without SO_REUSEADDR set
server = socket.tcp()
assert(server:bind("*", PORT))
assert(server:listen())
success, err = cutils.is_port_bindable(PORT)
server:close()
assert.falsy(success, err)

end)
end)

0 comments on commit 1a57aba

Please sign in to comment.