rev |
line source |
jbe@0
|
1 -- Moonbridge example application
|
jbe@0
|
2 -- invoke with ./moonbridge example_application.lua
|
jbe@0
|
3
|
jbe@4
|
4 local http = require "moonbridge_http"
|
jbe@0
|
5
|
jbe@0
|
6 local documents = {"example_webpage.html", "example_webpage.css"}
|
jbe@0
|
7
|
jbe@0
|
8 listen{
|
jbe@0
|
9 -- listen to a tcp version 4 socket
|
jbe@0
|
10 { proto = "tcp4", port = 8080, localhost = true },
|
jbe@0
|
11
|
jbe@0
|
12 -- listen to a tcp version 6 socket
|
jbe@0
|
13 { proto = "tcp6", port = 8080, localhost = true },
|
jbe@0
|
14
|
jbe@0
|
15 -- listen to a unix domain socket
|
jbe@0
|
16 --{ proto = "local", path = 'socket' },
|
jbe@0
|
17
|
jbe@0
|
18 -- execute the listener regularly (without incoming connection)
|
jbe@0
|
19 --{ proto = "interval", name = "myint", delay = 10, strict = false },
|
jbe@0
|
20
|
jbe@0
|
21 -- desired number of spare (idle) processes
|
jbe@0
|
22 pre_fork = 1, -- number of forks
|
jbe@0
|
23
|
jbe@0
|
24 -- minimum number of processes
|
jbe@0
|
25 min_fork = 2, -- number of forks
|
jbe@0
|
26
|
jbe@0
|
27 -- maximum number of processes (hard limit)
|
jbe@0
|
28 max_fork = 16, -- number of forks
|
jbe@0
|
29
|
jbe@0
|
30 -- delay between creation of spare processes
|
jbe@0
|
31 fork_delay = 1, -- seconds
|
jbe@0
|
32
|
jbe@0
|
33 -- delay before retry of failed process creation
|
jbe@0
|
34 fork_error_delay = 2, -- seconds
|
jbe@0
|
35
|
jbe@0
|
36 -- delay between destruction of excessive spare processes
|
jbe@0
|
37 exit_delay = 60, -- seconds
|
jbe@0
|
38
|
jbe@0
|
39 -- idle time after a fork gets terminated
|
jbe@0
|
40 idle_timeout = 0, -- seconds (0 for no timeout)
|
jbe@0
|
41
|
jbe@0
|
42 -- maximum memory consumption before process gets terminated
|
jbe@0
|
43 memory_limit = 1024*1024, -- bytes
|
jbe@0
|
44
|
jbe@0
|
45 -- preparation of process (executed before fork)
|
jbe@0
|
46 prepare = function()
|
jbe@0
|
47 for i, document in ipairs(documents) do
|
jbe@0
|
48 local file = assert(io.open(document))
|
jbe@0
|
49 documents[document] = file:read("*a")
|
jbe@0
|
50 file:close()
|
jbe@0
|
51 end
|
jbe@0
|
52 end,
|
jbe@0
|
53
|
jbe@0
|
54 -- connection handler
|
jbe@0
|
55 connect = http.generate_handler(
|
jbe@0
|
56 {
|
jbe@0
|
57 static_headers = {"Server: Moonbridge Example Server"},
|
jbe@0
|
58 request_body_size_limit = 16*1024*1024*1024 -- allow big file uploads
|
jbe@0
|
59 },
|
jbe@0
|
60 function(request)
|
jbe@0
|
61
|
jbe@0
|
62 if request.method == "GET" or request.method == "HEAD" then
|
jbe@0
|
63
|
jbe@0
|
64 if request.path == "/" then
|
jbe@0
|
65 request:send_status("303 See Other")
|
jbe@0
|
66 request:send_header("Location", "http://" .. request.headers_value.host .. "/example_webpage.html")
|
jbe@0
|
67
|
jbe@0
|
68 else
|
jbe@0
|
69 local document_name = string.match(request.path, "^/(.*)$")
|
jbe@0
|
70 local document_extension = string.match(document_name, "%.([^.])$")
|
jbe@0
|
71 local document = documents[string.match(request.path, "^/(.*)$")]
|
jbe@0
|
72 if document then
|
jbe@0
|
73 request:send_status("200 OK")
|
jbe@0
|
74
|
jbe@0
|
75 if document_extension == "html" then
|
jbe@0
|
76 request:send_header("Content-Type", "text/html; charset=UTF-8")
|
jbe@0
|
77 elseif document_extension == "css" then
|
jbe@0
|
78 request:send_header("Content-Type", "text/css; charset=UTF-8")
|
jbe@0
|
79 end
|
jbe@0
|
80 request:send_data(document)
|
jbe@0
|
81 else
|
jbe@0
|
82 request:send_status("404 Not Found")
|
jbe@0
|
83 request:send_header("Content-Type", "text/html; chatset=UTF-8")
|
jbe@0
|
84 request:send_data("<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1></body></html>")
|
jbe@0
|
85 end
|
jbe@0
|
86
|
jbe@0
|
87 end
|
jbe@0
|
88
|
jbe@0
|
89 elseif request.method == "POST" then
|
jbe@0
|
90
|
jbe@0
|
91 if request.path == "/post_example" then
|
jbe@0
|
92 local files = {}
|
jbe@0
|
93 do
|
jbe@0
|
94 local file
|
jbe@0
|
95 request:stream_post_param("files", function(chunk, field_name, meta)
|
jbe@0
|
96 if meta then
|
jbe@0
|
97 file = {
|
jbe@0
|
98 file_name = meta.file_name,
|
jbe@0
|
99 content_type = meta.content_type,
|
jbe@0
|
100 length = 0
|
jbe@0
|
101 }
|
jbe@0
|
102 end
|
jbe@0
|
103 if chunk then
|
jbe@0
|
104 file.length = file.length + #chunk
|
jbe@0
|
105 else
|
jbe@0
|
106 files[#files+1] = file
|
jbe@0
|
107 end
|
jbe@0
|
108 end)
|
jbe@0
|
109 end
|
jbe@0
|
110
|
jbe@0
|
111 request:send_status("200 OK")
|
jbe@0
|
112 request:send_header("Content-Type", "text/html; chatset=UTF-8")
|
jbe@0
|
113 request:send_data("<html>\n<head>\n")
|
jbe@0
|
114 request:send_data('<link href="example_webpage.css" rel="stylesheet" type="text/css">\n')
|
jbe@0
|
115 request:send_data("<title>Moonbridge Network Server for Lua Applications – Example Application</title>\n")
|
jbe@0
|
116 request:send_data("</head>\n<body>\n")
|
jbe@0
|
117 request:send_data("<h1>Moonbridge Network Server for Lua – Example Application</h1>\n")
|
jbe@0
|
118 request:send_data("<h2>POST request successful</h2>\n")
|
jbe@0
|
119 request:send_data('<table>\n<thead><th>File name</th><th>Content type</th><th class="numeric">Bytes received</th></thead>\n<tbody>\n')
|
jbe@0
|
120 for i, file in ipairs(files) do
|
jbe@0
|
121 request:send_data("<tr>")
|
jbe@0
|
122 request:send_data("<td>", http.encode_html(file.file_name or "(unknown)"), "</td>")
|
jbe@0
|
123 request:send_data("<td>", http.encode_html(file.content_type or "(unknown)"), "</td>")
|
jbe@0
|
124 request:send_data('<td class="numeric">', http.encode_html(tostring(file.length)), "</td>")
|
jbe@0
|
125 request:send_data("</tr>\n")
|
jbe@0
|
126 end
|
jbe@0
|
127 request:send_data("</tbody>\n</table>\n")
|
jbe@0
|
128 request:send_data("<p>Submitted comment: ", http.encode_html(request.post_params.comment), "</p>\n")
|
jbe@0
|
129 request:send_data("</body>\n</html>\n")
|
jbe@0
|
130
|
jbe@0
|
131 else
|
jbe@0
|
132 request:send_status("404 Not Found")
|
jbe@0
|
133 request:send_data("<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1></body></html>")
|
jbe@0
|
134
|
jbe@0
|
135 end
|
jbe@0
|
136
|
jbe@0
|
137 else
|
jbe@0
|
138 request:send_status("405 Method not allowed")
|
jbe@0
|
139
|
jbe@0
|
140 end
|
jbe@0
|
141
|
jbe@0
|
142 -- returning false causes termination of current process (and re-forking)
|
jbe@0
|
143 return true
|
jbe@0
|
144 end),
|
jbe@0
|
145
|
jbe@0
|
146 -- executed on process termination
|
jbe@0
|
147 finish = function()
|
jbe@0
|
148 end
|
jbe@0
|
149 }
|
jbe@0
|
150
|