Skip to content

Commit

Permalink
Added support for ranged GET requests
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienCastex committed Jun 10, 2017
1 parent 992620b commit 5bee991
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 8 deletions.
63 changes: 60 additions & 3 deletions lib/server/commands/Get.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var WebDAVRequest_1 = require("../WebDAVRequest");
var stream_1 = require("stream");
var RangedStream = (function (_super) {
__extends(RangedStream, _super);
function RangedStream(min, max) {
var _this = _super.call(this) || this;
_this.min = min;
_this.max = max;
_this.nb = 0;
return _this;
}
RangedStream.prototype._transform = function (chunk, encoding, callback) {
if (this.nb < this.min) {
this.nb += chunk.length;
if (this.nb > this.min) {
chunk = chunk.slice(this.nb - this.min);
callback(null, chunk);
}
else
callback(null, new Buffer(0));
}
else if (this.nb > this.max) {
this.nb += chunk.length;
callback(null, new Buffer(0));
}
else {
this.nb += chunk.length;
if (this.nb > this.max)
chunk = chunk.slice(0, this.max - (this.nb - chunk.length));
callback(null, chunk);
}
};
return RangedStream;
}(stream_1.Transform));
function default_1(arg, callback) {
arg.noBodyExpected(function () {
arg.getResource(function (e, r) {
Expand All @@ -18,9 +61,23 @@ function default_1(arg, callback) {
callback();
}
else {
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
rstream.on('end', callback);
rstream.pipe(arg.response);
var range = arg.findHeader('Range');
if (range) {
var rex = /([0-9]+)/g;
var min = parseInt(rex.exec(range)[1], 10);
var max = parseInt(rex.exec(range)[1], 10);
arg.setCode(WebDAVRequest_1.HTTPCodes.PartialContent);
arg.response.setHeader('Accept-Ranges', 'bytes');
arg.response.setHeader('Content-Length', (max - min).toString());
arg.response.setHeader('Content-Range', 'bytes ' + min + '-' + max + '/*');
rstream.on('end', callback);
rstream.pipe(new RangedStream(min, max)).pipe(arg.response);
}
else {
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
rstream.on('end', callback);
rstream.pipe(arg.response);
}
}
}); });
});
Expand Down
66 changes: 61 additions & 5 deletions src/server/commands/Get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
import { HTTPCodes, MethodCallArgs, WebDAVRequest } from '../WebDAVRequest'
import { IResource } from '../../resource/IResource'
import { Readable } from 'stream'
import { Readable, Transform } from 'stream'

class RangedStream extends Transform
{
nb : number;

constructor(public min : number, public max : number)
{
super();

this.nb = 0;
}

_transform(chunk: any, encoding: string, callback: Function)
{
if(this.nb < this.min)
{
this.nb += chunk.length;
if(this.nb > this.min)
{
chunk = chunk.slice(this.nb - this.min);
callback(null, chunk);
}
else
callback(null, new Buffer(0));
}
else if(this.nb > this.max)
{
this.nb += chunk.length;
callback(null, new Buffer(0));
}
else
{
this.nb += chunk.length;
if(this.nb > this.max)
chunk = chunk.slice(0, this.max - (this.nb - chunk.length));
callback(null, chunk);
}
}
}

export default function(arg : MethodCallArgs, callback)
{
Expand All @@ -25,10 +64,27 @@ export default function(arg : MethodCallArgs, callback)
}
else
{
arg.setCode(HTTPCodes.OK);

rstream.on('end', callback);
rstream.pipe(arg.response);
const range = arg.findHeader('Range');
if(range)
{
const rex = /([0-9]+)/g;
const min = parseInt(rex.exec(range)[1], 10);
const max = parseInt(rex.exec(range)[1], 10);

arg.setCode(HTTPCodes.PartialContent);
arg.response.setHeader('Accept-Ranges', 'bytes')
arg.response.setHeader('Content-Length', (max - min).toString())
arg.response.setHeader('Content-Range', 'bytes ' + min + '-' + max + '/*')

rstream.on('end', callback);
rstream.pipe(new RangedStream(min, max)).pipe(arg.response);
}
else
{
arg.setCode(HTTPCodes.OK);
rstream.on('end', callback);
rstream.pipe(arg.response);
}
}
}))
})
Expand Down

0 comments on commit 5bee991

Please sign in to comment.