10 Commits

9 changed files with 119 additions and 93 deletions

View File

@ -13,7 +13,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
luaVersion: [ "5.4", "5.3", "5.2", "5.1", "luajit", "luajit-openresty" ] luaVersion: [ "5.4", "5.3", "5.2", "5.1", "luajit", "luajit-openresty" ]
platform: [ "ubuntu-22.04", "macos-11", "windows-2022" ] platform: [ "ubuntu-22.04", "macos-14", "windows-2022" ]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- name: Checkout - name: Checkout
@ -22,11 +22,13 @@ jobs:
if: ${{ startsWith(matrix.platform, 'windows') && !startsWith(matrix.luaVersion, 'luajit') }} if: ${{ startsWith(matrix.platform, 'windows') && !startsWith(matrix.luaVersion, 'luajit') }}
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
- name: Setup lua - name: Setup lua
uses: leso-kn/gh-actions-lua@v11-staging uses: luarocks/gh-actions-lua@v10
with: with:
luaVersion: ${{ matrix.luaVersion }} luaVersion: ${{ matrix.luaVersion }}
buildCache: false
- name: Setup luarocks - name: Setup luarocks
uses: hishamhm/gh-actions-luarocks@master # master branch until tagged release has luajit & msvcrt fixes
uses: luarocks/gh-actions-luarocks@master
- name: Make and install - name: Make and install
run: | run: |
luarocks make -- luasocket-scm-3.rockspec luarocks make -- luasocket-scm-3.rockspec

View File

@ -37,70 +37,30 @@ Installation">
<!-- installation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <!-- installation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h2>Installation</h2> <h2>Installation via luarocks</h2>
<p> Here we describe the standard distribution. If the
standard doesn't meet your needs, we refer you to the Lua
discussion list, where any question about the package scheme
will likely already have been answered. </p>
<h3>Directory structure</h3>
<p> On Unix systems, the standard distribution uses two base <p>LuaSocket can be easily installed using <a href="https://luarocks.org/" target="_blank">LuaRocks</a>, the Lua package manager.</p>
directories, one for system dependent files, and another for system
independent files. Let's call these directories <tt>&lt;CDIR&gt;</tt>
and <tt>&lt;LDIR&gt;</tt>, respectively.
For example, in my laptp, Lua&nbsp;5.1 is configured to
use '<tt>/usr/local/lib/lua/5.1</tt>' for
<tt>&lt;CDIR&gt;</tt> and '<tt>/usr/local/share/lua/5.1</tt>' for
<tt>&lt;LDIR&gt;</tt>. On Windows, <tt>&lt;CDIR&gt;</tt>
usually points to the directory where the Lua executable is
found, and <tt>&lt;LDIR&gt;</tt> points to a
<tt>lua/</tt> directory inside <tt>&lt;CDIR&gt;</tt>. (These
settings can be overridden by environment variables
<tt>LUA_PATH</tt> and <tt>LUA_CPATH</tt>. See the Lua
documentation for details.) Here is the standard LuaSocket
distribution directory structure:</p>
<h3>Installing via LuaRocks</h3>
<p>Run the following command in your terminal:</p>
<pre class=example> <pre class=example>
&lt;LDIR&gt;/ltn12.lua luarocks install luasocket
&lt;LDIR&gt;/socket.lua
&lt;CDIR&gt;/socket/core.dll
&lt;LDIR&gt;/socket/http.lua
&lt;LDIR&gt;/socket/tp.lua
&lt;LDIR&gt;/socket/ftp.lua
&lt;LDIR&gt;/socket/smtp.lua
&lt;LDIR&gt;/socket/url.lua
&lt;LDIR&gt;/mime.lua
&lt;CDIR&gt;/mime/core.dll
</pre> </pre>
<p> Naturally, on Unix systems, <tt>core.dll</tt> <h3>Verification</h3>
would be replaced by <tt>core.so</tt>. <p>To verify that LuaSocket is installed correctly, open Lua and run:</p>
</p> <pre class=example><code>
local socket = require("socket")
print(socket._VERSION)
</code></pre>
<h3>Using LuaSocket</h3> <p>If you see output like <strong>LuaSocket 3.0</strong>, the installation was successful.</p>
<p> With the above setup, and an interpreter with shared library support, <h3>More Information</h3>
it should be easy to use LuaSocket. Just fire the interpreter and use the <p>For more details, visit the <a href="https://github.com/lunarmodules/luasocket" target="_blank">LuaSocket GitHub repository</a>.</p>
<tt>require</tt> function to gain access to whatever module you need:</p>
<pre class=example>
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
&gt; socket = require("socket")
&gt; print(socket._VERSION)
--&gt; LuaSocket 3.1.0
</pre>
<p> Each module loads their dependencies automatically, so you only need to
load the modules you directly depend upon: </p>
<pre class=example>
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
&gt; http = require("socket.http")
&gt; print(http.request("http://www.impa.br/~diego/software/luasocket"))
--&gt; homepage gets dumped to terminal
</pre>
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

