1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/masx200-koa-range

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
index.js 3.5 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
masx200 Отправлено 23.06.2021 15:26 d85c838
var util = require("util");
var slice = require("stream-slice").slice;
var Stream = require("stream");
const fs = require("fs");
const stat = util.promisify(fs.stat);
module.exports = async function (ctx, next) {
var range = ctx.header.range;
ctx.set("Accept-Ranges", "bytes");
if (!range) {
return next();
}
var ranges = rangeParse(range);
if (!ranges || ranges.length == 0) {
ctx.status = 416;
return;
}
if (ctx.method == "PUT") {
ctx.status = 400;
return;
}
await next();
if (ctx.response.has("Content-Range")) {
return;
}
if (ctx.method != "GET" || ctx.body == null) {
return;
}
var first = ranges[0];
var rawBody = ctx.body;
var len = rawBody.length;
// avoid multi ranges
var firstRange = ranges[0];
var start = firstRange[0];
var end = firstRange[1];
if (!Buffer.isBuffer(rawBody)) {
if (rawBody instanceof Stream.Readable) {
len = ctx.length || "*";
if (rawBody.path) {
let path = rawBody.path;
if (!Number.isInteger(len)) {
let stats = await stat(path);
len = stats.size;
}
rawBody = fs.createReadStream(rawBody.path, {
start,
end: end,
});
} else {
if (end === Infinity && !Number.isInteger(len)) {
return;
}
rawBody = rawBody.pipe(slice(start, end + 1));
}
} else if (typeof rawBody !== "string") {
rawBody = new Buffer(JSON.stringify(rawBody));
len = rawBody.length;
} else {
rawBody = new Buffer(rawBody);
len = rawBody.length;
}
}
// Adjust infinite end
if (end === Infinity) {
if (Number.isInteger(len)) {
end = len - 1;
} else {
// FIXME(Calle Svensson): If we don't know how much we can return, we do a normal HTTP 200 repsonse
ctx.status = 200;
return;
}
}
ctx.status = 206;
// Adjust end while larger than len
if (Number.isInteger(len) && end >= len) {
end = len - 1;
if (start === 0) {
ctx.status = 200;
}
}
var args = [start, end + 1].filter(function (item) {
return typeof item == "number";
});
ctx.set("Content-Range", rangeContentGenerator(start, end, len));
if (rawBody instanceof Stream) {
ctx.body = rawBody;
} else {
ctx.body = rawBody.slice.apply(rawBody, args);
}
if (len !== "*") {
let ctxlength = end - start + 1;
if (ctxlength <= 0) {
ctx.status = 416;
}
ctx.length = Math.max(0, ctxlength);
}
};
function rangeParse(str) {
var token = str.split("=");
if (!token || token.length != 2 || token[0] != "bytes") {
return null;
}
return token[1]
.split(",")
.map(function (range) {
return range.split("-").map(function (value) {
if (value === "") {
return Infinity;
}
return Number(value);
});
})
.filter(function (range) {
return !isNaN(range[0]) && !isNaN(range[1]) && range[0] <= range[1];
});
}
function rangeContentGenerator(start, end, length) {
return util.format("bytes %d-%d/%s", start, end, length);
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/masx200-koa-range.git
git@api.gitlife.ru:oschina-mirror/masx200-koa-range.git
oschina-mirror
masx200-koa-range
masx200-koa-range
master