-------------------------------------------------------------------------------- -- Title: LWApplication.lua -- Description: Like a square peg in a round hole -- Author: Raphaël Szwarc http://alt.textdrive.com/lua/ -- Creation Date: February 1, 2005 -- Legal: Copyright (C) 2005 Raphaël Szwarc -------------------------------------------------------------------------------- -- import dependencies local LUObject = require( "LUObject" ) local LULog = require( "LULog" ) local SocketRunLoop = require( "SocketRunLoop" ) local SocketServer = require( "SocketServer" ) local LWContext = require( "LWContext" ) local LWDispatcher = require( "LWDispatcher" ) local LWRequest = require( "LWRequest" ) local LWResponse = require( "LWResponse" ) local LWSession = require( "LWSession" ) -- define the class local super = LUObject local self = super() -- constants local MaximumUriSize = 1000 -- initialization method function self:init( aPort, anAddress ) self = super.init( self ) self._port = aPort self._address = anAddress return self end -- method to access this application address function self:address() if self._server ~= nil then return self:server():address() end if self._address == nil then self._address = "*" end return self._address end -- method to access this application port function self:port() if self._server ~= nil then return self:server():port() end if self._port == nil then self._port = 0 end return self._port end -- method to access this application server function self:server() if self._server == nil then self._server = SocketServer( self:address(), self:port(), self ) end return self._server end -- method to start this application function self:start( shouldStartRunLoop ) self:server():start() if shouldStartRunLoop == nil or shouldStartRunLoop == true then SocketRunLoop:default():start() end return self end -- method to access this application dispatcher function self:dispatcher() if self._dispatcher == nil then self._dispatcher = LWDispatcher() end return self._dispatcher end -- method to access the default service function self:defaultService() return self:dispatcher():defaultService() end -- method to register a service with this application function self:registerService( aService ) self:dispatcher():registerService( aService ) return self end -- method to access this application services function self:services() return self:dispatcher():services() end -- method to find a service for a given context function self:serviceWithContext( aContext ) return self:dispatcher():serviceWithContext( aContext ) end -- method to access this application session class function self:sessionClass() if self._sessionClass == nil then self._sessionClass = LWSession end return self._sessionClass end -- method to set this application session class function self:setSessionClass( aValue ) self._sessionClass = aValue return self end local function catch( anException ) LULog:warning( anException ) return nil, anException end -- method to run this application function self:run( aServer, aReader, aWriter ) while aReader:status() ~= "closed" and aWriter:status() ~= "closed" do local aRequest = LWRequest( aReader ) if aRequest ~= nil then local aResponse = LWResponse( aWriter, aRequest ) if aRequest:version() ~= nil then if aRequest:uri() ~= nil and aRequest:uri():path() ~= nil then if aRequest:uri():path():len() < MaximumUriSize then local aContext = LWContext( self, aRequest, aResponse ) local aService = self:serviceWithContext( aContext ) if aService:try( "run", aContext )( catch ) == nil then aResponse:writeStatus( 500 ) end else aResponse:writeStatus( 414 ) end else aResponse:writeStatus( 400 ) end else aResponse:writeStatus( 505 ) end else aReader:close() end end return self end -- method for string representation function self:toString() return ( "LWApplication@%s:%s" ):format( self:address(), self:port() ) end return self