View File

@ -149,8 +149,8 @@ wild-card address).
<!-- gettimeout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <!-- gettimeout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class="name" id="gettimeout"> <p class="name" id="gettimeout">
connected:<b>settimeout(</b>value<b>)</b><br> connected:<b>gettimeout()</b><br>
unconnected:<b>settimeout(</b>value<b>)</b> unconnected:<b>gettimeout()</b>
</p> </p>
<p class="description"> <p class="description">

View File

@ -60,7 +60,7 @@ An URL is defined by the following grammar:
<blockquote> <blockquote>
<tt> <tt>
&lt;url&gt; ::= [&lt;scheme&gt;:][//&lt;authority&gt;][/&lt;path&gt;][?&lt;query&gt;][#&lt;fragment&gt;]<br> &lt;url&gt; ::= [&lt;scheme&gt;:][//&lt;authority&gt;][/&lt;path&gt;][;&lt;params&gt;][?&lt;query&gt;][#&lt;fragment&gt;]<br>
&lt;authority&gt; ::= [&lt;userinfo&gt;@]&lt;host&gt;[:&lt;port&gt;]<br> &lt;authority&gt; ::= [&lt;userinfo&gt;@]&lt;host&gt;[:&lt;port&gt;]<br>
&lt;userinfo&gt; ::= &lt;user&gt;[:&lt;password&gt;]<br> &lt;userinfo&gt; ::= &lt;user&gt;[:&lt;password&gt;]<br>
&lt;path&gt; ::= {&lt;segment&gt;/}&lt;segment&gt;<br> &lt;path&gt; ::= {&lt;segment&gt;/}&lt;segment&gt;<br>
@ -225,6 +225,7 @@ parsed_url = {<br>
&nbsp;&nbsp;scheme = <i>string</i>,<br> &nbsp;&nbsp;scheme = <i>string</i>,<br>
&nbsp;&nbsp;authority = <i>string</i>,<br> &nbsp;&nbsp;authority = <i>string</i>,<br>
&nbsp;&nbsp;path = <i>string</i>,<br> &nbsp;&nbsp;path = <i>string</i>,<br>
&nbsp;&nbsp;params = <i>string</i>,<br>
&nbsp;&nbsp;query = <i>string</i>,<br> &nbsp;&nbsp;query = <i>string</i>,<br>
&nbsp;&nbsp;fragment = <i>string</i>,<br> &nbsp;&nbsp;fragment = <i>string</i>,<br>
&nbsp;&nbsp;userinfo = <i>string</i>,<br> &nbsp;&nbsp;userinfo = <i>string</i>,<br>
@ -254,6 +255,7 @@ parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i")
-- scheme = "ftp", -- scheme = "ftp",
-- authority = "root:passwd@unsafe.org", -- authority = "root:passwd@unsafe.org",
-- path = "/pub/virus.exe", -- path = "/pub/virus.exe",
-- params = "type=i",
-- userinfo = "root:passwd", -- userinfo = "root:passwd",
-- host = "unsafe.org", -- host = "unsafe.org",
-- user = "root", -- user = "root",

View File

@ -10,7 +10,7 @@
# print print the build settings # print print the build settings
PLAT?= linux PLAT?= linux
PLATS= macosx linux win32 win64 mingw freebsd solaris PLATS= macosx linux win32 win64 mingw freebsd solaris ucrt64
all: $(PLAT) all: $(PLAT)

View File

@ -207,6 +207,7 @@ local function adjusturi(reqt)
if not reqt.proxy and not _M.PROXY then if not reqt.proxy and not _M.PROXY then
u = { u = {
path = socket.try(reqt.path, "invalid path 'nil'"), path = socket.try(reqt.path, "invalid path 'nil'"),
params = reqt.params,
query = reqt.query, query = reqt.query,
fragment = reqt.fragment fragment = reqt.fragment
} }

View File

@ -74,6 +74,13 @@ LUAPREFIX_mingw?=/usr
CDIR_mingw?=lua/$(LUAV) CDIR_mingw?=lua/$(LUAV)
LDIR_mingw?=lua/$(LUAV)/lua LDIR_mingw?=lua/$(LUAV)/lua
# where lua headers are found for ucrt64 builds
# LUAINC_ucrt64:
LUAINC_ucrt64?=/ucrt64/include
LUALIB_ucrt64?=/ucrt64/bin/lua$(subst .,,$(LUAV)).dll
LUAPREFIX_ucrt64?=/ucrt64
CDIR_ucrt64?=lib/lua/$(LUAV)
LDIR_ucrt64?=share/lua/$(LUAV)
# LUAINC_win32: # LUAINC_win32:
# LUALIB_win32: # LUALIB_win32:
@ -153,7 +160,7 @@ print:
#------ #------
# Supported platforms # Supported platforms
# #
PLATS= macosx linux win32 win64 mingw solaris PLATS= macosx linux win32 win64 mingw solaris ucrt64
#------ #------
# Compiler and linker settings # Compiler and linker settings
@ -219,6 +226,21 @@ LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
LD_mingw=gcc LD_mingw=gcc
SOCKET_mingw=wsocket.o SOCKET_mingw=wsocket.o
#------
# Compiler and linker settings
# for ucrt64
SO_ucrt64=dll
O_ucrt64=o
CC_ucrt64=gcc
DEF_ucrt64= -DLUASOCKET_$(DEBUG) \
-DWINVER=0x0501
CFLAGS_ucrt64= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common
# \
-fvisibility=hidden
LDFLAGS_ucrt64= $(LUALIB) -shared -Wl,-s -lws2_32 -o
LD_ucrt64=gcc
SOCKET_ucrt64=wsocket.o
#------ #------
# Compiler and linker settings # Compiler and linker settings
@ -384,6 +406,9 @@ linux:
mingw: mingw:
$(MAKE) all PLAT=mingw $(MAKE) all PLAT=mingw
ucrt64:
$(MAKE) all PLAT=ucrt64
solaris: solaris:
$(MAKE) all-unix PLAT=solaris $(MAKE) all-unix PLAT=solaris

View File

@ -125,7 +125,7 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Parses a url and returns a table with all its parts according to RFC 2396 -- Parses a url and returns a table with all its parts according to RFC 2396
-- The following grammar describes the names given to the URL parts -- The following grammar describes the names given to the URL parts
-- <url> ::= <scheme>://<authority>/<path>?<query>#<fragment> -- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
-- <authority> ::= <userinfo>@<host>:<port> -- <authority> ::= <userinfo>@<host>:<port>
-- <userinfo> ::= <user>[:<password>] -- <userinfo> ::= <user>[:<password>]
-- <path> :: = {<segment>/}<segment> -- <path> :: = {<segment>/}<segment>
@ -136,7 +136,7 @@ end
-- table with the following fields, where RFC naming conventions have -- table with the following fields, where RFC naming conventions have
-- been preserved: -- been preserved:
-- scheme, authority, userinfo, user, password, host, port, -- scheme, authority, userinfo, user, password, host, port,
-- path, query, fragment -- path, params, query, fragment
-- Obs: -- Obs:
-- the leading '/' in {/<path>} is considered part of <path> -- the leading '/' in {/<path>} is considered part of <path>
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@ -166,6 +166,11 @@ function _M.parse(url, default)
parsed.query = q parsed.query = q
return "" return ""
end) end)
-- get params
url = string.gsub(url, "%;(.*)", function(p)
parsed.params = p
return ""
end)
-- path is whatever was left -- path is whatever was left
if url ~= "" then parsed.path = url end if url ~= "" then parsed.path = url end
local authority = parsed.authority local authority = parsed.authority
@ -198,6 +203,7 @@ function _M.build(parsed)
--local ppath = _M.parse_path(parsed.path or "") --local ppath = _M.parse_path(parsed.path or "")
--local url = _M.build_path(ppath) --local url = _M.build_path(ppath)
local url = parsed.path or "" local url = parsed.path or ""
if parsed.params then url = url .. ";" .. parsed.params end
if parsed.query then url = url .. "?" .. parsed.query end if parsed.query then url = url .. "?" .. parsed.query end
local authority = parsed.authority local authority = parsed.authority
if parsed.host then if parsed.host then
@ -252,8 +258,11 @@ function _M.absolute(base_url, relative_url)
relative_parsed.authority = base_parsed.authority relative_parsed.authority = base_parsed.authority
if not relative_parsed.path then if not relative_parsed.path then
relative_parsed.path = base_parsed.path relative_parsed.path = base_parsed.path
if not relative_parsed.query then if not relative_parsed.params then
relative_parsed.query = base_parsed.query relative_parsed.params = base_parsed.params
if not relative_parsed.query then
relative_parsed.query = base_parsed.query
end
end end
else else
relative_parsed.path = absolute_path(base_parsed.path or "", relative_parsed.path = absolute_path(base_parsed.path or "",

View File

@ -99,7 +99,8 @@ check_parse_url{
userinfo = "user:pass$%?#wd", userinfo = "user:pass$%?#wd",
password = "pass$%?#wd", password = "pass$%?#wd",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -112,7 +113,8 @@ check_parse_url{
userinfo = "user:pass?#wd", userinfo = "user:pass?#wd",
password = "pass?#wd", password = "pass?#wd",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -125,7 +127,8 @@ check_parse_url{
userinfo = "user:pass-wd", userinfo = "user:pass-wd",
password = "pass-wd", password = "pass-wd",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -138,7 +141,8 @@ check_parse_url{
userinfo = "user:pass#wd", userinfo = "user:pass#wd",
password = "pass#wd", password = "pass#wd",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -151,7 +155,8 @@ check_parse_url{
userinfo = "user:pass#wd", userinfo = "user:pass#wd",
password = "pass#wd", password = "pass#wd",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
} }
check_parse_url{ check_parse_url{
@ -162,7 +167,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -176,7 +182,8 @@ check_parse_url{
userinfo = "user:password", userinfo = "user:password",
user = "user", user = "user",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment", fragment = "fragment",
} }
@ -189,7 +196,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "" fragment = ""
} }
@ -202,7 +210,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "", query = "",
fragment = "fragment" fragment = "fragment"
} }
@ -215,7 +224,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
fragment = "fragment" fragment = "fragment"
} }
@ -227,7 +237,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;", path = "/path",
params = "",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -253,7 +264,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/;params", path = "/",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -275,7 +287,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -425,7 +438,8 @@ check_parse_url{
port = "port", port = "port",
userinfo = "userinfo", userinfo = "userinfo",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -439,7 +453,8 @@ check_parse_url{
userinfo = "user:password", userinfo = "user:password",
user = "user", user = "user",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -452,7 +467,8 @@ check_build_url {
port = "port", port = "port",
user = "user", user = "user",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -462,7 +478,8 @@ check_build_url{
host = "::FFFF:129.144.52.38", host = "::FFFF:129.144.52.38",
port = "port", port = "port",
user = "userinfo", user = "userinfo",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -474,7 +491,8 @@ check_build_url{
port = "port", port = "port",
user = "user", user = "user",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -485,7 +503,8 @@ check_build_url {
host = "host", host = "host",
user = "user", user = "user",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -495,7 +514,8 @@ check_build_url {
scheme = "scheme", scheme = "scheme",
host = "host", host = "host",
user = "user", user = "user",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -504,7 +524,8 @@ check_build_url {
url = "scheme://host/path;params?query#fragment", url = "scheme://host/path;params?query#fragment",
scheme = "scheme", scheme = "scheme",
host = "host", host = "host",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -513,7 +534,8 @@ check_build_url {
url = "scheme://host/path;params#fragment", url = "scheme://host/path;params#fragment",
scheme = "scheme", scheme = "scheme",
host = "host", host = "host",
path = "/path;params", path = "/path",
params = "params",
fragment = "fragment" fragment = "fragment"
} }
@ -551,7 +573,9 @@ check_build_url {
user = "user", user = "user",
userinfo = "not used", userinfo = "not used",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -564,7 +588,8 @@ check_build_url {
userinfo = "not used", userinfo = "not used",
authority = "not used", authority = "not used",
password = "password", password = "password",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -576,7 +601,8 @@ check_build_url {
port = "port", port = "port",
userinfo = "user:password", userinfo = "user:password",
authority = "not used", authority = "not used",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }
@ -585,7 +611,8 @@ check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment", url = "scheme://user:password@host:port/path;params?query#fragment",
scheme = "scheme", scheme = "scheme",
authority = "user:password@host:port", authority = "user:password@host:port",
path = "/path;params", path = "/path",
params = "params",
query = "query", query = "query",
fragment = "fragment" fragment = "fragment"
} }