diff --git a/spec/configuration_spec.lua b/spec/configuration_spec.lua index 9dd3dba35..387d4de2c 100644 --- a/spec/configuration_spec.lua +++ b/spec/configuration_spec.lua @@ -70,4 +70,22 @@ describe('Configuration object', function() assert.same(nil, configuration.decode('')) end) end) + + describe('.url', function() + it('works with port', function() + assert.same({'https', false, false, 'example.com', '8443'}, configuration.url('https://example.com:8443')) + end) + + it('works with user', function() + assert.same({'https', 'user', false, 'example.com', false }, configuration.url('https://user@example.com')) + end) + + it('works with user and password', function() + assert.same({'https', 'user', 'password', 'example.com', false }, configuration.url('https://user:password@example.com')) + end) + + it('works with port and path', function() + assert.same({'http', false, false, 'example.com', '8080', '/path'}, configuration.url('http://example.com:8080/path')) + end) + end) end) diff --git a/src/configuration.lua b/src/configuration.lua index af9b59040..0842da57d 100644 --- a/src/configuration.lua +++ b/src/configuration.lua @@ -235,8 +235,10 @@ function _M.download(endpoint) return nil, err end - local scheme, user, pass, host, path = unpack(url) - local url = table.concat({ scheme, '://', host, path }, '') + local scheme, user, pass, host, port, path = unpack(url) + if port then host = table.concat({host, port}, ':') end + + local url = table.concat({ scheme, '://', host, path or '/admin/api/nginx/spec.json' }, '') local http = require "resty.http" local httpc = http.new() @@ -278,20 +280,20 @@ function _M.url(endpoint) return nil, 'missing endpoint' end - local match = ngx.re.match(endpoint, "^(https?):\\/\\/(?:(.+)@)?([^\\/\\s]+)(\\/.+)?$") + local match = ngx.re.match(endpoint, "^(https?):\\/\\/(?:(.+)@)?([^\\/\\s]+?)(?::(\\d+))?(\\/.+)?$") if not match then return nil, 'invalid endpoint' -- TODO: maybe improve the error message? end - local scheme, userinfo, host, path = unpack(match) + local scheme, userinfo, host, port, path = unpack(match) if path == '/' then path = nil end - local match = ngx.re.match(tostring(userinfo), "^([^:\\s]+)?(?::(.*))?$") - local user, pass = unpack(match) + local match = userinfo and ngx.re.match(tostring(userinfo), "^([^:\\s]+)?(?::(.*))?$") + local user, pass = unpack(match or {}) - return { scheme, user or nil, pass or nil, host, path or '/admin/api/nginx/spec.json' } + return { scheme, user or false, pass or false, host, port or false, path or nil } end @@ -302,9 +304,11 @@ function _M.curl(endpoint) return nil, err end - local scheme, user, pass, host, path = unpack(url) + local scheme, user, pass, host, port, path = unpack(url) + + if port then host = table.concat({host, port}, ':') end - local url = table.concat({ scheme, '://', table.concat({user or '', pass or ''}, ':'), '@', host, path }, '') + local url = table.concat({ scheme, '://', table.concat({user or '', pass or ''}, ':'), '@', host, path or '/admin/api/nginx/spec.json' }, '') local config, exit, code = util.system('curl --silent --show-error --fail --max-time 3 ' .. url) diff --git a/t/003-apicast.t b/t/003-apicast.t index d8a29315b..8860182d5 100644 --- a/t/003-apicast.t +++ b/t/003-apicast.t @@ -145,7 +145,7 @@ It asks backend and then forwards the request to the api. } location /api-backend/ { - echo 'yay, api backend: $host'; + echo 'yay, api backend: $http_host'; } --- request GET /?user_key=value