Julian Rubin
Julian Rubin

Reputation: 1235

Default file in Tornado's StaticFileHandler

I have following Application configuration:

settings = {
    'default_handler_class': BaseHandler
}

app = web.Application([
        (r'/', IndexHandler),
        (r'/ws', SocketHandler),
        (r'/js/(.*)', web.StaticFileHandler, {'path': 'assets/js', 'default_filename': 'templates/error.html'}),
        (r'/css/(.*)', web.StaticFileHandler, {'path': 'assets/css'}),
        (r'/images/(.*)', web.StaticFileHandler, {'path': 'assets/images'})
    ], **settings)

When I type in http://localhost:8888/js/d3.min.js the file is served, but when I mispell file name and provide http://localhost:8888/js/d3.mi.js for example I would like to obtain my default error page which is located at templates/error.html. For URL like http://localhost:8888/not/existing it works fine but the http://localhost:8888/js/d3.mi.js gives me just plain 404: Not Found.

I found following part in documentation:

To serve a file like index.html automatically when a directory is requested, set static_handler_args=dict(default_filename="index.html") in your application settings, or add default_filename as an initializer argument for your StaticFileHandler.

However I can't understand where I should specify mentioned code. The 'default_filename': 'templates/error.html' in my code doesn't work.

Upvotes: 0

Views: 2031

Answers (2)

kwarunek
kwarunek

Reputation: 12587

default_filename

The file specified in default_filename should be in given static path. So if you move error.html to assets/js directory, than navigate to /js/ you will see content of error.html.

Basically this functionality is a helper with limited usecase (imho). More at https://stackoverflow.com/a/27891339/681044.

Custom error pages

Every request handler handles/renders errors in write_error function. This is the recommended way to create custom error pages:

class MyStaticFileHandler(tornado.web.StaticFileHandler):

    def write_error(self, status_code, *args, **kwargs):
        # custom 404 page
        if status_code in [404]:
            self.render('templates/error.html')
        else:
            super().write_error(status_code, *args, **kwargs)

Upvotes: 2

zhongkunchen
zhongkunchen

Reputation: 46

In fact The 'default_filename' work well in your code.

What does default_filename mean ?

"default_filename" means that if you request a directory such as "http://localhost:1234/js/" ,server will return a default file to you. so, you must be aware that "default file" is not error file, "default_filename" isn't what you need.

What do you need?

to write a subclass of "StaticFileHandler" will resolve. in the method "validate_absolute_path" of "StaticFileHandler"

   if not os.path.exists(absolute_path):
        raise HTTPError(404)

Don't raise 404, just return your error file path (such as js/error.js). Good luck!

my english is poor, i don't known if you can get it ^_^. it's my pleasure to exchange experience with you.

Upvotes: 1

Related Questions