root/LW/Web.lua

Revision 903 (checked in by rsz, 3 years ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               Web.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       February 1, 2005
6 -- Legal:               Copyright (C) 2005 Raphaël Szwarc
7 --------------------------------------------------------------------------------
8
9 -- import dependencies
10 local LWApplication = require( "LWApplication" )
11 local LWService = require( "LWService" )
12 local LULog = require( "LULog" )
13 local LUMap = require( "LUMap" )
14 local LUTask = require( "LUTask" )
15
16 -- define the class
17 local super = LWService
18 local self = super()
19
20 function self:init( aPrefix, someMappings )
21         self = super.init( self, aPrefix )
22        
23         self._mappings = someMappings
24
25         return self
26 end
27
28 function self:buffers()
29         if self._buffers == nil then
30                 self._buffers = LUMap( nil, "k" )
31         end
32        
33         return self._buffers
34 end
35
36 function self:buffer()
37         local aTask = LUTask:currentTask()
38         local someBuffers = self:buffers()
39         local aBuffer = someBuffers:get( aTask )
40        
41         if aBuffer == nil then
42                 aBuffer = {}
43                 someBuffers:put( aTask, aBuffer )
44         end
45        
46         return aBuffer
47 end
48
49 function self:contexts()
50         if self._contexts == nil then
51                 self._contexts = LUMap( nil, "kv" )
52         end
53        
54         return self._contexts
55 end
56
57 function self:context()
58         return self:contexts():get( LUTask:currentTask() )
59 end
60
61 function self:mappings()
62         return self._mappings or {}
63 end
64
65 function self:request()
66         return self:context():request()
67 end
68
69 function self:response()
70         return self:context():response()
71 end
72
73 function self:write( ... )
74         local aBuffer = self:buffer()
75         local aCount = select( "#", ... )
76        
77         for anIndex = 1, aCount do
78                 local aValue = select( anIndex, ... )
79        
80                 aBuffer[ #aBuffer + 1 ] = tostring( aValue )
81         end
82 end
83
84 function self:flushBuffer()
85         local aTask = LUTask:currentTask()
86         local someBuffers = self:buffers()
87         local aBuffer = someBuffers:get( aTask )
88
89         if aBuffer ~= nil and #aBuffer > 0 then
90                 self:response():writeContent( table.concat( aBuffer, "" ) )
91                 someBuffers:remove( aTask )
92         end
93 end
94
95 function self:iterator()
96         local aPrefix = self:prefix()
97         local someMappings = self:mappings()
98         local aPairIterator = ipairs( someMappings )
99         local anIndex = 0
100         local anIterator = function()
101                 local aPattern = nil
102                 local anHandler = nil
103
104                 anIndex, aPattern = aPairIterator( someMappings, anIndex )
105
106                 if anIndex ~= nil then
107                         anIndex, anHandler = aPairIterator( someMappings, anIndex )
108
109                         if aPattern ~= nil and anHandler ~= nil then
110                                 aPattern = "^" .. aPrefix .. aPattern .. "$"
111                        
112                                 return aPattern, anHandler
113                         end
114                 end
115
116                 return nil
117         end
118        
119         return anIterator
120 end
121
122 local function Print( ... )
123         self:write( ... )
124 end
125
126 function self:handlerWithMethod( anHandler, aMethod, someMatches )
127         local aType = type( anHandler )
128        
129         if aType == "string" then
130                 anHandler = require( anHandler )
131                 aType = type( anHandler )
132         end
133        
134         if aType == "table" then
135                 table.insert( someMatches, 1, anHandler() )
136
137                 anHandler = anHandler[ aMethod:lower() ]
138         end
139        
140         if type( anHandler ) == "function" then
141                 local anEnviromnent = { print = Print }
142        
143                 setmetatable( anEnviromnent, { __index = _G } )
144
145                 setfenv( anHandler, anEnviromnent )
146         else
147                 anHandler = nil
148         end
149
150         return anHandler, someMatches
151 end
152
153 -- method to run this service
154 function self:run( aContext )
155         local aMethod = aContext:request():method()
156         local anURI = aContext:request():uri()
157        
158         if aMethod ~= nil and anURI ~= nil and anURI:path() ~= nil then
159                 local aPath = anURI:path()
160
161                 for aPattern, anHandler in self:iterator() do
162                         if aPath:find( aPattern ) ~= nil then
163                                 local someMatches = { aPath:match( aPattern ) }       
164
165                                 anHandler, someMatches = self:handlerWithMethod( anHandler, aMethod, someMatches )
166                                
167                                 if anHandler ~= nil then
168                                         self:contexts():put( LUTask:currentTask(), aContext )
169                                        
170                                         anHandler( unpack( someMatches ) )
171                                        
172                                         self:flushBuffer()
173                                        
174                                         return self
175                                 end
176                         end
177                 end
178         end
179        
180         return super.run( self, aContext )
181 end
182
183 -- method to start this service
184 function self:start( someMappings, aPort )
185         local anApplication = LWApplication( aPort or 1080 )
186         local aService = self:new( "/", someMappings )
187        
188         anApplication:registerService( aService )
189        
190         LULog:info( anApplication )
191
192         anApplication:start()
193 end
194
195 return self
Note: See TracBrowser for help on using the browser.