moved lbryuri to own file and handled errors

This commit is contained in:
bill bittner 2017-12-06 18:49:05 -08:00
parent 87d026b5ec
commit 075332275e
5 changed files with 108 additions and 113 deletions

View file

@ -1,5 +1,4 @@
const logger = require('winston');
const { postToStats } = require('../controllers/statsController.js');
module.exports = {
returnErrorMessageAndStatus: function (error) {
@ -33,17 +32,15 @@ module.exports = {
}
return [status, message];
},
handleRequestError: function (action, originalUrl, ip, error, res) {
handleRequestError: function (originalUrl, ip, error, res) {
logger.error(`Request Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
postToStats(action, originalUrl, ip, null, null, error);
const [status, message] = module.exports.returnErrorMessageAndStatus(error);
res
.status(status)
.render('requestError', module.exports.createErrorResponsePayload(status, message));
},
handleApiError: function (action, originalUrl, ip, error, res) {
logger.error(`Api ${action} Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
postToStats(action, originalUrl, ip, null, null, error);
handleApiError: function (originalUrl, ip, error, res) {
logger.error(`Api Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
const [status, message] = module.exports.returnErrorMessageAndStatus(error);
res
.status(status)

90
helpers/lbryuri.js Normal file
View file

@ -0,0 +1,90 @@
const logger = require('winston');
// const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
module.exports = {
REGEXP_INVALID_URI: /[^A-Za-z0-9-]/g,
REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
CHANNEL_CHAR : '@',
parseIdentifier : function (identifier) {
logger.debug('parsing identifier:', identifier);
const componentsRegex = new RegExp(
'([^:$#/]*)' + // value (stops at the first separator or end)
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
const [proto, value, modifierSeperator, modifier] = componentsRegex
.exec(identifier)
.map(match => match || null);
logger.debug(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`);
// Validate and process name
const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
const channelName = isChannel ? value : null;
let claimId;
if (isChannel) {
if (!channelName) {
throw new Error('No channel name after @.');
}
const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_URI);
if (nameBadChars) {
throw new Error(`Invalid characters in channel name: ${nameBadChars.join(', ')}.`);
}
} else {
claimId = value;
}
// Validate and process modifier
let channelClaimId;
if (modifierSeperator) {
if (!modifier) {
throw new Error(`No modifier provided after separator ${modifierSeperator}.`);
}
if (modifierSeperator === ':') {
channelClaimId = modifier;
} else {
throw new Error(`The ${modifierSeperator} modifier is not currently supported.`);
}
}
return {
isChannel,
channelName,
channelClaimId,
claimId,
};
},
parseName: function (name) {
logger.debug('parsing name:', name);
const componentsRegex = new RegExp(
'([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
.exec(name)
.map(match => match || null);
logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
// Validate and process name
if (!claimName) {
throw new Error('No claim name provided before .');
}
const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_URI);
if (nameBadChars) {
throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);
}
// Validate and process modifier
let isServeRequest = false;
if (modifierSeperator) {
if (!modifier) {
throw new Error(`No file extension provided after separator ${modifierSeperator}.`);
}
if (modifierSeperator !== '.') {
throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);
}
isServeRequest = true;
}
return {
claimName,
isServeRequest,
};
},
};

View file

@ -39,7 +39,7 @@ module.exports = (app) => {
res.status(200).json(claimsList);
})
.catch(error => {
errorHandlers.handleApiError('claim_list', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
// route to see if asset is available locally
@ -55,7 +55,7 @@ module.exports = (app) => {
res.status(200).json({status: 'success', message: isLocalFileAvailable});
})
.catch(error => {
errorHandlers.handleApiError('get', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
// route to get an asset
@ -81,7 +81,7 @@ module.exports = (app) => {
res.status(200).json({ status: 'success', message, completed });
})
.catch(error => {
errorHandlers.handleApiError('get', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
@ -123,7 +123,7 @@ module.exports = (app) => {
res.status(200).json(resolvedUri);
})
.catch(error => {
errorHandlers.handleApiError('resolve', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
// route to run a publish request on the daemon
@ -211,7 +211,7 @@ module.exports = (app) => {
});
})
.catch(error => {
errorHandlers.handleApiError('publish', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
// route to get a short claim id from long claim Id
@ -234,7 +234,7 @@ module.exports = (app) => {
})
.catch(error => {
logger.error('api error getting short channel id', error);
errorHandlers.handleApiError('short channel id', originalUrl, ip, error, res);
errorHandlers.handleApiError(originalUrl, ip, error, res);
});
});
};

View file

@ -36,7 +36,7 @@ module.exports = (app) => {
});
})
.catch(error => {
errorHandlers.handleRequestError('popular', originalUrl, ip, error, res);
errorHandlers.handleRequestError(originalUrl, ip, error, res);
});
});
// route to display a list of the trending images
@ -47,7 +47,7 @@ module.exports = (app) => {
res.status(200).render('new', { newClaims: result });
})
.catch(error => {
errorHandlers.handleRequestError('new', originalUrl, ip, error, res);
errorHandlers.handleRequestError(originalUrl, ip, error, res);
});
});
// route to send embedable video player (for twitter)

View file

