Merge pull request #205 from CartoDB/url_rewrite

added /u/:user routing
This commit is contained in:
Raul Ochoa 2015-03-20 12:22:07 +01:00
commit 9dcb397737
7 changed files with 56 additions and 25 deletions

View File

@ -164,13 +164,12 @@ app.set("trust proxy", true);
// basic routing
app.options('*', function(req,res) { setCrossDomain(res); res.end(); });
app.all(global.settings.base_url+'/sql', function(req, res) { handleQuery(req, res) } );
app.all(global.settings.base_url+'/sql.:f', function(req, res) { handleQuery(req, res) } );
app.get(global.settings.base_url+'/cachestatus', function(req, res) { handleCacheStatus(req, res) } );
app.get(global.settings.base_url+'/health', function(req, res) { handleHealthCheck(req, res) } );
app.get(global.settings.base_url+'/version', function(req, res) {
res.send(getVersion());
});
app.all(global.settings.base_url + '/sql', handleQuery);
app.all(global.settings.base_url + '/sql.:f', handleQuery);
app.get(global.settings.base_url + '/cachestatus', handleCacheStatus);
app.get(global.settings.base_url + '/health', handleHealthCheck);
app.get(global.settings.base_url + '/version', handleVersion);
var sqlQueryMayWriteRegex = new RegExp("\\b(alter|insert|update|delete|create|drop|reindex|truncate|refresh)\\b", "i");
/**
@ -192,6 +191,10 @@ function sanitize_filename(filename) {
}
// request handlers
function handleVersion(req, res) {
res.send(getVersion());
}
function handleQuery(req, res) {
// extract input
@ -207,6 +210,7 @@ function handleQuery(req, res) {
var requestedFilename = params.filename;
var filename = requestedFilename;
var requestedSkipfields = params.skipfields;
var cdbUsername = cdbReq.userByReq(req);
var skipfields;
var dp = params.dp; // decimal point digits (defaults to 6)
var gn = "the_geom"; // TODO: read from configuration file
@ -280,8 +284,7 @@ function handleQuery(req, res) {
var formatter;
var cdbUsername = cdbReq.userByReq(req),
authApi = new AuthApi(req, params),
var authApi = new AuthApi(req, params),
dbParams;
if ( req.profiler ) req.profiler.done('init');

View File

@ -8,21 +8,30 @@ function CartodbRequest() {
module.exports = CartodbRequest;
/**
* If the request contains the user use it, if not guess from the host
*/
CartodbRequest.prototype.userByReq = function(req) {
var host = req.headers.host;
var mat = host.match(re_userFromHost);
if ( ! mat ) {
console.error("ERROR: user pattern '" + re_userFromHost + "' does not match hostname '" + host + "'");
return;
}
// console.log("Matches: "); console.dir(mat);
if ( ! mat.length === 2 ) {
console.error("ERROR: pattern '" + re_userFromHost + "' gave unexpected matches against '" + host + "': " + mat);
return;
}
return mat[1];
if (req.params.user) {
return req.params.user;
}
return userByHostName(req.headers.host);
};
var re_userFromHost = new RegExp(
global.settings.user_from_host || '^([^\\.]+)\\.' // would extract "strk" from "strk.cartodb.com"
);
function userByHostName(host) {
var mat = host.match(re_userFromHost);
if (!mat) {
console.error("ERROR: user pattern '" + re_userFromHost + "' does not match hostname '" + host + "'");
return;
}
if (mat.length !== 2) {
console.error("ERROR: pattern '" + re_userFromHost + "' gave unexpected matches against '" + host + "': " + mat);
return;
}
return mat[1];
}

View File

@ -1,4 +1,6 @@
module.exports.base_url = '/api/:version';
// In case the base_url has a :user param the username will be the one specified in the URL,
// otherwise it will fallback to extract the username from the host header.
module.exports.base_url = '(?:/api/:version|/u/:user/api/:version)';
// If useProfiler is true every response will be served with an
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.

View File

@ -1,4 +1,6 @@
module.exports.base_url = '/api/:version';
// In case the base_url has a :user param the username will be the one specified in the URL,
// otherwise it will fallback to extract the username from the host header.
module.exports.base_url = '(?:/api/:version|/u/:user/api/:version)';
// If useProfiler is true every response will be served with an
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.

View File

@ -1,4 +1,6 @@
module.exports.base_url = '/api/:version';
// In case the base_url has a :user param the username will be the one specified in the URL,
// otherwise it will fallback to extract the username from the host header.
module.exports.base_url = '(?:/api/:version|/u/:user/api/:version)';
// If useProfiler is true every response will be served with an
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.

View File

@ -1,4 +1,6 @@
module.exports.base_url = '/api/:version';
// In case the base_url has a :user param the username will be the one specified in the URL,
// otherwise it will fallback to extract the username from the host header.
module.exports.base_url = '(?:/api/:version|/u/:user/api/:version)';
// If useProfiler is true every response will be served with an
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.

View File

@ -147,6 +147,17 @@ test('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just
});
});
test('GET /u/vizzuality/api/v1/sql with SQL parameter on SELECT only', function(done){
assert.response(app, {
url: '/u/vizzuality/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
method: 'GET'
},{ }, function(res) {
assert.equal(res.statusCode, 200, res.body);
done();
});
});
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/121
test('SELECT from user-specific database', function(done){
var backupDBHost = global.settings.db_host;