Created
March 1, 2013 15:12
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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