How to solve problem with embed AppStream in recent Chrome update

AppStream from Amazon is service that allows to have Remote Desktop Session in your browser. Our company is using it to do evaluation of our software for potential customers. Customers can play with, explore it features etc, before buy. On other side, we can see what people are struggling it and adjust our software.

We were using it for some time, but recent Chrome update broke it. Safari stopped working some time before that. Now instead of opening remote session, we got 404 from Amazon. I believe it happens because Chrome stopped providing cooking for embedded iframe. And following post will show, how to fix it.

Normally service works like this. Web page calls some service on backend to get streaming url. Then following code will embed AppStream session on your page:

  var appstreamOptions = {
    sessionURL: url,
    userInterfaceConfig: {[AppStream.Embed.Options.HIDDEN_ELEMENTS]: []}
  };

  appstreamEmbed = new AppStream.Embed('embed-app-stream-container', appstreamOptions);

But because stream URL is actually Amazon URL, all cookies will not apply and as result session will fail to load with 404 errors.

To fix it Amazon suggests to create sub-domain: https://docs.aws.amazon.com/appstream2/latest/developerguide/embed-streaming-sessions.html#configuration-requirements-custom-domains.  And here I will show how to do it and how to test it.

Let’s assume you have this site: training.example.com. We have to create content.training.example.com that will forward all requests to appropriate Amazon services. In this example I will use ap-northeast-1 region. I will show to create test environment on your PC. For live web site it is better to contact your IT, but principle is exactly the same.

Ok, first thing I did is to create following entry in C:\Windows\System32\drivers\etc\hosts file and add following line:
127.0.0.1 training.example.com

From now on, when I will access training.example.com, it will go to my PC instead of internet. It is obvious step for any web site development.

Next thing, I create new web site in IIS and bind it to training.example.com. You have to bind it only for HTTPS. I did mistake of binding it HTTP and then nothing worked correctly until I tried Firefox that actually let me know that I was accessing HTTPS from HTTP page.

On that site I put one html page from real web site as well as couple of JS scripts that used on that page. You should know what to copy. Open HTTP Response Headers and add item “appstream-custom-url-domain” with value “training.example.com”. Without quotes obviously. Check that everything except AppStream is working. You will see few requests going to Amazon and finally 404 response.

On next step you should install Application Request Routing Cache for your IIS. After that start IIS Manger, select server node (top node) in left tree and open “Application Request Routing Cache”. On the left side click on “Server Proxy Settings…”. There check “Enable proxy”, uncheck “Reverse rewrite host in response headers” (it does not work properly). I also unchecked “Include TCP port from client IP” and “Enable disk cache”

After that create new web site in IIS and bind it to content.training.example.com and to *. content.training.example.com. Then open URL Rewrite for that site, click Add Rule from the top-left side and select Reverse Proxy. Enter appstream2.ap-northeast-1.aws.amazon.com as server name and uncheck “Enable SSL Offloading”.

Basically we have requests that coming towards content.training.example.com  in form of  <prefix>content.training.example.com<suffix> . For example, request:
abc.content.training.example.com/path/param=value

should be changed to
abc.appstream2.ap-northeast-1.aws.amazon.com/path/param1=value1

but then on return all 302 responses should change location back to content.training.example.com. For example, when Amazon returns
xyz.appstream2.ap-northeast-1.aws.amazon.com/path/param2=value2

as location, it should be changed to

xyz.content.training.example.com/path/param2=value2

and browser will query our content.training.example.com site instead of Amazons.

To do this open Inbound rule that IIS created and change conditions to this:
(.*)content.training.example.com

And Rewrite URL in “Action Properties” to:
{C:1}appstream2.ap-northeast-1.aws.amazon.com/{R:1}

This will allow to change incoming URL, change to appropriate Amazon URL and request it from Amazon. This implements first part.

Next, create new blank Outbond rule. Create one precondition using “Regular Expressions” and add this condition: {RESPONSE_STATUS} Matches the Pattern “3\d\d” without quotes. Then in Match section select “Server Variable”  and in “Variable name” use “RESPONSE_Location” (without quotes).

Then use this as Pattern:
^https://([^\.]+\.)appstream2.ap-northeast-1.aws.amazon.com(.*)

Action type suppose to be rewrite, and “Value” in “Action Properties” should be this:
https://{R:1}content.training.example.com{R:2}

This will replace location in response from Amazon link to our sub-domain and browser will request next response from us and not from Amazon.

We are almost there. Next I found that first request to Amazon always redirect to subdomain that have many digits and letters. Let’s say it is abc01.appstream2.ap-northeast-1.aws.amazon.com. As result I also added abc01.content.training.example.com to hosts file. And remember that we added *.content.training.example.com  to IIS binding. That should cover it.

And last thing to do is to change URL in script file to this:

  var newUrl = url.replace('/appstream2.ap-northeast-1.aws.amazon.com/', '/content.training.example.com/');
  var appstreamOptions = {
    sessionURL: newUrl,
    userInterfaceConfig: {[AppStream.Embed.Options.HIDDEN_ELEMENTS]: []}
  };

  appstreamEmbed = new AppStream.Embed('embed-app-stream-container', appstreamOptions);

And now, from browser’s point of view, we are accessing sub-domain, and all cookies and everything will nicely flow from our main site to our sub-domain and AppStream is working correctly.

As I said before, this is setup for local testing. Live site should be setup by professionals.

I hope it helps someone.