-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(middleware): add range middleware factory
- Loading branch information
1 parent
3fbef2e
commit 1926b02
Showing
4 changed files
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export { | ||
assert, | ||
assertEquals, | ||
assertThrows, | ||
} from "https://deno.land/std@0.178.0/testing/asserts.ts"; | ||
export { describe, it } from "https://deno.land/std@0.178.0/testing/bdd.ts"; | ||
export { | ||
assertSpyCall, | ||
assertSpyCalls, | ||
spy, | ||
} from "https://deno.land/std@0.178.0/testing/mock.ts"; | ||
export { Status } from "https://deno.land/std@0.178.0/http/http_status.ts"; | ||
export { equalsResponse } from "https://deno.land/x/http_utils@1.0.0-beta.13/response.ts"; | ||
export { | ||
ConditionalHeader, | ||
RangeHeader, | ||
RepresentationHeader, | ||
} from "https://deno.land/x/http_utils@1.0.0-beta.13/header.ts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
export { Status } from "https://deno.land/std@0.178.0/http/http_status.ts"; | ||
export { | ||
isNull, | ||
isNumber, | ||
isString, | ||
} from "https://deno.land/x/isx@1.0.0-beta.24/mod.ts"; | ||
export { type Middleware } from "https://deno.land/x/http_middleware@1.0.0-beta.1/mod.ts"; | ||
export { | ||
ConditionalHeader, | ||
RangeHeader, | ||
RepresentationHeader, | ||
} from "https://deno.land/x/http_utils@1.0.0-beta.12/header.ts"; | ||
export { Method } from "https://deno.land/x/http_utils@1.0.0-beta.12/method.ts"; | ||
export { isErr, unsafe } from "https://deno.land/x/result_js@1.0.0/mod.ts"; | ||
import { | ||
RepresentationHeader, | ||
} from "https://deno.land/x/http_utils@1.0.0-beta.12/header.ts"; | ||
export { | ||
type IntRange, | ||
isIntRange, | ||
isOtherRange, | ||
isSuffixRange, | ||
type OtherRange, | ||
parse, | ||
type Range, | ||
type RangeSpec, | ||
type RangesSpecifier, | ||
type SuffixRange, | ||
} from "https://deno.land/x/range_parser@1.0.0/mod.ts"; | ||
export { concat } from "https://deno.land/std@0.178.0/bytes/concat.ts"; | ||
export { toHashString } from "https://deno.land/std@0.178.0/crypto/to_hash_string.ts"; | ||
|
||
/** Create headers with no representation header fields. */ | ||
export class NoContentHeaders extends Headers { | ||
constructor(init?: HeadersInit | undefined) { | ||
super(init); | ||
|
||
const allHeaders = [ | ||
RepresentationHeader.ContentEncoding, | ||
RepresentationHeader.ContentLanguage, | ||
RepresentationHeader.ContentLength, | ||
RepresentationHeader.ContentLocation, | ||
RepresentationHeader.ContentType, | ||
RepresentationHeader.ETag, | ||
RepresentationHeader.LastModified, | ||
]; | ||
|
||
allHeaders.forEach(this.delete.bind(this)); | ||
} | ||
} | ||
|
||
export function isNotEmpty<T>(input: readonly T[]): input is [T, ...T[]] { | ||
return !!input.length; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// deno-lint-ignore-file no-explicit-any | ||
|
||
import { type Middleware } from "./deps.ts"; | ||
import { withContentRange } from "./transform.ts"; | ||
import { BytesRange } from "./ranges/bytes.ts"; | ||
import type { Range } from "./types.ts"; | ||
|
||
interface Options { | ||
readonly ranges?: readonly Range<any>[]; | ||
} | ||
|
||
export function range(options?: Options): Middleware { | ||
const ranges = options?.ranges ?? [new BytesRange() as Range<any>]; | ||
|
||
return async (request, next) => { | ||
const response = await next(request); | ||
|
||
return withContentRange(request, response, { ranges }); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { range } from "./middleware.ts"; | ||
import { | ||
assert, | ||
describe, | ||
equalsResponse, | ||
it, | ||
RangeHeader, | ||
RepresentationHeader, | ||
Status, | ||
} from "./_dev_deps.ts"; | ||
|
||
describe("range", () => { | ||
it("should", async () => { | ||
const middleware = range(); | ||
const rangeRequest = new Request("test:", { | ||
headers: { range: "bytes=5-9" }, | ||
}); | ||
const response = await middleware( | ||
rangeRequest, | ||
() => new Response("abcdefghijklmnopqrstuvwxyz"), | ||
); | ||
|
||
assert( | ||
await equalsResponse( | ||
response, | ||
new Response(`fghij`, { | ||
status: Status.PartialContent, | ||
headers: { | ||
[RangeHeader.ContentRange]: `bytes 5-9/26`, | ||
}, | ||
}), | ||
true, | ||
), | ||
); | ||
}); | ||
|
||
it("should", async () => { | ||
const middleware = range(); | ||
const rangeRequest = new Request("test:", { | ||
headers: { range: "bytes=5-9, 20-, -5" }, | ||
}); | ||
const response = await middleware( | ||
rangeRequest, | ||
() => new Response("abcdefghijklmnopqrstuvwxyz"), | ||
); | ||
|
||
const boundary = `32d10c7b8cf96570ca04ce37f2a19d84240d3a89`; | ||
|
||
assert( | ||
await equalsResponse( | ||
response, | ||
new Response( | ||
`--${boundary} | ||
Content-Type: text/plain;charset=UTF-8 | ||
Content-Range: 5-9/26 | ||
fghij | ||
--${boundary} | ||
Content-Type: text/plain;charset=UTF-8 | ||
Content-Range: 20-25/26 | ||
uvwxyz | ||
--${boundary} | ||
Content-Type: text/plain;charset=UTF-8 | ||
Content-Range: 21-25/26 | ||
vwxyz | ||
--${boundary}--`, | ||
{ | ||
status: Status.PartialContent, | ||
headers: { | ||
[RepresentationHeader.ContentType]: | ||
`multipart/byteranges; boundary=${boundary}`, | ||
}, | ||
}, | ||
), | ||
true, | ||
), | ||
); | ||
}); | ||
}); |