Skip to content

Instantly share code, notes, and snippets.

@laczoka
Created March 1, 2013 15:12
Show Gist options
  • Save laczoka/5065270 to your computer and use it in GitHub Desktop.
Save laczoka/5065270 to your computer and use it in GitHub Desktop.
Show how to implement proper CORS support in Stardog (stardog.com) using a Node.js example
/* ISSUE: Stardog (up to v1.1.3) does not properly support CORS[1] interaction.
The issue is two-fold:
1) Stardog tries to authenticated the OPTIONS "pre-flight" request.
2) Stardog doesn't return CORS headers, hence can only be accessed
by browser web apps running in a different domain via a proxy.
Effected browsers: Firefox and IE*. Safari and Chrome work due to a bug in webkit (see [2]).
Expected behavior: Stardog MUST NOT try to authenticate the pre-flight request, it SHOULD rather return
proper CORS headers. [4]
As pers CORS spec: if the pre-flight request fails (response code != 200), the original request will not be sent.
For security reasons, browsers will not send any authentication information or custom HTTP headers in the pre-flight request.
[1] https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=778548
[3] https://bugzilla.mozilla.org/show_bug.cgi?id=778548#c5
[4] https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request
This is an example implementation to demostrate how should Stardog work in a CORS scenario
Run it:
> node testCORS.js
*/
var http = require('http');
/* Always add these CORS headers to the response */
function addCORSHeaders(res) {
res.setHeader("Access-Control-Allow-Headers","accept, Authorization, origin, sd-connection-string");
res.setHeader("Access-Control-Allow-Methods","OPTIONS, GET");
res.setHeader("Access-Control-Allow-Origin","*");
}
var server = http.createServer(function(req, res){
console.log('Connection');
/* Browsers will send a "pre-flight" HTTP request and scan the response for CORS headers.
The pre-flight OPTIONS request MUST NOT be authenticated.
*/
if (req.method == "OPTIONS") {
console.log('Preflight request OPTIONS received');
res.setHeader('Content-Type', 'text/plain')
addCORSHeaders(res);
res.writeHead(200);
res.end();
} else {
/* Regular requests MAY be authenticated. */
if (req.headers['authorization']) {
console.log('Authorization header received: '+req.headers['authorization']);
res.setHeader('Content-Type', 'application/sparql-results+json')
addCORSHeaders(res);
res.writeHead(200);
res.write(JSON.stringify({"head": {"vars": [ "name" ]}, "results": {
"bindings": [
{"name": { "type": "literal", "xml:lang": "en", "value": "DMP-BDT310 3D Blu-ray Player" }},
{"name": { "type": "literal", "xml:lang": "en", "value": "DVP-SR350"}}]}}));
res.end();
} else {
res.setHeader('Content-Type', 'text/plain')
res.setHeader('WWW-Authenticate','BASIC realm="Stardog"');
addCORSHeaders(res);
res.writeHead(401);
res.end();
}
}
});
server.listen('8088');
console.log("HTTP Server started on http://localhost:8088");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment