pax_global_header00006660000000000000000000000064134654116170014522gustar00rootroot0000000000000052 comment=0f56ff8d4b579599f9f225f0a19f4ef1628c585f range-parser-1.2.1/000077500000000000000000000000001346541161700141115ustar00rootroot00000000000000range-parser-1.2.1/.eslintignore000066400000000000000000000000421346541161700166100ustar00rootroot00000000000000.nyc_output coverage node_modules range-parser-1.2.1/.eslintrc.yml000066400000000000000000000000351346541161700165330ustar00rootroot00000000000000root: true extends: standard range-parser-1.2.1/.gitignore000066400000000000000000000000641346541161700161010ustar00rootroot00000000000000.nyc_output node_modules coverage package-lock.json range-parser-1.2.1/.travis.yml000066400000000000000000000061151346541161700162250ustar00rootroot00000000000000language: node_js node_js: - "0.6" - "0.8" - "0.10" - "0.12" - "1.8" - "2.5" - "3.3" - "4.9" - "5.12" - "6.17" - "7.10" - "8.16" - "9.11" - "10.15" - "11.15" - "12.2" sudo: false dist: trusty env: global: # Suppress Node.js 0.6 compile warnings - "CXXCOM='$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-narrowing -Wno-strict-overflow $_CCCOMCOM $SOURCES'" cache: directories: - node_modules before_install: - | # Setup utility functions function node_version_lt () { [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v "${1}")" ]] } function npm_module_installed () { npm -lsp ls | grep -Fq "$(pwd)/node_modules/${1}:${1}@" } function npm_remove_module_re () { node -e ' fs = require("fs"); p = JSON.parse(fs.readFileSync("package.json", "utf8")); r = RegExp(process.argv[1]); for (k in p.devDependencies) { if (r.test(k)) delete p.devDependencies[k]; } fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); ' "$@" } function npm_use_module () { node -e ' fs = require("fs"); p = JSON.parse(fs.readFileSync("package.json", "utf8")); p.devDependencies[process.argv[1]] = process.argv[2]; fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); ' "$@" } function v () { tr '.' '\n' <<< "${1}" \ | awk '{ printf "%03d", $0 }' \ | sed 's/^0*//' } # Configure npm - | # Skip updating shrinkwrap / lock npm config set shrinkwrap false - | # Remove benchmark dependencies npm_remove_module_re '(^|-)benchmark$' # Setup Node.js version-specific dependencies - | # Configure eslint for linting if node_version_lt '6.0'; then npm_remove_module_re '^eslint(-|$)' fi - | # Configure mocha for testing if node_version_lt '0.8' ; then npm_use_module 'mocha' '1.21.5' elif node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' fi - | # Configure nyc for testing if node_version_lt '0.10'; then npm_remove_module_re '^nyc$' elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2' elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0' fi # Update Node.js modules - | # Prune & rebuild node_modules if [[ -d node_modules ]]; then npm prune npm rebuild fi before_scrpt: - | # Contents of node_modules npm -s ls ||: script: - | # Run test script, depending on nyc install if npm_module_installed 'nyc'; then npm run-script test-travis else npm test fi - | # Run linting, if eslint exists if npm_module_installed 'eslint'; then npm run-script lint fi after_script: - | # Upload coverage to coveralls if exists if [[ -d .nyc_output ]]; then npm install --save-dev coveralls@2 nyc report --reporter=text-lcov | coveralls fi range-parser-1.2.1/HISTORY.md000066400000000000000000000016251346541161700156000ustar00rootroot000000000000001.2.1 / 2019-05-10 ================== * Improve error when `str` is not a string 1.2.0 / 2016-06-01 ================== * Add `combine` option to combine overlapping ranges 1.1.0 / 2016-05-13 ================== * Fix incorrectly returning -1 when there is at least one valid range * perf: remove internal function 1.0.3 / 2015-10-29 ================== * perf: enable strict mode 1.0.2 / 2014-09-08 ================== * Support Node.js 0.6 1.0.1 / 2014-09-07 ================== * Move repository to jshttp 1.0.0 / 2013-12-11 ================== * Add repository to package.json * Add MIT license 0.0.4 / 2012-06-17 ================== * Change ret -1 for unsatisfiable and -2 when invalid 0.0.3 / 2012-06-17 ================== * Fix last-byte-pos default to len - 1 0.0.2 / 2012-06-14 ================== * Add `.type` 0.0.1 / 2012-06-11 ================== * Initial release range-parser-1.2.1/LICENSE000066400000000000000000000022321346541161700151150ustar00rootroot00000000000000(The MIT License) Copyright (c) 2012-2014 TJ Holowaychuk Copyright (c) 2015-2016 Douglas Christopher Wilson ```js var parseRange = require('range-parser') ``` ### parseRange(size, header, options) Parse the given `header` string where `size` is the maximum size of the resource. An array of ranges will be returned or negative numbers indicating an error parsing. * `-2` signals a malformed header string * `-1` signals an unsatisfiable range ```js // parse header from request var range = parseRange(size, req.headers.range) // the type of the range if (range.type === 'bytes') { // the ranges range.forEach(function (r) { // do something with r.start and r.end }) } ``` #### Options These properties are accepted in the options object. ##### combine Specifies if overlapping & adjacent ranges should be combined, defaults to `false`. When `true`, ranges will be combined and returned as if they were specified that way in the header. ```js parseRange(100, 'bytes=50-55,0-10,5-10,56-60', { combine: true }) // => [ // { start: 0, end: 10 }, // { start: 50, end: 60 } // ] ``` ## License [MIT](LICENSE) [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/range-parser/master [coveralls-url]: https://coveralls.io/r/jshttp/range-parser?branch=master [node-image]: https://badgen.net/npm/node/range-parser [node-url]: https://nodejs.org/en/download [npm-downloads-image]: https://badgen.net/npm/dm/range-parser [npm-url]: https://npmjs.org/package/range-parser [npm-version-image]: https://badgen.net/npm/v/range-parser [travis-image]: https://badgen.net/travis/jshttp/range-parser/master [travis-url]: https://travis-ci.org/jshttp/range-parser range-parser-1.2.1/index.js000066400000000000000000000055241346541161700155640ustar00rootroot00000000000000/*! * range-parser * Copyright(c) 2012-2014 TJ Holowaychuk * Copyright(c) 2015-2016 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module exports. * @public */ module.exports = rangeParser /** * Parse "Range" header `str` relative to the given file `size`. * * @param {Number} size * @param {String} str * @param {Object} [options] * @return {Array} * @public */ function rangeParser (size, str, options) { if (typeof str !== 'string') { throw new TypeError('argument str must be a string') } var index = str.indexOf('=') if (index === -1) { return -2 } // split the range string var arr = str.slice(index + 1).split(',') var ranges = [] // add ranges type ranges.type = str.slice(0, index) // parse all ranges for (var i = 0; i < arr.length; i++) { var range = arr[i].split('-') var start = parseInt(range[0], 10) var end = parseInt(range[1], 10) // -nnn if (isNaN(start)) { start = size - end end = size - 1 // nnn- } else if (isNaN(end)) { end = size - 1 } // limit last-byte-pos to current length if (end > size - 1) { end = size - 1 } // invalid or unsatisifiable if (isNaN(start) || isNaN(end) || start > end || start < 0) { continue } // add range ranges.push({ start: start, end: end }) } if (ranges.length < 1) { // unsatisifiable return -1 } return options && options.combine ? combineRanges(ranges) : ranges } /** * Combine overlapping & adjacent ranges. * @private */ function combineRanges (ranges) { var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart) for (var j = 0, i = 1; i < ordered.length; i++) { var range = ordered[i] var current = ordered[j] if (range.start > current.end + 1) { // next range ordered[++j] = range } else if (range.end > current.end) { // extend range current.end = range.end current.index = Math.min(current.index, range.index) } } // trim ordered array ordered.length = j + 1 // generate combined range var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex) // copy ranges type combined.type = ranges.type return combined } /** * Map function to add index value to ranges. * @private */ function mapWithIndex (range, index) { return { start: range.start, end: range.end, index: index } } /** * Map function to remove index value from ranges. * @private */ function mapWithoutIndex (range) { return { start: range.start, end: range.end } } /** * Sort function to sort ranges by index. * @private */ function sortByRangeIndex (a, b) { return a.index - b.index } /** * Sort function to sort ranges by start position. * @private */ function sortByRangeStart (a, b) { return a.start - b.start } range-parser-1.2.1/package.json000066400000000000000000000022401346541161700163750ustar00rootroot00000000000000{ "name": "range-parser", "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "description": "Range header field string parser", "version": "1.2.1", "contributors": [ "Douglas Christopher Wilson ", "James Wyatt Cready ", "Jonathan Ong (http://jongleberry.com)" ], "license": "MIT", "keywords": [ "range", "parser", "http" ], "repository": "jshttp/range-parser", "devDependencies": { "deep-equal": "1.0.1", "eslint": "5.16.0", "eslint-config-standard": "12.0.0", "eslint-plugin-markdown": "1.0.0", "eslint-plugin-import": "2.17.2", "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.1.1", "eslint-plugin-standard": "4.0.0", "mocha": "6.1.4", "nyc": "14.1.1" }, "files": [ "HISTORY.md", "LICENSE", "index.js" ], "engines": { "node": ">= 0.6" }, "scripts": { "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --reporter spec", "test-cov": "nyc --reporter=html --reporter=text npm test", "test-travis": "nyc --reporter=text npm test" } } range-parser-1.2.1/test/000077500000000000000000000000001346541161700150705ustar00rootroot00000000000000range-parser-1.2.1/test/.eslintrc.yml000066400000000000000000000000231346541161700175070ustar00rootroot00000000000000env: mocha: true range-parser-1.2.1/test/range-parser.js000066400000000000000000000100241346541161700200110ustar00rootroot00000000000000 var assert = require('assert') var deepEqual = require('deep-equal') var parse = require('..') describe('parseRange(len, str)', function () { it('should reject non-string str', function () { assert.throws(parse.bind(null, 200, {}), /TypeError: argument str must be a string/) }) it('should return -2 for invalid str', function () { assert.strictEqual(parse(200, 'malformed'), -2) }) it('should return -1 if all specified ranges are invalid', function () { assert.strictEqual(parse(200, 'bytes=500-20'), -1) assert.strictEqual(parse(200, 'bytes=500-999'), -1) assert.strictEqual(parse(200, 'bytes=500-999,1000-1499'), -1) }) it('should parse str', function () { var range = parse(1000, 'bytes=0-499') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 499 }) }) it('should cap end at size', function () { var range = parse(200, 'bytes=0-499') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 199 }) }) it('should parse str', function () { var range = parse(1000, 'bytes=40-80') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 40, end: 80 }) }) it('should parse str asking for last n bytes', function () { var range = parse(1000, 'bytes=-400') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 600, end: 999 }) }) it('should parse str with only start', function () { var range = parse(1000, 'bytes=400-') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 400, end: 999 }) }) it('should parse "bytes=0-"', function () { var range = parse(1000, 'bytes=0-') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 999 }) }) it('should parse str with no bytes', function () { var range = parse(1000, 'bytes=0-0') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 0 }) }) it('should parse str asking for last byte', function () { var range = parse(1000, 'bytes=-1') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 999, end: 999 }) }) it('should parse str with multiple ranges', function () { var range = parse(1000, 'bytes=40-80,81-90,-1') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 3) deepEqual(range[0], { start: 40, end: 80 }) deepEqual(range[1], { start: 81, end: 90 }) deepEqual(range[2], { start: 999, end: 999 }) }) it('should parse str with some invalid ranges', function () { var range = parse(200, 'bytes=0-499,1000-,500-999') assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 199 }) }) it('should parse non-byte range', function () { var range = parse(1000, 'items=0-5') assert.strictEqual(range.type, 'items') assert.strictEqual(range.length, 1) deepEqual(range[0], { start: 0, end: 5 }) }) describe('when combine: true', function () { it('should combine overlapping ranges', function () { var range = parse(150, 'bytes=0-4,90-99,5-75,100-199,101-102', { combine: true }) assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 2) deepEqual(range[0], { start: 0, end: 75 }) deepEqual(range[1], { start: 90, end: 149 }) }) it('should retain original order', function () { var range = parse(150, 'bytes=-1,20-100,0-1,101-120', { combine: true }) assert.strictEqual(range.type, 'bytes') assert.strictEqual(range.length, 3) deepEqual(range[0], { start: 149, end: 149 }) deepEqual(range[1], { start: 20, end: 120 }) deepEqual(range[2], { start: 0, end: 1 }) }) }) })