Skip to content

httpland/content-range-parser

Repository files navigation

content-range-parser

deno land deno doc GitHub release (latest by date) codecov GitHub

test NPM

HTTP Content-Range header field parser.

Compliant with RFC 9110, 14.4. Content-Range.

Deserialization

Parses string into ContentRange.

import { parseContentRange } from "https://deno.land/x/content_range_parser@$VERSION/parse.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

assertEquals(parseContentRange("bytes 0-100/1000"), {
  rangeUnit: "bytes",
  firstPos: 0,
  lastPos: 100,
  completeLength: 1000,
});
assertEquals(parseContentRange("bytes 100-200/*"), {
  rangeUnit: "bytes",
  firstPos: 100,
  lastPos: 200,
  completeLength: undefined,
});
assertEquals(parseContentRange("bytes */1000"), {
  rangeUnit: "bytes",
  completeLength: 1000,
});

Throwing error

If input is invalid, the following error occurs:

Syntax error

Throws SyntaxError if the input is invalid <Content-Range> syntax.

import { parseContentRange } from "https://deno.land/x/content_range_parser@$VERSION/parse.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() => parseContentRange("<invalid>"));

Semantic error

Throw Error if the input contains invalid semantics.

Invalid semantics are indicated as follows:

A Content-Range field value is invalid if it contains a range-resp that has a last-pos value less than its first-pos value, or a complete-length value less than or equal to its last-pos value. The recipient of an invalid Content-Range MUST NOT attempt to recombine the received content with a stored representation.

import { parseContentRange } from "https://deno.land/x/content_range_parser@$VERSION/parse.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() => parseContentRange("bytes 100-0/*"));
assertThrows(() => parseContentRange("bytes 100-200/0"));

Serialization

Serialize ContentRange into string.

import { stringifyContentRange } from "https://deno.land/x/content_range_parser@$VERSION/stringify.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

assertEquals(
  stringifyContentRange({
    rangeUnit: "bytes",
    firstPos: 0,
    lastPos: 100,
    completeLength: 1000,
  }),
  "bytes 0-100/1000",
);
assertEquals(
  stringifyContentRange({
    rangeUnit: "bytes",
    firstPos: 100,
    lastPos: 200,
    completeLength: undefined,
  }),
  "bytes 100-200/*",
);
assertEquals(
  stringifyContentRange({ rangeUnit: "bytes", completeLength: 1000 }),
  "bytes */1000",
);

Throwing error

Throws TypeError if ContentRange contains invalid value.

import { stringifyContentRange } from "https://deno.land/x/content_range_parser@$VERSION/stringify.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() =>
  stringifyContentRange({ rangeUnit: "<range-unit>", completeLength: NaN })
);

then, semantic errors are also checked.

import { stringifyContentRange } from "https://deno.land/x/content_range_parser@$VERSION/stringify.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() =>
  stringifyContentRange({
    rangeUnit: "<range-unit>",
    firstPos: 1,
    lastPos: 0, // firstPos <= lastPos
    completeLength: undefined,
  })
);
assertThrows(() =>
  stringifyContentRange({
    rangeUnit: "<range-unit>",
    firstPos: 0,
    lastPos: 100,
    completeLength: 0, // lastPos < completeLength
  })
);

Content Range

ContentRange is a structured object for Content-Range header.

Each field name is from camel Case of ABNF definition name.

Name Type Description
rangeUnit string Representation of <range-unit>.

and

<range-resp>:

Name Type Description
firstPost number Representation of <first-pos>.
lastPos number Representation of <last-pos>.
completeLength number | undefined Representation of <unsatisfied-range>.

or

<unsatisfied-range>:

Name Type Description
completeLength number Representation of <unsatisfied-range>

Utilities

It provides utilities.

isRangeResp

Whether the input is RangeResp or not.

import {
  type ContentRange,
  isRangeResp,
} from "https://deno.land/x/content_range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const contentRange: ContentRange;
assert(isRangeResp(contentRange));

isUnsatisfiedRange

Whether the input is UnsatisfiedRange or not.

import {
  type ContentRange,
  isUnsatisfiedRange,
} from "https://deno.land/x/content_range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const contentRange: ContentRange;
assert(isUnsatisfiedRange(contentRange));

API

All APIs can be found in the deno doc.

License

Copyright © 2023-present httpland.

Released under the MIT license