diff --git a/.changeset/wise-dogs-clean.md b/.changeset/wise-dogs-clean.md new file mode 100644 index 0000000..c5f922b --- /dev/null +++ b/.changeset/wise-dogs-clean.md @@ -0,0 +1,5 @@ +--- +"@web-std/fetch": patch +--- + +Support HTTP2 pseudo-headers like `:authority`, `:method`, etc. diff --git a/.github/workflows/blob.yml b/.github/workflows/blob.yml index c147ad9..8346c0d 100644 --- a/.github/workflows/blob.yml +++ b/.github/workflows/blob.yml @@ -17,6 +17,7 @@ jobs: name: Typecheck runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 @@ -42,9 +43,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: node-version: - - 14 - 16 os: - ubuntu-latest diff --git a/.github/workflows/fetch.yml b/.github/workflows/fetch.yml index 663430c..65d022f 100644 --- a/.github/workflows/fetch.yml +++ b/.github/workflows/fetch.yml @@ -18,6 +18,7 @@ jobs: name: Typecheck runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 @@ -44,9 +45,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: node-version: - - 14 - 16 os: - ubuntu-latest @@ -54,12 +55,6 @@ jobs: - macos-latest project: - fetch - exclude: - - os: windows-latest - node-version: 14 - # On macOS, run tests with only the LTS environments. - - os: macos-latest - node-version: 14 steps: - uses: actions/checkout@v2 @@ -75,12 +70,5 @@ jobs: - name: Test (ESM) run: yarn --cwd packages/${{matrix.project}} test -- --colors - # upload coverage only once - - name: Coveralls - uses: coverallsapp/github-action@master - if: matrix.node == '14' && matrix.os == 'ubuntu-latest' - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Test (CJS) run: yarn --cwd packages/${{matrix.project}} test:cjs diff --git a/.github/workflows/file.yml b/.github/workflows/file.yml index 5ffe24c..04c49b8 100644 --- a/.github/workflows/file.yml +++ b/.github/workflows/file.yml @@ -17,6 +17,7 @@ jobs: name: Typecheck runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 @@ -42,9 +43,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: node-version: - - 14 - 16 os: - ubuntu-latest diff --git a/.github/workflows/form-data.yml b/.github/workflows/form-data.yml index 6238204..0cf3ada 100644 --- a/.github/workflows/form-data.yml +++ b/.github/workflows/form-data.yml @@ -18,6 +18,7 @@ jobs: name: Typecheck runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 @@ -43,9 +44,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: node-version: - - 14 - 16 os: - ubuntu-latest diff --git a/.github/workflows/stream.yml b/.github/workflows/stream.yml index e93c534..321ef92 100644 --- a/.github/workflows/stream.yml +++ b/.github/workflows/stream.yml @@ -17,6 +17,7 @@ jobs: name: Typecheck runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 @@ -43,9 +44,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: node-version: - - 14 - 16 os: - ubuntu-latest @@ -76,6 +77,7 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: - 16 diff --git a/packages/fetch/src/headers.js b/packages/fetch/src/headers.js index e1fb035..95a08d2 100644 --- a/packages/fetch/src/headers.js +++ b/packages/fetch/src/headers.js @@ -8,27 +8,25 @@ import {types} from 'util'; import http from 'http'; import { isIterable } from './utils/is.js' -const validators = /** @type {{validateHeaderName?:(name:string) => any, validateHeaderValue?:(name:string, value:string) => any}} */ -(http) +/** @type {{validateHeaderValue?:(name:string, value:string) => any}} */ +const validators = (http) -const validateHeaderName = typeof validators.validateHeaderName === 'function' ? - validators.validateHeaderName : - /** - * @param {string} name - */ - name => { - if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) { - const err = new TypeError(`Header name must be a valid HTTP token [${name}]`); - Object.defineProperty(err, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'}); - throw err; - } - }; +/** + * @param {string} name + */ +const validateHeaderName = name => { + if (!/^[\^`\-\w!#$%&'*+.|~:]+$/.test(name)) { + const err = new TypeError(`Header name must be a valid HTTP token [${name}]`); + Object.defineProperty(err, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'}); + throw err; + } +}; const validateHeaderValue = typeof validators.validateHeaderValue === 'function' ? validators.validateHeaderValue : /** - * @param {string} name - * @param {string} value + * @param {string} name + * @param {string} value */ (name, value) => { if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) { @@ -166,8 +164,8 @@ export default class Headers extends URLSearchParams { } /** - * - * @param {string} name + * + * @param {string} name */ get(name) { const values = this.getAll(name); @@ -184,8 +182,8 @@ export default class Headers extends URLSearchParams { } /** - * @param {(value: string, key: string, parent: this) => void} callback - * @param {any} thisArg + * @param {(value: string, key: string, parent: this) => void} callback + * @param {any} thisArg * @returns {void} */ forEach(callback, thisArg = undefined) { diff --git a/packages/fetch/test/headers.js b/packages/fetch/test/headers.js index beed9d9..6078eda 100644 --- a/packages/fetch/test/headers.js +++ b/packages/fetch/test/headers.js @@ -216,6 +216,19 @@ describe('Headers', () => { expect(() => headers.append('', 'ok')).to.throw(TypeError); }); + it('should allow HTTP2 pseudo-headers', () => { + let headers = new Headers({':authority': 'something'}); + headers.append(":method", "something else") + + const result = []; + for (const pair of headers) { + result.push(pair); + } + + expect(result).to.deep.equal([[':authority', 'something'], [':method', 'something else']]); + + }) + it('should ignore unsupported attributes while reading headers', () => { const FakeHeader = function () { }; // Prototypes are currently ignored