Massively Multiplayer
Seamless Open-World
Real Time Strategy
 

Twitter   Facebook   Google+   YouTube   E-Mail   RSS
The One Man MMO Project: XML: NO!! XSS! CORS! Same-origin policy!!! JSON: Sure, OK
By Robert Basler on 2015-05-03 14:35:32
Homepage: onemanmmo.com email:one at onemanmmo dot com

The server software I wrote at EA had a really nice feature: it would display an XML file of its status if you made an HTTP GET request to a specific port on the server. This is handy because it can be used by server-farm monitoring tools or for things as simple as a server up/down indicator. I wanted a server up/down indicator for the theimperialrealm.com site as well as on the game's login screen.

Adding an HTTP server to the game server's front door was easy, a few lines to parse a new command line parameter for the port number, four lines to add the HTTP server and about 20 lines to output the game status as XML. Easy peasy.


<?xml version="1.0" encoding="utf-8" ?><server><status>up</status></server>

Now I needed to get that status to display in the HTML5 news page that displays on the game's login screen. My whole game UI is built on AJAX and XML, so I figured it would be pretty easy to use the same tools to add a simple up/down indicator. Wrong!

I coded up the web page, but as soon as I tried it, the AJAX call returned a mysterious 0 result status and no data. Some Googling about reminded me of AJAX's rules about Same-Origin Policy. If the XML is not on the same server as the web page calling it, it runs afoul of XSS (cross-site scripting) restrictions. I'm not going to be running my web server on the same server as the game, so that was a non-starter.

I did some research on ways to circumvent Same-Origin Policy, and discovered CORS (Cross-Origin Resource Sharing) which would work fine for this, but it would mean implementing a new feature into my in-game HTTP server. Too much trouble.

Next I tried having the server status as a super-simple HTTP5 document and embedding it in the news page as an IFRAME. This worked fine, but IFRAME's are kind of a pain to position and make flow with the document. The real killer though, was when the game server was actually down. In that case it would display the chrome error page where the server status was supposed to go, and I couldn't find any reasonable way to overcome that ugliness.


<!DOCTYPE html><html lang="en"><head><meta http-equiv="content-type" content="text/html;charset=UTF-8"/></head><body style="font-family:Helvetica,Arial,sans-serif;">Server is <font color="green">Up</font></body></html>

I did some more reading on ways to work around Same-Origin Policy and discovered JSONP. JSON is just another data format like XML (it's name value pairs.) The P part is where it gets tricky. I'm a little impressed by whoever came up with this technique, because its pretty devious. I modified the server a third time to spit out a JSONP document, embedded it in the page and presto, problem solved.

server({"Status": "down"});

There are some caveats using JSONP, the first I discovered is that the script runs before the page completes loading so I wasn't able to modify the DIV I wanted to put the server status in directly from the function called by JSONP. Instead, I had to save the data returned in a variable and then load it into the page in an onLoad handler.

Next I tested what happens if the server is down completely. It turns out, the JSONP code just doesn't run and everything else is fine, so I modified my code to have the default message if no data is available from the server via the JSONP code be that the server is down.

The last thing to do was to add a refresh tag to the news document so that the server status would change if the server status changed while the page was showing.

<meta http-equiv="refresh" content="60">

When the game becomes so popular that this simple server status is too much of a load on the front-door server, I'll modify the news page to point to a PHP page proxy with cacheing on the game's main web server (kind of like this.)

So given that you can do with JSON what I wanted to do with XML, I think Cross-Origin policy is stupid.

You can view the full source for the final news page with the JSONP request here.

New Comment

Cookie Warning

We were unable to retrieve our session cookie from your web browser. If pressing F5 once to reload this page does not get rid of this message, please read this to learn more.

You will not be able to post until you resolve this problem.

Comment (You can use HTML, but please double-check web link URLs and HTML tags!)
Your Name
Homepage (optional, don't include http://)
Email (optional, but automatically spam protected so please do)
Multiply: 2 and 6 = (What's this?)

Admin Log In



[The Imperial Realm :: Miranda] [Blog] [Gallery] [About]
Terms Of Use & Privacy Policy