Preflight raw file requests to get better error messages

This commit is contained in:
calzoneman 2015-05-24 11:06:02 -04:00
parent cd0cc69fd8
commit c4add8f142
1 changed files with 102 additions and 53 deletions

View File

@ -1,6 +1,9 @@
var Logger = require("./logger"); var Logger = require("./logger");
var Config = require("./config"); var Config = require("./config");
var spawn = require("child_process").spawn; var spawn = require("child_process").spawn;
var https = require("https");
var http = require("http");
var urlparse = require("url");
var USE_JSON = true; var USE_JSON = true;
@ -21,6 +24,47 @@ var audioOnlyContainers = {
"mp3": true "mp3": true
}; };
function testUrl(url, cb, redirected) {
var data = urlparse.parse(url);
if (!/https?:/.test(data.protocol)) {
return cb("Video links must start with http:// or https://");
}
if (!data.hostname) {
return cb("Invalid link");
}
var transport = (data.protocol === "https:") ? https : http;
data.method = "HEAD";
var req = transport.request(data, function (res) {
req.abort();
if (res.statusCode === 301 || res.statusCode === 302) {
if (redirected) {
return cb("Too many redirects. Please provide a direct link to the "
"file");
}
return testUrl(res.headers['location'], cb, true);
}
if (res.statusCode !== 200) {
return cb("HTTP " + res.statusCode + " " + res.statusMessage);
}
if (!/^audio|^video/.test(res.headers['content-type'])) {
return cb("Server did not return an audio or video file");
}
cb();
});
req.on("error", function (err) {
cb(err);
});
req.end();
}
function readOldFormat(buf) { function readOldFormat(buf) {
var lines = buf.split("\n"); var lines = buf.split("\n");
var tmp = { tags: {} }; var tmp = { tags: {} };
@ -149,18 +193,22 @@ exports.query = function (filename, cb) {
"or HTTPS"); "or HTTPS");
} }
testUrl(filename, function (err) {
if (err) {
return cb(err);
}
exports.ffprobe(filename, function (err, data) { exports.ffprobe(filename, function (err, data) {
if (err) { if (err) {
if (err.code && err.code === "ENOENT") { if (err.code && err.code === "ENOENT") {
return cb("Failed to execute `ffprobe`. Set ffmpeg.ffprobe-exec to " + return cb("Failed to execute `ffprobe`. Set ffmpeg.ffprobe-exec " +
"the correct name of the executable in config.yaml. If " + "to the correct name of the executable in config.yaml. " +
"you are using Debian or Ubuntu, it is probably avprobe."); "If you are using Debian or Ubuntu, it is probably " +
"avprobe.");
} else if (err.message) { } else if (err.message) {
if (err.message.match(/protocol not found/i)) if (err.message.match(/protocol not found/i))
return cb("Link uses a protocol unsupported by this server's ffmpeg"); return cb("Link uses a protocol unsupported by this server's " +
"version of ffmpeg");
var m = err.message.match(/(http error .*)/i);
if (m) return cb(m[1]);
Logger.errlog.log(err.stack || err); Logger.errlog.log(err.stack || err);
return cb("Unable to query file data with ffmpeg"); return cb("Unable to query file data with ffmpeg");
@ -204,9 +252,10 @@ exports.query = function (filename, cb) {
cb(null, data); cb(null, data);
} else { } else {
return cb("Parsed metadata did not contain a valid video or audio stream. " + return cb("Parsed metadata did not contain a valid video or audio " +
"Either the file is invalid or it has a format unsupported by " + "stream. Either the file is invalid or it has a format " +
"this server's version of ffmpeg."); "unsupported by this server's version of ffmpeg.");
} }
}); });
});
}; };