Skip to content

Commit 6396592

Browse files
committed
http/util: Add is_ip() function
1 parent e600a28 commit 6396592

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

doc/modules/http.util.md

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ Returns a boolean indicating if the passed string `method` is a "safe" method.
5151
See [RFC 7231 section 4.2.1](https://tools.ietf.org/html/rfc7231#section-4.2.1) for more information.
5252

5353

54+
### `is_ip(str)` <!-- --> {#http.util.is_ip}
55+
56+
Returns a boolean indicating if the passed string `str` is a valid IP.
57+
58+
5459
### `scheme_to_port` <!-- --> {#http.util.scheme_to_port}
5560

5661
Map from schemes (as strings) to default ports (as integers).

http/client.lua

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local ca = require "cqueues.auxlib"
22
local cs = require "cqueues.socket"
33
local http_tls = require "http.tls"
4+
local http_util = require "http.util"
45
local connection_common = require "http.connection_common"
56
local onerror = connection_common.onerror
67
local new_h1_connection = require "http.h1_connection".new
@@ -9,11 +10,6 @@ local openssl_ssl = require "openssl.ssl"
910
local openssl_ctx = require "openssl.ssl.context"
1011
local openssl_verify_param = require "openssl.x509.verify_param"
1112

12-
local EOF = require "lpeg".P(-1)
13-
local IPv4address = require "lpeg_patterns.IPv4".IPv4address
14-
local IPv6addrz = require "lpeg_patterns.IPv6".IPv6addrz
15-
local IPaddress = (IPv4address + IPv6addrz) * EOF
16-
1713
-- Create a shared 'default' TLS context
1814
local default_ctx = http_tls.new_client_context()
1915

@@ -24,7 +20,7 @@ local function negotiate(s, options, timeout)
2420
if tls then
2521
local ctx = options.ctx or default_ctx
2622
local ssl = openssl_ssl.new(ctx)
27-
local ip = options.host and IPaddress:match(options.host)
23+
local ip = options.host and http_util.is_ip(options.host)
2824
if options.sendname ~= nil then
2925
if options.sendname then -- false indicates no sendname wanted
3026
ssl:setHostName(options.sendname)

http/util.lua

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
local lpeg = require "lpeg"
22
local http_patts = require "lpeg_patterns.http"
3+
local IPv4_patts = require "lpeg_patterns.IPv4"
4+
local IPv6_patts = require "lpeg_patterns.IPv6"
5+
6+
local EOF = lpeg.P(-1)
37

48
-- Encodes a character as a percent encoded string
59
local function char_to_pchar(c)
@@ -138,6 +142,11 @@ local function is_safe_method(method)
138142
return safe_methods[method] or false
139143
end
140144

145+
local IPaddress = (IPv4_patts.IPv4address + IPv6_patts.IPv6addrz) * EOF
146+
local function is_ip(str)
147+
return IPaddress:match(str) ~= nil
148+
end
149+
141150
local scheme_to_port = {
142151
http = 80;
143152
ws = 80;
@@ -193,7 +202,6 @@ end
193202
-- This pattern checks if it's argument is a valid token, if so, it returns it as is.
194203
-- Otherwise, it returns it as a quoted string (with any special characters escaped)
195204
local maybe_quote do
196-
local EOF = lpeg.P(-1)
197205
local patt = http_patts.token * EOF
198206
+ lpeg.Cs(lpeg.Cc'"' * ((lpeg.S"\\\"") / "\\%0" + http_patts.qdtext)^0 * lpeg.Cc'"') * EOF
199207
maybe_quote = function (s)
@@ -254,6 +262,7 @@ return {
254262
dict_to_query = dict_to_query;
255263
resolve_relative_path = resolve_relative_path;
256264
is_safe_method = is_safe_method;
265+
is_ip = is_ip;
257266
scheme_to_port = scheme_to_port;
258267
split_authority = split_authority;
259268
to_authority = to_authority;

spec/util_spec.lua

+11
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ describe("http.util module", function()
6464
assert.same(false, util.is_safe_method "POST")
6565
assert.same(false, util.is_safe_method "PUT")
6666
end)
67+
it("is_ip works", function()
68+
assert.same(true, util.is_ip "127.0.0.1")
69+
assert.same(true, util.is_ip "192.168.1.1")
70+
assert.same(true, util.is_ip "::")
71+
assert.same(true, util.is_ip "::1")
72+
assert.same(true, util.is_ip "2001:0db8:85a3:0042:1000:8a2e:0370:7334")
73+
assert.same(true, util.is_ip "::FFFF:204.152.189.116")
74+
assert.same(false, util.is_ip "not an ip")
75+
assert.same(false, util.is_ip "0x80")
76+
assert.same(false, util.is_ip "::FFFF:0.0.0")
77+
end)
6778
it("split_authority works", function()
6879
assert.same({"example.com", 80}, {util.split_authority("example.com", "http")})
6980
assert.same({"example.com", 8000}, {util.split_authority("example.com:8000", "http")})

0 commit comments

Comments
 (0)