List,

Just to be sure that if someone reads this thread can also test what I
did, I'm attaching my implementation of the static_handler.

Cheers,

On Sun, Oct 25, 2009 at 4:37 PM, Andres Riancho
<[email protected]> wrote:
> Adam,
>
> On Sun, Oct 25, 2009 at 2:08 AM, Adam Atlas <[email protected]> wrote:
>>
>> I totally understand why this is counterintuitive coming from PHP, as
>> I wondered the exact same thing during my own "conversion" from PHP to
>> Python/web.py. :)
>
> I think that this is counter-intuitive when moving from any other
> programming language. One thing is the programming language, and
> another is the framework. I all programming languages for the web
> (that I know of), Apache or IIS will have special "handlers" that are
> only called based on the extension.
>
>> Coming from PHP or any other CGI-like environment (i.e. an external
>> server directly serves some files and executes some others), you'll
>> need to shift your thinking a bit. You're not going to have URLs like 
>> "http://.../foo.py?something
>> "; web.py (and most other Python web frameworks) don't impose that
>> kind of automatic mapping between URLs and files -- and that's very
>> much a feature. Unless you actually *are* just serving a tree of
>> static files, that style results in a tradeoff between the potential
>> for clean, expressive URLs and the ability to structure your code as
>> you please. With web.py -- and most other Python web frameworks -- you
>> don't have to compromise between the two.
>
> Ok, I understand why in a world ruled by Google and SEO this is a
> "must have feature".
>
>> So you're not going to have URLs getting mapped directly to an
>> "index.py" script and other .py files. Of course you can still call it
>> index.py if you want, but that might reinforce that CGI/PHP mindset
>> that doesn't apply here. Just try to forget about the idea of URLs
>> referring to filesystem paths, *except* within the self-contained /
>> static/ ghetto. Instead, design the "urls" list according to how you
>> actually want your URLs to look,
>
> In my case, I don't really care about how URLs look, but I'll keep this in 
> mind.
>
>> and understand that index.py (or
>> whatever you rename it) represents your entire application, handling
>> requests for *all* of your pages and dispatching them to library code
>> accordingly -- not a file that is called externally to serve your
>> site's index page living alongside co-equal .py files for other pages.
>
> Sorry, but I failed to understand this. Could you please post a small
> code snippet for me to understand? Would it be something like this?:
>
> """
> import web
> import module_a
> import module_b
>
> class index:
>    def GET(self):
>        if web.path... == 'a':
>            return module_a.run( web.input )
>        else:
>            return module_b.run( web.input )
> """
>
>
>> The CGI/PHP style isn't necessarily bad, but that's not how web.py
>> does it (and that's unlikely to change), and I think the web.py
>> approach offers many significant advantages, once you get used to it.
>
> Pretty URLs are an advantage, having a "static" dir is kind of odd.
> Maybe another way to solve this issue, that could be more in the lines
> of web.py, would be to handle requests this way:
>
> - If the user requested something that was previously defined in
> application's mapping parameter, then handle it as expected.
> - If the user requested something that WAS NOT previously defined in
> the mapping, then try to read the file that's being requested.
>
> This could be easily added to web.py , and would not modify the
> frameworks feature of having nice URLs, right?
>
> While I was writing this answer, I realized that this could be easily
> done with something like:
>
> urls = ('/', 'index'
>           '/passwd/', 'passwd'
>           '.*', 'static_handler')
>
> Where static_handler.py is going to read what path was requested, and
> read the static file.
> No modifications to web.py are needed with this approach, and I can be happy 
> ;)
>
>> (For what it's worth, I've tried doing "line-to-line" ports from PHP
>> to Python, and while the result might work, it might not be structured
>> very well or take full advantage of Python's benefits. I usually find
>> it's better to have a clear definition of the application's behavior
>> and requirements, and to rebuild it from that, using pure Python
>> idioms. I'm not saying you should throw away your existing code, but
>> I'd use it more as a reference for building the new version, rather
>> than doing a straight port.)
>
> Yes, well... I'm not doing a 100% line by line port, I'm trying to use
> web.py and python features also =)
>
> Thanks for your answer, and for making me see that I can write my own
> static_handler (haven't tested it yet, but I think it could work).
>
> Cheers,
>
>> - Adam
>>
>>
>> On 24 Oct 2009, at 19:30, Andres Riancho wrote:
>>> List,
>>>
>>>    Hi, I'm new to webpy and also new to the list, so sorry if I'm
>>> doing a stupid question ;)
>>>
>>>    I'm porting a PHP application to Python using webpy. The PHP
>>> application has a decent size, and my idea is to perform a "line to
>>> line" port. One of the reasons I chose webpy was the ability to run
>>> its own server, that would allow me to run this python application
>>> without the need of Apache+mod_python.
>>>
>>>    After porting the index, and trying it with "python index.py" ,
>>> I'm seeing that the HTML code that is generated (which is the same as
>>> the PHP web application) is pointing to the correct locations for the
>>> static files like ".js" and ".css", but the embedded webpy server
>>> isn't serving those files.
>>>
>>>    Quick google search, and I found that static files should all be
>>> located in the "static" directory. My first thought was... these guys
>>> have to be kidding, right? Is there a real reason for this? Why not
>>> using the classic method of "running" the files with particular
>>> extensions like ".py", and just reading the rest of the files?
>>>
>>>    If I move all the static files, to the static directory, it would
>>> only be needed for running in the embedded HTTP daemon, because Apache
>>> wouldn't send the "run this" request to webpy for those files, right?
>>> I think that the embedded HTTP daemon should mimic Apache as much as
>>> possible.
>>>
>>>    Am I the only one that finds this particularly annoying?
>>>
>>>    I know that I could have just patched the "if" that matches the
>>> static content, but that wouldn't have been useful for the
>>> community ;) . If you guys tell me its ok, I could send you a patch
>>> for webpy where all the "py" files are run, and the rest is treated as
>>> static content.
>>>
>>> Cheers,
>>> Andrés Riancho
>>> http://w3af.sf.net/
>>>
>>> >
>>
>>
>> >>
>>
>
>
>
> --
> Andrés Riancho
> Founder, Bonsai - Information Security
> http://www.bonsai-sec.com/
> http://w3af.sf.net/
>



-- 
Andrés Riancho
Founder, Bonsai - Information Security
http://www.bonsai-sec.com/
http://w3af.sf.net/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web.py" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [email protected]
For more options, visit this group at http://groups.google.com/group/webpy?hl=en
-~----------~----~----~----~------~----~------~--~---

'''
Copyright (c) 2006-2009, Wade Alcorn 
All Rights Reserved
[email protected] - http://www.bindshell.net
'''

#
# System includes
#
import cgi
import web
import os


class static_handler:
    '''
    This class is called when NO MATCH IS FOUND in the mapping that is passed to the webpy
    application (urls parameter in index.py).
    '''

    def GET(self, path):
        '''
        @parameter path: The path that was requested by the user, and was forwarded here by index.py
        @return: The contents of a static file.
        '''
        full_path = os.path.join( os.getcwd() , path )
        
        #
        #   Path traversal protection
        #
        if not full_path.startswith( os.getcwd() ):
            return web.notfound("Sorry, the page you were looking for was not found.")


        if os.path.exists( full_path ) and os.path.isfile( full_path ):
            if os.access( full_path, os.R_OK ):
                fh = file( full_path, 'r')
                return fh.read()
            else:
                #
                #   The user has no privileges to read this file
                #
                return web.notfound("Sorry, the file you are trying to access can not be read.")

        return web.notfound("Sorry, the page you were looking for was not found.")

Reply via email to