[Seaside] Seaside serving static contents

Nevin Pratt nevin at smalltalkpro.com
Sat Aug 30 13:02:05 CEST 2003



Avi Bryant wrote:

>On Sat, 30 Aug 2003, Giovanni Giorgi wrote:
>
>  
>
>>For example I'd like to serve static html documentation and so on.
>>I do not want to install another http server.
>>I have tryed the KomHttpServer-6.1 but i get some errors when I use it.
>>    
>>
>
>What are the problems you're having with Kom 6.1?
>I've had success using Comanche 5 to serve static content alongside
>Seaside.  You have to use the ChieftainModule to attach both a WAKom
>module and a file serving module (forget the class name) to the same port
>on different paths.
>  
>

I also serve static content along side Seaside, plus I allow virtual 
hosting of many domains simultaneously.  To do this, rather than using 
the ChieftainModule, I created a subclass of WAKom, which I call 
ComancheInterface (for lack of a better name).  It has the following 
#process: method:

process: aRequest
    "This is the required Comanche method that kicks everything off. 
    Nothing else works until this method is properly run, and it will 
    automatically be run by Comanche."
    | url |
    httpRequest _ aRequest.
    url _ httpRequest url.
    (url beginsWith: '/seaside/')
        ifTrue: [^super process: aRequest].
    WebHit logRequest: aRequest.
    ((url beginsWith: '/secure/')
            and: [httpRequest ipString ~= '127.0.0.1'])
        ifTrue: [^ self redirectToSecurePort].
    (url endsWithAnyOf: MicrosoftRedirects)
        ifTrue: [^ self redirectToMicrosoft].
    (url endsWithAnyOf: SenderRedirects)
        ifTrue: [^ self redirectToSender].
    self processMultipartFields: aRequest.
    ^ self siteManager process: httpRequest

My three 'redirect' methods are implemented thus:

redirectToMicrosoft
    "So that I can redirect all the NT/XP/2K virii to the originator of the
    problem "
    ^ httpRequest redirectTo: 'http://www.microsoft.com'


redirectToSecurePort
    "In case they hit my secure pages via port 80 instead of port 443"
    ^ httpRequest redirectTo: 'https://' , httpRequest host , '/' , 
httpRequest url


redirectToSender
    "Primarily so that requests from kiddie scripts that are probing the
    system can just get routed back to the originator."
    ^ httpRequest redirectTo: 'http://' , httpRequest ipString , 
httpRequest url


The #siteManager method is implemented thus:

siteManager
    | tok site host |
    site _ 'default'.
    host _ httpRequest host.
    host notNil
        ifTrue: [tok _ host findTokens: '.'.
            tok size > 1
                ifTrue: [site _ tok at: tok size - 1].
            tok size = 1
                ifTrue: [site _ tok last].
            (SiteMap includesKey: site)
                ifFalse: [site _ 'default']].
    ^ (SiteMap at: site) default

The SiteMap is a class var containing a dictionary.  The keys of the 
dictionary contain the domain names that I host, and the values are the 
individual classes that handle serving content for each particular 
domain.  Thus, I can have a customized handler for each domain that I 
host (it also will automatically use a default handler class if some 
other isn't explicitly specified in the SiteMap).  The only mandatory 
instance method those handler classes must implement is #process:

The default site handler class (as defined in the SiteMap class var) is 
called DefaultSite (and the others are all specialized subclasses of 
DefaultSite).  It's implementation of DefaultSite>>process: is as follows:

process: httpRequest
    | str docFile doc |
    doc _ self relativePath.
    (self class cgiMap
            at: doc
            ifAbsent: []) isNil
        ifFalse: [^ self
                perform: (self class cgiMap at: doc)].
    [docFile _ (FileDirectory on: self docRoot)
                oldFileNamed: doc]
        on: FileDoesNotExistException
        do: [:ex |
            self logError: ex asString.
            ^ self errorPage].
    (docFile name endsWith: 'ssp')
        ifTrue: [str _ HTMLformatter evalEmbedded: docFile contents 
with: httpRequest.
            docFile close]
        ifFalse: [str _ docFile].
    ^ str

The implementation of DefaultSite>>relativePath is as follows:

relativePath
    | filePath dir lastChar |
    filePath _ httpRequest url copyFrom: 2 to: httpRequest url size.
    filePath size > 0
        ifTrue: [lastChar _ filePath last].
    filePath _ filePath filePath.
    (lastChar = $/
            or: [filePath = ''])
        ifTrue: [dir _ FileDirectory on: self docRoot , filePath.
            [(dir fileExists: 'index.html')
                ifTrue: [filePath _ filePath , 'index.html']
                ifFalse: [filePath _ filePath , 'index.htm']]
                on: Error
                do: [^ '']].
    ^ filePath

You will notice that all of the above also allows standard cgi-style web 
request processing.  It also allows SSP (Smalltalk Server Pages, or 
embedded Smalltalk code within an html page being served).  It also 
serves static content.  And, it does virtual hosting.  And, it all 
happily lives along side of Seaside (Seaside, plus static content, plus 
SSP content, plus virtual domain hosting, plus a few other bells and 
whistles).

Nevin

-- 
Nevin Pratt
Bountiful Baby
http://www.bountifulbaby.com
(801) 992-3137


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/seaside/attachments/20030830/27d027c2/attachment.htm


More information about the Seaside mailing list