_ah/warmup requests coming with hosts prefixed with app version - google-app-engine

I am using the warmup service to carry out precaching/etc. The request gets called with self.request.host being prefixed with a version of the app.
All other handler requests are coming with the expected host name for the app.
So if the app name is myapp - then all requests are called with self.request.host set to myapp.appspot.com, whereas for "_ah/warmup" call it is getting set to nnn.myapp.appspot.com.
My code is expecting the self.request.host to be always 'myapp.appspot.com'. Is this by design or am I missing something.
Thanks.

I think this is by design because the warmup service is for a specific version. All other requests are going straight to your main app URL, which is just "aliased" to whatever version happens to be the default version at the time.
By the way, it is documented that you can access all deployed versions of your app by prefixing the version number to the domain name, so you should be aware that any users could access any version if they know about this, and if you haven't taken countermeasures! So you should definitely support this - it's an official feature of App Engine.

Related

managing app engine versions through API calls

Is there anyway that I can manage the appengine versions and instances through API calls?
What I mean by managing is to start/stop/delete versions deployed to the appengine through API calls.
Is that possible by using gcloud sdk commands from command line ?
Another question , does google provide APIs (or commands) to check the status of running instances ? check if the instance is idle or not and how long its being idle
There is a beta API for managing versions and services here:
https://cloud.google.com/appengine/docs/admin-api/
The API is still beta because it's under active development; there are still a few methods and fields which aren't implemented. Shortly after those are complete, the API will be marked "v1", though v1beta4 and v1beta5 will continue to be supported for several months in transition.
For example, the API doesn't yet include operations on instances, but I expect that List/Get/Delete will be available fairly soon. Since App Engine automatically creates instances for you, there is no create instance API.
I just noticed that the most recent documentation re-skin seems to have hidden the documentation for the REST interface, so I'll drop that link there so you that you can find the currently implemented methods. (Version.Update is also implemented for a few fields, so that documentation update should be coming out very soon.)
2020 UPDATE: You can do it using the apps.services.versions api. You can stop/start a version with the PATCH method, setting the mask to "servingStatus" and in the body set the "servingStatus" field to "STOPPED"/"SERVING".
Similarly, you can use the delete/create methods to launch and remove new versions
Reference:
https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions/patch

Url for routing to specifc version with SSL and custom domain on app engine

Is there a url pattern that will by default route traffic to a specific version using a custom domain and SSL on app engine, without specifying the routing in a disptach file? I.e. something like
https://themagic.mydomain.com
Where themagic may include dots, dashes - whatever it takes?
The docs specify various options, but none that are both SSL and mydomain.com, they are:
https://instance-dot-version-dot-module-dot-app-id.appspot.com
http://instance.version.module.app-id.my-custom-domain.com
Sends the request to the named module, version, and instance.
https://version-dot-module-dot-app-id.appspot.com
http://version.module.app-id.my-custom-domain.com
Sends the request to an available instance of the named module and version.
These address forms have a default routing behavior. Note that the default routing is overridden if there is a matching pattern in the dispatch file:
https://module-dot-app-id.appspot.com
http://module.app-id.my-custom-domain.com
Sends the request to an available instance of the default version of the named module.
https://version-dot-app-id.appspot.com
http://version.app-id.my-custom-domain.com
Sends the request to an available instance of the given version of the default module.
https://app-id.appspot.com
http://app-id.my-custom-domain.com
Sends the request to an available instance of the default version of the default module.
For several years I have been using the routing
https://version1.www.mydomain.com
This historically worked fine to route traffic to the version called version1 on the default modile, and continues to work. But I'm uncomfortable with it because a) it's not documented (as far as I can find) b) it's tricky to get the SSL setup. Specificall on the SSL, the only way (as far as I can tell) is to use a wildcard SSL cert (which is either pricey, or self signed). My attempts to use this URL with an SSL cert signed only for version1.www.mydomain.com resulted in the traffic being routed to the default version, presumably because of the specific 'custom domain' rules that one needs to add via appengine's web UI (cloud console) in order to add the SSL cert. So for now, a self signed wild-card cert is the only way I can make it work.
Through experimentation, it also seems that version-www.mydomain.com may be a valid routing to that version, but again, whether this can be setup with SSL is in doubt, and there's no docs on it.
If at all possible, please link to documentation.
Updated answer
It appears that while this is working as intended, it's not a case of soft routing, but rather subdomain -> version / module routing described elsewhere on the same docs page linked originally. There was an issue with the form of the subdomains shown in the docs at the time this comment exchange occurred, which should be fixed shortly to be more clearly readable.
https://module-dot-app-id.appspot.com
http://module.app-id.my-custom-domain.com
Should become:
http(s)://module-dot-appid.appspot.com
OR
http(s)://module.appid.appspot.com
OR
http(s)://module.custom-domain.com
Or an equivalent.
Original answer
The documentation you linked adequately describes the routing rules. What you've observed in terms of default-module routing is an example of the "Soft Routing" the docs describe. Explicit addressing of modules and versions will need to take the form the docs requires, else the request will go to the default module.

