Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-static

Package Overview
Dependencies
Maintainers
3
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-static - npm Package Compare versions

Comparing version 0.7.4 to 0.7.5

10

bin/cli.js

@@ -18,2 +18,7 @@ #!/usr/bin/env node

})
.option('host-address', {
alias: 'a',
'default': '127.0.0.1',
description: 'the local network interface at which to listen'
})
.option('cache', {

@@ -105,5 +110,4 @@ alias: 'c',

}).resume();
}).listen(+argv.port);
}).listen(+argv.port, argv['host-address']);
console.log('serving "' + dir + '" at http://127.0.0.1:' + argv.port);
console.log('serving "' + dir + '" at http://' + argv['host-address'] + ':' + argv.port);

@@ -11,3 +11,3 @@ var fs = require('fs')

// Current version
var version = [0, 7, 3];
var version = [0, 7, 5];

@@ -231,2 +231,40 @@ Server = function (root, options) {

Server.prototype.parseByteRange = function(req, stat) {
var byteRange = {
from: 0,
to: 0,
valid: false
}
var rangeHeader = req.headers['range'];
var flavor = 'bytes=';
if (rangeHeader) {
if (rangeHeader.indexOf(flavor) == 0 && rangeHeader.indexOf(',') == -1) {
/* Parse */
rangeHeader = rangeHeader.substr(flavor.length).split('-');
byteRange.from = parseInt(rangeHeader[0]);
byteRange.to = parseInt(rangeHeader[1]);
/* Replace empty fields of differential requests by absolute values */
if (isNaN(byteRange.from) && !isNaN(byteRange.to)) {
byteRange.from = stat.size - byteRange.to;
byteRange.to = stat.size - 1;
} else if (!isNaN(byteRange.from) && isNaN(byteRange.to)) {
byteRange.to = stat.size - 1;
}
/* General byte range validation */
if (!isNaN(byteRange.from) && !!byteRange.to && 0 <= byteRange.from < byteRange.to) {
byteRange.valid = true;
} else {
console.warn("Request contains invalid range header: ", rangeHeader);
}
} else {
console.warn("Request contains unsupported range header: ", rangeHeader);
}
}
return byteRange;
}
Server.prototype.respondNoGzip = function (pathname, status, contentType, _headers, files, stat, req, res, finish) {

@@ -237,5 +275,25 @@ var mtime = Date.parse(stat.mtime),

clientETag = req.headers['if-none-match'],
clientMTime = Date.parse(req.headers['if-modified-since']);
clientMTime = Date.parse(req.headers['if-modified-since']),
startByte = 0,
length = stat.size,
byteRange = this.parseByteRange(req, stat);
/* Handle byte ranges */
if (files.length == 1 && byteRange.valid) {
if (byteRange.to < length) {
// Note: HTTP Range param is inclusive
startByte = byteRange.from;
length = byteRange.to - byteRange.from + 1;
status = 206;
} else {
byteRange.valid = false;
console.warn("Range request exceeds file boundaries, goes until byte no", byteRange.to, "against file size of", length, "bytes");
}
}
/* In any case, check for unhandled byte range headers */
if (!byteRange.valid && req.headers['range']) {
console.error(new Error("Range request present but invalid, might serve whole file instead"));
}
// Copy default headers

@@ -250,3 +308,3 @@ for (var k in this.options.headers) { headers[k] = this.options.headers[k] }

headers['Content-Type'] = contentType;
headers['Content-Length'] = stat.size;
headers['Content-Length'] = length;

@@ -275,5 +333,6 @@ for (var k in _headers) { headers[k] = _headers[k] }

} else {
res.writeHead(status, headers);
this.stream(key, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
this.stream(key, files, new(buffer.Buffer)(length), startByte, res, function (e, buffer) {
if (e) { return finish(500, {}) }

@@ -289,2 +348,3 @@ finish(status, headers);

'application/octet-stream';
if(this.options.gzip) {

@@ -297,3 +357,4 @@ this.respondGzip(pathname, status, contentType, _headers, files, stat, req, res, finish);

Server.prototype.stream = function (pathname, files, buffer, res, callback) {
Server.prototype.stream = function (pathname, files, buffer, startByte, res, callback) {
(function streamFile(files, offset) {

@@ -308,3 +369,5 @@ var file = files.shift();

flags: 'r',
mode: 0666
mode: 0666,
start: startByte,
end: startByte + buffer.length - 1
}).on('data', function (chunk) {

@@ -311,0 +374,0 @@ // Bounds check the incoming chunk and offset, as copying

@@ -34,5 +34,5 @@ {

},
"version" : "0.7.4",
"version" : "0.7.5",
"engines" : { "node": ">= 0.4.1" }
}

@@ -220,4 +220,8 @@ node-static

# expose the server to your local network
$ static -a 0.0.0.0
serving "." at http://0.0.0.0:8080
# show help message, including all options
$ static -h
```

@@ -114,2 +114,50 @@ var vows = require('vows')

}).addBatch({
'serving first 5 bytes of hello.txt': {
topic : function(){
var options = {
url: TEST_SERVER + '/hello.txt',
headers: {
'Range': 'bytes=0-4'
}
};
request.get(options, this.callback);
},
'should respond with 206' : function(error, response, body){
assert.equal(response.statusCode, 206);
},
'should respond with text/plain': function(error, response, body){
assert.equal(response.headers['content-type'], 'text/plain');
},
'should have content-length of 5 bytes': function(error, response, body){
assert.equal(response.headers['content-length'], 5);
},
'should respond with hello': function(error, response, body){
assert.equal(body, 'hello');
}
}
}).addBatch({
'serving last 5 bytes of hello.txt': {
topic : function(){
var options = {
url: TEST_SERVER + '/hello.txt',
headers: {
'Range': 'bytes=6-10'
}
};
request.get(options, this.callback);
},
'should respond with 206' : function(error, response, body){
assert.equal(response.statusCode, 206);
},
'should respond with text/plain': function(error, response, body){
assert.equal(response.headers['content-type'], 'text/plain');
},
'should have content-length of 5 bytes': function(error, response, body){
assert.equal(response.headers['content-length'], 5);
},
'should respond with world': function(error, response, body){
assert.equal(body, 'world');
}
}
}).addBatch({
'serving directory index': {

@@ -116,0 +164,0 @@ topic : function(){

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc