root/HTTP/Nanoki.lua

Revision 1455 (checked in by rsz, 2 weeks ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               Nanoki.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       January 30, 2007
6 -- Legal:               Copyright (C) 2007 Raphaël Szwarc
7 --                      Under the terms of the MIT License
8 --                      http://www.opensource.org/licenses/mit-license.html
9 --------------------------------------------------------------------------------
10
11 package.cpath = package.cpath .. ';lib/?.so'
12 os.setlocale( 'en_US.US-ASCII', 'all' )
13
14 -- import dependencies
15 local io = require( 'io' )
16 local os = require( 'os' )
17 local table = require( 'table' )
18
19 local assert = assert
20 local error = error
21 local getfenv = getfenv
22 local getmetatable = getmetatable
23 local require = require
24 local select = select
25 local setfenv = setfenv
26 local setmetatable = setmetatable
27 local tonumber = tonumber
28 local tostring = tostring
29 local unpack = unpack
30
31 local _G = _G
32
33 --------------------------------------------------------------------------------
34 -- Nanoki
35 --------------------------------------------------------------------------------
36
37 module( 'Nanoki' )
38 _VERSION = '1.08'
39
40 local self = setmetatable( _M, {} )
41 local meta = getmetatable( self )
42
43 --------------------------------------------------------------------------------
44 -- Utilities
45 --------------------------------------------------------------------------------
46
47 local function Argument( ... )
48     if select( '#', ... ) > 0 then
49         return ...
50     end
51    
52     if _G.arg then
53         return unpack( _G.arg )
54     end
55 end
56
57 local function Environment( aFunction, aKey, aValue )
58     local anEnvironment = getfenv( assert( aFunction, 'invalid function' ) )
59    
60     if not anEnvironment or anEnvironment == _G then
61         anEnvironment = {}
62         setfenv( aFunction, anEnvironment )
63     end
64    
65     if aKey then
66         anEnvironment[ aKey ] = aValue
67     end
68    
69     return anEnvironment
70 end
71
72 local function Log( ... )
73     local aWriter = io.stderr
74     local aBuffer = { os.date( '!%Y-%m-%d %H:%M:%S', os.time() ) }
75
76     for anIndex = 1, select( '#', ... ) do
77         aBuffer[ #aBuffer + 1 ] = tostring( select( anIndex, ... ) )
78     end
79
80     aWriter:write( table.concat( aBuffer, ' ' ), '\n' )
81     aWriter:flush()
82 end
83
84 local function Path( aName )
85     local Bundle = require( 'Bundle' )
86    
87     return ( '%s%s%s' ):format( Bundle(), aName, Bundle.separator )
88 end
89
90 local function ConnectionFilter( aRequest, aResponse )
91     aResponse.header[ 'connection' ] = 'close'
92 end
93
94 local function ServerFilter( aRequest, aResponse )
95     aResponse.header[ 'server' ] = tostring( self )
96 end
97
98 --------------------------------------------------------------------------------
99 -- Arguments
100 --------------------------------------------------------------------------------
101
102 local function Location( ... )
103     local aLocation = select( 1, ... ) or '.'
104
105     Log( 'Location', '\t', aLocation )
106    
107     return aLocation
108 end
109
110 local function Server( ... )
111     local anAddress = select( 2, ... )   
112     local aPort = tonumber( select( 3, ... ) or nil )
113    
114     if anAddress and not aPort then
115         error( 'Missing port number for address \'' .. anAddress .. '\'' )
116     end
117    
118     if anAddress and aPort then
119         local TCPServer = require( 'TCPServer' )
120         local aServer = TCPServer( anAddress, aPort )
121
122         Log( 'Server', '\t', 'tcp', anAddress, aPort )
123
124         return aServer
125     end
126
127     Log( 'Server', '\t', 'io', 'stdin' )
128 end
129
130 local function Forwarded( ... )
131     local isForwarded = select( 4, ... ) == 'forwarded'
132
133     Log( 'Forwarded', '\t', isForwarded )
134
135     return isForwarded
136 end
137
138 local function Secure( ... )
139     local isSecure = select( 5, ... ) == 'secure'
140
141     Log( 'Secure', '\t', isSecure )
142
143     return isSecure
144 end
145
146 --------------------------------------------------------------------------------
147 -- Metamethods
148 --------------------------------------------------------------------------------
149
150 function meta:__call( ... )
151     local HTTP = require( 'HTTP' )
152     local HTTPExtra = require( 'HTTPExtra' )
153     local HTTPFile = require( 'HTTPFile' )
154     local HTTPRequest = require( 'HTTPRequest' )
155     local HTTPResponse = require( 'HTTPResponse' )
156     local HTTPService = require( 'HTTPService' )
157     local Wiki = require( 'Wiki' )
158           Wiki.location = Location( ... )
159     local WikiAbout = require( 'WikiAbout' )
160     local WikiContentService = require( 'WikiContentService' )
161     local WikiDateService = require( 'WikiDateService' )
162     local WikiIndexService = require( 'WikiIndexService' )
163     local WikiMainService = require( 'WikiMainService' )
164     local WikiRecentService = require( 'WikiRecentService' )
165     local WikiSearchService = require( 'WikiSearchService' )
166     local aServer = Server( ... )
167     local aService = nil
168    
169     Environment( HTTPRequest.AddressFilter, 'forwarded', Forwarded( ... ) )
170     HTTPRequest.secure = Secure( ... )
171     HTTPResponse.filter[ #HTTPResponse.filter + 1 ] = ServerFilter
172    
173     HTTP[ '/' ] = WikiMainService()
174     HTTP[ '/a' ] = WikiAbout()
175     HTTP[ '/etc/(.+)' ] = HTTPFile( Path( 'etc' ) )
176    
177     aService = HTTPService( '/date', WikiDateService )
178     HTTP[ aService.pattern ] = aService()
179    
180     aService = HTTPService( '/index', WikiIndexService )
181     HTTP[ aService.pattern ] = aService()
182    
183     aService = HTTPService( '/recent', WikiRecentService )
184     HTTP[ aService.pattern ] = aService()
185    
186     aService = HTTPService( '/search', WikiSearchService )
187     HTTP[ aService.pattern ] = aService()
188    
189     aService = HTTPService( '/', WikiContentService )
190     HTTP[ aService.pattern ] = aService()
191    
192     if aServer then
193         HTTPResponse.filter[ #HTTPResponse.filter + 1 ] = ConnectionFilter
194        
195         aServer( HTTP )
196     else
197         HTTP()
198     end
199 end
200
201 function meta:__concat( aValue )
202     return tostring( self ) .. tostring( aValue )
203 end
204
205 function meta:__tostring()
206     return ( '%s/%s' ):format( self._NAME, self._VERSION )
207 end
208
209 --------------------------------------------------------------------------------
210 -- Main
211 --------------------------------------------------------------------------------
212
213 Log( 'Version', '\t', self )
214
215 self( Argument( ... ) )
Note: See TracBrowser for help on using the browser.