0
0
Fork 0
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:
ztplz 2018-10-20 00:12:36 +08:00 committed by Ryan Dahl
parent 198fa31ec1
commit 7210e7b33b
6 changed files with 130 additions and 1 deletions

View file

@ -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 =

View file

@ -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 {

View file

@ -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));
}
});

View file

@ -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";

View file

@ -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
View 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]);
}
});