GAE how to serve 404 pages - google-app-engine

I have app engine an app with some static pages.
I want to serve my static content, and a script. Finally, I want to serve 404 for everything else.
My app.yaml file looks something like
runtime: go113
handlers:
- url: /myscripy
script: auto
- url: /$
static_files: public/index.html
secure: always
upload: public/index.html
- url: /(.*/)?$
static_files: public/\1index.html
secure: always
upload: public/(.*/)?index.html
http_headers:
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
OK, that's working except a few things
it's unclear to me why the - url: /$ is necessary, why is it not subsumed by - url: /(.*/)?$, but that's just a side note.
main problem: any URL that matches nothing will be rendered as empty file with a 200 status code instead of a 404.
I can force 404s by adding something like
- url: /.*
static_files: public/some_non_existing_file.html
secure: always
upload: public/some_non_existing_file.html
at the end of the app.yaml file, but that triggers an ugly 404 last ditch page that is not very appealing.
I can serve nice 404 custom pages like
- url: /.*
secure: always
static_files: public/404.html
upload: public/404.html
http_headers:
Status: 404
where public/404.html exists, however the Status: 200 header is sent before the Status: 404 header, making the whole response a 200.
I had hopes for
error_handlers:
- file: 404.html
to do something for me, but no, it seems to not do anything at all.
I can of course add a custom script to create the 404 response, but it feels a bit silly to me. Isn't there a better way ?
I'm a bit stumped - I can't believe that a long standing industry tool like GAE has no way to statically define a custom 404 page, or even render 404 status code for nonexisting pages.
Really appreciate any advice, thanks in advance!

Indeed, there is not easier way for you to achieve the custom 404 page, then adding a custom script to create the 404 response. App Engine, unfortunately, still doesn't work very well with handling some errors, which includes the error 404. As you can check in this official documentation here, there is no custom handlers from this error on Java.
This is just an example that a custom script is the viable solution.Otherwise, the solutions won't return the error 404 - as you well mentioned - or you would need to use a catch-all handler, which is not very recommended as well, since it's too broad of a solution.
In case you are using Python, there is a very good example of how to configure the trigger and example of script here.
Let me know if the information helped you!

Related

