mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
Make fetch header compliant with the current spec (#1019)
This commit is contained in:
parent
198fa31ec1
commit
7210e7b33b
6 changed files with 130 additions and 1 deletions
|
@ -296,6 +296,11 @@ export interface Headers {
|
|||
append(name: string, value: string): void;
|
||||
/** Deletes a header from a `Headers` object. */
|
||||
delete(name: string): void;
|
||||
/** Returns an iterator allowing to go through all key/value pairs
|
||||
* contained in this Headers object. The both the key and value of each pairs
|
||||
* are ByteString objects.
|
||||
*/
|
||||
entries(): IterableIterator<[string, string]>;
|
||||
/** Returns a `ByteString` sequence of all the values of a header within a
|
||||
* `Headers` object with a given name.
|
||||
*/
|
||||
|
@ -304,15 +309,27 @@ export interface Headers {
|
|||
* header.
|
||||
*/
|
||||
has(name: string): boolean;
|
||||
/** Returns an iterator allowing to go through all keys contained in
|
||||
* this Headers object. The keys are ByteString objects.
|
||||
*/
|
||||
keys(): IterableIterator<string>;
|
||||
/** Sets a new value for an existing header inside a Headers object, or adds
|
||||
* the header if it does not already exist.
|
||||
*/
|
||||
set(name: string, value: string): void;
|
||||
/** Returns an iterator allowing to go through all values contained in
|
||||
* this Headers object. The values are ByteString objects.
|
||||
*/
|
||||
values(): IterableIterator<string>;
|
||||
forEach(
|
||||
callbackfn: (value: string, key: string, parent: Headers) => void,
|
||||
// tslint:disable-next-line:no-any
|
||||
thisArg?: any
|
||||
): void;
|
||||
/** The Symbol.iterator well-known symbol specifies the default
|
||||
* iterator for this Headers object
|
||||
*/
|
||||
[Symbol.iterator](): IterableIterator<[string, string]>;
|
||||
}
|
||||
|
||||
type RequestCache =
|
||||
|
|
22
js/fetch.ts
22
js/fetch.ts
|
@ -5,7 +5,8 @@ import {
|
|||
createResolvable,
|
||||
Resolvable,
|
||||
typedArrayToArrayBuffer,
|
||||
notImplemented
|
||||
notImplemented,
|
||||
CreateIterableIterator
|
||||
} from "./util";
|
||||
import * as flatbuffers from "./flatbuffers";
|
||||
import { sendAsync } from "./dispatch";
|
||||
|
@ -70,6 +71,11 @@ export class DenoHeaders implements domTypes.Headers {
|
|||
this.headerMap.delete(newname);
|
||||
}
|
||||
|
||||
entries(): IterableIterator<[string, string]> {
|
||||
const iterators = this.headerMap.entries();
|
||||
return new CreateIterableIterator(iterators);
|
||||
}
|
||||
|
||||
get(name: string): string | null {
|
||||
const [newname] = this.normalizeParams(name);
|
||||
const value = this.headerMap.get(newname);
|
||||
|
@ -81,11 +87,21 @@ export class DenoHeaders implements domTypes.Headers {
|
|||
return this.headerMap.has(newname);
|
||||
}
|
||||
|
||||
keys(): IterableIterator<string> {
|
||||
const iterators = this.headerMap.keys();
|
||||
return new CreateIterableIterator(iterators);
|
||||
}
|
||||
|
||||
set(name: string, value: string): void {
|
||||
const [newname, newvalue] = this.normalizeParams(name, value);
|
||||
this.headerMap.set(newname, newvalue);
|
||||
}
|
||||
|
||||
values(): IterableIterator<string> {
|
||||
const iterators = this.headerMap.values();
|
||||
return new CreateIterableIterator(iterators);
|
||||
}
|
||||
|
||||
forEach(
|
||||
callbackfn: (value: string, key: string, parent: domTypes.Headers) => void,
|
||||
// tslint:disable-next-line:no-any
|
||||
|
@ -95,6 +111,10 @@ export class DenoHeaders implements domTypes.Headers {
|
|||
callbackfn(value, name, this);
|
||||
});
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, string]> {
|
||||
return this.entries();
|
||||
}
|
||||
}
|
||||
|
||||
class FetchResponse implements domTypes.Response {
|
||||
|
|
|
@ -147,6 +147,41 @@ test(function headerGetSuccess() {
|
|||
}
|
||||
});
|
||||
|
||||
test(function headerEntriesSuccess() {
|
||||
const headers = new Headers(headerDict);
|
||||
const iterators = headers.entries();
|
||||
assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
|
||||
for (const it of iterators) {
|
||||
const key = it[0];
|
||||
const value = it[1];
|
||||
assert(headers.has(key));
|
||||
assertEqual(value, headers.get(key));
|
||||
}
|
||||
});
|
||||
|
||||
test(function headerKeysSuccess() {
|
||||
const headers = new Headers(headerDict);
|
||||
const iterators = headers.keys();
|
||||
assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
|
||||
for (const it of iterators) {
|
||||
assert(headers.has(it));
|
||||
}
|
||||
});
|
||||
|
||||
test(function headerValuesSuccess() {
|
||||
const headers = new Headers(headerDict);
|
||||
const iterators = headers.values();
|
||||
const entries = headers.entries();
|
||||
const values = [];
|
||||
for (const pair of entries) {
|
||||
values.push(pair[1]);
|
||||
}
|
||||
assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
|
||||
for (const it of iterators) {
|
||||
assert(values.includes(it));
|
||||
}
|
||||
});
|
||||
|
||||
const headerEntriesDict = {
|
||||
name1: "value1",
|
||||
Name2: "value2",
|
||||
|
@ -172,3 +207,14 @@ test(function headerForEachSuccess() {
|
|||
});
|
||||
assertEqual(callNum, keys.length);
|
||||
});
|
||||
|
||||
test(function headerSymbolIteratorSuccess() {
|
||||
assert(Symbol.iterator in Headers.prototype);
|
||||
const headers = new Headers(headerEntriesDict);
|
||||
for (const header of headers) {
|
||||
const key = header[0];
|
||||
const value = header[1];
|
||||
assert(headers.has(key));
|
||||
assertEqual(value, headers.get(key));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -27,3 +27,4 @@ import "./truncate_test.ts";
|
|||
import "./v8_source_maps_test.ts";
|
||||
import "../website/app_test.js";
|
||||
import "./metrics_test.ts";
|
||||
import "./util_test.ts";
|
||||
|
|
19
js/util.ts
19
js/util.ts
|
@ -125,3 +125,22 @@ export function deferred(): Deferred {
|
|||
reject: reject!
|
||||
};
|
||||
}
|
||||
|
||||
/** Create a IterableIterator. */
|
||||
// @internal
|
||||
export class CreateIterableIterator<T> implements IterableIterator<T> {
|
||||
private readonly _iterators: IterableIterator<T>;
|
||||
readonly [Symbol.toStringTag] = "Iterator";
|
||||
|
||||
constructor(iterators: IterableIterator<T>) {
|
||||
this._iterators = iterators;
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
next(): IteratorResult<T> {
|
||||
return this._iterators.next();
|
||||
}
|
||||
}
|
||||
|
|
26
js/util_test.ts
Normal file
26
js/util_test.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||
import { test, assert, assertEqual } from "./test_util.ts";
|
||||
import { CreateIterableIterator } from "./util";
|
||||
|
||||
test(function CreateIterableIteratorSuccess() {
|
||||
const list = [1, 2, 3, 4, 5];
|
||||
const listIterators = new CreateIterableIterator(list.values());
|
||||
let idx = 0;
|
||||
for (const it of listIterators) {
|
||||
assertEqual(it, list[idx++]);
|
||||
}
|
||||
const obj = {
|
||||
a: "foo",
|
||||
b: "bar",
|
||||
c: "baz"
|
||||
};
|
||||
const list1 = [];
|
||||
const keys = Object.keys(obj);
|
||||
keys.forEach(key => list1.push([key, obj[key]]));
|
||||
const objectIterators = new CreateIterableIterator(list1.values());
|
||||
for (const it of objectIterators) {
|
||||
const [key, value] = it;
|
||||
assert(key in obj);
|
||||
assertEqual(value, obj[key]);
|
||||
}
|
||||
});
|
Loading…
Add table
Reference in a new issue