build: introduce luci-base
[project/luci.git] / modules / base / luasrc / sgi / cgi.lua
1 --[[
2 LuCI - SGI-Module for CGI
3
4 Description:
5 Server Gateway Interface for CGI
6
7 FileId:
8 $Id$
9
10 License:
11 Copyright 2008 Steven Barth <steven@midlink.org>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at 
16
17         http://www.apache.org/licenses/LICENSE-2.0 
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 ]]--
26 exectime = os.clock()
27 module("luci.sgi.cgi", package.seeall)
28 local ltn12 = require("luci.ltn12")
29 require("nixio.util")
30 require("luci.http")
31 require("luci.sys")
32 require("luci.dispatcher")
33
34 -- Limited source to avoid endless blocking
35 local function limitsource(handle, limit)
36         limit = limit or 0
37         local BLOCKSIZE = ltn12.BLOCKSIZE
38
39         return function()
40                 if limit < 1 then
41                         handle:close()
42                         return nil
43                 else
44                         local read = (limit > BLOCKSIZE) and BLOCKSIZE or limit
45                         limit = limit - read
46
47                         local chunk = handle:read(read)
48                         if not chunk then handle:close() end
49                         return chunk
50                 end
51         end
52 end
53
54 function run()
55         local r = luci.http.Request(
56                 luci.sys.getenv(),
57                 limitsource(io.stdin, tonumber(luci.sys.getenv("CONTENT_LENGTH"))),
58                 ltn12.sink.file(io.stderr)
59         )
60         
61         local x = coroutine.create(luci.dispatcher.httpdispatch)
62         local hcache = ""
63         local active = true
64         
65         while coroutine.status(x) ~= "dead" do
66                 local res, id, data1, data2 = coroutine.resume(x, r)
67
68                 if not res then
69                         print("Status: 500 Internal Server Error")
70                         print("Content-Type: text/plain\n")
71                         print(id)
72                         break;
73                 end
74
75                 if active then
76                         if id == 1 then
77                                 io.write("Status: " .. tostring(data1) .. " " .. data2 .. "\r\n")
78                         elseif id == 2 then
79                                 hcache = hcache .. data1 .. ": " .. data2 .. "\r\n"
80                         elseif id == 3 then
81                                 io.write(hcache)
82                                 io.write("\r\n")
83                         elseif id == 4 then
84                                 io.write(tostring(data1 or ""))
85                         elseif id == 5 then
86                                 io.flush()
87                                 io.close()
88                                 active = false
89                         elseif id == 6 then
90                                 data1:copyz(nixio.stdout, data2)
91                                 data1:close()
92                         end
93                 end
94         end
95 end