@ -3,11 +3,11 @@ const { getClaimId, getChannelInfoAndContent, getLocalFileRecord } = require('..
const serveHelpers = require('../helpers/serveHelpers.js');
const { handleRequestError } = require('../helpers/errorHandlers.js');
const db = require('../models');
const lbryuri = require('../helpers/lbryuri.js');
const SERVE = 'SERVE';
const SHOW = 'SHOW';
const SHOWLITE = 'SHOWLITE';
const CHANNEL_CHAR = '@';
const CLAIMS_PER_PAGE = 10;
const NO_CHANNEL = 'NO_CHANNEL';
const NO_CLAIM = 'NO_CLAIM';
@ -116,7 +116,7 @@ function showChannelPageToClient (channelName, channelClaimId, originalUrl, ip,
sendChannelInfoAndContentToClient(result, query, res);
})
.catch(error => {
handleRequestError('serve', originalUrl, ip, error, res);
handleRequestError(originalUrl, ip, error, res);
});
}
@ -211,95 +211,6 @@ function logRequestData (responseType, claimName, channelName, claimId) {
logger.debug('claim id ===', claimId);
}
const lbryuri = {};
lbryuri.REGEXP_INVALID_URI = /[^A-Za-z0-9-]/g;
lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/;
lbryuri.parseIdentifier = function (identifier) {
logger.debug('parsing identifier:', identifier);
const componentsRegex = new RegExp(
'([^:$#/]*)' + // value (stops at the first separator or end)
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
const [proto, value, modifierSeperator, modifier] = componentsRegex
.exec(identifier)
.map(match => match || null);
logger.debug(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`);
// Validate and process name
const isChannel = value.startsWith(CHANNEL_CHAR);
const channelName = isChannel ? value : null;
let claimId;
if (isChannel) {
if (!channelName) {
throw new Error('No channel name after @.');
}
const nameBadChars = (channelName).match(lbryuri.REGEXP_INVALID_URI);
if (nameBadChars) {
throw new Error(`Invalid characters in channel name: ${nameBadChars.join(', ')}.`);
}
} else {
claimId = value;
}
// Validate and process modifier
let channelClaimId;
if (modifierSeperator) {
if (!modifier) {
throw new Error(`No modifier provided after separator ${modifierSeperator}.`);
}
if (modifierSeperator === ':') {
channelClaimId = modifier;
} else {
throw new Error(`The ${modifierSeperator} modifier is not currently supported.`);
}
}
return {
isChannel,
channelName,
channelClaimId,
claimId,
};
};
lbryuri.parseName = function (name) {
logger.debug('parsing name:', name);
const componentsRegex = new RegExp(
'([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
.exec(name)
.map(match => match || null);
logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
// Validate and process name
if (!claimName) {
throw new Error('No claim name provided before .');
}
const nameBadChars = (claimName).match(lbryuri.REGEXP_INVALID_URI);
if (nameBadChars) {
throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);
}
// Validate and process modifier
let isServeRequest = false;
if (modifierSeperator) {
if (!modifier) {
throw new Error(`No file extension provided after separator ${modifierSeperator}.`);
}
if (modifierSeperator !== '.') {
throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);
}
isServeRequest = true;
}
return {
claimName,
isServeRequest,
};
};
module.exports = (app) => {
// route to serve a specific asset using the channel or claim id
app.get('/:identifier/:name', ({ headers, ip, originalUrl, params }, res) => {
@ -308,8 +219,7 @@ module.exports = (app) => {
({ isChannel, channelName, channelClaimId, claimId } = lbryuri.parseIdentifier(params.identifier));
({ claimName, isServeRequest } = lbryuri.parseName(params.name));
} catch (error) {
logger.error(error);
return res.status(400).json({success: false, message: error});
return handleRequestError(originalUrl, ip, error, res);
}
if (!isChannel) {
[claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);
@ -328,7 +238,7 @@ module.exports = (app) => {
showOrServeAsset(responseType, fullClaimId, claimName, res);
})
.catch(error => {
handleRequestError('serve', originalUrl, ip, error, res);
handleRequestError(originalUrl, ip, error, res);
});
});
// route to serve the winning asset at a claim or a channel page
@ -337,8 +247,7 @@ module.exports = (app) => {
try {
({ isChannel, channelName, channelClaimId } = lbryuri.parseIdentifier(params.identifier));
} catch (error) {
logger.error(error);
return res.status(400).json({success: false, message: error});
return handleRequestError(originalUrl, ip, error, res);
}
if (isChannel) {
// log the request data for debugging
@ -350,8 +259,7 @@ module.exports = (app) => {
try {
({claimName, isServeRequest} = lbryuri.parseName(params.identifier));
} catch (error) {
logger.error(error);
return res.status(400).json({success: false, message: error});
return handleRequestError(originalUrl, ip, error, res);
}
let responseType = determineResponseType(isServeRequest, headers);
// log the request data for debugging
@ -365,7 +273,7 @@ module.exports = (app) => {
showOrServeAsset(responseType, fullClaimId, claimName, res);
})
.catch(error => {
handleRequestError(responseType, originalUrl, ip, error, res);
handleRequestError(originalUrl, ip, error, res);
});
}
});