9

I'm working on a GAE application which largely consists of static content. I've configured the following handlers:

- url: /content/(.*\..*)
  static_files: static/content/\1
  upload: static/content/(.*)

- url: /content/(.+)
  static_files: static/content/\1.html
  upload: static/content/(.*)\.html

The first handler is used to serve images, stylesheets, etc.; the second handles plain URLs like /content/zoo/monkeys/george and serves a corresponding HTML file.

Right now, GAE is returning an empty page if there is no corresponding static file for a URL. I'd like to set up a custom 404 page for these cases, but apparently this is not straightforward.

Answers to similar questions suggested putting a "catch-all" handler on the bottom of my app.yaml, with a RequestHandler that generates the error page. However, /content/(.+) matches all URLs under /content/, valid or not, which means such a handler won't get invoked.

I can only think of two other solutions:

  1. Route all requests through a dynamic handler, which writes out content for valid URLs, or an error page for invalid ones. I don't like this, because it is far less efficient than letting GAE serve the static files.
  2. Declare a separate static handler that explicitly matches each static file, and then put a "catch-all" handler at the bottom -- I don't like this either, because it would result in a long list of handlers.

Is there another way to set up a proper 404 page for this case?

Tony the Pony
  • 40,327
  • 71
  • 187
  • 281

2 Answers2

7

Answer to an old thread for those that would find it useful.

  1. Add require_matching_file: true as the last property of the handler.

    If there is no corresponding file, the next handler in the waterfall will be invoked, instead of generating the default 404 page.

  2. Then add a new catch-all section at the bottom of app.yaml with a dynamic handler that processes invalid URLs

Example:

- url: /content/(.*\..*)
  static_files: static/content/\1
  upload: static/content/(.*)
  require_matching_file: true

- url: /content/(.+)
  static_files: static/content/\1.html
  upload: static/content/(.*)\.html
  require_matching_file: true

- url: /.*
  script: auto

This way GAE will serve all existing static assets through the first 2 handlers. The dynamic handler will be invoked only for non-existing URLs. You will need to write the code for that obviously...

One big disclaimer here : require_matching_file is undocumented. But it turns out that GAE adds that field automatically to your app.yaml when you upload it.

Vejja
  • 81
  • 1
  • 4
-1

Try 'error_handlers'.

error_handlers:
 - file: custom_404.html

From GAE App.yaml documentation - Each file entry indicates a static file that should be served in place of the generic error response. If you specify a file element without a corresponding error_code element, the static file will be the default error page for your app.

N.P
  • 245
  • 1
  • 12