I currently route any request where the path starts with /app to a single static file, that does routing using Javascript.
Now, I'd like to support Google's ajax crawling protocol, which means I have to return HTML snapshots at any url that starts with /app and ends with ?_escaped_fragment=.
I have these two handlers:
- url: /app\?_escaped_fragment=
script: main.app
- url: /app(/.*)?
static_files: static/pages/app.html
upload: static/pages/app\.html
But requests to /app?_escaped_fragment= are still routed to the static page. Is there a way to match the query parameters?
I know I can route /app(/.*)? to a script that returns either the static page, or a snapshot based on the presence of the query parameter, but serving static files is a lot cheaper, so I'd like only requests with the query parameter to hit my app server.
While it would be nice, if you read the spec, the handlers section is for REGEXP matching on paths only, not query params. If you design your app using RESTful principles, you can easily convert your query param access to URI-based access. Just route based on /app/escaped_fragment/.* and in the handler function, inspect the rest of the path to find which specific resource of type escaped_fragment is being requested.
This isn't something you'd do in app.yaml. Those requests should still be routed to your handlers, where they can check the request parameter and return either JSON or HTML as appropriate.
Related
My apologies if the information that I have provided is vague as I am not so experience with AWS and React.
I have a React Application being deployed on S3 and CloudFront as per what is suggested in the following link.
Use S3 and CloudFront to host Static Single Page Apps (SPAs) with HTTPs and www-redirects
So most of the things are working fine. I have 403 and 404 errors being redirected to index.html. However the issue comes in where I have query parameters in my url. eg. https://example.com/example?sample=123 when I enter the url in my browser the query string gets removed from the url. The end result I got is https://example.com/example I have read some articles about forwarding query parameters but it's not working for me.
AWS Documentation - Query String Parameters
Hope I will be able to get some advise here. Thanks in advance.
The example?sample=123 is redirected to example because S3 sees example?sample=123 as path (a folder named example?sample=123), it will throw 404 as there is no such folder.
As you have mentioned, you have configured 404 -> index.html, the browser then goes back to example, which is very likely the default page of your react app.
Overall it looks like your query string is being cleared, actually it is lost during the redirection.
The solution includes three parts:
React
You can follow these two great tutorials, one for NextJs and another for RCA.
The way it works is to detect #! in the path, keep and store the query string after redirection.
S3
As included in the two links above, you have to set the redirection rule of the S3 Bucket, to add a #!/ prefix before the path on 403 or 404, it helps React to determine which parts of the url include query string. You can configure it in Properties -> Static website hosting -> Redirection rules – optional. You need to also set index.html as the Index document and enable static web hosting with the correct permission configured.
CloudFront
In General, set Default Root Object to index.html, make sure you don't make it as /index.html.
In Origin, set Origin domain to the S3 Static Web Hosting URL (http://[bucket-name].s3-website.[region].amazonaws.com, do not choose the bucket itself.
In Behavior, change Viewer to Redirect HTTP to HTTPS, set Origin request policy - optional to AllViewer to let all query strings go through.
Hope it helps.
Is there a way via the dispatch.yaml file to dispatch a request to the right service based on the version and the service name ?
I mean, I have this request:
https://va4-0-0-dot-api-acceptance-dot-myapp.appspot.com/auth/user
It is sent by my api-acceptance service but I'd like it to go to my auth-acceptance service.
I have written in my dispatch those rules, but it does not work...
- url: "va4-0-0.myapp.appspot.com/auth/*"
service: auth-acceptance
- url: "api-acceptance.myapp.appspot.com/auth/*"
service: auth-acceptance
According to the documentation, the URL pattern that you're using:
https://[VERSION_ID]-dot-[SERVICE_ID]-dot-[MY_PROJECT_ID].appspot.com
will be bypassed by the dispatch.yaml file, so it's not possible to reroute the request this way.
Using the above pattern you are already being very specific to which service and version you want to route the request.
So either you change the URL to https://[VERSION_ID]-dot-auth-acceptance-dot-[MY_PROJECT_ID].appspot.com/auth/user or use a default routing which can later be overriden by a dispatch.yaml.
I have a single GAE app, which serves two different variations of the application depending on the invoked URL. Is it possible to have a per-url welcome page, without having the request map to a servlet which would slow the page load too much.
So, by way of example...
My app lives at myapp.appspot.com
I have two domains mapped to this app, myapp1.com and myapp2.com
If the user accesses myapp1.com, I want to serve myapp1-index.html, and
if he accesses myapp2.com, I want to serve myapp2-index.html
I never played with GAE on Java but I'm guessing you could do something based on the requested URL. I believe you can check the requested URL with the following inside your request:
httpServletRequest.getRequestURI()
Where httpServletRequest is the HttpServletRequest parameter from your doGet() method.
I am using google app engine to upload my php files.
For example this is my testing url http://testing12399234.appspot.com/index.php , whenever the url is not found i want the page to point to http://testing12399234.appspot.com/index.php , for example visiting http://testing12399234.appspot.com/randomblabla12312 must show contents of http://testing12399234.appspot.com/index.php . I know its possible via .htaccess .But how to use .htaaccess in google GAE
The app.yaml file holds the handlers for your application. The first handler that matches the requested URL is used to serve the request. In the linked documentation the last handler is:
- url: /.*
script: not_found.php
So this will match any URL that hasn't already been matched, and send it to your custom not found page. Just make sure it is the last handler in your configuration file, or it will take precedence over other handlers.
Google AppEngine PHP AppConfig documentation
I am developing a GAE application. Using the localhost for development is a nuisance because there are some interacting components that require the system to be on the internet. However, I feel weird about having a pre-release version of the app live so I am enable it when I'm troubleshooting it and then disable it. It would be better to require admin login so I can have it online and keep it private. When I make the (very simple) necessary changes to app.yaml and update the app, nothing changes. I can still access it without being logged in (I checked that I was logged out of google). Any ideas? My app.yaml text is below. Incidentally, the only other handler that requires a login, remote_api, is also misbehaving. It returns the error 'This request did not contain a necessary header'.
application: (removed for privacy)
version: 1
runtime: python
api_version: 1
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
- url: /stylesheets
static_dir: stylesheets
- url: /javascript
static_dir: javascript
- url: /images
static_dir: images
- url: /.*
script: example.py
login: admin
My best guess is that you weren't actually logged out. This can happen because there's a delay when you use the logout feature on other Google apps -- to avoid having to check back with the Google Account service for every request, App Engine uses a short-lived cookie that allows access regardless of what the Google Accounts service things until it times out (I think it's 5 minutes).
If you really want to check whether you can access this while logged out, use Chrome's Incognito Window. (Or wait 5 minutes. :-)
The remote_api behavior can also be explained: for security reasons (to thwart certain Javascript-based attacks) the remote_api handler doesn't let web browsers access the handler. It only accepts requests from the dedicated remote_api client library, which passes an extra header that Javascript code cannot set.
By the way, it's probably better to use the standard remote_api handler location and use the builtins clause to enable it:
builtins:
- remote_api: on