AppEngine Cloud EndPoint 404 Not Found with version 2 of my App

I have deployed a new version of my App that contains a new cloud endpoint.
I have made the new version the default version.
I have even deleted the old version (version 1).
If I try to hit https://<myappid>.appspot.com/_ah/api/ then I get a
404 Not Found.
If I try to hit https://2-dot-<myappid>.appspot.com/_ah/api/ then
my request gets served.
It's been a full 24 hours since I uploaded version 2. And more than an hour since I marked version 2 as default and deleted version 1, but I'm still getting the 404.
I don't want to ship my client explicitly pointing to 2-dot-<myappid> as this locks the client to a particular version.
Any ideas on what is going wrong?
Cloud Console currently doesn't automatically update Endpoints when changing app versions. You need to use the old App Engine Admin Console to make it update. So, I suggest trying switching versions to another version and switching back immediately. It should fix it for you.
Upload a new major version of your app. This can be identical to your current default version, which just the version name changed.
Visit the App Engine Admin Console and select your project.
Click Versions.
Change the default version to the one you just deployed.
Change the default version back to the one it just was.
At this point, the default domain should be working for you.
how about trying "https://xandar-wordgame.appspot.com/_ah/api/explorer",it may redirect the page to api-explorer where you can explore your api.
Others:
I've also encountered the same problem. but then I realized I have not changed the javascript code that load the api client. I changed the version in java annotation , but forgot to change the gapi.client.load(_apiName, _version, _your_call_back_function,_apiRoot) in web client .
Hope it will help.

How to work with authentication in local Google App Engine tests written in Go?

I'm building a webapp in Go that requires authentication. I'd like to run local tests using appengine/aetest that validate the authentication behavior. However, I do not see any way to create an aetest.Context with a dummy user. Am I missing something?
I had a similar issue with Python sdk. The gist of the solution is to bypass authentication when tests run locally.
You should have access to the [web] app object at the the test setup time - create a user object and save it into the app (or wherever your get_current_user() method will check).
This will let you unit test all application functions except authentication itself. For the later part you can deploy your latest changes as unpublished google app version, then test authentication and if all works - publish the version.
I've discovered some header values that seem to do the trick. appengine/user/user_dev.go has the following:
X-AppEngine-Internal-User-Email
X-AppEngine-Internal-User-Federated-Identity
X-AppEngine-Internal-User-Federated-Provider
X-AppEngine-Internal-User-Id
X-AppEngine-Internal-User-Is-Admin
If I set those headers on the Context's Request when doing in-process tests, things seem to work as expected. If I set the headers on a request that I create separately, things are less successful, since the 'user.Current()' call consults the Context's Request.
These headers might work in a Python environment as well.

http request from Google App Engine

I'm trying to make http requests from my Google App Engine webapp, and discovered I have to use URLConnection since it's the only whitelisted class. The corresponding Clojure library is clojure.contrib.http.agent, and my code is as follows:
(defroutes example
(GET "/" [] (http/string (http/http-agent "http://www.example.com")))
(route/not-found "Page not found"))
This works fine in my development environment- the browser displays the text for example.com. But when I test it out with Google's development app server:
phrygian:example wei$ dev_appserver.sh war
2010-09-28 14:53:36.120 java[43845:903] [Java CocoaComponent compatibility mode]: Enabled
...
INFO: The server is running at http://localhost:8080/
It just hangs when I load the page. No error, or anything. Any idea what might be going on?
http-agent creates threads so that might be why it does not work.
From the API documentation:
Creates (and immediately returns) an Agent representing an HTTP
request running in a new thread.
You could try http-connection, which is a wrapper around HttpURLConnection, so this should work.
Another alternative is to try clj-http. The API seems to be a bit more high-level, but it uses Apache HttpComponents which might be blacklisted.
I am guessing http.async.client is a definite no-go due to its strong asynchronous approach.
You might want to try appengine.urlfetch/fetch from appengine-clj (http://github.com/r0man/appengine-clj, also in clojars)

Resources