Remove Luasocket - obsoleted by nixio
Remove old luasocket based LuCI Httpd - obsoleted by lucittpd Remove lpeg - not in use Rewrite luci-splashd using nixio
This commit is contained in:
parent
78d8ad784b
commit
67fbe1b33c
17 changed files with 11 additions and 1040 deletions
3
Makefile
3
Makefile
|
@ -48,8 +48,7 @@ runboa: hostenv
|
|||
runhttpd: hostenv
|
||||
build/hostenv.sh $(realpath host) $(LUA_MODULEDIR) $(LUA_LIBRARYDIR) "$(realpath host/usr/bin/lucittpd) $(realpath host)/usr/lib/lucittpd/plugins"
|
||||
|
||||
runluci: luahost
|
||||
build/hostenv.sh $(realpath host) $(LUA_MODULEDIR) $(LUA_LIBRARYDIR) "$(realpath libs/httpd/host/runluci) $(realpath host) $(HTDOCS)"
|
||||
runluci: runhttpd
|
||||
|
||||
runlua: hostenv
|
||||
build/hostenv.sh $(realpath host) $(LUA_MODULEDIR) $(LUA_LIBRARYDIR) lua
|
||||
|
|
|
@ -1,41 +1,20 @@
|
|||
#!/usr/bin/lua
|
||||
|
||||
require("socket")
|
||||
require("luci.ip")
|
||||
require("luci.model.uci")
|
||||
local nixio = require "nixio"
|
||||
local server = nixio.bind(nil, arg[1] or 8082)
|
||||
local stat = server:listen(32)
|
||||
|
||||
local uci = luci.model.uci.cursor_state()
|
||||
uci:load("network")
|
||||
|
||||
local server = socket.bind("0.0.0.0", arg[1] or 8082)
|
||||
server:settimeout(0, "t")
|
||||
|
||||
while true do
|
||||
while stat do
|
||||
local client = server:accept()
|
||||
|
||||
if client then
|
||||
client:settimeout(1)
|
||||
local srv
|
||||
local ip = luci.ip.IPv4((client:getpeername()))
|
||||
client:setopt("socket", "rcvtimeo", 1)
|
||||
client:setopt("socket", "sndtimeo", 1)
|
||||
local srv = client:getsockname()
|
||||
|
||||
local function find_srv(section)
|
||||
if section.ipaddr then
|
||||
local net = luci.ip.IPv4(section.ipaddr, section.netmask)
|
||||
if ip and net and net:contains(ip) then
|
||||
srv = section.ipaddr
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
uci:foreach("network", "interface", find_srv)
|
||||
uci:foreach("network", "alias", find_srv)
|
||||
|
||||
client:receive()
|
||||
client:send("HTTP/1.0 302 Found\r\nLocation: http://" .. srv ..
|
||||
client:read(1024)
|
||||
client:writeall("HTTP/1.0 302 Found\r\nLocation: http://" .. srv ..
|
||||
(arg[2] or "/luci/splash") .. "\r\n\r\n")
|
||||
client:close()
|
||||
else
|
||||
socket.sleep(0.1)
|
||||
end
|
||||
end
|
||||
|
|
1
contrib/lpeg/.gitignore
vendored
1
contrib/lpeg/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
lpeg-*
|
|
@ -1,33 +0,0 @@
|
|||
include ../../build/config.mk
|
||||
include ../../build/gccconfig.mk
|
||||
|
||||
LPEG_VERSION = 0.8.1
|
||||
LPEG_SITE = http://www.inf.puc-rio.br/~roberto/lpeg
|
||||
LPEG_DIR = lpeg-$(LPEG_VERSION)
|
||||
LPEG_FILE = $(LPEG_DIR).tar.gz
|
||||
LPEG_URL = $(LPEG_SITE)/$(LPEG_FILE)
|
||||
|
||||
all: compile
|
||||
|
||||
include ../../build/module.mk
|
||||
|
||||
$(LPEG_FILE):
|
||||
wget -O $@ $(LPEG_URL) || rm -f $@
|
||||
|
||||
$(LPEG_DIR)/.prepared: $(LPEG_FILE)
|
||||
rm -rf $(LPEG_DIR)
|
||||
tar xvfz $(LPEG_FILE)
|
||||
touch $@
|
||||
|
||||
compile: $(LPEG_DIR)/.prepared
|
||||
$(MAKE) -C $(LPEG_DIR) CC=$(CC) COPT="$(CFLAGS) $(LUA_CFLAGS) -fpic"
|
||||
mkdir -p dist$(LUA_LIBRARYDIR)
|
||||
cp $(LPEG_DIR)/{lpeg.so,re.lua} dist$(LUA_LIBRARYDIR)
|
||||
|
||||
luasource:
|
||||
luastrip:
|
||||
luacompile:
|
||||
compile-all: compile
|
||||
|
||||
clean:
|
||||
rm -rf $(LPEG_DIR) $(LPEG_FILE)
|
1
contrib/luasocket/.gitignore
vendored
1
contrib/luasocket/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
luasocket-*
|
|
@ -1,32 +0,0 @@
|
|||
include ../../build/config.mk
|
||||
include ../../build/gccconfig.mk
|
||||
|
||||
LUASOCKET_VERSION = 2.0.2
|
||||
LUASOCKET_SITE = http://dev.luci.freifunk-halle.net/sources/
|
||||
LUASOCKET_DIR = luasocket-$(LUASOCKET_VERSION)
|
||||
LUASOCKET_FILE = $(LUASOCKET_DIR).tar.gz
|
||||
LUASOCKET_URL = $(LUASOCKET_SITE)/$(LUASOCKET_FILE)
|
||||
INSTALL_MODULEDIR = dist$(LUA_MODULEDIR)
|
||||
INSTALL_LIBRARYDIR = dist$(LUA_LIBRARYDIR)
|
||||
|
||||
all: compile
|
||||
|
||||
include ../../build/module.mk
|
||||
|
||||
$(LUASOCKET_FILE):
|
||||
wget -O $@ $(LUASOCKET_URL) || rm -f $@
|
||||
|
||||
$(LUASOCKET_DIR)/.prepared: $(LUASOCKET_FILE)
|
||||
rm -rf $(LUASOCKET_DIR)
|
||||
tar xvfz $(LUASOCKET_FILE)
|
||||
touch $@
|
||||
|
||||
compile: $(LUASOCKET_DIR)/.prepared
|
||||
$(MAKE) -C $(LUASOCKET_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(LUA_CFLAGS) $(FPIC)" LDFLAGS="$(LDFLAGS) $(LUA_SHLIBS) $(SHLIB_FLAGS)" OS="$(OS)"
|
||||
mkdir -p $(INSTALL_LIBRARYDIR) $(INSTALL_MODULEDIR)
|
||||
$(MAKE) -C $(LUASOCKET_DIR) install INSTALL_TOP_SHARE=../../$(INSTALL_MODULEDIR) INSTALL_TOP_LIB=../../$(INSTALL_LIBRARYDIR)
|
||||
|
||||
compile-all: compile
|
||||
|
||||
clean:
|
||||
rm -rf $(LUASOCKET_DIR) $(LUASOCKET_FILE)
|
|
@ -1,42 +0,0 @@
|
|||
# Copyright (C) 2008 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=lpeg
|
||||
PKG_VERSION:=0.8.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://www.inf.puc-rio.br/~roberto/lpeg
|
||||
PKG_MD5SUM:=b6b172bbcdcba5c87b37eef9bb5ae199
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/lpeg
|
||||
SECTION:=lang
|
||||
CATEGORY:=Languages
|
||||
SUBMENU:=LUA
|
||||
TITLE:=LPEG - Parsing Expression Grammars
|
||||
URL:=http://www.inf.puc-rio.br/~roberto/lpeg.html
|
||||
DEPENDS:=+liblua
|
||||
endef
|
||||
|
||||
MAKE_FLAGS += COPT="$(TARGET_CFLAGS) $(FPIC) -I$(STAGING_DIR)/usr/include"
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/lpeg/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua
|
||||
$(CP) $(PKG_BUILD_DIR)/{lpeg.so,re.lua} $(1)/usr/lib/lua
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,lpeg))
|
|
@ -1,40 +0,0 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luasocket
|
||||
PKG_VERSION:=2.0.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://dev.luci.freifunk-halle.net/sources/\
|
||||
http://luaforge.net/frs/download.php/2664/
|
||||
PKG_MD5SUM:=41445b138deb7bcfe97bff957503da8e
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luasocket
|
||||
SECTION:=lang
|
||||
CATEGORY:=Languages
|
||||
SUBMENU:=LUA
|
||||
TITLE:=Socket support for Lua
|
||||
URL:=http://luaforge.net/projects/luasockets/
|
||||
DEPENDS:=+liblua
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
for i in $(PKG_BUILD_DIR)/src/*.lua; do luac -s -o $$$$i $$$$i; done
|
||||
$(call Build/Compile/Default)
|
||||
endef
|
||||
|
||||
MAKE_FLAGS += LD="$(TARGET_CC)" CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include -pedantic -Wall -fpic" LDFLAGS="$(TARGET_LDFLAGS) -shared -fpic"
|
||||
|
||||
define Package/luasocket/install
|
||||
$(MAKE) -C$(PKG_BUILD_DIR) install INSTALL_TOP_SHARE=$(1)/usr/lib/lua INSTALL_TOP_LIB=$(1)/usr/lib/lua
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luasocket))
|
|
@ -462,7 +462,7 @@ endef
|
|||
|
||||
define Package/luci-app-splash
|
||||
$(call Package/luci/fftemplate)
|
||||
DEPENDS+=+PACKAGE_luci-app-splash:luasocket
|
||||
DEPENDS+=+PACKAGE_luci-app-splash:luci-nixio
|
||||
TITLE:=Freifunk DHCP-Splash application
|
||||
endef
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
include ../../build/config.mk
|
||||
include ../../build/module.mk
|
|
@ -1,48 +0,0 @@
|
|||
#!/usr/bin/env lua
|
||||
require("luci.httpd")
|
||||
require("luci.httpd.server")
|
||||
require("luci.httpd.handler.file")
|
||||
require("luci.httpd.handler.luci")
|
||||
|
||||
SYSROOT = arg[1]
|
||||
DOCROOT = SYSROOT .. arg[2]
|
||||
PORT = 8080
|
||||
|
||||
collectgarbage("setpause", 150)
|
||||
|
||||
serversocket = luci.httpd.Socket("0.0.0.0", PORT)
|
||||
|
||||
server = luci.httpd.server.Server()
|
||||
vhost = luci.httpd.server.VHost()
|
||||
|
||||
server:set_default_vhost(vhost)
|
||||
|
||||
pcall(function()
|
||||
require "uci"
|
||||
require "luci.model.uci".cursor = function(config, save)
|
||||
return uci.cursor(config or SYSROOT .. "/etc/config", save or SYSROOT .. "/tmp/.uci")
|
||||
end
|
||||
|
||||
local x = require "luci.uvl".UVL.__init__
|
||||
require "luci.uvl".UVL.__init__ = function(self, schemedir)
|
||||
x(self, schemedir or SYSROOT .. "/lib/uci/schema")
|
||||
end
|
||||
end)
|
||||
|
||||
require("luci.sys")
|
||||
luci.sys.user.checkpasswd = function() return true end
|
||||
|
||||
|
||||
filehandler = luci.httpd.handler.file.Simple(DOCROOT)
|
||||
vhost:set_default_handler(filehandler)
|
||||
|
||||
lucihandler = luci.httpd.handler.luci.Luci()
|
||||
vhost:set_handler("/luci", lucihandler)
|
||||
|
||||
io.stderr:write("Starting LuCI HTTPD on port " .. PORT .. "...\n")
|
||||
io.stderr:write("Point your browser to http://localhost:" .. PORT .. "/luci\n")
|
||||
|
||||
--daemon = luci.httpd.Daemon()
|
||||
--daemon.debug = true
|
||||
luci.httpd.register(serversocket, server:create_daemon_handlers())
|
||||
luci.httpd.run()
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=/luci" />
|
||||
</head>
|
||||
<body style="background-color: black">
|
||||
<a style="color: white; text-decoration: none" href="/luci">LuCI - Lua Configuration Interface</a>
|
||||
</body>
|
||||
</html>
|
|
@ -1,126 +0,0 @@
|
|||
--[[
|
||||
|
||||
HTTP server implementation for LuCI - core
|
||||
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||
(c) 2008 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
|
||||
]]--
|
||||
|
||||
module("luci.httpd", package.seeall)
|
||||
require("socket")
|
||||
|
||||
THREAD_IDLEWAIT = 0.01
|
||||
THREAD_TIMEOUT = 90
|
||||
THREAD_LIMIT = nil
|
||||
|
||||
local reading = {}
|
||||
local clhandler = {}
|
||||
local erhandler = {}
|
||||
|
||||
local threadc = 0
|
||||
local threads = {}
|
||||
local threadm = {}
|
||||
local threadi = {}
|
||||
|
||||
local _meta = {__mode = "k"}
|
||||
setmetatable(threadm, _meta)
|
||||
setmetatable(threadi, _meta)
|
||||
|
||||
|
||||
function Socket(ip, port)
|
||||
local sock, err = socket.bind( ip, port )
|
||||
|
||||
if sock then
|
||||
sock:settimeout( 0, "t" )
|
||||
end
|
||||
|
||||
return sock, err
|
||||
end
|
||||
|
||||
function corecv(socket, ...)
|
||||
threadi[socket] = true
|
||||
|
||||
while true do
|
||||
local chunk, err, part = socket:receive(...)
|
||||
|
||||
if err ~= "timeout" then
|
||||
threadi[socket] = false
|
||||
return chunk, err, part
|
||||
end
|
||||
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
function cosend(socket, chunk, i, ...)
|
||||
threadi[socket] = true
|
||||
i = i or 1
|
||||
|
||||
while true do
|
||||
local stat, err, sent = socket:send(chunk, i, ...)
|
||||
|
||||
if err ~= "timeout" then
|
||||
threadi[socket] = false
|
||||
return stat, err, sent
|
||||
else
|
||||
i = sent and (sent + 1) or i
|
||||
end
|
||||
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
function register(socket, s_clhandler, s_errhandler)
|
||||
table.insert(reading, socket)
|
||||
clhandler[socket] = s_clhandler
|
||||
erhandler[socket] = s_errhandler
|
||||
end
|
||||
|
||||
function run()
|
||||
while true do
|
||||
step()
|
||||
end
|
||||
end
|
||||
|
||||
function step()
|
||||
local idle = true
|
||||
if not THREAD_LIMIT or threadc < THREAD_LIMIT then
|
||||
local now = os.time()
|
||||
for i, server in ipairs(reading) do
|
||||
local client = server:accept()
|
||||
if client then
|
||||
threadm[client] = now
|
||||
threadc = threadc + 1
|
||||
threads[client] = coroutine.create(clhandler[server])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for client, thread in pairs(threads) do
|
||||
coroutine.resume(thread, client)
|
||||
local now = os.time()
|
||||
if coroutine.status(thread) == "dead" then
|
||||
threadc = threadc - 1
|
||||
threads[client] = nil
|
||||
elseif threadm[client] and threadm[client] + THREAD_TIMEOUT < now then
|
||||
threads[client] = nil
|
||||
threadc = threadc - 1
|
||||
client:close()
|
||||
elseif not threadi[client] then
|
||||
threadm[client] = now
|
||||
idle = false
|
||||
end
|
||||
end
|
||||
|
||||
if idle then
|
||||
socket.sleep(THREAD_IDLEWAIT)
|
||||
end
|
||||
end
|
|
@ -1,199 +0,0 @@
|
|||
--[[
|
||||
|
||||
HTTP server implementation for LuCI - file handler
|
||||
(c) 2008 Steven Barth <steven@midlink.org>
|
||||
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
|
||||
]]--
|
||||
|
||||
module("luci.httpd.handler.file", package.seeall)
|
||||
|
||||
require("luci.httpd.module")
|
||||
require("luci.http.protocol.date")
|
||||
require("luci.http.protocol.mime")
|
||||
require("luci.http.protocol.conditionals")
|
||||
require("luci.fs")
|
||||
local ltn12 = require("luci.ltn12")
|
||||
|
||||
Simple = luci.util.class(luci.httpd.module.Handler)
|
||||
Response = luci.httpd.module.Response
|
||||
|
||||
function Simple.__init__(self, docroot, dirlist)
|
||||
luci.httpd.module.Handler.__init__(self)
|
||||
self.docroot = docroot
|
||||
self.dirlist = dirlist and true or false
|
||||
self.proto = luci.http.protocol
|
||||
self.mime = luci.http.protocol.mime
|
||||
self.date = luci.http.protocol.date
|
||||
self.cond = luci.http.protocol.conditionals
|
||||
end
|
||||
|
||||
function Simple.getfile(self, uri)
|
||||
local file = self.docroot .. uri:gsub("%.%./+", "")
|
||||
local stat = luci.fs.stat(file)
|
||||
|
||||
return file, stat
|
||||
end
|
||||
|
||||
function Simple.handle_get(self, request, sourcein, sinkerr)
|
||||
local file, stat = self:getfile( self.proto.urldecode( request.env.PATH_INFO, true ) )
|
||||
|
||||
if stat then
|
||||
if stat.type == "regular" then
|
||||
|
||||
-- Generate Entity Tag
|
||||
local etag = self.cond.mk_etag( stat )
|
||||
|
||||
-- Check conditionals
|
||||
local ok, code, hdrs
|
||||
|
||||
ok, code, hdrs = self.cond.if_modified_since( request, stat )
|
||||
if ok then
|
||||
ok, code, hdrs = self.cond.if_match( request, stat )
|
||||
if ok then
|
||||
ok, code, hdrs = self.cond.if_unmodified_since( request, stat )
|
||||
if ok then
|
||||
ok, code, hdrs = self.cond.if_none_match( request, stat )
|
||||
if ok then
|
||||
local f, err = io.open(file)
|
||||
|
||||
if f then
|
||||
-- Send Response
|
||||
return Response(
|
||||
200, {
|
||||
["Date"] = self.date.to_http( os.time() );
|
||||
["Last-Modified"] = self.date.to_http( stat.mtime );
|
||||
["Content-Type"] = self.mime.to_mime( file );
|
||||
["Content-Length"] = stat.size;
|
||||
["ETag"] = etag;
|
||||
}
|
||||
), ltn12.source.file(f)
|
||||
else
|
||||
return self:failure( 403, err:gsub("^.+: ", "") )
|
||||
end
|
||||
else
|
||||
return Response( code, hdrs or { } )
|
||||
end
|
||||
else
|
||||
return Response( code, hdrs or { } )
|
||||
end
|
||||
else
|
||||
return Response( code, hdrs or { } )
|
||||
end
|
||||
else
|
||||
return Response( code, hdrs or { } )
|
||||
end
|
||||
|
||||
elseif stat.type == "directory" then
|
||||
|
||||
local ruri = request.request_uri:gsub("/$","")
|
||||
local duri = self.proto.urldecode( ruri, true )
|
||||
local root = self.docroot:gsub("/$","")
|
||||
|
||||
-- check for index files
|
||||
local index_candidates = {
|
||||
"index.html", "index.htm", "default.html", "default.htm",
|
||||
"index.txt", "default.txt"
|
||||
}
|
||||
|
||||
-- try to find an index file and redirect to it
|
||||
for i, candidate in ipairs( index_candidates ) do
|
||||
local istat = luci.fs.stat(
|
||||
root .. "/" .. duri .. "/" .. candidate
|
||||
)
|
||||
|
||||
if istat ~= nil and istat.type == "regular" then
|
||||
return Response( 301, {
|
||||
["Location"] = ruri .. "/" .. candidate
|
||||
} ), ltn12.source.empty()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local html = string.format(
|
||||
'<?xml version="1.0" encoding="ISO-8859-15"?>\n' ..
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' ..
|
||||
'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n' ..
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml" ' ..
|
||||
'xml:lang="en" lang="en">\n' ..
|
||||
'<head>\n' ..
|
||||
'<title>Index of %s/</title>\n' ..
|
||||
'<style type="text/css"><!--\n' ..
|
||||
'body { background-color:#FFFFFF; color:#000000 } ' ..
|
||||
'li { border-bottom:1px dotted #CCCCCC; padding:3px } ' ..
|
||||
'small { font-size:60%%; color:#999999 } ' ..
|
||||
'p { margin:0 }' ..
|
||||
'\n--></style></head><body><h1>Index of %s/</h1><hr /><ul>',
|
||||
duri, duri
|
||||
)
|
||||
|
||||
local entries = luci.fs.dir( file )
|
||||
|
||||
if type(entries) == "table" then
|
||||
for i, e in luci.util.spairs(
|
||||
entries, function(a,b)
|
||||
if entries[a] == '..' then
|
||||
return true
|
||||
elseif entries[b] == '..' then
|
||||
return false
|
||||
else
|
||||
return ( entries[a] < entries[b] )
|
||||
end
|
||||
end
|
||||
) do
|
||||
if e ~= '.' and ( e == '..' or e:sub(1,1) ~= '.' ) then
|
||||
local estat = luci.fs.stat( file .. "/" .. e )
|
||||
|
||||
if estat.type == "directory" then
|
||||
html = html .. string.format(
|
||||
'<li><p><a href="%s/%s/">%s/</a> ' ..
|
||||
'<small>(directory)</small><br />' ..
|
||||
'<small>Changed: %s</small></li>',
|
||||
ruri, self.proto.urlencode( e ), e,
|
||||
self.date.to_http( estat.mtime )
|
||||
)
|
||||
else
|
||||
html = html .. string.format(
|
||||
'<li><p><a href="%s/%s">%s</a> ' ..
|
||||
'<small>(%s)</small><br />' ..
|
||||
'<small>Size: %i Bytes | ' ..
|
||||
'Changed: %s</small></li>',
|
||||
ruri, self.proto.urlencode( e ), e,
|
||||
self.mime.to_mime( e ),
|
||||
estat.size, self.date.to_http( estat.mtime )
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
html = html .. '</ul><hr /></body></html>'
|
||||
|
||||
return Response(
|
||||
200, {
|
||||
["Date"] = self.date.to_http( os.time() );
|
||||
["Content-Type"] = "text/html; charset=ISO-8859-15";
|
||||
}
|
||||
), ltn12.source.string(html)
|
||||
else
|
||||
return self:failure(403, "Permission denied")
|
||||
end
|
||||
else
|
||||
return self:failure(403, "Unable to transmit " .. stat.type .. " " .. file)
|
||||
end
|
||||
else
|
||||
return self:failure(404, "No such file: " .. file)
|
||||
end
|
||||
end
|
||||
|
||||
function Simple.handle_head(self, ...)
|
||||
local response, sourceout = self:handle_get(...)
|
||||
return response
|
||||
end
|
|
@ -1,96 +0,0 @@
|
|||
--[[
|
||||
|
||||
HTTP server implementation for LuCI - luci handler
|
||||
(c) 2008 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
|
||||
]]--
|
||||
|
||||
module("luci.httpd.handler.luci", package.seeall)
|
||||
|
||||
require("luci.dispatcher")
|
||||
require("luci.http")
|
||||
require("luci.http.protocol.date")
|
||||
local ltn12 = require("luci.ltn12")
|
||||
|
||||
Luci = luci.util.class(luci.httpd.module.Handler)
|
||||
Response = luci.httpd.module.Response
|
||||
|
||||
function Luci.__init__(self, limit)
|
||||
luci.httpd.module.Handler.__init__(self)
|
||||
self.limit = limit or 5
|
||||
self.running = {}
|
||||
setmetatable(self.running, {__mode = "k"})
|
||||
end
|
||||
|
||||
function Luci.handle_head(self, ...)
|
||||
local response, sourceout = self:handle_get(...)
|
||||
return response
|
||||
end
|
||||
|
||||
function Luci.handle_post(self, ...)
|
||||
return self:handle_get(...)
|
||||
end
|
||||
|
||||
function Luci.handle_get(self, request, sourcein, sinkerr)
|
||||
local r = luci.http.Request(
|
||||
request.env,
|
||||
sourcein,
|
||||
sinkerr
|
||||
)
|
||||
|
||||
local res, id, data1, data2 = true, 0, nil, nil
|
||||
local headers = {}
|
||||
local status = 200
|
||||
local active = true
|
||||
|
||||
local x = coroutine.create(luci.dispatcher.httpdispatch)
|
||||
while not id or id < 3 do
|
||||
coroutine.yield()
|
||||
|
||||
res, id, data1, data2 = coroutine.resume(x, r)
|
||||
|
||||
if not res then
|
||||
status = 500
|
||||
headers["Content-Type"] = "text/plain"
|
||||
local err = {id}
|
||||
return Response( status, headers ), function() return table.remove(err) end
|
||||
end
|
||||
|
||||
if id == 1 then
|
||||
status = data1
|
||||
elseif id == 2 then
|
||||
headers[data1] = data2
|
||||
end
|
||||
end
|
||||
|
||||
local function iter()
|
||||
local res, id, data = coroutine.resume(x)
|
||||
if not res then
|
||||
return nil, id
|
||||
elseif not id or not active then
|
||||
return true
|
||||
elseif id == 5 then
|
||||
active = false
|
||||
|
||||
while (coroutine.resume(x)) do
|
||||
end
|
||||
|
||||
return nil
|
||||
elseif id == 4 then
|
||||
return data
|
||||
end
|
||||
if coroutine.status(x) == "dead" then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return Response(status, headers), iter
|
||||
end
|
|
@ -1,136 +0,0 @@
|
|||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
]]--
|
||||
module("luci.httpd.module", package.seeall)
|
||||
require("luci.util")
|
||||
require("luci.http.protocol")
|
||||
local ltn12 = require("luci.ltn12")
|
||||
|
||||
|
||||
|
||||
-- Server handler implementation
|
||||
Handler = luci.util.class()
|
||||
|
||||
-- Constructor
|
||||
function Handler.__init__(self)
|
||||
self.filters = {}
|
||||
self.handler = {}
|
||||
end
|
||||
|
||||
|
||||
-- Adds a filter to the filter chain
|
||||
function Handler.addfilter(self, filter)
|
||||
table.insert(self.filters, filter)
|
||||
end
|
||||
|
||||
|
||||
-- Creates a failure reply
|
||||
function Handler.failure(self, code, message)
|
||||
local response = Response(code, { ["Content-Type"] = "text/plain" })
|
||||
local sourceout = ltn12.source.string(message)
|
||||
|
||||
return response, sourceout
|
||||
end
|
||||
|
||||
-- Processes a request
|
||||
function Handler.process(self, request, sourcein, sinkerr, ...)
|
||||
local stat, response, sourceout
|
||||
|
||||
-- Process incoming filters
|
||||
for i, f in ipairs(self.filters) do
|
||||
local i = f:get("input")
|
||||
|
||||
if i then
|
||||
sourcein = ltn12.source.chain(sourcein, i)
|
||||
end
|
||||
|
||||
if f.request then
|
||||
f:request(request)
|
||||
end
|
||||
end
|
||||
|
||||
-- Detect request Method
|
||||
local hname = "handle_" .. request.request_method
|
||||
if self[hname] then
|
||||
-- Run the handler
|
||||
stat, response, sourceout = luci.util.copcall(
|
||||
self[hname], self, request, sourcein, sinkerr, ...
|
||||
)
|
||||
|
||||
-- Check for any errors
|
||||
if not stat then
|
||||
response, sourceout = self:failure(500, response)
|
||||
end
|
||||
else
|
||||
response, sourceout = self:failure(405, luci.http.protocol.statusmsg[405])
|
||||
end
|
||||
|
||||
-- Check data
|
||||
if not luci.util.instanceof(response, Response) then
|
||||
response, sourceout = self:failure(500, "Core error: Invalid module response!")
|
||||
end
|
||||
|
||||
-- Process outgoing filters
|
||||
for i, f in ipairs(self.filters) do
|
||||
local o = f:get("output")
|
||||
|
||||
if o then
|
||||
sourceout = ltn12.source.chain(sourceout, o)
|
||||
end
|
||||
|
||||
if f.response then
|
||||
f:response(response)
|
||||
end
|
||||
end
|
||||
|
||||
return response, sourceout
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Server Filter implementation
|
||||
Filter = luci.util.class()
|
||||
|
||||
function Filter.get(self, name)
|
||||
return self[name] and function(...) return self[name](self, ...) end
|
||||
end
|
||||
|
||||
-- Filters the incoming body stream
|
||||
-- abstract function Filter.input(chunk)
|
||||
|
||||
-- Filters the outgoing body stream
|
||||
-- abstract function Filter.output(chunk)
|
||||
|
||||
-- Filters the request object
|
||||
-- abstract function Filter.request(request)
|
||||
|
||||
-- Filters the response object
|
||||
-- abstract function Filter.response(response)
|
||||
|
||||
|
||||
|
||||
-- Handler Response
|
||||
Response = luci.util.class()
|
||||
|
||||
function Response.__init__(self, status, headers)
|
||||
self.status = tonumber(status) or 200
|
||||
self.headers = (type(headers) == "table") and headers or {}
|
||||
end
|
||||
|
||||
function Response.addheader(self, key, value)
|
||||
self.headers[key] = value
|
||||
end
|
||||
|
||||
function Response.setstatus(self, status)
|
||||
self.status = status
|
||||
end
|
|
@ -1,241 +0,0 @@
|
|||
--[[
|
||||
|
||||
HTTP server implementation for LuCI - helper class
|
||||
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||
(c) 2008 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
|
||||
]]--
|
||||
|
||||
module("luci.httpd.server", package.seeall)
|
||||
require("socket")
|
||||
require("socket.http")
|
||||
require("luci.util")
|
||||
|
||||
READ_BUFSIZE = 1024
|
||||
VERSION = 0.2
|
||||
|
||||
|
||||
VHost = luci.util.class()
|
||||
|
||||
function VHost.__init__(self, handler)
|
||||
self.handler = handler
|
||||
self.dhandler = {}
|
||||
end
|
||||
|
||||
function VHost.process(self, request, sourcein, sinkerr, ...)
|
||||
local handler = self.handler
|
||||
|
||||
local uri = request.env.REQUEST_URI:match("^([^?]*)")
|
||||
|
||||
-- SCRIPT_NAME
|
||||
request.env.SCRIPT_NAME = ""
|
||||
|
||||
-- Call URI part
|
||||
request.env.PATH_INFO = uri
|
||||
|
||||
for k, dhandler in pairs(self.dhandler) do
|
||||
if k == uri or k.."/" == uri:sub(1, #k+1) then
|
||||
handler = dhandler
|
||||
request.env.SCRIPT_NAME = k
|
||||
request.env.PATH_INFO = uri:sub(#k+1)
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
if handler then
|
||||
return handler:process(request, sourcein, sinkerr, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function VHost.set_default_handler(self, handler)
|
||||
self.handler = handler
|
||||
end
|
||||
|
||||
|
||||
function VHost.set_handler(self, match, handler)
|
||||
self.dhandler[match] = handler
|
||||
end
|
||||
|
||||
|
||||
|
||||
Server = luci.util.class()
|
||||
|
||||
function Server.__init__(self, host)
|
||||
self.host = host
|
||||
self.vhosts = {}
|
||||
end
|
||||
|
||||
function Server.set_default_vhost(self, vhost)
|
||||
self.host = vhost
|
||||
end
|
||||
|
||||
-- Sets a vhost
|
||||
function Server.set_vhost(self, name, vhost)
|
||||
self.vhosts[name] = vhost
|
||||
end
|
||||
|
||||
function Server.create_daemon_handlers(self)
|
||||
return function(...) return self:process(...) end,
|
||||
function(...) return self:error_overload(...) end
|
||||
end
|
||||
|
||||
|
||||
function Server.error(self, socket, code, msg)
|
||||
hcode = tostring(code)
|
||||
|
||||
socket:send( "HTTP/1.0 " .. hcode .. " " ..
|
||||
luci.http.protocol.statusmsg[code] .. "\r\n" )
|
||||
socket:send( "Connection: close\r\n" )
|
||||
socket:send( "Content-Type: text/plain\r\n\r\n" )
|
||||
|
||||
if msg then
|
||||
socket:send( "HTTP-Error " .. code .. ": " .. msg .. "\r\n" )
|
||||
end
|
||||
end
|
||||
|
||||
function Server.error_overload(self, socket)
|
||||
self:error(socket, 503, "Too many simultaneous connections")
|
||||
end
|
||||
|
||||
|
||||
function Server.process( self, client )
|
||||
|
||||
-- Setup sockets and sources
|
||||
local thread = {
|
||||
receive = function(self, ...) return luci.httpd.corecv(client, ...) end,
|
||||
send = function(self, ...) return luci.httpd.cosend(client, ...) end,
|
||||
close = function(self, ...) return client:close(...) end,
|
||||
getfd = function(self, ...) return client:getfd(...) end,
|
||||
dirty = function(self, ...) return client:dirty(...) end
|
||||
}
|
||||
|
||||
client:settimeout( 0 )
|
||||
|
||||
local sourcein = ltn12.source.empty()
|
||||
local sourcehdr = luci.http.protocol.header_source( thread )
|
||||
local sinkerr = ltn12.sink.file( io.stderr )
|
||||
|
||||
local close = false
|
||||
|
||||
local reading = { client }
|
||||
|
||||
local message, err
|
||||
|
||||
repeat
|
||||
-- parse headers
|
||||
message, err = luci.http.protocol.parse_message_header( sourcehdr )
|
||||
|
||||
if not message then
|
||||
self:error( thread, 400, err )
|
||||
break
|
||||
end
|
||||
|
||||
-- keep-alive
|
||||
if message.http_version == 1.1 then
|
||||
close = (message.env.HTTP_CONNECTION == "close")
|
||||
else
|
||||
close = not message.env.HTTP_CONNECTION or message.env.HTTP_CONNECTION == "close"
|
||||
end
|
||||
|
||||
if message.request_method == "get" or message.request_method == "head" then
|
||||
-- Be happy
|
||||
|
||||
elseif message.request_method == "post" then
|
||||
-- If we have a HTTP/1.1 client and an Expect: 100-continue header then
|
||||
-- respond with HTTP 100 Continue message
|
||||
if message.http_version == 1.1 and message.headers['Expect'] and
|
||||
message.headers['Expect'] == '100-continue'
|
||||
then
|
||||
thread:send("HTTP/1.1 100 Continue\r\n\r\n")
|
||||
end
|
||||
|
||||
if message.headers['Transfer-Encoding'] and
|
||||
message.headers['Transfer-Encoding'] ~= "identity" then
|
||||
sourcein = socket.source("http-chunked", thread)
|
||||
elseif message.env.CONTENT_LENGTH then
|
||||
sourcein = socket.source("by-length", thread,
|
||||
tonumber(message.env.CONTENT_LENGTH))
|
||||
else
|
||||
self:error( thread, 411, luci.http.protocol.statusmsg[411] )
|
||||
break;
|
||||
end
|
||||
|
||||
-- FIXME: Close for POST requests
|
||||
close = true
|
||||
else
|
||||
self:error( thread, 405, luci.http.protocol.statusmsg[405] )
|
||||
break;
|
||||
|
||||
end
|
||||
|
||||
|
||||
local host = self.vhosts[message.env.HTTP_HOST] or self.host
|
||||
if not host then
|
||||
self:error( thread, 500, "Unable to find matching host" )
|
||||
break;
|
||||
end
|
||||
|
||||
local response, sourceout = host:process(
|
||||
message, sourcein, sinkerr,
|
||||
client, io.stderr
|
||||
)
|
||||
if not response then
|
||||
self:error( thread, 500, "Error processing handler" )
|
||||
end
|
||||
|
||||
-- Post process response
|
||||
local sinkmode = close and "close-when-done" or "keep-open"
|
||||
|
||||
if sourceout then
|
||||
if not response.headers["Content-Length"] then
|
||||
if message.http_version == 1.1 then
|
||||
response.headers["Transfer-Encoding"] = "chunked"
|
||||
sinkmode = "http-chunked"
|
||||
else
|
||||
close = true
|
||||
sinkmode = "close-when-done"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if close then
|
||||
response.headers["Connection"] = "close"
|
||||
end
|
||||
|
||||
|
||||
local sinkout = socket.sink(sinkmode, thread)
|
||||
|
||||
local header =
|
||||
message.env.SERVER_PROTOCOL .. " " ..
|
||||
tostring(response.status) .. " " ..
|
||||
luci.http.protocol.statusmsg[response.status] .. "\r\n"
|
||||
|
||||
header = header .. "Server: LuCI HTTPd/" .. tostring(VERSION) .. "\r\n"
|
||||
|
||||
|
||||
for k,v in pairs(response.headers) do
|
||||
header = header .. k .. ": " .. v .. "\r\n"
|
||||
end
|
||||
|
||||
thread:send(header .. "\r\n")
|
||||
|
||||
if sourceout then
|
||||
local eof = false
|
||||
repeat
|
||||
coroutine.yield()
|
||||
eof = not ltn12.pump.step(sourceout, sinkout)
|
||||
until eof
|
||||
end
|
||||
until close
|
||||
|
||||
client:close()
|
||||
end
|
Loading…
Reference in a new issue