1if not modules then modules = { } end modules [ ' util-imp-evohome-server ' ] = {
2 version = 1 . 002 ,
3 comment = " simple server for simple evohome extensions " ,
4 author = " Hans Hagen, PRAGMA-ADE, Hasselt NL " ,
5 copyright = " PRAGMA ADE " ,
6 license = " see context related readme files "
7}
8
9local P , C , patterns , lpegmatch = lpeg . P , lpeg . C , lpeg . patterns , lpeg . match
10local urlhashed , urlquery , urlunescapeget = url . hashed , url . query , url . unescapeget
11local ioflush = io . flush
12
13local newline = patterns . newline
14local spacer = patterns . spacer
15local whitespace = patterns . whitespace
16local method = P ( " GET " )
17 + P ( " POST " )
18local identify = ( 1 - method ) ^ 0
19 * C ( method )
20 * spacer ^ 1
21 * C ( ( 1 - spacer ) ^ 1 )
22 * spacer ^ 1
23 * P ( " HTTP/ " )
24 * ( 1 - whitespace ) ^ 0
25 * C ( P ( 1 ) ^ 0 )
26
27do
28
29 local loaded = package . loaded
30
31 if not loaded . socket then loaded . socket = loaded [ " socket.core " ] end
32 if not loaded . mime then loaded . mime = loaded [ " mime.core " ] end
33
34end
35
36local evohome = require ( " util-evo " )
37 require ( " trac-lmx " )
38
39local report = logs . reporter ( " evohome " , " server " )
40local convert = lmx . convert
41
42function evohome . server ( specification )
43
44 local filename = specification . filename
45
46 if not filename then
47 report ( " unable to run server, no filename given " )
48 return
49 end
50
51 local step , process , presets = evohome . actions . poller ( filename )
52
53 if not ( step and process and presets ) then
54 report ( " unable to run server, invalid presets " )
55 return
56 end
57
58 local template = presets . files . template
59
60 if not template then
61 report ( " unable to run server, no template given " )
62 return
63 end
64
65 local port = specification . port or ( presets . server and presets . server . port ) or 8068
66 local host = specification . host or ( presets . server and presets . server . host ) or " * "
67
68 package . extraluapath ( presets . filepath )
69
70 local socket = socket or require ( " socket " )
71 local copas = copas or require ( " copas " )
72
73 local function copashttp ( skt )
74 local client = copas . wrap ( skt )
75 local request , e = client : receive ( )
76 if not e then
77 local method , fullurl , body = lpegmatch ( identify , request )
78 if method ~ = " " and fullurl ~ = " " then
79 local fullurl = urlunescapeget ( fullurl )
80 local hashed = urlhashed ( fullurl )
81 process ( hashed . queries or { } )
82 ioflush ( )
83 end
84
85 local content = convert ( presets . results and presets . results . template or template , false , presets )
86 if not content then
87 report ( " error in converting template " )
88 content = " error in template "
89 end
90 client : send ( " HTTP/1.1 200 OK\r\n " )
91 client : send ( " Connection: close\r\n " )
92 client : send ( " Content-Length: " . . # content . . " \r\n " )
93 client : send ( " Content-Type: text/html\r\n " )
94 client : send ( " Location: " . . host . . " \r\n " )
95 client : send ( " Cache-Control: no-cache, no-store, must-revalidate, max-age=0\r\n " )
96 client : send ( " \r\n " )
97 client : send ( content )
98 client : send ( " \r\n " )
99 client : close ( )
100 end
101 end
102
103 local function copaspoll ( )
104 while step do
105 local delay = step ( )
106 if type ( delay ) = = " number " then
107 copas . sleep ( delay or 0 )
108 end
109 end
110 end
111
112 local server = socket . bind ( host , port )
113
114 if server then
115 report ( " server started at %s:%s " , host , port )
116 ioflush ( )
117 copas . addserver ( server , copashttp )
118 copas . addthread ( copaspoll )
119 copas . loop ( )
120 else
121 report ( " unable to start server at %s:%s " , host , port )
122 os . exit ( )
123 end
124
125end
126
127return evohome
128 |