React Static Website Problem Deploying on GCP (can't find main.js or main.css)

I followed this tutorial: https://cloud.google.com/storage/docs/hosting-static-website to host my React webapp. Here is what I have so far:
// app.yaml
runtime: nodejs10
handlers:
- url: /static
static_dir: build/static
- url: /(.*\.(json|ico|js))$
static_files: build/\1
upload: build/.*\.(json|ico|js)$
- url: /.*
static_files: build/index.html
upload: build/index.html
(I've tried MANY configurations here)
I run npm run build and put the build directory in GCP Cloud Storage along with app.yaml. When I go to my website I get this:
This happens when I hit the root url.
It looks like it is looking at the static directory which should then look at build/static according to my app.yaml.
If I go directly to the webpage such as https://www.drinkingbuddy.io/build/static/js/main.39aaab31.js, the browser displays the file as expected. So it is there being hosted but something is messed up with pathing? I'm not sure.
Testing locally, everything works. Even when serving the build files.
Any guidance would be greatly appreciated! Thank you.
EDIT:
Another thing is that when I go to the base url, it just shows the document tree.
EDIT 2:
When accessing the files directly from the bucket such as https://www.storage.googleapis.com/drinkingbuddy-static/build/index.html, I then get this error:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>UserProjectAccountProblem</Code>
<Message>User project billing account not in good standing.</Message>
<Details>The billing account for the owning project is disabled in state absent</Details>
</Error>
But looking through my account I don't see any billing issues.
EDIT 3:
Now I am able to get to .../build/index.html and it displays my site. but the root / is still throwing errors saying it can't find main.js. I added homepage: "." to my package.json.
I was able to get it to work by doing homepage:"/build". Now I can access the root url and get expected behavior.

Google App Engine: Routing which appends .html

I'm deploying a React app to Google App Engine. Currently I need to append .html or /index.html to the requests but I would like to avoid this so I have clean routes.
For example, I can load mywebsite.com/docs/page1.html and mywebsite.com/docs/page1/index.html but I want to load mywebsite.com/docs/page1. The react app actually builds both of these duplicate pages so it appears this is somewhat default behaviour. The routing is only "broken" like this when I build, it works fine in the dev server.
Directory structure
- build/my_docs/
- css/
- img/
- js/
- docs/
- page1.html
- page1/
- index.html
app.yaml
runtime: python3
service: docs
handlers:
- url: /
secure: always
redirect_http_response_code: 301
static_files: build/my_docs/index.html
upload: build/my_docs/index.html
- url: /css/(.*)
static_files: build/my_docs/css/\1
upload: build/my_docs/css/(.*)
- url: /img/(.*)
static_files: build/my_docs/img/\1
upload: build/my_docs/img/(.*)
- url: /js/(.*)
static_files: build/my_docs/s/\1
upload: build/my_docs/js/(.*)
- url: /(.*\.(json|ico|xml))$
static_files: build/my_docs/\1
upload: build/my_docs/.*\.(json|ico|xml)$
- url: /docs/(.*)
static_files: build/my_docs/docs/\1
upload: build/my_docs/docs/(.*).html
# Trying to append .html to non css/img/js requests but it doesn't work!
I also tried to deploy the sample Docusaurus project to GAE with no app.yaml handlers, and I see the same undesired routing (need to append .html).
Are you satisfied with serving these html files as static docs, or should they be templates which you can pass content to?
First, in your / handler, there is no such file build/my_docs/index.html
Your /docs/(.*) handler appears to be fine. You say it works in dev but not in build? That sounds like a routing problem inside React. Check your React routing. Also, make sure you're resetting your browser cache frequently, as you may be caching old React code.
** EDIT **
Let's look at this handler:
- url: /docs/(.*)
static_files: build/my_docs/docs/\1
upload: build/my_docs/docs/(.*).html
If you request at the url /docs/page1, it is going to try to load the static file from the directory build/my_docs/docs/page1. So far, so good, as that directory exists.
The problem comes in the next line. You are asking to serve the static file build/my_docs/docs/page1.html, which does not exist in the directory specified. Try one of these:
- url: /docs/(.*)
static_files: build/my_docs/docs/\1
upload: build/my_docs/docs/(.*)/index.html
or:
- url: /docs/(.*)
static_files: build/my_docs/docs
upload: build/my_docs/docs/(.*).html
I other words, there is a mismatch between the static_files directory you specify and the location of the file you're trying to serve.

Where do I put my sitemap on appengine?

I know for typical static file such as stylesheets app.yaml must contain the path to the directory holding said files. E.g.
- url: /stylesheets
static_dir: stylesheets
How do I go about adding a sitemap to GAE server?
this is what i did for my favicon, since it's a static file:
- url: /favicon.ico
static_files: media/img/favicon.ico
upload: media/img/favicon.ico
the xml sitemap is a static file too, so you may want to do the same:
- url: /sitemap.xml
static_files: my/folder/path/sitemap.xml
upload: my/folder/path/sitemap.xml
not completely sure about the upload line, tho. but my favicon didn't work in the first place without it
edit: if you want a dynamic sitemap, you could follow the instructions in this link to generate them everytime the sitemap page gets visited
In order to follow the best practices on App Engine I would recommend you to check this Boilerplate http://appengine.beecoss.com
Over there you will find where put sitemap.xml and many more files you need. This is the best way to do it.
- url: /(robots\.txt|humans\.txt|crossdomain\.xml|sitemap\.xml)
static_files: static/\1
upload: static/(robots\.txt|humans\.txt|crossdomain\.xml|sitemap\.xml)

Can I configure all URLs to be secure on Google App Engine (python app) with just one setting?

Is it possible in the app.yaml to make sure that all requests to my app on http get redirected to https without having to specify secure: always for every url endpoint in my app.
Currently I am doing this:
url: /users/login
script: users_handler.app
secure: always
url: /signin
script: authentication.app
secure: always
url: /users/logout
script: users_handler.app
secure: always
But as new urls are added, its risky as a developer might forget to specify secure always. I would prefer to just specify a global setting that applies to all urls in my app.
If you don not want to use secure in your app.yaml you can accomplish this with webapp2.
https://webapp2.readthedocs.io/en/latest/guide/routing.html#restricting-uri-schemes
And here is a working code eaxmple: How to use WSGI to reroute a user from http to https
I feel like archaeologist, but nonetheless I'll share my findings.
All it has to be made is to add this into app.yaml:
handlers:
- url: /.*
secure: always
script: auto
There is even documentation example with that case. It's exactly the same as mine, but I removed redirection.
I don't believe that is possible. However, I think you can mitigate the problem by restructuring the URLs you have defined in your app.yaml.
The URLs is matched against handlers in your app.yaml starting from the top. So you should specify your one-off URLs and then at the bottom have a catch all setting that routes all URLs that didn't match the other settings to your default handler. You application should then display 404 pages etc. for URLs that don't exist in your application.
Something like this would work:
- url: /signin
script: authentication.app
secure: always
- url: /.*
script: users_handler.app
secure: always
This way you only have to specify a couple handlers for your application and you are much less likely to miss setting secure:always when adding a new URL or setting.
Hope that helps!

Static dir in app.yaml with space in dir name, how do I handle this?

I have a GAE + webapp2 app and i get this error for href line in my html,
INFO 2012-08-25 00:08:47,461 dev_appserver.py:2891] "GET /components%20copy_files/bootstrap-typeahead.js HTTP/1.1" 404 -
INFO 2012-08-25 00:08:47,470 dev_appserver.py:2891] "GET /components%20copy_files/application.js HTTP/1.1" 404 -
(I have a bunch of them but..)
The problem is my html is referencing to this folder for css/js
"components copy_files"
how do i map it in my app.yaml? I tried
- url: /components%20copy_files
static_dir: templates/components%20copy_files
and
- url: /components copy_files
static_dir: templates/components copy_files
and
- url: /components\%20copy_files
static_dir: templates/components\%20copy_files
But I can't get my site to load its css/js...? Thanks in advance for the help.
Also as a follow up question, if i'm porting html/css/js from a different hosting server and all the href links and dir are in place how do i get app.yaml/webapp2 to route to all those files.. do i have to declare every static dir in my app.yaml? btw: i'm porting a proj that uses twitter bootstrap (written by someone else) but i don't want to go back thru their code and edit all the hrefs, is there any quick solution to have these nested resource files play nicely with gae+app.yaml/webapp2?
Thanks a ton if you can help!!
The right configuration it's:
- url: /components%20copy_files
static_dir: templates/components copy_files
- url: /components%20copy_files
static_dir: you can have whatever name you want here(doesn't have to match the url)

Resources