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.")
