-------------------------------------------------------------------------------- -- Title: LWRequest.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 LUList = require( "LUList" ) local LUMap = require( "LUMap" ) local LUString = require( "LUString" ) local LUURI = require( "LUURI" ) local MIME = require( "MIME" ) local socket = require( "socket" ) -- define the class local super = LUObject local self = super() -- initialization method function self:init( aReader ) self = super.init( self ) self._reader = aReader do local aRequestLine = aReader:read() if aRequestLine ~= nil then local aMethod, anURI, aVersion = aRequestLine:match( "(%S*) (%S*) (%S*)") local someHeaders = LUMap() local aLine = aReader:read() LULog:debug( aRequestLine ) while aLine ~= nil and aLine ~= "" do local aKey, aValue = aLine:match( "(%S-): (.*)" ) if aKey ~= nil and aValue ~= nil then someHeaders:put( aKey:lower(), aValue ) end aLine = aReader:read() end self._method = aMethod self._rawURI = anURI self._version = aVersion self._headers = someHeaders self:content() LULog:debug( someHeaders ) else return nil end return self end end -- method to access this request method function self:method() return self._method end -- method to access this request raw uri function self:rawURI() return self._rawURI end -- method to access this request uri function self:uri() if self._uri == nil then if self:rawURI() ~= nil then local anURI = LUURI( self:rawURI() ) if anURI:host() == nil then local anHost = self:headers():get( "host" ) if anHost ~= nil then local aSchema = "http" if LUString:endsWith( anHost, "443" ) == true then aSchema = aSchema .. "s" end anURI = LUURI( aSchema .. "://" .. anHost .. self:rawURI() ) end end self._uri = anURI end end return self._uri end -- method to access this request version function self:version() return self._version end -- method to access this request headers function self:headers() if self._headers == nil then self._headers = LUMap() end return self._headers end -- method to access a given header attributes function self:headerAttributes( anHeader ) local someAttributes = LUMap() local anHeaderValue = self:headers():get( anHeader ) if anHeaderValue ~= nil then anHeaderValue = anHeaderValue .. "," for aKey, aValue in anHeaderValue:gmatch( "(%w+)=(.-)," ) do if aValue:sub( 1, 1 ) == "\"" then aValue = aValue:sub( 2, aValue:len() - 1 ) end someAttributes:put( aKey:lower(), aValue ) end end return someAttributes end -- method to access this request content function self:content() if self._content == nil then local anEncoding = self:headers():get( "transfer-encoding" ) or "" if anEncoding:lower():find( "chunked", 1, true ) ~= nil then local aReader = self:reader() local aBuffer = LUList() local aLine = aReader:read() local aSize = tonumber( aLine, 16 ) while aSize ~= nil and aSize > 0 do aBuffer:add( aReader:read( aSize ) ) aReader:read() aLine = aReader:read() aSize = tonumber( aLine, 16 ) end aLine = aReader:read() while aLine ~= nil and aLine ~= "" do aLine = aReader:read() end self._content = aBuffer:join() else local aLength = self:contentLength() if aLength > 0 then self._content = self:reader():read( aLength ) end end end return self._content end -- method to access this request content length function self:contentLength() local aLength = self:headers():get( "content-length" ) if aLength ~= nil then aLength = tonumber( aLength ) if aLength ~= nil then return aLength end end return -1 end -- method to access this request parameters function self:parameters() if self._parameters == nil then local someParameters = LUMap( self:uri():queries() ) local aType = self:headers():get( "content-type" ) or "" if aType:lower():find( "multipart/form-data", 1, true ) ~= nil then local aContent = self:content() if aContent ~= nil then aContent = "content-type: " .. aType .. "\r\n\r\n\r\n" .. aContent someParameters:putAll( MIME( aContent ):content():data() ) end elseif aType:lower():find( "application/x-www-form-urlencoded", 1, true ) ~= nil then someParameters:putAll( LUURI:componentsWithParameter( self:content() ) ) end self._parameters = someParameters end return self._parameters end -- method to access this request reader function self:reader() return self._reader end -- method to access this request address function self:address() local aPeer = self:reader():socket():getpeername() local anAddress = socket.dns.toip( aPeer ) or aPeer return anAddress end -- method to check if this is a local request function self:isLocal() local anAddress = self:address() local aLocalAddress = socket.dns.toip( socket.dns.gethostname() ) if anAddress == "127.0.0.1" or anAddress == aLocalAddress then return true end return false end return self