From 393094ad50eefce5a8f76cadf904c029df5ec026 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sun, 8 Feb 2026 00:06:22 +0100 Subject: [PATCH 01/15] Remove legacy handler wrappers (#4786) --- .github/workflows/ci.yml | 11 +- .github/workflows/nodejs.yml | 4 +- .gitignore | 4 + docs/docs/api/Client.md | 2 +- docs/docs/api/Dispatcher.md | 66 +- docs/docs/api/H2CClient.md | 2 +- docs/docs/api/RedirectHandler.md | 23 +- docs/docs/api/RetryHandler.md | 25 +- docs/examples/proxy/proxy.js | 42 +- lib/api/api-connect.js | 24 +- lib/api/api-pipeline.js | 35 +- lib/api/api-request.js | 51 +- lib/api/api-stream.js | 45 +- lib/api/api-upgrade.js | 24 +- lib/core/request.js | 114 +- lib/core/util.js | 56 +- lib/dispatcher/client-h1.js | 10 +- lib/dispatcher/client-h2.js | 14 +- lib/dispatcher/dispatcher-base.js | 7 +- lib/dispatcher/dispatcher.js | 4 - lib/dispatcher/pool-base.js | 2 +- lib/dispatcher/proxy-agent.js | 10 +- lib/handler/decorator-handler.js | 3 +- lib/handler/retry-handler.js | 3 +- lib/handler/unwrap-handler.js | 96 - lib/handler/wrap-handler.js | 95 - lib/interceptor/cache.js | 47 +- lib/interceptor/decompress.js | 27 + lib/mock/mock-utils.js | 29 +- lib/mock/snapshot-agent.js | 20 +- lib/web/fetch/index.js | 38 +- package.json | 6 +- scripts/find-hanging-tests.sh | 47 + test/client-request.js | 12 +- test/client-timeout.js | 48 +- test/decorator-handler.js | 93 +- test/env-http-proxy-agent-nodejs-bundle.js | 7 +- test/http2-body.js | 19 +- test/http2-trailers.js | 16 +- test/issue-3934.js | 2 +- test/issue-4780.js | 62 + test/mock-agent.js | 18 +- test/mock-client.js | 16 +- test/mock-interceptor.js | 48 +- test/mock-pool.js | 16 +- test/node-test/agent.js | 42 +- test/node-test/client-abort.js | 48 +- test/node-test/client-dispatch.js | 341 +- test/node-test/util.js | 68 +- test/pool.js | 60 +- test/retry-handler.js | 150 +- test/retry-handler2.js | 150 +- test/web-platform-tests/expectation.json | 9398 ++------------------ types/dispatcher.d.ts | 26 +- 54 files changed, 1750 insertions(+), 9876 deletions(-) delete mode 100644 lib/handler/unwrap-handler.js delete mode 100644 lib/handler/wrap-handler.js create mode 100755 scripts/find-hanging-tests.sh create mode 100644 test/issue-4780.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d63cf8b3c67..d4b076cc403 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,11 +59,8 @@ jobs: fail-fast: false max-parallel: 0 matrix: - node-version: ['20', '22', '24', '25'] + node-version: ['22', '24', '25'] runs-on: ['ubuntu-latest', 'windows-latest', 'macos-latest'] - exclude: - - node-version: '20' - runs-on: windows-latest uses: ./.github/workflows/nodejs.yml with: codecov: ${{ (matrix.node-version == '24' || matrix.node-version == '25') && matrix.runs-on == 'ubuntu-latest' }} @@ -77,7 +74,7 @@ jobs: fail-fast: false max-parallel: 0 matrix: - node-version: ['24', '25'] + node-version: ['22', '24', '25'] runs-on: ['ubuntu-latest'] uses: ./.github/workflows/nodejs.yml with: @@ -92,7 +89,7 @@ jobs: fail-fast: false max-parallel: 0 matrix: - node-version: ['20', '22', '24', '25'] + node-version: ['22', '24', '25'] runs-on: ubuntu-latest timeout-minutes: 120 steps: @@ -178,7 +175,7 @@ jobs: fail-fast: false max-parallel: 0 matrix: - node-version: ['20', '22', '24', '25'] + node-version: ['22', '24', '25'] runs-on: ubuntu-latest timeout-minutes: 120 steps: diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 49920ec10d9..1936b969ff5 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -110,12 +110,12 @@ jobs: NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }} UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }} - - name: Test cache-interceptor ${{ inputs.node-version != '20' && 'with' || 'without' }} sqlite + - name: Test cache-interceptor with sqlite run: npm run test:cache-interceptor id: test-cache-interceptor env: CI: true - NODE_OPTIONS: ${{ inputs.node-version != '20' && '--experimental-sqlite' || '' }} + NODE_OPTIONS: --experimental-sqlite NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }} UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }} diff --git a/.gitignore b/.gitignore index b07f936559f..00abb95f2c1 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,7 @@ test/request-timeout.10mb.bin # Claude files CLAUDE.md .claude + +# Local tooling +.githuman/ +.pi/ diff --git a/docs/docs/api/Client.md b/docs/docs/api/Client.md index abc02d87d17..a28bfbf0bfb 100644 --- a/docs/docs/api/Client.md +++ b/docs/docs/api/Client.md @@ -281,4 +281,4 @@ console.log('requests completed') ### Event: `'error'` -Invoked for users errors such as throwing in the `onError` handler. +Invoked for user errors such as throwing in the `onResponseError` handler. diff --git a/docs/docs/api/Dispatcher.md b/docs/docs/api/Dispatcher.md index f8639267825..437cbfdab0b 100644 --- a/docs/docs/api/Dispatcher.md +++ b/docs/docs/api/Dispatcher.md @@ -212,6 +212,26 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo * **onResponseEnd** `(controller: DispatchController, trailers: Record) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests. * **onResponseError** `(controller: DispatchController, error: Error) => void` - Invoked when an error has occurred. May not throw. +#### Migration from legacy handler API + +If you were previously using `onConnect/onHeaders/onData/onComplete/onError`, switch to the new callbacks: + +- `onConnect(abort)` → `onRequestStart(controller)` and call `controller.abort(reason)` +- `onHeaders(status, rawHeaders, resume, statusText)` → `onResponseStart(controller, status, headers, statusText)` +- `onData(chunk)` → `onResponseData(controller, chunk)` +- `onComplete(trailers)` → `onResponseEnd(controller, trailers)` +- `onError(err)` → `onResponseError(controller, err)` +- `onUpgrade(status, rawHeaders, socket)` → `onRequestUpgrade(controller, status, headers, socket)` + +To access raw header arrays (for preserving duplicates/casing), read them from the controller: + +- `controller.rawHeaders` for response headers +- `controller.rawTrailers` for trailers + +Pause/resume now uses the controller: + +- Call `controller.pause()` and `controller.resume()` instead of returning `false` from handlers. + #### Example 1 - Dispatch GET request ```js @@ -236,21 +256,21 @@ client.dispatch({ 'x-foo': 'bar' } }, { - onConnect: () => { + onRequestStart: () => { console.log('Connected!') }, - onError: (error) => { + onResponseError: (_controller, error) => { console.error(error) }, - onHeaders: (statusCode, headers) => { - console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`) + onResponseStart: (_controller, statusCode, headers) => { + console.log(`onResponseStart | statusCode: ${statusCode} | headers: ${JSON.stringify(headers)}`) }, - onData: (chunk) => { - console.log('onData: chunk received') + onResponseData: (_controller, chunk) => { + console.log('onResponseData: chunk received') data.push(chunk) }, - onComplete: (trailers) => { - console.log(`onComplete | trailers: ${trailers}`) + onResponseEnd: (_controller, trailers) => { + console.log(`onResponseEnd | trailers: ${JSON.stringify(trailers)}`) const res = Buffer.concat(data).toString('utf8') console.log(`Data: ${res}`) client.close() @@ -288,15 +308,15 @@ client.dispatch({ method: 'GET', upgrade: 'websocket' }, { - onConnect: () => { - console.log('Undici Client - onConnect') + onRequestStart: () => { + console.log('Undici Client - onRequestStart') }, - onError: (error) => { - console.log('onError') // shouldn't print + onResponseError: () => { + console.log('onResponseError') // shouldn't print }, - onUpgrade: (statusCode, headers, socket) => { - console.log('Undici Client - onUpgrade') - console.log(`onUpgrade Headers: ${headers}`) + onRequestUpgrade: (_controller, statusCode, headers, socket) => { + console.log('Undici Client - onRequestUpgrade') + console.log(`onRequestUpgrade Headers: ${JSON.stringify(headers)}`) socket.on('data', buffer => { console.log(buffer.toString('utf8')) }) @@ -339,21 +359,21 @@ client.dispatch({ }, body: JSON.stringify({ message: 'Hello' }) }, { - onConnect: () => { + onRequestStart: () => { console.log('Connected!') }, - onError: (error) => { + onResponseError: (_controller, error) => { console.error(error) }, - onHeaders: (statusCode, headers) => { - console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`) + onResponseStart: (_controller, statusCode, headers) => { + console.log(`onResponseStart | statusCode: ${statusCode} | headers: ${JSON.stringify(headers)}`) }, - onData: (chunk) => { - console.log('onData: chunk received') + onResponseData: (_controller, chunk) => { + console.log('onResponseData: chunk received') data.push(chunk) }, - onComplete: (trailers) => { - console.log(`onComplete | trailers: ${trailers}`) + onResponseEnd: (_controller, trailers) => { + console.log(`onResponseEnd | trailers: ${JSON.stringify(trailers)}`) const res = Buffer.concat(data).toString('utf8') console.log(`Response Data: ${res}`) client.close() diff --git a/docs/docs/api/H2CClient.md b/docs/docs/api/H2CClient.md index d9ba3089135..ebb26752a8c 100644 --- a/docs/docs/api/H2CClient.md +++ b/docs/docs/api/H2CClient.md @@ -259,4 +259,4 @@ console.log("requests completed"); ### Event: `'error'` -Invoked for users errors such as throwing in the `onError` handler. +Invoked for user errors such as throwing in the `onResponseError` handler. diff --git a/docs/docs/api/RedirectHandler.md b/docs/docs/api/RedirectHandler.md index bb16284fff4..86aff1250fd 100644 --- a/docs/docs/api/RedirectHandler.md +++ b/docs/docs/api/RedirectHandler.md @@ -34,57 +34,62 @@ Returns: `RedirectHandler` ### Methods -#### `onConnect(abort)` +#### `onRequestStart(controller, context)` -Called when the connection is established. +Called when the request starts. Parameters: -- **abort** `function` - The abort function. +- **controller** `DispatchController` - The request controller. +- **context** `object` - The dispatch context. -#### `onUpgrade(statusCode, headers, socket)` +#### `onRequestUpgrade(controller, statusCode, headers, socket)` Called when an upgrade is requested. Parameters: +- **controller** `DispatchController` - The request controller. - **statusCode** `number` - The HTTP status code. - **headers** `object` - The headers received in the response. - **socket** `object` - The socket object. -#### `onError(error)` +#### `onResponseError(controller, error)` Called when an error occurs. Parameters: +- **controller** `DispatchController` - The request controller. - **error** `Error` - The error that occurred. -#### `onHeaders(statusCode, headers, resume, statusText)` +#### `onResponseStart(controller, statusCode, headers, statusText)` Called when headers are received. Parameters: +- **controller** `DispatchController` - The request controller. - **statusCode** `number` - The HTTP status code. - **headers** `object` - The headers received in the response. -- **resume** `function` - The resume function. - **statusText** `string` - The status text. -#### `onData(chunk)` +#### `onResponseData(controller, chunk)` Called when data is received. Parameters: +- **controller** `DispatchController` - The request controller. - **chunk** `Buffer` - The data chunk received. -#### `onComplete(trailers)` +#### `onResponseEnd(controller, trailers)` Called when the request is complete. Parameters: +- **controller** `DispatchController` - The request controller. - **trailers** `object` - The trailers received. #### `onBodySent(chunk)` diff --git a/docs/docs/api/RetryHandler.md b/docs/docs/api/RetryHandler.md index d7b3e88d0f7..b420a569a54 100644 --- a/docs/docs/api/RetryHandler.md +++ b/docs/docs/api/RetryHandler.md @@ -82,17 +82,16 @@ const handler = new RetryHandler( return client.dispatch(...args); }, handler: { - onConnect() {}, - onBodySent() {}, - onHeaders(status, _rawHeaders, resume, _statusMessage) { + onRequestStart() {}, + onBodySent(chunk) {}, + onResponseStart(_controller, status, headers) { // do something with headers }, - onData(chunk) { + onResponseData(_controller, chunk) { chunks.push(chunk); - return true; }, - onComplete() {}, - onError() { + onResponseEnd() {}, + onResponseError(_controller, err) { // handle error properly }, }, @@ -107,12 +106,12 @@ const client = new Client(`http://localhost:${server.address().port}`); const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect() {}, - onBodySent() {}, - onHeaders(status, _rawHeaders, resume, _statusMessage) {}, - onData(chunk) {}, - onComplete() {}, - onError(err) {}, + onRequestStart() {}, + onBodySent(chunk) {}, + onResponseStart(_controller, status, headers) {}, + onResponseData(_controller, chunk) {}, + onResponseEnd() {}, + onResponseError(_controller, err) {}, }, }); ``` diff --git a/docs/examples/proxy/proxy.js b/docs/examples/proxy/proxy.js index 8826bc722ce..14d91f5edb3 100644 --- a/docs/examples/proxy/proxy.js +++ b/docs/examples/proxy/proxy.js @@ -49,34 +49,36 @@ class HTTPHandler { }) } - onConnect (abort) { + onRequestStart (controller) { if (this.req.aborted) { - abort() + controller.abort() } else { - this.abort = abort - this.res.on('close', abort) + this.abort = (reason) => controller.abort(reason) + this.res.on('close', this.abort) } } - onHeaders (statusCode, headers, resume) { + onResponseStart (controller, statusCode) { if (statusCode < 200) { return } - this.resume = resume - this.res.on('drain', resume) + this.resume = () => controller.resume() + this.res.on('drain', this.resume) this.res.writeHead(statusCode, getHeaders({ - headers, + headers: controller.rawHeaders ?? [], proxyName: this.proxyName, httpVersion: this.httpVersion })) } - onData (chunk) { - return this.res.write(chunk) + onResponseData (controller, chunk) { + if (this.res.write(chunk) === false) { + controller.pause() + } } - onComplete () { + onResponseEnd () { this.res.off('close', this.abort) this.res.off('drain', this.resume) @@ -84,7 +86,7 @@ class HTTPHandler { this.callback() } - onError (err) { + onResponseError (_controller, err) { this.res.off('close', this.abort) this.res.off('drain', this.resume) @@ -108,16 +110,16 @@ class WSHandler { }) } - onConnect (abort) { + onRequestStart (controller) { if (this.socket.destroyed) { - abort() + controller.abort() } else { - this.abort = abort - this.socket.on('close', abort) + this.abort = (reason) => controller.abort(reason) + this.socket.on('close', this.abort) } } - onUpgrade (statusCode, headers, socket) { + onRequestUpgrade (controller, statusCode, _headers, socket) { this.socket.off('close', this.abort) // TODO: Check statusCode? @@ -128,8 +130,8 @@ class WSHandler { setupSocket(socket) - headers = getHeaders({ - headers, + const headers = getHeaders({ + headers: controller.rawHeaders ?? [], proxyName: this.proxyName, httpVersion: this.httpVersion }) @@ -144,7 +146,7 @@ class WSHandler { pipeline(socket, this.socket, socket, this.callback) } - onError (err) { + onResponseError (_controller, err) { this.socket.off('close', this.abort) this.callback(err) diff --git a/lib/api/api-connect.js b/lib/api/api-connect.js index c8b86dd7d53..b545a3eb5c1 100644 --- a/lib/api/api-connect.js +++ b/lib/api/api-connect.js @@ -32,45 +32,48 @@ class ConnectHandler extends AsyncResource { addSignal(this, signal) } - onConnect (abort, context) { + onRequestStart (controller, context) { if (this.reason) { - abort(this.reason) + controller.abort(this.reason) return } assert(this.callback) - this.abort = abort + this.abort = (reason) => controller.abort(reason) this.context = context } - onHeaders () { + onResponseStart () { throw new SocketError('bad connect', null) } - onUpgrade (statusCode, rawHeaders, socket) { + onRequestUpgrade (controller, statusCode, headers, socket) { const { callback, opaque, context } = this removeSignal(this) this.callback = null - let headers = rawHeaders + let responseHeaders = headers + const rawHeaders = controller?.rawHeaders // Indicates is an HTTP2Session - if (headers != null) { - headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + if (responseHeaders != null) { + responseHeaders = this.responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers } this.runInAsyncScope(callback, null, null, { statusCode, - headers, + headers: responseHeaders, socket, opaque, context }) } - onError (err) { + onResponseError (_controller, err) { const { callback, opaque } = this removeSignal(this) @@ -96,7 +99,6 @@ function connect (opts, callback) { try { const connectHandler = new ConnectHandler(opts, callback) const connectOptions = { ...opts, method: 'CONNECT' } - this.dispatch(connectOptions, connectHandler) } catch (err) { if (typeof callback !== 'function') { diff --git a/lib/api/api-pipeline.js b/lib/api/api-pipeline.js index 77f3520a83f..c8bd7414932 100644 --- a/lib/api/api-pipeline.js +++ b/lib/api/api-pipeline.js @@ -146,40 +146,46 @@ class PipelineHandler extends AsyncResource { addSignal(this, signal) } - onConnect (abort, context) { + onRequestStart (controller, context) { const { res } = this if (this.reason) { - abort(this.reason) + controller.abort(this.reason) return } assert(!res, 'pipeline cannot be retried') - this.abort = abort + this.abort = (reason) => controller.abort(reason) this.context = context } - onHeaders (statusCode, rawHeaders, resume) { + onResponseStart (controller, statusCode, headers, _statusMessage) { const { opaque, handler, context } = this if (statusCode < 200) { if (this.onInfo) { - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.onInfo({ statusCode, headers }) + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers + this.onInfo({ statusCode, headers: responseHeaders }) } return } - this.res = new PipelineResponse(resume) + this.res = new PipelineResponse(() => controller.resume()) let body try { this.handler = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers body = this.runInAsyncScope(handler, null, { statusCode, - headers, + headers: responseHeaders, opaque, body: this.res, context @@ -222,17 +228,20 @@ class PipelineHandler extends AsyncResource { this.body = body } - onData (chunk) { + onResponseData (controller, chunk) { const { res } = this - return res.push(chunk) + + if (res.push(chunk) === false) { + controller.pause() + } } - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { const { res } = this res.push(null) } - onError (err) { + onResponseError (_controller, err) { const { ret } = this this.handler = null util.destroy(ret, err) diff --git a/lib/api/api-request.js b/lib/api/api-request.js index c3461b23c84..b75a6dcae0e 100644 --- a/lib/api/api-request.js +++ b/lib/api/api-request.js @@ -54,6 +54,7 @@ class RequestHandler extends AsyncResource { this.body = body this.trailers = {} this.context = null + this.controller = null this.onInfo = onInfo || null this.highWaterMark = highWaterMark this.reason = null @@ -73,36 +74,40 @@ class RequestHandler extends AsyncResource { } } - onConnect (abort, context) { + onRequestStart (controller, context) { if (this.reason) { - abort(this.reason) + controller.abort(this.reason) return } assert(this.callback) - this.abort = abort + this.controller = controller + this.abort = (reason) => controller.abort(reason) this.context = context } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this + onResponseStart (controller, statusCode, headers, _statusMessage) { + const { callback, opaque, context, responseHeaders, highWaterMark } = this - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + const rawHeaders = controller?.rawHeaders + const responseHeaderData = responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers if (statusCode < 200) { if (this.onInfo) { - this.onInfo({ statusCode, headers }) + this.onInfo({ statusCode, headers: responseHeaderData }) } return } - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - const contentLength = parsedHeaders['content-length'] + const parsedHeaders = headers + const contentType = parsedHeaders?.['content-type'] + const contentLength = parsedHeaders?.['content-length'] const res = new Readable({ - resume, - abort, + resume: () => controller.resume(), + abort: (reason) => controller.abort(reason), contentType, contentLength: this.method !== 'HEAD' && contentLength ? Number(contentLength) @@ -121,7 +126,7 @@ class RequestHandler extends AsyncResource { try { this.runInAsyncScope(callback, null, null, { statusCode, - headers, + headers: responseHeaderData, trailers: this.trailers, opaque, body: res, @@ -143,16 +148,24 @@ class RequestHandler extends AsyncResource { } } - onData (chunk) { - return this.res.push(chunk) + onResponseData (controller, chunk) { + if (!this.res) { + return + } + + if (this.res.push(chunk) === false) { + controller.pause() + } } - onComplete (trailers) { - util.parseHeaders(trailers, this.trailers) - this.res.push(null) + onResponseEnd (_controller, trailers) { + if (trailers && typeof trailers === 'object') { + Object.assign(this.trailers, trailers) + } + this.res?.push(null) } - onError (err) { + onResponseError (_controller, err) { const { res, callback, body, opaque } = this if (callback) { diff --git a/lib/api/api-stream.js b/lib/api/api-stream.js index 5d0b3fbe633..daee5681223 100644 --- a/lib/api/api-stream.js +++ b/lib/api/api-stream.js @@ -53,39 +53,44 @@ class StreamHandler extends AsyncResource { this.res = null this.abort = null this.context = null + this.controller = null this.trailers = null this.body = body this.onInfo = onInfo || null if (util.isStream(body)) { body.on('error', (err) => { - this.onError(err) + this.onResponseError(this.controller, err) }) } addSignal(this, signal) } - onConnect (abort, context) { + onRequestStart (controller, context) { if (this.reason) { - abort(this.reason) + controller.abort(this.reason) return } assert(this.callback) - this.abort = abort + this.controller = controller + this.abort = (reason) => controller.abort(reason) this.context = context } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { + onResponseStart (controller, statusCode, headers, _statusMessage) { const { factory, opaque, context, responseHeaders } = this - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + const rawHeaders = controller?.rawHeaders + const responseHeaderData = responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers if (statusCode < 200) { if (this.onInfo) { - this.onInfo({ statusCode, headers }) + this.onInfo({ statusCode, headers: responseHeaderData }) } return } @@ -98,7 +103,7 @@ class StreamHandler extends AsyncResource { const res = this.runInAsyncScope(factory, null, { statusCode, - headers, + headers: responseHeaderData, opaque, context }) @@ -129,7 +134,7 @@ class StreamHandler extends AsyncResource { } }) - res.on('drain', resume) + res.on('drain', () => controller.resume()) this.res = res @@ -137,16 +142,24 @@ class StreamHandler extends AsyncResource { ? res.writableNeedDrain : res._writableState?.needDrain - return needDrain !== true + if (needDrain === true) { + controller.pause() + } } - onData (chunk) { + onResponseData (controller, chunk) { const { res } = this - return res ? res.write(chunk) : true + if (!res) { + return + } + + if (res.write(chunk) === false) { + controller.pause() + } } - onComplete (trailers) { + onResponseEnd (_controller, trailers) { const { res } = this removeSignal(this) @@ -155,12 +168,14 @@ class StreamHandler extends AsyncResource { return } - this.trailers = util.parseHeaders(trailers) + if (trailers && typeof trailers === 'object') { + this.trailers = trailers + } res.end() } - onError (err) { + onResponseError (_controller, err) { const { res, callback, opaque, body } = this removeSignal(this) diff --git a/lib/api/api-upgrade.js b/lib/api/api-upgrade.js index 2b03f207562..9f1d80c62dc 100644 --- a/lib/api/api-upgrade.js +++ b/lib/api/api-upgrade.js @@ -34,23 +34,23 @@ class UpgradeHandler extends AsyncResource { addSignal(this, signal) } - onConnect (abort, context) { + onRequestStart (controller, context) { if (this.reason) { - abort(this.reason) + controller.abort(this.reason) return } assert(this.callback) - this.abort = abort - this.context = null + this.abort = (reason) => controller.abort(reason) + this.context = context } - onHeaders () { + onResponseStart () { throw new SocketError('bad upgrade', null) } - onUpgrade (statusCode, rawHeaders, socket) { + onRequestUpgrade (controller, statusCode, headers, socket) { assert(socket[kHTTP2Stream] === true ? statusCode === 200 : statusCode === 101) const { callback, opaque, context } = this @@ -58,16 +58,21 @@ class UpgradeHandler extends AsyncResource { removeSignal(this) this.callback = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + : headers + this.runInAsyncScope(callback, null, null, { - headers, + headers: responseHeaders, socket, opaque, context }) } - onError (err) { + onResponseError (_controller, err) { const { callback, opaque } = this removeSignal(this) @@ -97,7 +102,6 @@ function upgrade (opts, callback) { method: opts.method || 'GET', upgrade: opts.protocol || 'Websocket' } - this.dispatch(upgradeOpts, upgradeHandler) } catch (err) { if (typeof callback !== 'function') { diff --git a/lib/core/request.js b/lib/core/request.js index 7dbf781b4c4..b4561a1b1c2 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -15,6 +15,7 @@ const { isIterable, isBlobLike, serializePathWithQuery, + parseHeaders, assertRequestHandler, getServerName, normalizedMethodRecords, @@ -27,6 +28,55 @@ const { headerNameLowerCasedRecord } = require('./constants') const invalidPathRegex = /[^\u0021-\u00ff]/ const kHandler = Symbol('handler') +const kController = Symbol('controller') +const kResume = Symbol('resume') + +class RequestController { + #paused = false + #reason = null + #aborted = false + #abort + + [kResume] = null + + rawHeaders = null + rawTrailers = null + + constructor (abort) { + this.#abort = abort + } + + pause () { + this.#paused = true + } + + resume () { + if (this.#paused) { + this.#paused = false + this[kResume]?.() + } + } + + abort (reason) { + if (!this.#aborted) { + this.#aborted = true + this.#reason = reason + this.#abort(reason) + } + } + + get aborted () { + return this.#aborted + } + + get reason () { + return this.#reason + } + + get paused () { + return this.#paused + } +} class Request { constructor (origin, { @@ -229,23 +279,26 @@ class Request { } } - onConnect (abort) { + onRequestStart (abort, context) { assert(!this.aborted) assert(!this.completed) + this[kController] = new RequestController(abort) + if (this.error) { - abort(this.error) - } else { - this.abort = abort - return this[kHandler].onConnect(abort) + this[kController].abort(this.error) + return } + + this.abort = abort + return this[kHandler].onRequestStart(this[kController], context) } onResponseStarted () { return this[kHandler].onResponseStarted?.() } - onHeaders (statusCode, headers, resume, statusText) { + onResponseStart (statusCode, headers, resume, statusText) { assert(!this.aborted) assert(!this.completed) @@ -253,36 +306,56 @@ class Request { channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) } + const controller = this[kController] + if (controller) { + controller[kResume] = resume + controller.rawHeaders = headers + } + + const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers + try { - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + this[kHandler].onResponseStart?.(controller, statusCode, parsedHeaders, statusText) + return !controller?.paused } catch (err) { this.abort(err) + return false } } - onData (chunk) { + onResponseData (chunk) { assert(!this.aborted) assert(!this.completed) if (channels.bodyChunkReceived.hasSubscribers) { channels.bodyChunkReceived.publish({ request: this, chunk }) } + + const controller = this[kController] try { - return this[kHandler].onData(chunk) + this[kHandler].onResponseData?.(controller, chunk) + return !controller?.paused } catch (err) { this.abort(err) return false } } - onUpgrade (statusCode, headers, socket) { + onRequestUpgrade (statusCode, headers, socket) { assert(!this.aborted) assert(!this.completed) - return this[kHandler].onUpgrade(statusCode, headers, socket) + const controller = this[kController] + if (controller) { + controller.rawHeaders = headers + } + + const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers + + return this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket) } - onComplete (trailers) { + onResponseEnd (trailers) { this.onFinally() assert(!this.aborted) @@ -293,15 +366,22 @@ class Request { channels.trailers.publish({ request: this, trailers }) } + const controller = this[kController] + if (controller) { + controller.rawTrailers = trailers + } + + const parsedTrailers = Array.isArray(trailers) ? parseHeaders(trailers) : trailers + try { - return this[kHandler].onComplete(trailers) + return this[kHandler].onResponseEnd?.(controller, parsedTrailers) } catch (err) { // TODO (fix): This might be a bad idea? - this.onError(err) + this.onResponseError(err) } } - onError (error) { + onResponseError (error) { this.onFinally() if (channels.error.hasSubscribers) { @@ -313,7 +393,9 @@ class Request { } this.aborted = true - return this[kHandler].onError(error) + const controller = this[kController] + + return this[kHandler].onResponseError?.(controller, error) } onFinally () { diff --git a/lib/core/util.js b/lib/core/util.js index be2c1a7320d..54a80e5e2cc 100644 --- a/lib/core/util.js +++ b/lib/core/util.js @@ -473,6 +473,26 @@ function parseRawHeaders (headers) { return ret } +/** + * @param {Record} headers + * @returns {Buffer[]} + */ +function toRawHeaders (headers) { + const rawHeaders = [] + + for (const [name, value] of Object.entries(headers)) { + if (Array.isArray(value)) { + for (const entry of value) { + rawHeaders.push(Buffer.from(name, 'latin1'), Buffer.from(`${entry}`, 'latin1')) + } + } else { + rawHeaders.push(Buffer.from(name, 'latin1'), Buffer.from(`${value}`, 'latin1')) + } + } + + return rawHeaders +} + /** * @param {string[]} headers * @param {Buffer[]} headers @@ -506,38 +526,37 @@ function assertRequestHandler (handler, method, upgrade) { throw new InvalidArgumentError('handler must be an object') } - if (typeof handler.onRequestStart === 'function') { - // TODO (fix): More checks... - return + if (typeof handler.onRequestStart !== 'function') { + throw new InvalidArgumentError('invalid onRequestStart method') } - if (typeof handler.onConnect !== 'function') { - throw new InvalidArgumentError('invalid onConnect method') - } - - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') + if (typeof handler.onResponseError !== 'function') { + throw new InvalidArgumentError('invalid onResponseError method') } if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { throw new InvalidArgumentError('invalid onBodySent method') } + if (typeof handler.onRequestSent !== 'function' && handler.onRequestSent !== undefined) { + throw new InvalidArgumentError('invalid onRequestSent method') + } + if (upgrade || method === 'CONNECT') { - if (typeof handler.onUpgrade !== 'function') { - throw new InvalidArgumentError('invalid onUpgrade method') + if (typeof handler.onRequestUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onRequestUpgrade method') } } else { - if (typeof handler.onHeaders !== 'function') { - throw new InvalidArgumentError('invalid onHeaders method') + if (typeof handler.onResponseStart !== 'function') { + throw new InvalidArgumentError('invalid onResponseStart method') } - if (typeof handler.onData !== 'function') { - throw new InvalidArgumentError('invalid onData method') + if (typeof handler.onResponseData !== 'function') { + throw new InvalidArgumentError('invalid onResponseData method') } - if (typeof handler.onComplete !== 'function') { - throw new InvalidArgumentError('invalid onComplete method') + if (typeof handler.onResponseEnd !== 'function') { + throw new InvalidArgumentError('invalid onResponseEnd method') } } } @@ -778,7 +797,7 @@ function removeAllListeners (obj) { */ function errorRequest (client, request, err) { try { - request.onError(err) + request.onResponseError(err) assert(request.aborted) } catch (err) { client.emit('error', err) @@ -926,6 +945,7 @@ module.exports = { removeAllListeners, errorRequest, parseRawHeaders, + toRawHeaders, encodeRawHeaders, parseHeaders, parseKeepAliveTimeout, diff --git a/lib/dispatcher/client-h1.js b/lib/dispatcher/client-h1.js index 09d1a7599c4..18211ca73ad 100644 --- a/lib/dispatcher/client-h1.js +++ b/lib/dispatcher/client-h1.js @@ -507,7 +507,7 @@ class Parser { client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) try { - request.onUpgrade(statusCode, headers, socket) + request.onRequestUpgrade(statusCode, headers, socket) } catch (err) { util.destroy(socket, err) } @@ -605,7 +605,7 @@ class Parser { socket[kReset] = true } - const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false + const pause = request.onResponseStart(statusCode, headers, this.resume, statusText) === false if (request.aborted) { return -1 @@ -657,7 +657,7 @@ class Parser { this.bytesRead += buf.length - if (request.onData(buf) === false) { + if (request.onResponseData(buf) === false) { return constants.ERROR.PAUSED } @@ -703,7 +703,7 @@ class Parser { return -1 } - request.onComplete(headers) + request.onResponseEnd(headers) client[kQueue][client[kRunningIdx]++] = null @@ -1073,7 +1073,7 @@ function writeH1 (client, request) { } try { - request.onConnect(abort) + request.onRequestStart(abort, null) } catch (err) { util.errorRequest(client, request, err) } diff --git a/lib/dispatcher/client-h2.js b/lib/dispatcher/client-h2.js index c9aec504af1..cb3fc061ddc 100644 --- a/lib/dispatcher/client-h2.js +++ b/lib/dispatcher/client-h2.js @@ -457,7 +457,7 @@ function writeH2 (client, request) { try { // We are already connected, streams are pending. // We can call on connect, and wait for abort - request.onConnect(abort) + request.onRequestStart(abort, null) } catch (err) { util.errorRequest(client, request, err) } @@ -497,7 +497,7 @@ function writeH2 (client, request) { stream.once('response', (headers, _flags) => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers - request.onUpgrade(statusCode, parseH2Headers(realHeaders), stream) + request.onRequestUpgrade(statusCode, parseH2Headers(realHeaders), stream) ++session[kOpenStreams] client[kQueue][client[kRunningIdx]++] = null @@ -531,7 +531,7 @@ function writeH2 (client, request) { stream.on('response', headers => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers - request.onUpgrade(statusCode, parseH2Headers(realHeaders), stream) + request.onRequestUpgrade(statusCode, parseH2Headers(realHeaders), stream) ++session[kOpenStreams] client[kQueue][client[kRunningIdx]++] = null }) @@ -660,13 +660,13 @@ function writeH2 (client, request) { return } - if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { + if (request.onResponseStart(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { stream.pause() } }) stream.on('data', (chunk) => { - if (request.onData(chunk) === false) { + if (request.onResponseData(chunk) === false) { stream.pause() } }) @@ -676,7 +676,7 @@ function writeH2 (client, request) { // If we received a response, this is a normal completion if (responseReceived) { if (!request.aborted && !request.completed) { - request.onComplete({}) + request.onResponseEnd({}) } client[kQueue][client[kRunningIdx]++] = null @@ -730,7 +730,7 @@ function writeH2 (client, request) { return } - request.onComplete(trailers) + request.onResponseEnd(trailers) }) return true diff --git a/lib/dispatcher/dispatcher-base.js b/lib/dispatcher/dispatcher-base.js index a6f47100257..59ad3abd046 100644 --- a/lib/dispatcher/dispatcher-base.js +++ b/lib/dispatcher/dispatcher-base.js @@ -1,7 +1,6 @@ 'use strict' const Dispatcher = require('./dispatcher') -const UnwrapHandler = require('../handler/unwrap-handler') const { ClientDestroyedError, ClientClosedError, @@ -134,8 +133,6 @@ class DispatcherBase extends Dispatcher { throw new InvalidArgumentError('handler must be an object') } - handler = UnwrapHandler.unwrap(handler) - try { if (!opts || typeof opts !== 'object') { throw new InvalidArgumentError('opts must be an object.') @@ -151,11 +148,11 @@ class DispatcherBase extends Dispatcher { return this[kDispatch](opts, handler) } catch (err) { - if (typeof handler.onError !== 'function') { + if (typeof handler.onResponseError !== 'function') { throw err } - handler.onError(err) + handler.onResponseError(null, err) return false } diff --git a/lib/dispatcher/dispatcher.js b/lib/dispatcher/dispatcher.js index 824dfb6d822..ecff2a9b168 100644 --- a/lib/dispatcher/dispatcher.js +++ b/lib/dispatcher/dispatcher.js @@ -1,8 +1,5 @@ 'use strict' const EventEmitter = require('node:events') -const WrapHandler = require('../handler/wrap-handler') - -const wrapInterceptor = (dispatch) => (opts, handler) => dispatch(opts, WrapHandler.wrap(handler)) class Dispatcher extends EventEmitter { dispatch () { @@ -32,7 +29,6 @@ class Dispatcher extends EventEmitter { } dispatch = interceptor(dispatch) - dispatch = wrapInterceptor(dispatch) if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) { throw new TypeError('invalid interceptor') diff --git a/lib/dispatcher/pool-base.js b/lib/dispatcher/pool-base.js index 4de14f920e8..ee750d466a9 100644 --- a/lib/dispatcher/pool-base.js +++ b/lib/dispatcher/pool-base.js @@ -137,7 +137,7 @@ class PoolBase extends DispatcherBase { if (!item) { break } - item.handler.onError(err) + item.handler.onResponseError(null, err) } const destroyAll = new Array(this[kClients].length) diff --git a/lib/dispatcher/proxy-agent.js b/lib/dispatcher/proxy-agent.js index 4403b8d87ce..b3b29e25142 100644 --- a/lib/dispatcher/proxy-agent.js +++ b/lib/dispatcher/proxy-agent.js @@ -53,15 +53,15 @@ class Http1ProxyWrapper extends DispatcherBase { } [kDispatch] (opts, handler) { - const onHeaders = handler.onHeaders - handler.onHeaders = function (statusCode, data, resume) { + const onResponseStart = handler.onResponseStart + handler.onResponseStart = function (controller, statusCode, data, statusMessage) { if (statusCode === 407) { - if (typeof handler.onError === 'function') { - handler.onError(new InvalidArgumentError('Proxy Authentication Required (407)')) + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(controller, new InvalidArgumentError('Proxy Authentication Required (407)')) } return } - if (onHeaders) onHeaders.call(this, statusCode, data, resume) + if (onResponseStart) onResponseStart.call(this, controller, statusCode, data, statusMessage) } // Rewrite request as an HTTP1 Proxy request, without tunneling. diff --git a/lib/handler/decorator-handler.js b/lib/handler/decorator-handler.js index 50fbb0cf892..1b53c711324 100644 --- a/lib/handler/decorator-handler.js +++ b/lib/handler/decorator-handler.js @@ -1,7 +1,6 @@ 'use strict' const assert = require('node:assert') -const WrapHandler = require('./wrap-handler') /** * @deprecated @@ -16,7 +15,7 @@ module.exports = class DecoratorHandler { if (typeof handler !== 'object' || handler === null) { throw new TypeError('handler must be an object') } - this.#handler = WrapHandler.wrap(handler) + this.#handler = handler } onRequestStart (...args) { diff --git a/lib/handler/retry-handler.js b/lib/handler/retry-handler.js index 1cbc78981b1..ee2f69a2043 100644 --- a/lib/handler/retry-handler.js +++ b/lib/handler/retry-handler.js @@ -3,7 +3,6 @@ const assert = require('node:assert') const { kRetryHandlerDefaultRetry } = require('../core/symbols') const { RequestRetryError } = require('../core/errors') -const WrapHandler = require('./wrap-handler') const { isDisturbed, parseRangeHeader, @@ -35,7 +34,7 @@ class RetryHandler { this.error = null this.dispatch = dispatch - this.handler = WrapHandler.wrap(handler) + this.handler = handler this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) } this.retryOpts = { throwOnError: throwOnError ?? true, diff --git a/lib/handler/unwrap-handler.js b/lib/handler/unwrap-handler.js deleted file mode 100644 index 865593a327b..00000000000 --- a/lib/handler/unwrap-handler.js +++ /dev/null @@ -1,96 +0,0 @@ -'use strict' - -const { parseHeaders } = require('../core/util') -const { InvalidArgumentError } = require('../core/errors') - -const kResume = Symbol('resume') - -class UnwrapController { - #paused = false - #reason = null - #aborted = false - #abort - - [kResume] = null - - constructor (abort) { - this.#abort = abort - } - - pause () { - this.#paused = true - } - - resume () { - if (this.#paused) { - this.#paused = false - this[kResume]?.() - } - } - - abort (reason) { - if (!this.#aborted) { - this.#aborted = true - this.#reason = reason - this.#abort(reason) - } - } - - get aborted () { - return this.#aborted - } - - get reason () { - return this.#reason - } - - get paused () { - return this.#paused - } -} - -module.exports = class UnwrapHandler { - #handler - #controller - - constructor (handler) { - this.#handler = handler - } - - static unwrap (handler) { - // TODO (fix): More checks... - return !handler.onRequestStart ? handler : new UnwrapHandler(handler) - } - - onConnect (abort, context) { - this.#controller = new UnwrapController(abort) - this.#handler.onRequestStart?.(this.#controller, context) - } - - onUpgrade (statusCode, rawHeaders, socket) { - this.#handler.onRequestUpgrade?.(this.#controller, statusCode, parseHeaders(rawHeaders), socket) - } - - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - this.#controller[kResume] = resume - this.#handler.onResponseStart?.(this.#controller, statusCode, parseHeaders(rawHeaders), statusMessage) - return !this.#controller.paused - } - - onData (data) { - this.#handler.onResponseData?.(this.#controller, data) - return !this.#controller.paused - } - - onComplete (rawTrailers) { - this.#handler.onResponseEnd?.(this.#controller, parseHeaders(rawTrailers)) - } - - onError (err) { - if (!this.#handler.onResponseError) { - throw new InvalidArgumentError('invalid onError method') - } - - this.#handler.onResponseError?.(this.#controller, err) - } -} diff --git a/lib/handler/wrap-handler.js b/lib/handler/wrap-handler.js deleted file mode 100644 index 47caa5fa68b..00000000000 --- a/lib/handler/wrap-handler.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict' - -const { InvalidArgumentError } = require('../core/errors') - -module.exports = class WrapHandler { - #handler - - constructor (handler) { - this.#handler = handler - } - - static wrap (handler) { - // TODO (fix): More checks... - return handler.onRequestStart ? handler : new WrapHandler(handler) - } - - // Unwrap Interface - - onConnect (abort, context) { - return this.#handler.onConnect?.(abort, context) - } - - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - return this.#handler.onHeaders?.(statusCode, rawHeaders, resume, statusMessage) - } - - onUpgrade (statusCode, rawHeaders, socket) { - return this.#handler.onUpgrade?.(statusCode, rawHeaders, socket) - } - - onData (data) { - return this.#handler.onData?.(data) - } - - onComplete (trailers) { - return this.#handler.onComplete?.(trailers) - } - - onError (err) { - if (!this.#handler.onError) { - throw err - } - - return this.#handler.onError?.(err) - } - - // Wrap Interface - - onRequestStart (controller, context) { - this.#handler.onConnect?.((reason) => controller.abort(reason), context) - } - - onRequestUpgrade (controller, statusCode, headers, socket) { - const rawHeaders = [] - for (const [key, val] of Object.entries(headers)) { - rawHeaders.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val)) - } - - this.#handler.onUpgrade?.(statusCode, rawHeaders, socket) - } - - onResponseStart (controller, statusCode, headers, statusMessage) { - const rawHeaders = [] - for (const [key, val] of Object.entries(headers)) { - rawHeaders.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val)) - } - - if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) { - controller.pause() - } - } - - onResponseData (controller, data) { - if (this.#handler.onData?.(data) === false) { - controller.pause() - } - } - - onResponseEnd (controller, trailers) { - const rawTrailers = [] - for (const [key, val] of Object.entries(trailers)) { - rawTrailers.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val)) - } - - this.#handler.onComplete?.(rawTrailers) - } - - onResponseError (controller, err) { - if (!this.#handler.onError) { - throw new InvalidArgumentError('invalid onError method') - } - - this.#handler.onError?.(err) - } -} diff --git a/lib/interceptor/cache.js b/lib/interceptor/cache.js index b0449374fd4..3ecd30e992f 100644 --- a/lib/interceptor/cache.js +++ b/lib/interceptor/cache.js @@ -124,30 +124,39 @@ function handleUncachedResponse ( ) { if (reqCacheControl?.['only-if-cached']) { let aborted = false - try { - if (typeof handler.onConnect === 'function') { - handler.onConnect(() => { - aborted = true - }) - if (aborted) { - return - } + const controller = { + paused: false, + rawHeaders: [], + rawTrailers: [], + pause () { + this.paused = true + }, + resume () { + this.paused = false + }, + abort: (reason) => { + aborted = true + handler.onResponseError?.(controller, reason ?? new AbortError()) } + } - if (typeof handler.onHeaders === 'function') { - handler.onHeaders(504, [], nop, 'Gateway Timeout') - if (aborted) { - return - } + try { + handler.onRequestStart?.(controller, null) + + if (aborted) { + return } - if (typeof handler.onComplete === 'function') { - handler.onComplete([]) + handler.onResponseStart?.(controller, 504, {}, 'Gateway Timeout') + if (aborted) { + return } + + handler.onResponseEnd?.(controller, {}) } catch (err) { - if (typeof handler.onError === 'function') { - handler.onError(err) + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(controller, err) } } @@ -175,6 +184,8 @@ function sendCachedValue (handler, opts, result, age, context, isStale) { assert(!stream.readableDidRead, 'stream should not be readableDidRead') const controller = { + rawHeaders: [], + rawTrailers: [], resume () { stream.resume() }, @@ -227,6 +238,8 @@ function sendCachedValue (handler, opts, result, age, context, isStale) { headers.warning = '110 - "response is stale"' } + controller.rawHeaders = util.toRawHeaders(headers) + handler.onResponseStart?.(controller, result.statusCode, headers, result.statusMessage) if (opts.method === 'HEAD') { diff --git a/lib/interceptor/decompress.js b/lib/interceptor/decompress.js index ee4202a96f7..c43565a0535 100644 --- a/lib/interceptor/decompress.js +++ b/lib/interceptor/decompress.js @@ -181,6 +181,33 @@ class DecompressHandler extends DecoratorHandler { // Remove compression headers since we're decompressing const { 'content-encoding': _, 'content-length': __, ...newHeaders } = headers + if (controller?.rawHeaders) { + const rawHeaders = controller.rawHeaders + + if (Array.isArray(rawHeaders)) { + const filteredHeaders = [] + for (let i = 0; i < rawHeaders.length; i += 2) { + const headerName = rawHeaders[i] + const name = Buffer.isBuffer(headerName) ? headerName.toString('latin1') : `${headerName}` + const lowerName = name.toLowerCase() + + if (lowerName === 'content-encoding' || lowerName === 'content-length') { + continue + } + + filteredHeaders.push(rawHeaders[i], rawHeaders[i + 1]) + } + controller.rawHeaders = filteredHeaders + } else if (typeof rawHeaders === 'object') { + for (const name of Object.keys(rawHeaders)) { + const lowerName = name.toLowerCase() + if (lowerName === 'content-encoding' || lowerName === 'content-length') { + delete rawHeaders[name] + } + } + } + } + if (this.#decompressors.length === 1) { this.#setupSingleDecompressor(controller) } else { diff --git a/lib/mock/mock-utils.js b/lib/mock/mock-utils.js index e1e3f040643..3e48b83f57f 100644 --- a/lib/mock/mock-utils.js +++ b/lib/mock/mock-utils.js @@ -8,7 +8,7 @@ const { kOrigin, kGetNetConnect } = require('./mock-symbols') -const { serializePathWithQuery } = require('../core/util') +const { serializePathWithQuery, parseHeaders } = require('../core/util') const { STATUS_CODES } = require('node:http') const { types: { @@ -308,7 +308,7 @@ function mockDispatch (opts, handler) { // If specified, trigger dispatch error if (error !== null) { deleteMockDispatch(this[kDispatches], key) - handler.onError(error) + handler.onResponseError(null, error) return true } @@ -344,15 +344,28 @@ function mockDispatch (opts, handler) { const responseHeaders = generateKeyValues(headers) const responseTrailers = generateKeyValues(trailers) - handler.onConnect?.(err => handler.onError(err), null) - handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode)) - handler.onData?.(Buffer.from(responseData)) - handler.onComplete?.(responseTrailers) + const controller = { + paused: false, + rawHeaders: responseHeaders, + rawTrailers: responseTrailers, + pause () { + this.paused = true + }, + resume () { + this.paused = false + }, + abort: (reason) => { + handler.onResponseError?.(controller, reason) + } + } + + handler.onRequestStart?.(controller, null) + handler.onResponseStart?.(controller, statusCode, parseHeaders(responseHeaders), getStatusText(statusCode)) + handler.onResponseData?.(controller, Buffer.from(responseData)) + handler.onResponseEnd?.(controller, parseHeaders(responseTrailers)) deleteMockDispatch(mockDispatches, key) } - function resume () {} - return true } diff --git a/lib/mock/snapshot-agent.js b/lib/mock/snapshot-agent.js index 80280111921..a3aee68cb2d 100644 --- a/lib/mock/snapshot-agent.js +++ b/lib/mock/snapshot-agent.js @@ -3,8 +3,8 @@ const Agent = require('../dispatcher/agent') const MockAgent = require('./mock-agent') const { SnapshotRecorder } = require('./snapshot-recorder') -const WrapHandler = require('../handler/wrap-handler') const { InvalidArgumentError, UndiciError } = require('../core/errors') +const util = require('../core/util') const { validateSnapshotMode } = require('./snapshot-utils') const kSnapshotRecorder = Symbol('kSnapshotRecorder') @@ -79,7 +79,6 @@ class SnapshotAgent extends MockAgent { } dispatch (opts, handler) { - handler = WrapHandler.wrap(handler) const mode = this[kSnapshotMode] // Check if URL should be excluded (pass through without mocking/recording) @@ -107,8 +106,8 @@ class SnapshotAgent extends MockAgent { } else { // Playback mode but no snapshot found const error = new UndiciError(`No snapshot found for ${opts.method || 'GET'} ${opts.path}`) - if (handler.onError) { - handler.onError(error) + if (handler.onResponseError) { + handler.onResponseError(null, error) return } throw error @@ -173,6 +172,10 @@ class SnapshotAgent extends MockAgent { }) .then(() => handler.onResponseEnd(controller, trailers)) .catch((error) => handler.onResponseError(controller, error)) + }, + + onResponseError (controller, error) { + return handler.onResponseError(controller, error) } } @@ -192,7 +195,12 @@ class SnapshotAgent extends MockAgent { try { const { response } = snapshot + const rawHeaders = response.headers ? util.toRawHeaders(response.headers) : [] + const rawTrailers = response.trailers ? util.toRawHeaders(response.trailers) : [] + const controller = { + rawHeaders, + rawTrailers, pause () { }, resume () { }, abort (reason) { @@ -206,7 +214,7 @@ class SnapshotAgent extends MockAgent { handler.onRequestStart(controller) - handler.onResponseStart(controller, response.statusCode, response.headers) + handler.onResponseStart(controller, response.statusCode, response.headers, response.statusMessage) // Body is always stored as base64 string const body = Buffer.from(response.body, 'base64') @@ -214,7 +222,7 @@ class SnapshotAgent extends MockAgent { handler.onResponseEnd(controller, response.trailers) } catch (error) { - handler.onError?.(error) + handler.onResponseError?.(null, error) } } diff --git a/lib/web/fetch/index.js b/lib/web/fetch/index.js index bb33e8d77e8..43124a4c235 100644 --- a/lib/web/fetch/index.js +++ b/lib/web/fetch/index.js @@ -2146,7 +2146,7 @@ async function httpNetworkFetch ( body: null, abort: null, - onConnect (abort) { + onRequestStart (controller) { // TODO (fix): Do we need connection here? const { connection } = fetchParams.controller @@ -2156,6 +2156,8 @@ async function httpNetworkFetch ( // TODO: implement connection timing timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(undefined, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability) + const abort = (reason) => controller.abort(reason) + if (connection.destroyed) { abort(new DOMException('The operation was aborted.', 'AbortError')) } else { @@ -2176,11 +2178,12 @@ async function httpNetworkFetch ( timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) }, - onHeaders (status, rawHeaders, resume, statusText) { + onResponseStart (controller, status, _headers, statusText) { if (status < 200) { - return false + return } + const rawHeaders = controller?.rawHeaders ?? [] const headersList = new HeadersList() for (let i = 0; i < rawHeaders.length; i += 2) { @@ -2188,7 +2191,7 @@ async function httpNetworkFetch ( } const location = headersList.get('location', true) - this.body = new Readable({ read: resume }) + this.body = new Readable({ read: () => controller.resume() }) const willFollow = location && request.redirect === 'follow' && redirectStatusSet.has(status) @@ -2208,7 +2211,7 @@ async function httpNetworkFetch ( const maxContentEncodings = 5 if (codings.length > maxContentEncodings) { reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)) - return true + return } for (let i = codings.length - 1; i >= 0; --i) { @@ -2245,7 +2248,7 @@ async function httpNetworkFetch ( } } - const onError = this.onError.bind(this) + const onError = (err) => this.onResponseError(controller, err) resolve({ status, @@ -2254,16 +2257,14 @@ async function httpNetworkFetch ( body: decoders.length ? pipeline(this.body, ...decoders, (err) => { if (err) { - this.onError(err) + this.onResponseError(controller, err) } }).on('error', onError) : this.body.on('error', onError) }) - - return true }, - onData (chunk) { + onResponseData (controller, chunk) { if (fetchParams.controller.dump) { return } @@ -2283,20 +2284,22 @@ async function httpNetworkFetch ( // 4. See pullAlgorithm... - return this.body.push(bytes) + if (this.body.push(bytes) === false) { + controller.pause() + } }, - onComplete () { + onResponseEnd () { if (this.abort) { fetchParams.controller.off('terminated', this.abort) } fetchParams.controller.ended = true - this.body.push(null) + this.body?.push(null) }, - onError (error) { + onResponseError (_controller, error) { if (this.abort) { fetchParams.controller.off('terminated', this.abort) } @@ -2308,13 +2311,14 @@ async function httpNetworkFetch ( reject(error) }, - onUpgrade (status, rawHeaders, socket) { + onRequestUpgrade (controller, status, _headers, socket) { // We need to support 200 for websocket over h2 as per RFC-8441 // Absence of session means H1 if ((socket.session != null && status !== 200) || (socket.session == null && status !== 101)) { - return false + return } + const rawHeaders = controller?.rawHeaders ?? [] const headersList = new HeadersList() for (let i = 0; i < rawHeaders.length; i += 2) { @@ -2327,8 +2331,6 @@ async function httpNetworkFetch ( headersList, socket }) - - return true } } )) diff --git a/package.json b/package.json index bdfe7896b19..98be6e7d653 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "test:websocket:autobahn": "node test/autobahn/client.js", "test:websocket:autobahn:report": "node test/autobahn/report.js", "test:wpt:setup": "node test/web-platform-tests/wpt-runner.mjs setup", - "test:wpt": "npm run test:wpt:setup && node test/web-platform-tests/wpt-runner.mjs run /fetch /mimesniff /xhr /websockets /serviceWorkers /eventsource", + "test:wpt": "npm run test:wpt:setup && node test/web-platform-tests/wpt-runner.mjs run /fetch /mimesniff /websockets /serviceWorkers /eventsource", "test:cache-tests": "node test/cache-interceptor/cache-tests.mjs --ci", "coverage": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report", "coverage:ci": "npm run coverage:clean && cross-env NODE_V8_COVERAGE=./coverage/tmp npm run test:javascript && npm run coverage:report:ci", @@ -113,7 +113,7 @@ "@matteo.collina/tspl": "^0.2.0", "@metcoder95/https-pem": "^1.0.0", "@sinonjs/fake-timers": "^12.0.0", - "@types/node": "^20.19.22", + "@types/node": "^22.0.0", "abort-controller": "^3.0.0", "borp": "^0.20.0", "c8": "^10.0.0", @@ -133,7 +133,7 @@ "ws": "^8.11.0" }, "engines": { - "node": ">=20.18.1" + "node": ">=22.0.0" }, "tsd": { "directory": "test/types", diff --git a/scripts/find-hanging-tests.sh b/scripts/find-hanging-tests.sh new file mode 100755 index 00000000000..759f6642d0c --- /dev/null +++ b/scripts/find-hanging-tests.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -euo pipefail + +TIMEOUT_SECONDS=${TIMEOUT_SECONDS:-120} +TEST_GLOB=${TEST_GLOB:-"test/*.js"} +LOG_DIR=${LOG_DIR:-"/tmp/undici-test-hang"} + +mkdir -p "$LOG_DIR" + +failures=() +timeouts=() + +while IFS= read -r test_file; do + echo "==> ${test_file}" + log_file="$LOG_DIR/$(basename "$test_file").log" + if timeout "$TIMEOUT_SECONDS" npx borp -p "$test_file" >"$log_file" 2>&1; then + echo "PASS ${test_file}" + else + exit_code=$? + if [[ $exit_code -eq 124 || $exit_code -eq 137 ]]; then + echo "TIMEOUT ${test_file}" + timeouts+=("$test_file") + else + echo "FAIL ${test_file} (exit $exit_code)" + failures+=("$test_file") + fi + fi + echo + sleep 0.2 +done < <(ls $TEST_GLOB | sort) + +echo "=== Summary ===" +if [[ ${#timeouts[@]} -gt 0 ]]; then + echo "Timeouts:" + printf ' - %s\n' "${timeouts[@]}" +else + echo "Timeouts: none" +fi + +if [[ ${#failures[@]} -gt 0 ]]; then + echo "Failures:" + printf ' - %s\n' "${failures[@]}" +else + echo "Failures: none" +fi + +echo "Logs: $LOG_DIR" diff --git a/test/client-request.js b/test/client-request.js index d367435eeff..ff4abf4bb4f 100644 --- a/test/client-request.js +++ b/test/client-request.js @@ -154,8 +154,8 @@ test('request dump with abort signal', async (t) => { t.ok(stackLines[2].startsWith('at AbortController.abort')) t.ok(/client-request.js/.test(stackLines[3])) t.ok(stackLines[4].startsWith('at RequestHandler.runInAsyncScope')) - t.ok(stackLines[5].startsWith('at RequestHandler.onHeaders')) - t.ok(stackLines[6].startsWith('at Request.onHeaders')) + t.ok(stackLines[5].startsWith('at RequestHandler.onResponseStart')) + t.ok(stackLines[6].startsWith('at Request.onResponseStart')) server.close() }) ac.abort() @@ -193,8 +193,8 @@ test('request dump with POJO as invalid signal', async (t) => { t.ok(stackLines[1].startsWith('at BodyReadable.dump')) t.ok(/client-request.js/.test(stackLines[2])) t.ok(stackLines[3].startsWith('at RequestHandler.runInAsyncScope')) - t.ok(stackLines[4].startsWith('at RequestHandler.onHeaders')) - t.ok(stackLines[5].startsWith('at Request.onHeaders')) + t.ok(stackLines[4].startsWith('at RequestHandler.onResponseStart')) + t.ok(stackLines[5].startsWith('at Request.onResponseStart')) server.close() }) }) @@ -233,8 +233,8 @@ test('request dump with aborted signal', async (t) => { t.ok(stackLines[0].startsWith('AbortError: This operation was with purpose aborted')) t.ok(/client-request.js/.test(stackLines[1])) t.ok(stackLines[2].startsWith('at RequestHandler.runInAsyncScope')) - t.ok(stackLines[3].startsWith('at RequestHandler.onHeaders')) - t.ok(stackLines[4].startsWith('at Request.onHeaders')) + t.ok(stackLines[3].startsWith('at RequestHandler.onResponseStart')) + t.ok(stackLines[4].startsWith('at Request.onResponseStart')) server.close() }) ac.abort() diff --git a/test/client-timeout.js b/test/client-timeout.js index 26cf21913c2..4a5c2bc9059 100644 --- a/test/client-timeout.js +++ b/test/client-timeout.js @@ -26,21 +26,21 @@ test('refresh timeout on pause', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers, resume) { + onResponseStart (controller) { setTimeout(() => { - resume() + controller.resume() }, 1000) - return false + controller.pause() }, - onData () { + onResponseData () { }, - onComplete () { + onResponseEnd () { }, - onError (err) { + onResponseError (_controller, err) { t.ok(err instanceof errors.BodyTimeoutError) } }) @@ -78,7 +78,7 @@ test('start headers timeout after request body', async (t) => { body, method: 'GET' }, { - onConnect () { + onRequestStart () { process.nextTick(() => { clock.tick(200) }) @@ -89,15 +89,15 @@ test('start headers timeout after request body', async (t) => { }) }) }, - onHeaders (statusCode, headers, resume) { + onResponseStart () { }, - onData () { + onResponseData () { }, - onComplete () { + onResponseEnd () { }, - onError (err) { + onResponseError (_controller, err) { t.equal(body.readableEnded, true) t.ok(err instanceof errors.HeadersTimeoutError) } @@ -141,7 +141,7 @@ test('start headers timeout after async iterator request body', async (t) => { body, method: 'GET' }, { - onConnect () { + onRequestStart () { process.nextTick(() => { clock.tick(200) }) @@ -149,15 +149,15 @@ test('start headers timeout after async iterator request body', async (t) => { res() }) }, - onHeaders (statusCode, headers, resume) { + onResponseStart () { }, - onData () { + onResponseData () { }, - onComplete () { + onResponseEnd () { }, - onError (err) { + onResponseError (_controller, err) { t.ok(err instanceof errors.HeadersTimeoutError) } }) @@ -184,19 +184,19 @@ test('parser resume with no body timeout', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers, resume) { - setTimeout(resume, 2000) - return false + onResponseStart (controller) { + setTimeout(() => controller.resume(), 2000) + controller.pause() }, - onData () { + onResponseData () { }, - onComplete () { + onResponseEnd () { t.ok(true, 'pass') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } }) diff --git a/test/decorator-handler.js b/test/decorator-handler.js index fc3e657f169..06c2e83b011 100644 --- a/test/decorator-handler.js +++ b/test/decorator-handler.js @@ -33,28 +33,28 @@ describe('DecoratorHandler', () => { this.#handler = handler } - onConnect (abort, context) { - return this.#handler?.onConnect?.(abort, context) + onRequestStart (controller, context) { + return this.#handler?.onRequestStart?.(controller, context) } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - return this.#handler?.onHeaders?.(statusCode, rawHeaders, resume, statusMessage) + onResponseStart (controller, statusCode, headers, statusMessage) { + return this.#handler?.onResponseStart?.(controller, statusCode, headers, statusMessage) } - onUpgrade (statusCode, rawHeaders, socket) { - return this.#handler?.onUpgrade?.(statusCode, rawHeaders, socket) + onRequestUpgrade (controller, statusCode, headers, socket) { + return this.#handler?.onRequestUpgrade?.(controller, statusCode, headers, socket) } - onData (data) { - return this.#handler?.onData?.(data) + onResponseData (controller, data) { + return this.#handler?.onResponseData?.(controller, data) } - onComplete (trailers) { - return this.#handler?.onComplete?.(trailers) + onResponseEnd (controller, trailers) { + return this.#handler?.onResponseEnd?.(controller, trailers) } - onError (err) { - return this.#handler?.onError?.(err) + onResponseError (controller, err) { + return this.#handler?.onResponseError?.(controller, err) } } const Controller = class { @@ -76,13 +76,14 @@ describe('DecoratorHandler', () => { } } - describe('#onConnect', () => { - test('should delegate onConnect-method', t => { - t = tspl(t, { plan: 2 }) + describe('#onRequestStart', () => { + test('should delegate onRequestStart-method', t => { + t = tspl(t, { plan: 3 }) const handler = new Handler( { - onConnect: (abort, ctx) => { - t.equal(typeof abort, 'function') + onRequestStart: (controller, ctx) => { + t.equal(typeof controller, 'object') + t.equal(typeof controller.abort, 'function') t.equal(typeof ctx, 'object') } }) @@ -90,22 +91,22 @@ describe('DecoratorHandler', () => { decorator.onRequestStart(new Controller(), {}) }) - test('should not throw if onConnect-method is not defined in the handler', t => { + test('should not throw if onRequestStart-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) t.doesNotThrow(() => decorator.onRequestStart()) }) }) - describe('#onHeaders', () => { - test('should delegate onHeaders-method', t => { + describe('#onResponseStart', () => { + test('should delegate onResponseStart-method', t => { t = tspl(t, { plan: 4 }) const handler = new Handler( { - onHeaders: (statusCode, headers, resume, statusMessage) => { - t.equal(statusCode, '200') - t.equal(`${headers[0].toString('utf-8')}: ${headers[1].toString('utf-8')}`, 'content-type: application/json') - t.equal(typeof resume, 'function') + onResponseStart: (controller, statusCode, headers, statusMessage) => { + t.equal(statusCode, 200) + t.equal(headers['content-type'], 'application/json') + t.equal(typeof controller.resume, 'function') t.equal(statusMessage, 'OK') } }) @@ -115,7 +116,7 @@ describe('DecoratorHandler', () => { }, 'OK') }) - test('should not throw if onHeaders-method is not defined in the handler', t => { + test('should not throw if onResponseStart-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) t.doesNotThrow(() => decorator.onResponseStart(new Controller(), 200, { @@ -124,14 +125,14 @@ describe('DecoratorHandler', () => { }) }) - describe('#onUpgrade', () => { - test('should delegate onUpgrade-method', t => { + describe('#onRequestUpgrade', () => { + test('should delegate onRequestUpgrade-method', t => { t = tspl(t, { plan: 3 }) const handler = new Handler( { - onUpgrade: (statusCode, headers, socket) => { + onRequestUpgrade: (_controller, statusCode, headers, socket) => { t.equal(statusCode, 301) - t.equal(`${headers[0].toString('utf-8')}: ${headers[1].toString('utf-8')}`, 'content-type: application/json') + t.equal(headers['content-type'], 'application/json') t.equal(typeof socket, 'object') } }) @@ -141,7 +142,7 @@ describe('DecoratorHandler', () => { }, {}) }) - test('should not throw if onUpgrade-method is not defined in the handler', t => { + test('should not throw if onRequestUpgrade-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) t.doesNotThrow(() => decorator.onRequestUpgrade(new Controller(), 301, { @@ -150,12 +151,12 @@ describe('DecoratorHandler', () => { }) }) - describe('#onData', () => { - test('should delegate onData-method', t => { + describe('#onResponseData', () => { + test('should delegate onResponseData-method', t => { t = tspl(t, { plan: 1 }) const handler = new Handler( { - onData: (chunk) => { + onResponseData: (_controller, chunk) => { t.equal('chunk', chunk) } }) @@ -163,39 +164,39 @@ describe('DecoratorHandler', () => { decorator.onResponseData(new Controller(), 'chunk') }) - test('should not throw if onData-method is not defined in the handler', t => { + test('should not throw if onResponseData-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) t.doesNotThrow(() => decorator.onResponseData(new Controller(), 'chunk')) }) }) - describe('#onComplete', () => { - test('should delegate onComplete-method', t => { + describe('#onResponseEnd', () => { + test('should delegate onResponseEnd-method', t => { t = tspl(t, { plan: 1 }) const handler = new Handler( { - onComplete: (trailers) => { - t.equal(`${trailers[0].toString('utf-8')}: ${trailers[1].toString('utf-8')}`, 'x-trailer: trailer') + onResponseEnd: (_controller, trailers) => { + t.equal(trailers['x-trailer'], 'trailer') } }) const decorator = new DecoratorHandler(handler) decorator.onResponseEnd(new Controller(), { 'x-trailer': 'trailer' }) }) - test('should not throw if onComplete-method is not defined in the handler', t => { + test('should not throw if onResponseEnd-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) t.doesNotThrow(() => decorator.onResponseEnd(new Controller(), { 'x-trailer': 'trailer' })) }) }) - describe('#onError', () => { - test('should delegate onError-method', t => { + describe('#onResponseError', () => { + test('should delegate onResponseError-method', t => { t = tspl(t, { plan: 1 }) const handler = new Handler( { - onError: (err) => { + onResponseError: (_controller, err) => { t.equal(err.message, 'Oops!') } }) @@ -203,10 +204,10 @@ describe('DecoratorHandler', () => { decorator.onResponseError(new Controller(), new Error('Oops!')) }) - test('should throw if onError-method is not defined in the handler', t => { + test('should not throw if onResponseError-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({}) - t.throws(() => decorator.onResponseError(new Controller(), new Error('Oops!'))) + t.doesNotThrow(() => decorator.onResponseError(new Controller(), new Error('Oops!'))) }) }) }) @@ -379,7 +380,7 @@ describe('DecoratorHandler', () => { }) describe('#onResponseError', () => { - test('should delegate onError-method', t => { + test('should delegate onResponseError-method', t => { t = tspl(t, { plan: 2 }) const handler = new Handler( { @@ -392,7 +393,7 @@ describe('DecoratorHandler', () => { decorator.onResponseError(new Controller(), new Error('Oops!')) }) - test('should throw if onError-method is not defined in the handler', t => { + test('should throw if onResponseError-method is not defined in the handler', t => { t = tspl(t, { plan: 1 }) const decorator = new DecoratorHandler({ // To hin and not wrap the instance diff --git a/test/env-http-proxy-agent-nodejs-bundle.js b/test/env-http-proxy-agent-nodejs-bundle.js index 47c2649ff42..4cf238e9f6b 100644 --- a/test/env-http-proxy-agent-nodejs-bundle.js +++ b/test/env-http-proxy-agent-nodejs-bundle.js @@ -2,7 +2,7 @@ const { tspl } = require('@matteo.collina/tspl') const { describe, test, after, before } = require('node:test') -const { EnvHttpProxyAgent, setGlobalDispatcher } = require('../index-fetch') +const { EnvHttpProxyAgent, setGlobalDispatcher, fetch: undiciFetch } = require('../index-fetch') const http = require('node:http') const net = require('node:net') const { once } = require('node:events') @@ -20,7 +20,7 @@ describe('EnvHttpProxyAgent and setGlobalDispatcher', () => { process.env = { ...env } }) - test('should work with global fetch from undici bundled with Node.js', async (t) => { + test('should work with undici fetch from index-fetch', async (t) => { const { strictEqual } = tspl(t, { plan: 3 }) // Instead of using mocks, start a real server and a minimal proxy server @@ -75,8 +75,7 @@ describe('EnvHttpProxyAgent and setGlobalDispatcher', () => { process.env.http_proxy = proxyAddress setGlobalDispatcher(new EnvHttpProxyAgent()) - // eslint-disable-next-line no-restricted-globals - const res = await fetch(serverAddress) + const res = await undiciFetch(serverAddress) strictEqual(await res.text(), 'Hello world') }) }) diff --git a/test/http2-body.js b/test/http2-body.js index ac1d7fc2ff7..0db11a8b634 100644 --- a/test/http2-body.js +++ b/test/http2-body.js @@ -111,29 +111,30 @@ test('Should handle h2 request with body (string or buffer) - dispatch', async t body: expectedBody }, { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) }, - onHeaders (statusCode, headers) { + onResponseStart (controller, statusCode) { + const rawHeaders = controller.rawHeaders t.strictEqual(statusCode, 200) - t.strictEqual(headers[0].toString('utf-8'), 'content-type') + t.strictEqual(rawHeaders[0].toString('utf-8'), 'content-type') t.strictEqual( - headers[1].toString('utf-8'), + rawHeaders[1].toString('utf-8'), 'text/plain; charset=utf-8' ) - t.strictEqual(headers[2].toString('utf-8'), 'x-custom-h2') - t.strictEqual(headers[3].toString('utf-8'), 'foo') + t.strictEqual(rawHeaders[2].toString('utf-8'), 'x-custom-h2') + t.strictEqual(rawHeaders[3].toString('utf-8'), 'foo') }, - onData (chunk) { + onResponseData (_controller, chunk) { response.push(chunk) }, onBodySent (body) { t.strictEqual(body.toString('utf-8'), expectedBody) }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(response).toString('utf-8'), 'hello h2!') t.strictEqual( Buffer.concat(requestBody).toString('utf-8'), diff --git a/test/http2-trailers.js b/test/http2-trailers.js index 2d49e8b0bc2..673252c8d21 100644 --- a/test/http2-trailers.js +++ b/test/http2-trailers.js @@ -49,19 +49,13 @@ test('Should handle http2 trailers', async t => { method: 'PUT', body: 'hello' }, { - onConnect () { - - }, - onHeaders () { - return true - }, - onData () { - return true - }, - onComplete (trailers) { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd (_controller, trailers) { t.strictEqual(trailers['x-trailer'], 'hello') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } }) diff --git a/test/issue-3934.js b/test/issue-3934.js index 3898f1144c6..1caa417a48f 100644 --- a/test/issue-3934.js +++ b/test/issue-3934.js @@ -7,7 +7,7 @@ const assert = require('node:assert') const { Agent, RetryAgent, request } = require('..') // https://github.com/nodejs/undici/issues/3934 -test('WrapHandler works with multiple header values', async (t) => { +test('request preserves multiple header values', async (t) => { const server = createServer({ joinDuplicateHeaders: true }, async (_req, res) => { const headers = [ ['set-cookie', 'a'], diff --git a/test/issue-4780.js b/test/issue-4780.js new file mode 100644 index 00000000000..43ae663d3a9 --- /dev/null +++ b/test/issue-4780.js @@ -0,0 +1,62 @@ +'use strict' + +const { strictEqual } = require('node:assert') +const { test } = require('node:test') +const { Dispatcher } = require('..') +const DispatcherBase = require('../lib/dispatcher/dispatcher-base') + +function createController () { + return { + abort () {}, + pause () {}, + resume () {} + } +} + +class NewAPIDispatcher extends Dispatcher { + dispatch (opts, handler) { + const controller = createController() + + handler.onRequestStart?.(controller, {}) + handler.onResponseStart?.(controller, 200, { 'content-type': 'text/plain' }, 'OK') + handler.onResponseData?.(controller, Buffer.from('Hello, world!')) + handler.onResponseEnd?.(controller, {}) + + return true + } + + close () {} + + destroy () {} +} + +class NewAPIDispatcherBase extends DispatcherBase { + dispatch (opts, handler) { + const controller = createController() + + handler.onRequestStart?.(controller, {}) + handler.onResponseStart?.(controller, 200, { 'content-type': 'text/plain' }, 'OK') + handler.onResponseData?.(controller, Buffer.from('Hello, world!')) + handler.onResponseEnd?.(controller, {}) + + return true + } +} + +async function assertRequestSucceeds (dispatcher) { + const response = await dispatcher.request({ + origin: 'http://example.com', + path: '/', + method: 'GET' + }) + + strictEqual(await response.body.text(), 'Hello, world!') +} + +test('https://github.com/nodejs/undici/issues/4780 - request uses new handler API (Dispatcher)', async () => { + await assertRequestSucceeds(new NewAPIDispatcher()) +}) + +test('https://github.com/nodejs/undici/issues/4780 - request uses new handler API (DispatcherBase)', async () => { + await assertRequestSucceeds(new NewAPIDispatcherBase()) +}) diff --git a/test/mock-agent.js b/test/mock-agent.js index bb3d2afb9f7..ff0122c8f42 100644 --- a/test/mock-agent.js +++ b/test/mock-agent.js @@ -194,10 +194,11 @@ describe('MockAgent - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => resume(), - onData: () => {}, - onComplete: () => {}, - onError: () => {} + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} })) }) @@ -221,10 +222,11 @@ describe('MockAgent - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => resume(), - onData: () => {}, - onComplete: () => {}, - onError: () => {} + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} })) }) }) diff --git a/test/mock-client.js b/test/mock-client.js index e89bc516e52..751f157332d 100644 --- a/test/mock-client.js +++ b/test/mock-client.js @@ -60,9 +60,11 @@ describe('MockClient - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => resume(), - onData: () => {}, - onComplete: () => {} + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} })) }) @@ -95,9 +97,11 @@ describe('MockClient - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => { throw new Error('kaboom') }, - onData: () => {}, - onComplete: () => {} + onRequestStart () {}, + onResponseStart () { throw new Error('kaboom') }, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} }), new Error('kaboom')) }) }) diff --git a/test/mock-interceptor.js b/test/mock-interceptor.js index 1114b9075d3..099c48f2075 100644 --- a/test/mock-interceptor.js +++ b/test/mock-interceptor.js @@ -100,9 +100,11 @@ describe('MockInterceptor - reply options callback', () => { method: 'GET', headers: { foo: 'bar' } }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }) }) @@ -140,9 +142,11 @@ describe('MockInterceptor - reply options callback', () => { method: 'GET', headers: { foo: 'bar' } }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }) }) @@ -186,36 +190,44 @@ describe('MockInterceptor - reply options callback', () => { path: '/test-return-undefined', method: 'GET' }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }), new InvalidArgumentError('reply options callback must return an object')) t.assert.throws(() => mockPool.dispatch({ path: '/test-return-null', method: 'GET' }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }), new InvalidArgumentError('reply options callback must return an object')) t.assert.throws(() => mockPool.dispatch({ path: '/test3', method: 'GET' }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }), new InvalidArgumentError('responseOptions must be an object')) t.assert.throws(() => mockPool.dispatch({ path: '/test4', method: 'GET' }, { - onHeaders: () => { }, - onData: () => { }, - onComplete: () => { } + onRequestStart: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: () => {}, + onResponseError: () => {} }), new InvalidArgumentError('statusCode must be defined')) }) }) diff --git a/test/mock-pool.js b/test/mock-pool.js index ca4805dc434..0213397963d 100644 --- a/test/mock-pool.js +++ b/test/mock-pool.js @@ -61,9 +61,11 @@ describe('MockPool - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => resume(), - onData: () => { }, - onComplete: () => { } + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} })) }) @@ -96,9 +98,11 @@ describe('MockPool - dispatch', () => { path: '/foo', method: 'GET' }, { - onHeaders: (_statusCode, _headers, resume) => { throw new Error('kaboom') }, - onData: () => { }, - onComplete: () => { } + onRequestStart () {}, + onResponseStart () { throw new Error('kaboom') }, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} }), new Error('kaboom')) }) }) diff --git a/test/node-test/agent.js b/test/node-test/agent.js index d9aee46b597..2a8ba20912d 100644 --- a/test/node-test/agent.js +++ b/test/node-test/agent.js @@ -318,13 +318,13 @@ test('agent factory supports URL parameter', async (t) => { const p = tspl(t, { plan: 2 }) const noopHandler = { - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { server.close() }, - onError (err) { + onResponseError (_controller, err) { throw err } } @@ -356,13 +356,13 @@ test('agent factory supports string parameter', async (t) => { const p = tspl(t, { plan: 2 }) const noopHandler = { - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { server.close() }, - onError (err) { + onResponseError (_controller, err) { throw err } } @@ -709,13 +709,13 @@ test('dispatch validations', async t => { const dispatcher = new Agent() const noopHandler = { - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { server.close() }, - onError (err) { + onResponseError (_controller, err) { throw err } } @@ -730,7 +730,7 @@ test('dispatch validations', async t => { p.throws(() => dispatcher.dispatch('ASD', noopHandler), errors.InvalidArgumentError, 'throws on invalid opts argument type') p.throws(() => dispatcher.dispatch({}, noopHandler), errors.InvalidArgumentError, 'throws on invalid opts.origin argument') p.throws(() => dispatcher.dispatch({ origin: '' }, noopHandler), errors.InvalidArgumentError, 'throws on invalid opts.origin argument') - p.throws(() => dispatcher.dispatch({}, {}), errors.InvalidArgumentError, 'throws on invalid handler.onError') + p.throws(() => dispatcher.dispatch({}, {}), errors.InvalidArgumentError, 'throws on invalid handler.onResponseError') server.listen(0, () => { p.doesNotThrow(() => dispatcher.dispatch({ @@ -756,11 +756,11 @@ test('drain', async t => { }) class Handler { - onConnect () {} - onHeaders () {} - onData () {} - onComplete () {} - onError () { + onRequestStart () {} + onResponseStart () {} + onResponseData () {} + onResponseEnd () {} + onResponseError () { p.fail() } } diff --git a/test/node-test/client-abort.js b/test/node-test/client-abort.js index cf0c6fc1553..346e149bdf0 100644 --- a/test/node-test/client-abort.js +++ b/test/node-test/client-abort.js @@ -85,19 +85,19 @@ test('abort', async (t) => { method: 'GET', path: '/' }, { - onConnect (abort) { - setImmediate(abort) + onRequestStart (controller) { + setImmediate(() => controller.abort()) }, - onHeaders () { + onResponseStart () { p.ok(0) }, - onData () { + onResponseData () { p.ok(0) }, - onComplete () { + onResponseEnd () { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.RequestAbortedError) } }) @@ -129,23 +129,23 @@ test('abort pipelined', async (t) => { path: '/', blocking: false }, { - onConnect (abort) { + onRequestStart (controller) { // This request will be retried if (counter++ === 1) { - abort() + controller.abort() } p.ok(1) }, - onHeaders () { + onResponseStart () { p.ok(0) }, - onData () { + onResponseData () { p.ok(0) }, - onComplete () { + onResponseEnd () { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.RequestAbortedError) } }) @@ -155,19 +155,19 @@ test('abort pipelined', async (t) => { path: '/', blocking: false }, { - onConnect (abort) { - abort() + onRequestStart (controller) { + controller.abort() }, - onHeaders () { + onResponseStart () { p.ok(0) }, - onData () { + onResponseData () { p.ok(0) }, - onComplete () { + onResponseEnd () { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.RequestAbortedError) } }) @@ -196,19 +196,19 @@ test('propagate unallowed throws in request.onError', async (t) => { method: 'GET', path: '/' }, { - onConnect (abort) { - setImmediate(abort) + onRequestStart (controller) { + setImmediate(() => controller.abort()) }, - onHeaders () { + onResponseStart () { p.ok(0) }, - onData () { + onResponseData () { p.ok(0) }, - onComplete () { + onResponseEnd () { p.ok(0) }, - onError () { + onResponseError () { throw new OnAbortError('error') } }) diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index 06862150efb..0a278e5a8f3 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -43,7 +43,7 @@ test('dispatch invalid opts', (t) => { method: 'GET', upgrade: 1 }, { - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.InvalidArgumentError) p.strictEqual(err.message, 'upgrade must be a string') } @@ -54,7 +54,7 @@ test('dispatch invalid opts', (t) => { method: 'GET', headersTimeout: 'asd' }, { - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.InvalidArgumentError) p.strictEqual(err.message, 'invalid headersTimeout') } @@ -65,7 +65,7 @@ test('dispatch invalid opts', (t) => { method: 'GET', bodyTimeout: 'asd' }, { - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.InvalidArgumentError) p.strictEqual(err.message, 'invalid bodyTimeout') } @@ -77,14 +77,14 @@ test('dispatch invalid opts', (t) => { method: 'GET', bodyTimeout: 'asd' }, { - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.InvalidArgumentError) p.strictEqual(err.message, 'invalid bodyTimeout') } }) client.dispatch(null, { - onError (err) { + onResponseError (_controller, err) { p.ok(err instanceof errors.InvalidArgumentError) p.strictEqual(err.message, 'opts must be an object.') } @@ -122,20 +122,21 @@ test('basic dispatch get', async (t) => { method: 'GET', headers: reqHeaders }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (controller, statusCode) { + const rawHeaders = controller.rawHeaders p.strictEqual(statusCode, 200) - p.strictEqual(Array.isArray(headers), true) + p.strictEqual(Array.isArray(rawHeaders), true) }, - onData (buf) { + onResponseData (_controller, buf) { bufs.push(buf) }, - onComplete (trailers) { - p.deepStrictEqual(trailers, []) + onResponseEnd (controller) { + p.deepStrictEqual(controller.rawTrailers, []) p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }, - onError () { + onResponseError () { p.ok(0) } }) @@ -176,28 +177,30 @@ test('trailers dispatch get', async (t) => { method: 'GET', headers: reqHeaders }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (controller, statusCode) { + const rawHeaders = controller.rawHeaders p.strictEqual(statusCode, 200) - p.strictEqual(Array.isArray(headers), true) + p.strictEqual(Array.isArray(rawHeaders), true) { - const contentTypeIdx = headers.findIndex(x => x.toString() === 'Content-Type') - p.strictEqual(headers[contentTypeIdx + 1].toString(), 'text/plain') + const contentTypeIdx = rawHeaders.findIndex(x => x.toString() === 'Content-Type') + p.strictEqual(rawHeaders[contentTypeIdx + 1].toString(), 'text/plain') } }, - onData (buf) { + onResponseData (_controller, buf) { bufs.push(buf) }, - onComplete (trailers) { - p.strictEqual(Array.isArray(trailers), true) + onResponseEnd (controller) { + const rawTrailers = controller.rawTrailers + p.strictEqual(Array.isArray(rawTrailers), true) { - const contentMD5Idx = trailers.findIndex(x => x.toString() === 'Content-MD5') - p.strictEqual(trailers[contentMD5Idx + 1].toString(), 'test') + const contentMD5Idx = rawTrailers.findIndex(x => x.toString() === 'Content-MD5') + p.strictEqual(rawTrailers[contentMD5Idx + 1].toString(), 'test') } p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }, - onError () { + onResponseError () { p.ok(0) } }) @@ -206,7 +209,7 @@ test('trailers dispatch get', async (t) => { await p.completed }) -test('dispatch onHeaders error', async (t) => { +test('dispatch onResponseStart error', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -223,18 +226,18 @@ test('dispatch onHeaders error', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { throw _err }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err, _err) } }) @@ -243,7 +246,7 @@ test('dispatch onHeaders error', async (t) => { await p.completed }) -test('dispatch onComplete error', async (t) => { +test('dispatch onResponseEnd error', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -260,18 +263,18 @@ test('dispatch onComplete error', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(1) }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { throw _err }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err, _err) } }) @@ -280,7 +283,7 @@ test('dispatch onComplete error', async (t) => { await p.completed }) -test('dispatch onData error', async (t) => { +test('dispatch onResponseData error', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -297,18 +300,18 @@ test('dispatch onData error', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(1) }, - onData (buf) { + onResponseData (_controller, buf) { throw _err }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err, _err) } }) @@ -317,7 +320,7 @@ test('dispatch onData error', async (t) => { await p.completed }) -test('dispatch onConnect error', async (t) => { +test('dispatch onRequestStart error', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -334,19 +337,19 @@ test('dispatch onConnect error', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { throw _err }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(0) }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err, _err) } }) @@ -355,7 +358,7 @@ test('dispatch onConnect error', async (t) => { await p.completed }) -test('connect call onUpgrade once', async (t) => { +test('connect call onRequestUpgrade once', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (c) => { @@ -385,12 +388,12 @@ test('connect call onUpgrade once', async (t) => { method: 'CONNECT', path: '/' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { t.ok(true, 'should not throw') }, - onUpgrade (statusCode, headers, socket) { + onRequestUpgrade (_controller, statusCode, _headers, socket) { p.strictEqual(count++, 0) socket.on('data', (d) => { @@ -404,13 +407,13 @@ test('connect call onUpgrade once', async (t) => { socket.write('Body') socket.end() }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0) }, - onError () { + onResponseError () { p.ok(0) } }) @@ -419,7 +422,7 @@ test('connect call onUpgrade once', async (t) => { await p.completed }) -test('dispatch onHeaders missing', async (t) => { +test('dispatch onResponseStart missing', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -435,15 +438,15 @@ test('dispatch onHeaders missing', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0, 'should not throw') }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0, 'should not throw') }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) @@ -452,7 +455,7 @@ test('dispatch onHeaders missing', async (t) => { await p.completed }) -test('dispatch onData missing', async (t) => { +test('dispatch onResponseData missing', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -468,15 +471,15 @@ test('dispatch onData missing', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(0, 'should not throw') }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0, 'should not throw') }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) @@ -485,7 +488,7 @@ test('dispatch onData missing', async (t) => { await p.completed }) -test('dispatch onComplete missing', async (t) => { +test('dispatch onResponseEnd missing', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -501,15 +504,15 @@ test('dispatch onComplete missing', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(0) }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) @@ -518,7 +521,7 @@ test('dispatch onComplete missing', async (t) => { await p.completed }) -test('dispatch onError missing', async (t) => { +test('dispatch onResponseError missing', async (t) => { const p = tspl(t, { plan: 1 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -535,15 +538,15 @@ test('dispatch onError missing', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { p.ok(0) }, - onData (buf) { + onResponseData (_controller, buf) { p.ok(0) }, - onComplete (trailers) { + onResponseEnd (_controller, _trailers) { p.ok(0) } }) @@ -555,7 +558,7 @@ test('dispatch onError missing', async (t) => { await p.completed }) -test('dispatch CONNECT onUpgrade missing', async (t) => { +test('dispatch CONNECT onRequestUpgrade missing', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -572,13 +575,13 @@ test('dispatch CONNECT onUpgrade missing', async (t) => { method: 'GET', upgrade: 'Websocket' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') - p.strictEqual(err.message, 'invalid onUpgrade method') + p.strictEqual(err.message, 'invalid onRequestUpgrade method') } }) }) @@ -586,7 +589,7 @@ test('dispatch CONNECT onUpgrade missing', async (t) => { await p.completed }) -test('dispatch upgrade onUpgrade missing', async (t) => { +test('dispatch upgrade onRequestUpgrade missing', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -603,13 +606,13 @@ test('dispatch upgrade onUpgrade missing', async (t) => { method: 'GET', upgrade: 'Websocket' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, _headers) { }, - onError (err) { + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') - p.strictEqual(err.message, 'invalid onUpgrade method') + p.strictEqual(err.message, 'invalid onRequestUpgrade method') } }) }) @@ -617,7 +620,7 @@ test('dispatch upgrade onUpgrade missing', async (t) => { await p.completed }) -test('dispatch pool onError missing', async (t) => { +test('dispatch pool onResponseError missing', async (t) => { const p = tspl(t, { plan: 2 }) const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { @@ -661,10 +664,10 @@ test('dispatch onBodySent not a function', async (t) => { method: 'GET' }, { onBodySent: '42', - onConnect () {}, - onHeaders () {}, - onData () {}, - onError (err) { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseError (_controller, err) { p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') p.strictEqual(err.message, 'invalid onBodySent method') } @@ -697,13 +700,13 @@ test('dispatch onBodySent buffer', async (t) => { onRequestSent () { p.ok(1) }, - onError (err) { + onResponseError (_controller, err) { throw err }, - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { p.ok(1) } }) @@ -738,13 +741,13 @@ test('dispatch onBodySent stream', async (t) => { onRequestSent () { p.ok(1) }, - onError (err) { + onResponseError (_controller, err) { throw err }, - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { p.strictEqual(currentChunk, chunks.length) p.strictEqual(sentBytes, toSendBytes) p.ok(1) @@ -776,13 +779,13 @@ test('dispatch onBodySent async-iterable', (t, done) => { assert.strictEqual(chunks[currentChunk++], chunk) sentBytes += Buffer.byteLength(chunk) }, - onError (err) { + onResponseError (_controller, err) { throw err }, - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () { assert.strictEqual(currentChunk, chunks.length) assert.strictEqual(sentBytes, toSendBytes) done() @@ -809,15 +812,15 @@ test('dispatch onBodySent throws error', (t, done) => { onBodySent (chunk) { throw new Error('fail') }, - onError (err) { + onResponseError (_controller, err) { assert.ok(err instanceof Error) assert.strictEqual(err.message, 'fail') done() }, - onConnect () {}, - onHeaders () {}, - onData () {}, - onComplete () {} + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {} }) }) }) @@ -842,8 +845,8 @@ test('dispatches in expected order', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches.push('onConnect') + onRequestStart () { + dispatches.push('onRequestStart') }, onBodySent () { dispatches.push('onBodySent') @@ -851,17 +854,17 @@ test('dispatches in expected order', async (t) => { onResponseStarted () { dispatches.push('onResponseStarted') }, - onHeaders () { - dispatches.push('onHeaders') + onResponseStart () { + dispatches.push('onResponseStart') }, - onData () { - dispatches.push('onData') + onResponseData () { + dispatches.push('onResponseData') }, - onComplete () { - dispatches.push('onComplete') - p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + onResponseEnd () { + dispatches.push('onResponseEnd') + p.deepStrictEqual(dispatches, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) @@ -899,8 +902,8 @@ test('dispatches in expected order for http2', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches.push('onConnect') + onRequestStart () { + dispatches.push('onRequestStart') }, onBodySent () { dispatches.push('onBodySent') @@ -908,17 +911,17 @@ test('dispatches in expected order for http2', async (t) => { onResponseStarted () { dispatches.push('onResponseStarted') }, - onHeaders () { - dispatches.push('onHeaders') + onResponseStart () { + dispatches.push('onResponseStart') }, - onData () { - dispatches.push('onData') + onResponseData () { + dispatches.push('onResponseData') }, - onComplete () { - dispatches.push('onComplete') - p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + onResponseEnd () { + dispatches.push('onResponseEnd') + p.deepStrictEqual(dispatches, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) @@ -957,8 +960,8 @@ test('Issue#3065 - fix bad destroy handling', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches.push('onConnect') + onRequestStart () { + dispatches.push('onRequestStart') }, onBodySent () { dispatches.push('onBodySent') @@ -966,17 +969,17 @@ test('Issue#3065 - fix bad destroy handling', async (t) => { onResponseStarted () { dispatches.push('onResponseStarted') }, - onHeaders () { - dispatches.push('onHeaders') + onResponseStart () { + dispatches.push('onResponseStart') }, - onData () { - dispatches.push('onData') + onResponseData () { + dispatches.push('onResponseData') }, - onComplete () { - dispatches.push('onComplete') - p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + onResponseEnd () { + dispatches.push('onResponseEnd') + p.deepStrictEqual(dispatches, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) @@ -987,8 +990,8 @@ test('Issue#3065 - fix bad destroy handling', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches2.push('onConnect') + onRequestStart () { + dispatches2.push('onRequestStart') }, onBodySent () { dispatches2.push('onBodySent') @@ -996,17 +999,17 @@ test('Issue#3065 - fix bad destroy handling', async (t) => { onResponseStarted () { dispatches2.push('onResponseStarted') }, - onHeaders () { - dispatches2.push('onHeaders') + onResponseStart () { + dispatches2.push('onResponseStart') }, - onData () { - dispatches2.push('onData') + onResponseData () { + dispatches2.push('onResponseData') }, - onComplete () { - dispatches2.push('onComplete') - p.deepStrictEqual(dispatches2, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + onResponseEnd () { + dispatches2.push('onResponseEnd') + p.deepStrictEqual(dispatches2, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) @@ -1051,8 +1054,8 @@ test('Issue#3065 - fix bad destroy handling (h2)', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches.push('onConnect') + onRequestStart () { + dispatches.push('onRequestStart') }, onBodySent () { dispatches.push('onBodySent') @@ -1060,17 +1063,17 @@ test('Issue#3065 - fix bad destroy handling (h2)', async (t) => { onResponseStarted () { dispatches.push('onResponseStarted') }, - onHeaders () { - dispatches.push('onHeaders1') + onResponseStart () { + dispatches.push('onResponseStart1') }, - onData () { - dispatches.push('onData') + onResponseData () { + dispatches.push('onResponseData') }, - onComplete () { - dispatches.push('onComplete') - p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders1', 'onData', 'onComplete']) + onResponseEnd () { + dispatches.push('onResponseEnd') + p.deepStrictEqual(dispatches, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart1', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) @@ -1081,8 +1084,8 @@ test('Issue#3065 - fix bad destroy handling (h2)', async (t) => { method: 'POST', body: 'body' }, { - onConnect () { - dispatches2.push('onConnect') + onRequestStart () { + dispatches2.push('onRequestStart') }, onBodySent () { dispatches2.push('onBodySent') @@ -1090,17 +1093,17 @@ test('Issue#3065 - fix bad destroy handling (h2)', async (t) => { onResponseStarted () { dispatches2.push('onResponseStarted') }, - onHeaders () { - dispatches2.push('onHeaders2') + onResponseStart () { + dispatches2.push('onResponseStart2') }, - onData () { - dispatches2.push('onData') + onResponseData () { + dispatches2.push('onResponseData') }, - onComplete () { - dispatches2.push('onComplete') - p.deepStrictEqual(dispatches2, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders2', 'onData', 'onComplete']) + onResponseEnd () { + dispatches2.push('onResponseEnd') + p.deepStrictEqual(dispatches2, ['onRequestStart', 'onBodySent', 'onResponseStarted', 'onResponseStart2', 'onResponseData', 'onResponseEnd']) }, - onError (err) { + onResponseError (_controller, err) { p.ifError(err) } }) diff --git a/test/node-test/util.js b/test/node-test/util.js index c3f363ff40a..267486869f8 100644 --- a/test/node-test/util.js +++ b/test/node-test/util.js @@ -32,50 +32,58 @@ test('getServerName', () => { test('assertRequestHandler', () => { assert.throws(() => util.assertRequestHandler(null), InvalidArgumentError, 'handler must be an object') assert.throws(() => util.assertRequestHandler({ - onConnect: null - }), InvalidArgumentError, 'invalid onConnect method') + onRequestStart: null + }), InvalidArgumentError, 'invalid onRequestStart method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: null - }), InvalidArgumentError, 'invalid onError method') + onRequestStart: () => {}, + onResponseError: null + }), InvalidArgumentError, 'invalid onResponseError method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: null }), InvalidArgumentError, 'invalid onBodySent method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, + onRequestSent: null + }), InvalidArgumentError, 'invalid onRequestSent method') + assert.throws(() => util.assertRequestHandler({ + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: () => {}, - onHeaders: null - }), InvalidArgumentError, 'invalid onHeaders method') + onRequestSent: () => {}, + onResponseStart: null + }), InvalidArgumentError, 'invalid onResponseStart method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: () => {}, - onHeaders: () => {}, - onData: null - }), InvalidArgumentError, 'invalid onData method') + onRequestSent: () => {}, + onResponseStart: () => {}, + onResponseData: null + }), InvalidArgumentError, 'invalid onResponseData method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: () => {}, - onHeaders: () => {}, - onData: () => {}, - onComplete: null - }), InvalidArgumentError, 'invalid onComplete method') + onRequestSent: () => {}, + onResponseStart: () => {}, + onResponseData: () => {}, + onResponseEnd: null + }), InvalidArgumentError, 'invalid onResponseEnd method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: () => {}, - onUpgrade: 'null' - }, 'CONNECT'), InvalidArgumentError, 'invalid onUpgrade method') + onRequestUpgrade: 'null' + }, 'CONNECT'), InvalidArgumentError, 'invalid onRequestUpgrade method') assert.throws(() => util.assertRequestHandler({ - onConnect: () => {}, - onError: () => {}, + onRequestStart: () => {}, + onResponseError: () => {}, onBodySent: () => {}, - onUpgrade: 'null' - }, 'CONNECT', () => {}), InvalidArgumentError, 'invalid onUpgrade method') + onRequestUpgrade: 'null' + }, 'CONNECT', () => {}), InvalidArgumentError, 'invalid onRequestUpgrade method') }) test('parseHeaders', () => { diff --git a/test/pool.js b/test/pool.js index 88f2b281af2..c93f017dc23 100644 --- a/test/pool.js +++ b/test/pool.js @@ -366,7 +366,7 @@ test('backpressure algorithm', async (t) => { } const noopHandler = { - onError (err) { + onResponseError (_controller, err) { throw err } } @@ -645,18 +645,18 @@ test('pool dispatch', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.strictEqual(statusCode, 200) }, - onData (chunk) { + onResponseData (_controller, chunk) { buf += chunk }, - onComplete () { + onResponseEnd () { t.strictEqual(buf, 'asd') }, - onError () { + onResponseError () { } }) }) @@ -792,17 +792,17 @@ test('pool dispatch error', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.strictEqual(statusCode, 200) }, - onData (chunk) { + onResponseData (_controller, chunk) { }, - onComplete () { + onResponseEnd () { t.ok(true, 'pass') }, - onError () { + onResponseError () { } }) @@ -813,16 +813,16 @@ test('pool dispatch error', async (t) => { 'transfer-encoding': 'fail' } }, { - onConnect () { + onRequestStart () { t.fail() }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.fail() }, - onData (chunk) { + onResponseData (_controller, chunk) { t.fail() }, - onError (err) { + onResponseError (_controller, err) { t.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) @@ -850,17 +850,17 @@ test('pool request abort in queue', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.strictEqual(statusCode, 200) }, - onData (chunk) { + onResponseData (_controller, chunk) { }, - onComplete () { + onResponseEnd () { t.ok(true, 'pass') }, - onError () { + onResponseError () { } }) @@ -897,17 +897,17 @@ test('pool stream abort in queue', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.strictEqual(statusCode, 200) }, - onData (chunk) { + onResponseData (_controller, chunk) { }, - onComplete () { + onResponseEnd () { t.ok(true, 'pass') }, - onError () { + onResponseError () { } }) @@ -944,17 +944,17 @@ test('pool pipeline abort in queue', async (t) => { path: '/', method: 'GET' }, { - onConnect () { + onRequestStart () { }, - onHeaders (statusCode, headers) { + onResponseStart (_controller, statusCode, headers) { t.strictEqual(statusCode, 200) }, - onData (chunk) { + onResponseData (_controller, chunk) { }, - onComplete () { + onResponseEnd () { t.ok(true, 'pass') }, - onError () { + onResponseError () { } }) diff --git a/test/retry-handler.js b/test/retry-handler.js index 3a42fce3a7a..749b4d603b5 100644 --- a/test/retry-handler.js +++ b/test/retry-handler.js @@ -61,22 +61,22 @@ test('Should retry status code', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') t.strictEqual(counter, 2) }, - onError () { + onResponseError () { t.fail() } } @@ -156,22 +156,22 @@ test('Should account for network and response errors', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') t.strictEqual(counter, 2) }, - onError () { + onResponseError () { t.fail() } } @@ -227,19 +227,19 @@ test('Issue #3288 - request with body (asynciterable)', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { return true }, - onData (chunk) { + onResponseData (_controller, chunk) { return true }, - onComplete () { + onResponseEnd () { t.fail() }, - onError (err) { + onResponseError (_controller, err) { t.equal(err.message, 'Request failed') t.equal(err.statusCode, 500) t.equal(err.data.count, 1) @@ -304,21 +304,21 @@ test('Should use retry-after header for retries', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } } @@ -389,21 +389,21 @@ test('Should use retry-after header for retries (date)', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } } @@ -471,21 +471,21 @@ test('Should retry with defaults', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } } @@ -567,22 +567,22 @@ test('Should handle 206 partial content', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -652,20 +652,20 @@ test('Should handle 206 partial content - bad-etag', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (_status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, _status, _headers, _statusMessage) { return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.ifError('should not complete') }, - onError (err) { + onResponseError (_controller, err) { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abc') t.strictEqual(err.code, 'UND_ERR_REQ_RETRY') t.strictEqual(err.message, 'ETag mismatch') @@ -940,21 +940,21 @@ test('should not error if request is not meant to be retried', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 400) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'Bad request') }, - onError (err) { + onResponseError (_controller, err) { t.fail(err) } } @@ -1108,22 +1108,22 @@ test('Issue#2986 - Handle custom 206', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1208,22 +1208,22 @@ test('Issue#3128 - Support if-match', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1308,22 +1308,22 @@ test('Issue#3128 - Should ignore weak etags', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1408,22 +1408,22 @@ test('Weak etags are ignored on range-requests', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1503,21 +1503,21 @@ test('Should throw RequestRetryError when Content-Range mismatch', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.ifError('should not complete') }, - onError (err) { + onResponseError (_controller, err) { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abc') t.strictEqual(err.code, 'UND_ERR_REQ_RETRY') t.strictEqual(err.message, 'Content-Range mismatch') @@ -1592,21 +1592,21 @@ test('Should use retry-after header for retries (date) but date format is wrong' const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } } diff --git a/test/retry-handler2.js b/test/retry-handler2.js index f7b778de586..71821da7088 100644 --- a/test/retry-handler2.js +++ b/test/retry-handler2.js @@ -186,22 +186,22 @@ test('Should retry status code without throwing an error | throwOnError: false', const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') t.strictEqual(counter, 2) }, - onError () { + onResponseError () { t.fail() } } @@ -282,22 +282,22 @@ test('Should account for network and response errors | throwOnError: false', asy const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') t.strictEqual(counter, 2) }, - onError () { + onResponseError () { t.fail() } } @@ -358,21 +358,21 @@ test('Issue #3288 - request with body (asynciterable) should fail, without throw const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.ok(true, 'pass') }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { const data = Buffer.concat(chunks).toString('utf-8') t.strictEqual(data, '{"message": "failed"}') }, - onError () { + onResponseError () { t.fail() } } @@ -438,21 +438,21 @@ test('Should use retry-after header for retries | throwOnError: false', async t const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError () { + onResponseError () { t.fail() } } @@ -526,21 +526,21 @@ test('Should use retry-after header for retries (date) | throwOnError: false', a const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError () { + onResponseError () { t.fail() } } @@ -611,21 +611,21 @@ test('Should retry with defaults | throwOnError: false', async t => { const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError () { + onResponseError () { t.fail() } } @@ -708,22 +708,22 @@ test('Should handle 206 partial content | throwOnError: false', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -796,20 +796,20 @@ test('Should handle 206 partial content - bad-etag | throwOnError: false', async return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (_status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, _status, _headers, _statusMessage) { return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.ifError('should not complete') }, - onError (err) { + onResponseError (_controller, err) { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abc') t.strictEqual(err.code, 'UND_ERR_REQ_RETRY') t.strictEqual(err.message, 'ETag mismatch') @@ -1090,21 +1090,21 @@ test('should not error if request is not meant to be retried | throwOnError: fal const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 400) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'Bad request') }, - onError (err) { + onResponseError (_controller, err) { t.fail(err) } } @@ -1260,22 +1260,22 @@ test('Issue#2986 - Handle custom 206 | throwOnError: false', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1361,22 +1361,22 @@ test('Issue#3128 - Support if-match | throwOnError: false', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1462,22 +1462,22 @@ test('Issue#3128 - Should ignore weak etags | throwOnError: false', async t => { return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1563,22 +1563,22 @@ test('Weak etags are ignored on range-requests | throwOnError: false', async t = return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abcdef') t.strictEqual(counter, 1) }, - onError () { + onResponseError () { t.fail() } } @@ -1659,21 +1659,21 @@ test('Should throw RequestRetryError when Content-Range mismatch | throwOnError: return client.dispatch(...args) }, handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, _resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.ifError('should not complete') }, - onError (err) { + onResponseError (_controller, err) { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'abc') t.strictEqual(err.code, 'UND_ERR_REQ_RETRY') t.strictEqual(err.message, 'Content-Range mismatch') @@ -1749,21 +1749,21 @@ test('Should use retry-after header for retries (date) but date format is wrong const handler = new RetryHandler(dispatchOptions, { dispatch: client.dispatch.bind(client), handler: { - onConnect () { + onRequestStart () { t.ok(true, 'pass') }, - onHeaders (status, _rawHeaders, resume, _statusMessage) { + onResponseStart (_controller, status, _headers, _statusMessage) { t.strictEqual(status, 200) return true }, - onData (chunk) { + onResponseData (_controller, chunk) { chunks.push(chunk) return true }, - onComplete () { + onResponseEnd () { t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } } diff --git a/test/web-platform-tests/expectation.json b/test/web-platform-tests/expectation.json index 2d601880583..f238f7a36c2 100644 --- a/test/web-platform-tests/expectation.json +++ b/test/web-platform-tests/expectation.json @@ -563,11 +563,12 @@ { "name": "Empty string integrity for opaque response", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque response's status is 0 expected 0 but got 200" }, { "name": "SHA-* integrity for opaque response", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" } ] }, @@ -635,10 +636,10 @@ { "name": "Fetch https://web-platform.test:8443/fetch/api/resources/top.txt with no-cors mode", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { - "name": "Fetch http://web-platform.test:55268/fetch/api/resources/top.txt with no-cors mode", + "name": "Fetch http://web-platform.test:51579/fetch/api/resources/top.txt with no-cors mode", "success": false, "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" } @@ -657,7 +658,8 @@ }, { "name": "Fetch https://web-platform.test:8443/fetch/api/resources/top.txt with same-origin mode", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Fetch http://www1.web-platform.test:8000/fetch/api/resources/top.txt with same-origin mode", @@ -1239,8 +1241,7 @@ }, { "name": "Fetch with POST with Float16Array body", - "success": false, - "message": "Float16Array is not defined" + "success": true }, { "name": "Fetch with POST with Float32Array body", @@ -1889,8 +1890,7 @@ }, { "name": "Fetch with POST with Float16Array body", - "success": false, - "message": "Float16Array is not defined" + "success": true }, { "name": "Fetch with POST with Float32Array body", @@ -4636,7 +4636,7 @@ { "name": "Check response clone use structureClone for teed ReadableStreams (Float16Arraychunk)", "success": false, - "message": "assert_array_equals: Cloned buffer chunks have the same content value is undefined, expected array" + "message": "assert_not_equals: Buffer of cloned response stream is a clone of the original buffer got disallowed value object \"0,0,0,0,0,0,0,0\"" }, { "name": "Check response clone use structureClone for teed ReadableStreams (Float32Arraychunk)", @@ -4809,7 +4809,7 @@ { "name": "Consume response's body: from text with correct multipart type to formData with BOM", "success": false, - "message": "assert_equals: Retrieve and verify response's body expected \"--boundary-0.16075435275547334\\r\\nContent-Disposition: form-data;name=\\\"name\\\"\\r\\n\\r\\nquickfox\\r\\n--boundary-0.16075435275547334--\\r\\n\" but got \"--boundary-0.16075435275547334\\r\\nContent-Disposition: form-data;name=\\\"name\\\"\\r\\n\\r\\nquickfox\\r\\n--boundary-0.16075435275547334--\\r\\n\"" + "message": "assert_equals: Retrieve and verify response's body expected \"--boundary-0.35865449327189336\\r\\nContent-Disposition: form-data;name=\\\"name\\\"\\r\\n\\r\\nquickfox\\r\\n--boundary-0.35865449327189336--\\r\\n\" but got \"--boundary-0.35865449327189336\\r\\nContent-Disposition: form-data;name=\\\"name\\\"\\r\\n\\r\\nquickfox\\r\\n--boundary-0.35865449327189336--\\r\\n\"" }, { "name": "Consume response's body: from text without correct multipart type to formData (error case)", @@ -4867,7 +4867,7 @@ { "name": "Consume response's body: from FormData to blob", "success": false, - "message": "assert_equals: Blob body type should be computed from the response Content-Type expected \"multipart/form-data; boundary=----formdata-undici-035234180410\" but got \"multipart/form-data;boundary=----formdata-undici-035234180410\"" + "message": "assert_equals: Blob body type should be computed from the response Content-Type expected \"multipart/form-data; boundary=----formdata-undici-014505735818\" but got \"multipart/form-data;boundary=----formdata-undici-014505735818\"" }, { "name": "Consume response's body: from FormData to text", @@ -6780,16 +6780,17 @@ { "name": "Same domain different protocol different port [no-cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { "name": "Same domain different protocol different port [server forbid CORS]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Same domain different protocol different port [cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: CORS response's type is cors expected \"cors\" but got \"basic\"" }, { "name": "Cross domain basic usage [no-cors mode]", @@ -6824,16 +6825,17 @@ { "name": "Cross domain different protocol [no-cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { "name": "Cross domain different protocol [server forbid CORS]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross domain different protocol [cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: CORS response's type is cors expected \"cors\" but got \"basic\"" } ] }, @@ -7031,16 +7033,17 @@ { "name": "[keepalive] Same domain different protocol different port [no-cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { "name": "[keepalive] Same domain different protocol different port [cors mode, server forbid CORS]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "[keepalive] Same domain different protocol different port [cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: CORS response's type is cors expected \"cors\" but got \"basic\"" }, { "name": "[keepalive] Cross domain basic usage [no-cors mode]", @@ -7075,16 +7078,17 @@ { "name": "[keepalive] Cross domain different protocol [no-cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { "name": "[keepalive] Cross domain different protocol [cors mode, server forbid CORS]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "[keepalive] Cross domain different protocol [cors mode]", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: CORS response's type is cors expected \"cors\" but got \"basic\"" }, { "name": "[keepalive] Same domain different port GET request in unload [no-cors mode, server forbid CORS]; setting up", @@ -7340,13 +7344,11 @@ }, { "name": "Cross domain different protocol [GET]", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Same domain different protocol different port [GET]", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross domain [POST]", @@ -7422,21 +7424,21 @@ }, { "name": "Cross domain different protocol [origin OK]", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross domain different protocol [origin KO]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Same domain different protocol different port [origin OK]", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Same domain different protocol different port [origin KO]", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross domain [POST] [origin OK]", @@ -8729,13 +8731,11 @@ }, { "name": "getAuthorizationHeaderValue - same origin redirection", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "getAuthorizationHeaderValue - cross origin redirection", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true } ] }, @@ -11239,27 +11239,27 @@ { "name": "Decompresion using gzip-encoded dictionary works as expected", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" }, { "name": "Decompresion using Brotli-encoded dictionary works as expected", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" }, { "name": "Decompresion using Zstandard-encoded dictionary works as expected", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" }, { "name": "A dcb dictionary-compressed dictionary can be used as a dictionary for future requests.", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" }, { "name": "A dcz dictionary-compressed dictionary can be used as a dictionary for future requests.", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" } ] }, @@ -11279,7 +11279,7 @@ { "name": "Decompresion of a cross origin resource works as expected", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" } ] }, @@ -11344,7 +11344,7 @@ { "name": "Dictionary registration does not invalidate cache entry", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\" but got \"\\\"available-dictionary\\\" header is not available\"" }, { "name": "Expired dictionary is not used", @@ -12893,11 +12893,13 @@ }, { "name": "Cross-scheme (HTTP to HTTPS) no-cors fetch to a same-site URL with a 'Cross-Origin-Resource-Policy: same-site' response header.", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross-origin no-cors fetch to a same-site URL with a 'Cross-Origin-Resource-Policy: same-origin' response header.", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Valid cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.", @@ -12933,35 +12935,35 @@ }, { "name": "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross-origin cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header.", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a redirection.", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" }, { "name": "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' response header after a cross-origin redirection.", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-origin' redirect response header.", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" } ] }, @@ -12984,7 +12986,8 @@ "cases": [ { "name": "Cross-Origin-Resource-Policy: same-site blocks retrieving HTTPS from HTTP", - "success": true + "success": false, + "message": "assert_unreached: Should have rejected: undefined Reached unreachable code" } ] }, @@ -15256,7 +15259,7 @@ { "name": "Response with Cache-Control: max-age=2592000, public and Pragma: no-cache should be cached", "success": false, - "message": "assert_equals: Responses should be identical, indicating caching expected \"Timestamp: 1768756436.8170867\" but got \"Timestamp: 1768756436.8148103\"" + "message": "assert_equals: Responses should be identical, indicating caching expected \"Timestamp: 1769769728.994271\" but got \"Timestamp: 1769769728.9848197\"" } ] }, @@ -15582,13 +15585,47 @@ "cases": [ { "name": "Same-site fetch with preflight", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross-site fetch with preflight", + "success": true + }, + { + "name": "Same-site fetch with preflight: sec-fetch-dest", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Same-site fetch with preflight: sec-fetch-mode", + "success": true + }, + { + "name": "Same-site fetch with preflight: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-site\" but got \"\"" + }, + { + "name": "Same-site fetch with preflight: sec-fetch-user", + "success": true + }, + { + "name": "Cross-site fetch with preflight: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Cross-site fetch with preflight: sec-fetch-mode", + "success": true + }, + { + "name": "Cross-site fetch with preflight: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"cross-site\" but got \"\"" + }, + { + "name": "Cross-site fetch with preflight: sec-fetch-user", + "success": true } ] }, @@ -15597,33 +15634,135 @@ "cases": [ { "name": "Same-origin fetch", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Same-site fetch", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Cross-site fetch", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Same-origin mode", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "CORS mode", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "no-CORS mode", + "success": true + }, + { + "name": "Same-origin fetch: sec-fetch-dest", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Same-origin fetch: sec-fetch-mode", + "success": true + }, + { + "name": "Same-origin fetch: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-origin\" but got \"\"" + }, + { + "name": "Same-origin fetch: sec-fetch-user", + "success": true + }, + { + "name": "Same-site fetch: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Same-site fetch: sec-fetch-mode", + "success": true + }, + { + "name": "Same-site fetch: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-site\" but got \"\"" + }, + { + "name": "Same-site fetch: sec-fetch-user", + "success": true + }, + { + "name": "Cross-site fetch: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Cross-site fetch: sec-fetch-mode", + "success": true + }, + { + "name": "Cross-site fetch: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"cross-site\" but got \"\"" + }, + { + "name": "Cross-site fetch: sec-fetch-user", + "success": true + }, + { + "name": "Same-origin mode: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Same-origin mode: sec-fetch-mode", + "success": true + }, + { + "name": "Same-origin mode: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-origin\" but got \"\"" + }, + { + "name": "Same-origin mode: sec-fetch-user", + "success": true + }, + { + "name": "CORS mode: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "CORS mode: sec-fetch-mode", + "success": true + }, + { + "name": "CORS mode: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-origin\" but got \"\"" + }, + { + "name": "CORS mode: sec-fetch-user", + "success": true + }, + { + "name": "no-CORS mode: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "no-CORS mode: sec-fetch-mode", + "success": true + }, + { + "name": "no-CORS mode: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"same-origin\" but got \"\"" + }, + { + "name": "no-CORS mode: sec-fetch-user", + "success": true } ] }, @@ -19290,112 +19429,106 @@ { "name": "sec-fetch-site - Same origin, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Cross-site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Cross-Site -> Same-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Origin -> Same Origin, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Origin -> Same-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Origin -> Cross-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Site -> Same Origin, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Site -> Same-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-mode - no init", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-mode - init: mode=cors", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-mode - init: mode=no-cors", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-mode - init: mode=same-origin", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-dest - no init", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-dest\" missing" }, { "name": "sec-fetch-user - no init", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-storage-access - Cross-site, init: mode=no-cors, credentials=include", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-storage-access\" missing" }, { "name": "sec-fetch-storage-access - Same site, init: mode=no-cors, credentials=include", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true } ] }, @@ -19467,18 +19600,17 @@ }, { "name": "sec-fetch-site - HTTPS downgrade (header not sent), no init", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "sec-fetch-site - HTTPS upgrade, no init", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" }, { "name": "sec-fetch-site - HTTPS downgrade-upgrade, no init", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_own_property: expected property \"sec-fetch-site\" missing" } ] }, @@ -22171,18 +22303,69 @@ "cases": [ { "name": "Fetching a resource from the same origin, but spelled with a trailing dot.", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Fetching a resource from the same site, but spelled with a trailing dot.", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "success": true }, { "name": "Fetching a resource from a cross-site host, spelled with a trailing dot.", + "success": true + }, + { + "name": "Fetching a resource from the same origin, but spelled with a trailing dot.: sec-fetch-dest", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Fetching a resource from the same origin, but spelled with a trailing dot.: sec-fetch-mode", + "success": true + }, + { + "name": "Fetching a resource from the same origin, but spelled with a trailing dot.: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"cross-site\" but got \"\"" + }, + { + "name": "Fetching a resource from the same origin, but spelled with a trailing dot.: sec-fetch-user", + "success": true + }, + { + "name": "Fetching a resource from the same site, but spelled with a trailing dot.: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Fetching a resource from the same site, but spelled with a trailing dot.: sec-fetch-mode", + "success": true + }, + { + "name": "Fetching a resource from the same site, but spelled with a trailing dot.: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"cross-site\" but got \"\"" + }, + { + "name": "Fetching a resource from the same site, but spelled with a trailing dot.: sec-fetch-user", + "success": true + }, + { + "name": "Fetching a resource from a cross-site host, spelled with a trailing dot.: sec-fetch-dest", + "success": false, + "message": "assert_equals: expected \"empty\" but got \"\"" + }, + { + "name": "Fetching a resource from a cross-site host, spelled with a trailing dot.: sec-fetch-mode", + "success": true + }, + { + "name": "Fetching a resource from a cross-site host, spelled with a trailing dot.: sec-fetch-site", + "success": false, + "message": "assert_equals: expected \"cross-site\" but got \"\"" + }, + { + "name": "Fetching a resource from a cross-site host, spelled with a trailing dot.: sec-fetch-user", + "success": true } ] }, @@ -24050,9012 +24233,551 @@ } ] } - }, - "embedded-credentials.tentative.sub.html": { - "success": true, - "cases": [ - { - "name": "Embedded credentials are treated as network errors.", - "success": false, - "message": "document is not defined" - }, - { - "name": "Embedded credentials are treated as network errors in frames.", - "success": false, - "message": "document is not defined" - }, - { - "name": "Embedded credentials are treated as network errors in new windows.", - "success": false, - "message": "window.open is not a function" - }, - { - "name": "Embedded credentials matching the top-level are not treated as network errors for relative URLs.", - "success": false, - "message": "window.open is not a function" - }, - { - "name": "Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.", - "success": false, - "message": "window.open is not a function" - }, - { - "name": "Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.", - "success": false, - "message": "window.open is not a function" - } - ] - }, - "redirect-to-url-with-credentials.https.html": { - "success": true, - "cases": [ - { - "name": "No CORS fetch after a redirect with an URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" - }, - { - "name": "CORS fetch after a redirect with a cross origin URL containing credentials", - "success": true - }, - { - "name": "CORS fetch after a redirect with a same origin URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" - }, - { - "name": "Image loading after a redirect with an URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" - }, - { - "name": "CORS Image loading after a redirect with a cross origin URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" - }, - { - "name": "CORS Image loading after a redirect with a same origin URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" - }, - { - "name": "Frame loading after a redirect with an URL containing credentials", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: document is not defined\"" - } - ] - } - }, - "stale-while-revalidate": { - "fetch-sw.https.html": { - "success": true, - "cases": [ - { - "name": "Second fetch returns same response", - "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: Cannot read properties of undefined (reading 'register')\"" - } - ] - }, - "fetch.any.html": { - "success": true, - "cases": [ - { - "name": "Second fetch returns same response", - "success": false, - "message": "assert_equals: expected \"qoidijwtsfvgrbpjvqow\" but got \"pyimmkhbwsuwcvgrysyj\"" - } - ] - }, - "revalidate-not-blocked-by-csp.html": { - "success": false, - "cases": [] - }, - "stale-css.html": { - "success": false, - "cases": [] - }, - "stale-image.html": { - "success": false, - "cases": [] - }, - "stale-script.html": { - "success": false, - "cases": [] - } - } - }, - "mimesniff": { - "media": { - "media-sniff.window.html": { - "success": true, - "cases": [ - { - "name": "mp3-raw.mp3 loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-raw.mp3 loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-raw.mp3 loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-raw.mp3 loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-raw.mp3 loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-raw.mp3 loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp3-with-id3.mp3 loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "flac.flac loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "ogg.ogg loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "mp4.mp4 loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "wav.wav loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type ", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type bogus/mime", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type application/octet-stream", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type text/html", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type audio/ogg; codec=vorbis", - "success": false, - "message": "document is not defined" - }, - { - "name": "webm.webm loads when served with Content-Type application/pdf", - "success": false, - "message": "document is not defined" - } - ] - } - }, - "mime-types": { - "charset-parameter.window.html": { - "success": true, - "cases": [ - { - "name": "Loading data…", - "success": true - }, - { - "name": "text/html;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "TEXT/HTML;CHARSET=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=gbk(", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;x=(;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=gbk;charset=windows-1255", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=();charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset =gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html ;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html; charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset= gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset= \"gbk\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\u000bgbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\fgbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;\u000bcharset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;\fcharset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset='gbk'", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset='gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=gbk'", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=';charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;test;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;test=;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;';charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;\";charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html ; ; charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;;;;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset= \";charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\";charset=foo\";charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"gbk\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=gbk\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\" gbk\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"gbk \"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"\\ gbk\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"\\g\\b\\k\"", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"gbk\"x", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\"\";charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset=\";charset=GBK", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;charset={gbk}", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk", - "success": false, - "message": "document is not defined" - }, - { - "name": "text/html;test=ÿ;charset=gbk", - "success": false, - "message": "document is not defined" - } - ] - }, - "parsing.any.html": { - "success": "flaky", - "cases": [ - { - "name": "Loading data…", - "success": true - }, - { - "name": "text/html;charset=gbk (Blob/File)", - "success": true - }, - { - "name": "text/html;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "TEXT/HTML;CHARSET=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=GBK\" but got \"text/html;charset=gbk\"" - }, - { - "name": "TEXT/HTML;CHARSET=GBK (Request/Response)", - "success": false, - "message": "assert_equals: expected \"text/html;charset=GBK\" but got \"text/html;charset=gbk\"" - }, - { - "name": "text/html;charset=gbk( (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\"gbk(\\\"\" but got \"text/html;charset=gbk(\"" - }, - { - "name": "text/html;charset=gbk( (Request/Response)", - "success": true - }, - { - "name": "text/html;x=(;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;x=\\\"(\\\";charset=gbk\" but got \"text/html;x=(;charset=gbk\"" - }, - { - "name": "text/html;x=(;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=gbk;charset=windows-1255 (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;charset=gbk;charset=windows-1255\"" - }, - { - "name": "text/html;charset=gbk;charset=windows-1255 (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=();charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\"()\\\"\" but got \"text/html;charset=();charset=gbk\"" - }, - { - "name": "text/html;charset=();charset=GBK (Request/Response)", - "success": true - }, - { - "name": "text/html;charset =gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html\" but got \"text/html;charset =gbk\"" - }, - { - "name": "text/html;charset =gbk (Request/Response)", - "success": true - }, - { - "name": "text/html ;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html ;charset=gbk\"" - }, - { - "name": "text/html ;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html; charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html; charset=gbk\"" - }, - { - "name": "text/html; charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset= gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\" gbk\\\"\" but got \"text/html;charset= gbk\"" - }, - { - "name": "text/html;charset= gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset= \"gbk\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\" \\\\\\\"gbk\\\\\\\"\\\"\" but got \"text/html;charset= \\\"gbk\\\"\"" - }, - { - "name": "text/html;charset= \"gbk\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\u000bgbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html\" but got \"\"" - }, - { - "name": "text/html;charset=\u000bgbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\fgbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html\" but got \"\"" - }, - { - "name": "text/html;charset=\fgbk (Request/Response)", - "success": true - }, - { - "name": "text/html;\u000bcharset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html\" but got \"\"" - }, - { - "name": "text/html;\u000bcharset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;\fcharset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html\" but got \"\"" - }, - { - "name": "text/html;\fcharset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset='gbk' (Blob/File)", - "success": true - }, - { - "name": "text/html;charset='gbk' (Request/Response)", - "success": true - }, - { - "name": "text/html;charset='gbk (Blob/File)", - "success": true - }, - { - "name": "text/html;charset='gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=gbk' (Blob/File)", - "success": true - }, - { - "name": "text/html;charset=gbk' (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=';charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset='\" but got \"text/html;charset=';charset=gbk\"" - }, - { - "name": "text/html;charset=';charset=GBK (Request/Response)", - "success": true - }, - { - "name": "text/html;test;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;test;charset=gbk\"" - }, - { - "name": "text/html;test;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;test=;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;test=;charset=gbk\"" - }, - { - "name": "text/html;test=;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;';charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;';charset=gbk\"" - }, - { - "name": "text/html;';charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;\";charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;\\\";charset=gbk\"" - }, - { - "name": "text/html;\";charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html ; ; charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html ; ; charset=gbk\"" - }, - { - "name": "text/html ; ; charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;;;;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;;;;charset=gbk\"" - }, - { - "name": "text/html;;;;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset= \";charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=GBK\" but got \"\"" - }, - { - "name": "text/html;charset= \";charset=GBK (Request/Response)", - "success": false, - "message": "assert_equals: expected \"text/html;charset=GBK\" but got \"text/html;charset=gbk\"" - }, - { - "name": "text/html;charset=\";charset=foo\";charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=GBK\" but got \"\"" - }, - { - "name": "text/html;charset=\";charset=foo\";charset=GBK (Request/Response)", - "success": false, - "message": "assert_equals: expected \"text/html;charset=GBK\" but got \"text/html;charset=gbk\"" - }, - { - "name": "text/html;charset=\"gbk\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;charset=\\\"gbk\\\"\"" - }, - { - "name": "text/html;charset=\"gbk\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;charset=\\\"gbk\"" - }, - { - "name": "text/html;charset=\"gbk (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=gbk\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\"gbk\\\\\\\"\\\"\" but got \"text/html;charset=gbk\\\"\"" - }, - { - "name": "text/html;charset=gbk\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\" gbk\" (Blob/File)", - "success": true - }, - { - "name": "text/html;charset=\" gbk\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"gbk \" (Blob/File)", - "success": true - }, - { - "name": "text/html;charset=\"gbk \" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"\\ gbk\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\" gbk\\\"\" but got \"text/html;charset=\\\"\\\\ gbk\\\"\"" - }, - { - "name": "text/html;charset=\"\\ gbk\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"\\g\\b\\k\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;charset=\\\"\\\\g\\\\b\\\\k\\\"\"" - }, - { - "name": "text/html;charset=\"\\g\\b\\k\" (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"gbk\"x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=gbk\" but got \"text/html;charset=\\\"gbk\\\"x\"" - }, - { - "name": "text/html;charset=\"gbk\"x (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\"\";charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\"\\\"\" but got \"text/html;charset=\\\"\\\";charset=gbk\"" - }, - { - "name": "text/html;charset=\"\";charset=GBK (Request/Response)", - "success": true - }, - { - "name": "text/html;charset=\";charset=GBK (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\";charset=GBK\\\"\" but got \"text/html;charset=\\\";charset=gbk\"" - }, - { - "name": "text/html;charset=\";charset=GBK (Request/Response)", - "success": false, - "message": "assert_equals: expected \"text/html;charset=\\\";charset=GBK\\\"\" but got \"text/html;charset=\\\";charset=gbk\\\"\"" - }, - { - "name": "text/html;charset={gbk} (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;charset=\\\"{gbk}\\\"\" but got \"text/html;charset={gbk}\"" - }, - { - "name": "text/html;charset={gbk} (Request/Response)", - "success": true - }, - { - "name": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk (Blob/File)", - "success": true - }, - { - "name": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk (Request/Response)", - "success": true - }, - { - "name": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 (Blob/File)", - "success": true - }, - { - "name": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 (Request/Response)", - "success": true - }, - { - "name": "text/html;a]=bar;b[=bar;c=bar (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;c=bar\" but got \"text/html;a]=bar;b[=bar;c=bar\"" - }, - { - "name": "text/html;a]=bar;b[=bar;c=bar (Request/Response)", - "success": true - }, - { - "name": "text/html;valid=\";\";foo=bar (Blob/File)", - "success": true - }, - { - "name": "text/html;valid=\";\";foo=bar (Request/Response)", - "success": true - }, - { - "name": "text/html;in]valid=\";asd=foo\";foo=bar (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;foo=bar\" but got \"text/html;in]valid=\\\";asd=foo\\\";foo=bar\"" - }, - { - "name": "text/html;in]valid=\";asd=foo\";foo=bar (Request/Response)", - "success": true - }, - { - "name": "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\" but got \"!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"" - }, - { - "name": "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz (Request/Response)", - "success": false, - "message": "assert_equals: expected \"!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\" but got \"\"" - }, - { - "name": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\t !\\\\\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\\\"\" but got \"\"" - }, - { - "name": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\" (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\t !\\\\\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\\\"\" but got \"\"" - }, - { - "name": "x/x;test (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x\" but got \"x/x;test\"" - }, - { - "name": "x/x;test (Request/Response)", - "success": true - }, - { - "name": "x/x;test=\"\\ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;test=\\\"\\\\\\\\\\\"\" but got \"x/x;test=\\\"\\\\\"" - }, - { - "name": "x/x;test=\"\\ (Request/Response)", - "success": true - }, - { - "name": "x/x;x= (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x\" but got \"x/x;x= \"" - }, - { - "name": "x/x;x=\t (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x\" but got \"\"" - }, - { - "name": "x/x\n\r\t ;x=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=x\" but got \"\"" - }, - { - "name": "x/x\n\r\t ;x=x (Request/Response)", - "success": true - }, - { - "name": "\n\r\t x/x;x=x\n\r\t (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=x\" but got \"\"" - }, - { - "name": "x/x;\n\r\t x=x\n\r\t ;x=y (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=x\" but got \"\"" - }, - { - "name": "x/x;\n\r\t x=x\n\r\t ;x=y (Request/Response)", - "success": true - }, - { - "name": "text/html;test=ÿ;charset=gbk (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"text/html;test=\\\"ÿ\\\";charset=gbk\" but got \"\"" - }, - { - "name": "text/html;test=ÿ;charset=gbk (Request/Response)", - "success": false, - "message": "assert_equals: expected \"text/html;test=\\\"ÿ\\\";charset=gbk\" but got \"\"" - }, - { - "name": "x/x;test=�;x=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=x\" but got \"\"" - }, - { - "name": "x/x;test=�;x=x (Request/Response)", - "success": true - }, - { - "name": "\u000bx/x (Blob/File)", - "success": true - }, - { - "name": "\u000bx/x (Request/Response)", - "success": true - }, - { - "name": "\fx/x (Blob/File)", - "success": true - }, - { - "name": "\fx/x (Request/Response)", - "success": true - }, - { - "name": "x/x\u000b (Blob/File)", - "success": true - }, - { - "name": "x/x\u000b (Request/Response)", - "success": true - }, - { - "name": "x/x\f (Blob/File)", - "success": true - }, - { - "name": "x/x\f (Request/Response)", - "success": true - }, - { - "name": " (Blob/File)", - "success": true - }, - { - "name": " (Request/Response)", - "success": true - }, - { - "name": "\t (Blob/File)", - "success": true - }, - { - "name": "/ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"/\"" - }, - { - "name": "/ (Request/Response)", - "success": true - }, - { - "name": "bogus (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"bogus\"" - }, - { - "name": "bogus (Request/Response)", - "success": true - }, - { - "name": "bogus/ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"bogus/\"" - }, - { - "name": "bogus/ (Request/Response)", - "success": true - }, - { - "name": "bogus/ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"bogus/ \"" - }, - { - "name": "bogus/bogus/; (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"bogus/bogus/;\"" - }, - { - "name": "bogus/bogus/; (Request/Response)", - "success": true - }, - { - "name": " (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"\"" - }, - { - "name": " (Request/Response)", - "success": true - }, - { - "name": "(/) (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"(/)\"" - }, - { - "name": "(/) (Request/Response)", - "success": true - }, - { - "name": "ÿ/ÿ (Blob/File)", - "success": true - }, - { - "name": "ÿ/ÿ (Request/Response)", - "success": true - }, - { - "name": "text/html(;doesnot=matter (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"text/html(;doesnot=matter\"" - }, - { - "name": "text/html(;doesnot=matter (Request/Response)", - "success": true - }, - { - "name": "{/} (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"{/}\"" - }, - { - "name": "{/} (Request/Response)", - "success": true - }, - { - "name": "Ā/Ā (Blob/File)", - "success": true - }, - { - "name": "Ā/Ā (Request/Response)", - "success": true - }, - { - "name": "text /html (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"text /html\"" - }, - { - "name": "text /html (Request/Response)", - "success": true - }, - { - "name": "text/ html (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"text/ html\"" - }, - { - "name": "text/ html (Request/Response)", - "success": true - }, - { - "name": "\"text/html\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"\\\"text/html\\\"\"" - }, - { - "name": "\"text/html\" (Request/Response)", - "success": true - }, - { - "name": "\u0000/x (Blob/File)", - "success": true - }, - { - "name": "\u0000/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0000 (Blob/File)", - "success": true - }, - { - "name": "x/\u0000 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0000=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0000=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0000;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0000;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0000\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0000\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0001/x (Blob/File)", - "success": true - }, - { - "name": "\u0001/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0001 (Blob/File)", - "success": true - }, - { - "name": "x/\u0001 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0001=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0001=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0001;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0001;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0001\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0001\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0002/x (Blob/File)", - "success": true - }, - { - "name": "\u0002/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0002 (Blob/File)", - "success": true - }, - { - "name": "x/\u0002 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0002=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0002=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0002;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0002;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0002\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0002\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0003/x (Blob/File)", - "success": true - }, - { - "name": "\u0003/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0003 (Blob/File)", - "success": true - }, - { - "name": "x/\u0003 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0003=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0003=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0003;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0003;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0003\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0003\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0004/x (Blob/File)", - "success": true - }, - { - "name": "\u0004/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0004 (Blob/File)", - "success": true - }, - { - "name": "x/\u0004 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0004=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0004=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0004;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0004;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0004\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0004\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0005/x (Blob/File)", - "success": true - }, - { - "name": "\u0005/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0005 (Blob/File)", - "success": true - }, - { - "name": "x/\u0005 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0005=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0005=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0005;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0005;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0005\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0005\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0006/x (Blob/File)", - "success": true - }, - { - "name": "\u0006/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0006 (Blob/File)", - "success": true - }, - { - "name": "x/\u0006 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0006=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0006=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0006;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0006;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0006\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0006\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0007/x (Blob/File)", - "success": true - }, - { - "name": "\u0007/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0007 (Blob/File)", - "success": true - }, - { - "name": "x/\u0007 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0007=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0007=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0007;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0007;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0007\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0007\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\b/x (Blob/File)", - "success": true - }, - { - "name": "\b/x (Request/Response)", - "success": true - }, - { - "name": "x/\b (Blob/File)", - "success": true - }, - { - "name": "x/\b (Request/Response)", - "success": true - }, - { - "name": "x/x;\b=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\b=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\b;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\b;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\b\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\b\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\t/x (Blob/File)", - "success": true - }, - { - "name": "x/\t (Blob/File)", - "success": true - }, - { - "name": "x/x;\t=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\t=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "\n/x (Blob/File)", - "success": true - }, - { - "name": "x/\n (Blob/File)", - "success": true - }, - { - "name": "x/x;\n=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\n=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\n;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\n;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\n\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\n\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u000b/x (Blob/File)", - "success": true - }, - { - "name": "\u000b/x (Request/Response)", - "success": true - }, - { - "name": "x/\u000b (Blob/File)", - "success": true - }, - { - "name": "x/\u000b (Request/Response)", - "success": true - }, - { - "name": "x/x;\u000b=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u000b=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u000b;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u000b;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u000b\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u000b\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\f/x (Blob/File)", - "success": true - }, - { - "name": "\f/x (Request/Response)", - "success": true - }, - { - "name": "x/\f (Blob/File)", - "success": true - }, - { - "name": "x/\f (Request/Response)", - "success": true - }, - { - "name": "x/x;\f=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\f=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\f;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\f;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\f\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\f\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\r/x (Blob/File)", - "success": true - }, - { - "name": "x/\r (Blob/File)", - "success": true - }, - { - "name": "x/x;\r=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\r=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\r;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\r;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\r\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\r\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u000e/x (Blob/File)", - "success": true - }, - { - "name": "\u000e/x (Request/Response)", - "success": true - }, - { - "name": "x/\u000e (Blob/File)", - "success": true - }, - { - "name": "x/\u000e (Request/Response)", - "success": true - }, - { - "name": "x/x;\u000e=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u000e=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u000e;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u000e;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u000e\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u000e\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u000f/x (Blob/File)", - "success": true - }, - { - "name": "\u000f/x (Request/Response)", - "success": true - }, - { - "name": "x/\u000f (Blob/File)", - "success": true - }, - { - "name": "x/\u000f (Request/Response)", - "success": true - }, - { - "name": "x/x;\u000f=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u000f=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u000f;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u000f;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u000f\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u000f\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0010/x (Blob/File)", - "success": true - }, - { - "name": "\u0010/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0010 (Blob/File)", - "success": true - }, - { - "name": "x/\u0010 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0010=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0010=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0010;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0010;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0010\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0010\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0011/x (Blob/File)", - "success": true - }, - { - "name": "\u0011/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0011 (Blob/File)", - "success": true - }, - { - "name": "x/\u0011 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0011=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0011=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0011;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0011;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0011\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0011\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0012/x (Blob/File)", - "success": true - }, - { - "name": "\u0012/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0012 (Blob/File)", - "success": true - }, - { - "name": "x/\u0012 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0012=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0012=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0012;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0012;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0012\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0012\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0013/x (Blob/File)", - "success": true - }, - { - "name": "\u0013/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0013 (Blob/File)", - "success": true - }, - { - "name": "x/\u0013 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0013=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0013=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0013;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0013;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0013\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0013\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0014/x (Blob/File)", - "success": true - }, - { - "name": "\u0014/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0014 (Blob/File)", - "success": true - }, - { - "name": "x/\u0014 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0014=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0014=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0014;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0014;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0014\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0014\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0015/x (Blob/File)", - "success": true - }, - { - "name": "\u0015/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0015 (Blob/File)", - "success": true - }, - { - "name": "x/\u0015 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0015=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0015=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0015;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0015;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0015\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0015\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0016/x (Blob/File)", - "success": true - }, - { - "name": "\u0016/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0016 (Blob/File)", - "success": true - }, - { - "name": "x/\u0016 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0016=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0016=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0016;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0016;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0016\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0016\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0017/x (Blob/File)", - "success": true - }, - { - "name": "\u0017/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0017 (Blob/File)", - "success": true - }, - { - "name": "x/\u0017 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0017=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0017=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0017;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0017;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0017\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0017\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0018/x (Blob/File)", - "success": true - }, - { - "name": "\u0018/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0018 (Blob/File)", - "success": true - }, - { - "name": "x/\u0018 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0018=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0018=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0018;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0018;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0018\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0018\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u0019/x (Blob/File)", - "success": true - }, - { - "name": "\u0019/x (Request/Response)", - "success": true - }, - { - "name": "x/\u0019 (Blob/File)", - "success": true - }, - { - "name": "x/\u0019 (Request/Response)", - "success": true - }, - { - "name": "x/x;\u0019=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u0019=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u0019;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u0019;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u0019\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u0019\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001a/x (Blob/File)", - "success": true - }, - { - "name": "\u001a/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001a (Blob/File)", - "success": true - }, - { - "name": "x/\u001a (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001a=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001a=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001a;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001a;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001a\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001a\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001b/x (Blob/File)", - "success": true - }, - { - "name": "\u001b/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001b (Blob/File)", - "success": true - }, - { - "name": "x/\u001b (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001b=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001b=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001b;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001b;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001b\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001b\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001c/x (Blob/File)", - "success": true - }, - { - "name": "\u001c/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001c (Blob/File)", - "success": true - }, - { - "name": "x/\u001c (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001c=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001c=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001c;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001c;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001c\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001c\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001d/x (Blob/File)", - "success": true - }, - { - "name": "\u001d/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001d (Blob/File)", - "success": true - }, - { - "name": "x/\u001d (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001d=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001d=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001d;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001d;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001d\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001d\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001e/x (Blob/File)", - "success": true - }, - { - "name": "\u001e/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001e (Blob/File)", - "success": true - }, - { - "name": "x/\u001e (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001e=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001e=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001e;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001e;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001e\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001e\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\u001f/x (Blob/File)", - "success": true - }, - { - "name": "\u001f/x (Request/Response)", - "success": true - }, - { - "name": "x/\u001f (Blob/File)", - "success": true - }, - { - "name": "x/\u001f (Request/Response)", - "success": true - }, - { - "name": "x/x;\u001f=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;\u001f=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\u001f;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\u001f;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\u001f\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\u001f\";bonus=x (Request/Response)", - "success": true - }, - { - "name": " /x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \" /x\"" - }, - { - "name": "x/ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/ \"" - }, - { - "name": "x/x; =x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x; =x;bonus=x\"" - }, - { - "name": "x/x; =x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "\"/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"\\\"/x\"" - }, - { - "name": "\"/x (Request/Response)", - "success": true - }, - { - "name": "x/\" (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/\\\"\"" - }, - { - "name": "x/\" (Request/Response)", - "success": true - }, - { - "name": "x/x;\"=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;\\\"=x;bonus=x\"" - }, - { - "name": "x/x;\"=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "(/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"(/x\"" - }, - { - "name": "(/x (Request/Response)", - "success": true - }, - { - "name": "x/( (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/(\"" - }, - { - "name": "x/( (Request/Response)", - "success": true - }, - { - "name": "x/x;(=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;(=x;bonus=x\"" - }, - { - "name": "x/x;(=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=(;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"(\\\";bonus=x\" but got \"x/x;x=(;bonus=x\"" - }, - { - "name": "x/x;x=(;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"(\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"(\";bonus=x (Request/Response)", - "success": true - }, - { - "name": ")/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \")/x\"" - }, - { - "name": ")/x (Request/Response)", - "success": true - }, - { - "name": "x/) (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/)\"" - }, - { - "name": "x/) (Request/Response)", - "success": true - }, - { - "name": "x/x;)=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;)=x;bonus=x\"" - }, - { - "name": "x/x;)=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=);bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\")\\\";bonus=x\" but got \"x/x;x=);bonus=x\"" - }, - { - "name": "x/x;x=);bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\")\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\")\";bonus=x (Request/Response)", - "success": true - }, - { - "name": ",/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \",/x\"" - }, - { - "name": ",/x (Request/Response)", - "success": true - }, - { - "name": "x/, (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/,\"" - }, - { - "name": "x/, (Request/Response)", - "success": true - }, - { - "name": "x/x;,=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;,=x;bonus=x\"" - }, - { - "name": "x/x;,=x;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;bonus=x\" but got \"x/x\"" - }, - { - "name": "x/x;x=,;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\",\\\";bonus=x\" but got \"x/x;x=,;bonus=x\"" - }, - { - "name": "x/x;x=,;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\",\\\";bonus=x\" but got \"x/x\"" - }, - { - "name": "x/x;x=\",\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\",\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;/=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;/=x;bonus=x\"" - }, - { - "name": "x/x;/=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=/;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"/\\\";bonus=x\" but got \"x/x;x=/;bonus=x\"" - }, - { - "name": "x/x;x=/;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"/\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"/\";bonus=x (Request/Response)", - "success": true - }, - { - "name": ":/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \":/x\"" - }, - { - "name": ":/x (Request/Response)", - "success": true - }, - { - "name": "x/: (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/:\"" - }, - { - "name": "x/: (Request/Response)", - "success": true - }, - { - "name": "x/x;:=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;:=x;bonus=x\"" - }, - { - "name": "x/x;:=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=:;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\":\\\";bonus=x\" but got \"x/x;x=:;bonus=x\"" - }, - { - "name": "x/x;x=:;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\":\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\":\";bonus=x (Request/Response)", - "success": true - }, - { - "name": ";/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \";/x\"" - }, - { - "name": ";/x (Request/Response)", - "success": true - }, - { - "name": "x/; (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/;\"" - }, - { - "name": "x/; (Request/Response)", - "success": true - }, - { - "name": "/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \">/x\"" - }, - { - "name": ">/x (Request/Response)", - "success": true - }, - { - "name": "x/> (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/>\"" - }, - { - "name": "x/> (Request/Response)", - "success": true - }, - { - "name": "x/x;>=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;>=x;bonus=x\"" - }, - { - "name": "x/x;>=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=>;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\">\\\";bonus=x\" but got \"x/x;x=>;bonus=x\"" - }, - { - "name": "x/x;x=>;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\">\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\">\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "?/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"?/x\"" - }, - { - "name": "?/x (Request/Response)", - "success": true - }, - { - "name": "x/? (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/?\"" - }, - { - "name": "x/? (Request/Response)", - "success": true - }, - { - "name": "x/x;?=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;?=x;bonus=x\"" - }, - { - "name": "x/x;?=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=?;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"?\\\";bonus=x\" but got \"x/x;x=?;bonus=x\"" - }, - { - "name": "x/x;x=?;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"?\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"?\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "@/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"@/x\"" - }, - { - "name": "@/x (Request/Response)", - "success": true - }, - { - "name": "x/@ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/@\"" - }, - { - "name": "x/@ (Request/Response)", - "success": true - }, - { - "name": "x/x;@=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;@=x;bonus=x\"" - }, - { - "name": "x/x;@=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=@;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"@\\\";bonus=x\" but got \"x/x;x=@;bonus=x\"" - }, - { - "name": "x/x;x=@;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"@\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"@\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "[/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"[/x\"" - }, - { - "name": "[/x (Request/Response)", - "success": true - }, - { - "name": "x/[ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/[\"" - }, - { - "name": "x/[ (Request/Response)", - "success": true - }, - { - "name": "x/x;[=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;[=x;bonus=x\"" - }, - { - "name": "x/x;[=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=[;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"[\\\";bonus=x\" but got \"x/x;x=[;bonus=x\"" - }, - { - "name": "x/x;x=[;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"[\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"[\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "\\/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"\\\\/x\"" - }, - { - "name": "\\/x (Request/Response)", - "success": true - }, - { - "name": "x/\\ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/\\\\\"" - }, - { - "name": "x/\\ (Request/Response)", - "success": true - }, - { - "name": "x/x;\\=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;\\\\=x;bonus=x\"" - }, - { - "name": "x/x;\\=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "]/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"]/x\"" - }, - { - "name": "]/x (Request/Response)", - "success": true - }, - { - "name": "x/] (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/]\"" - }, - { - "name": "x/] (Request/Response)", - "success": true - }, - { - "name": "x/x;]=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;]=x;bonus=x\"" - }, - { - "name": "x/x;]=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=];bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"]\\\";bonus=x\" but got \"x/x;x=];bonus=x\"" - }, - { - "name": "x/x;x=];bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"]\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"]\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "{/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"{/x\"" - }, - { - "name": "{/x (Request/Response)", - "success": true - }, - { - "name": "x/{ (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/{\"" - }, - { - "name": "x/{ (Request/Response)", - "success": true - }, - { - "name": "x/x;{=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;{=x;bonus=x\"" - }, - { - "name": "x/x;{=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x={;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"{\\\";bonus=x\" but got \"x/x;x={;bonus=x\"" - }, - { - "name": "x/x;x={;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"{\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"{\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "}/x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"}/x\"" - }, - { - "name": "}/x (Request/Response)", - "success": true - }, - { - "name": "x/} (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"\" but got \"x/}\"" - }, - { - "name": "x/} (Request/Response)", - "success": true - }, - { - "name": "x/x;}=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"x/x;}=x;bonus=x\"" - }, - { - "name": "x/x;}=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=};bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"}\\\";bonus=x\" but got \"x/x;x=};bonus=x\"" - }, - { - "name": "x/x;x=};bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"}\";bonus=x (Blob/File)", - "success": true - }, - { - "name": "x/x;x=\"}\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": true - }, - { - "name": "€/x (Blob/File)", - "success": true - }, - { - "name": "€/x (Request/Response)", - "success": true - }, - { - "name": "x/€ (Blob/File)", - "success": true - }, - { - "name": "x/€ (Request/Response)", - "success": true - }, - { - "name": "x/x;€=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;€=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=€;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"€\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=€;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"€\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"€\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"€\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"€\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"€\\\";bonus=x\" but got \"\"" - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "‚/x (Blob/File)", - "success": true - }, - { - "name": "‚/x (Request/Response)", - "success": true - }, - { - "name": "x/‚ (Blob/File)", - "success": true - }, - { - "name": "x/‚ (Request/Response)", - "success": true - }, - { - "name": "x/x;‚=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;‚=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=‚;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‚\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=‚;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‚\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‚\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‚\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‚\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‚\\\";bonus=x\" but got \"\"" - }, - { - "name": "ƒ/x (Blob/File)", - "success": true - }, - { - "name": "ƒ/x (Request/Response)", - "success": true - }, - { - "name": "x/ƒ (Blob/File)", - "success": true - }, - { - "name": "x/ƒ (Request/Response)", - "success": true - }, - { - "name": "x/x;ƒ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ƒ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ƒ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ƒ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ƒ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ƒ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ƒ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ƒ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ƒ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ƒ\\\";bonus=x\" but got \"\"" - }, - { - "name": "„/x (Blob/File)", - "success": true - }, - { - "name": "„/x (Request/Response)", - "success": true - }, - { - "name": "x/„ (Blob/File)", - "success": true - }, - { - "name": "x/„ (Request/Response)", - "success": true - }, - { - "name": "x/x;„=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;„=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=„;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"„\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=„;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"„\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"„\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"„\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"„\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"„\\\";bonus=x\" but got \"\"" - }, - { - "name": "…/x (Blob/File)", - "success": true - }, - { - "name": "…/x (Request/Response)", - "success": true - }, - { - "name": "x/… (Blob/File)", - "success": true - }, - { - "name": "x/… (Request/Response)", - "success": true - }, - { - "name": "x/x;…=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;…=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=…;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"…\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=…;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"…\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"…\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"…\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"…\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"…\\\";bonus=x\" but got \"\"" - }, - { - "name": "†/x (Blob/File)", - "success": true - }, - { - "name": "†/x (Request/Response)", - "success": true - }, - { - "name": "x/† (Blob/File)", - "success": true - }, - { - "name": "x/† (Request/Response)", - "success": true - }, - { - "name": "x/x;†=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;†=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=†;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"†\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=†;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"†\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"†\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"†\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"†\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"†\\\";bonus=x\" but got \"\"" - }, - { - "name": "‡/x (Blob/File)", - "success": true - }, - { - "name": "‡/x (Request/Response)", - "success": true - }, - { - "name": "x/‡ (Blob/File)", - "success": true - }, - { - "name": "x/‡ (Request/Response)", - "success": true - }, - { - "name": "x/x;‡=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;‡=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=‡;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=‡;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‡\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‡\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‡\\\";bonus=x\" but got \"\"" - }, - { - "name": "ˆ/x (Blob/File)", - "success": true - }, - { - "name": "ˆ/x (Request/Response)", - "success": true - }, - { - "name": "x/ˆ (Blob/File)", - "success": true - }, - { - "name": "x/ˆ (Request/Response)", - "success": true - }, - { - "name": "x/x;ˆ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ˆ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ˆ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ˆ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ˆ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ˆ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ˆ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ˆ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ˆ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ˆ\\\";bonus=x\" but got \"\"" - }, - { - "name": "‰/x (Blob/File)", - "success": true - }, - { - "name": "‰/x (Request/Response)", - "success": true - }, - { - "name": "x/‰ (Blob/File)", - "success": true - }, - { - "name": "x/‰ (Request/Response)", - "success": true - }, - { - "name": "x/x;‰=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;‰=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=‰;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‰\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=‰;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‰\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‰\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‰\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‰\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‰\\\";bonus=x\" but got \"\"" - }, - { - "name": "Š/x (Blob/File)", - "success": true - }, - { - "name": "Š/x (Request/Response)", - "success": true - }, - { - "name": "x/Š (Blob/File)", - "success": true - }, - { - "name": "x/Š (Request/Response)", - "success": true - }, - { - "name": "x/x;Š=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Š=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Š;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Š;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Š\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Š\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Š\\\";bonus=x\" but got \"\"" - }, - { - "name": "‹/x (Blob/File)", - "success": true - }, - { - "name": "‹/x (Request/Response)", - "success": true - }, - { - "name": "x/‹ (Blob/File)", - "success": true - }, - { - "name": "x/‹ (Request/Response)", - "success": true - }, - { - "name": "x/x;‹=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;‹=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=‹;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=‹;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‹\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‹\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‹\\\";bonus=x\" but got \"\"" - }, - { - "name": "Œ/x (Blob/File)", - "success": true - }, - { - "name": "Œ/x (Request/Response)", - "success": true - }, - { - "name": "x/Œ (Blob/File)", - "success": true - }, - { - "name": "x/Œ (Request/Response)", - "success": true - }, - { - "name": "x/x;Œ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Œ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Œ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Œ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Œ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Œ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ž/x (Blob/File)", - "success": true - }, - { - "name": "Ž/x (Request/Response)", - "success": true - }, - { - "name": "x/Ž (Blob/File)", - "success": true - }, - { - "name": "x/Ž (Request/Response)", - "success": true - }, - { - "name": "x/x;Ž=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ž=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ž;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ž;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ž\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ž\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "‘/x (Blob/File)", - "success": true - }, - { - "name": "‘/x (Request/Response)", - "success": true - }, - { - "name": "x/‘ (Blob/File)", - "success": true - }, - { - "name": "x/‘ (Request/Response)", - "success": true - }, - { - "name": "x/x;‘=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;‘=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=‘;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‘\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=‘;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‘\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‘\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"‘\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"‘\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"‘\\\";bonus=x\" but got \"\"" - }, - { - "name": "’/x (Blob/File)", - "success": true - }, - { - "name": "’/x (Request/Response)", - "success": true - }, - { - "name": "x/’ (Blob/File)", - "success": true - }, - { - "name": "x/’ (Request/Response)", - "success": true - }, - { - "name": "x/x;’=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;’=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=’;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"’\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=’;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"’\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"’\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"’\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"’\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"’\\\";bonus=x\" but got \"\"" - }, - { - "name": "“/x (Blob/File)", - "success": true - }, - { - "name": "“/x (Request/Response)", - "success": true - }, - { - "name": "x/“ (Blob/File)", - "success": true - }, - { - "name": "x/“ (Request/Response)", - "success": true - }, - { - "name": "x/x;“=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;“=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=“;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"“\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=“;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"“\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"“\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"“\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"“\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"“\\\";bonus=x\" but got \"\"" - }, - { - "name": "”/x (Blob/File)", - "success": true - }, - { - "name": "”/x (Request/Response)", - "success": true - }, - { - "name": "x/” (Blob/File)", - "success": true - }, - { - "name": "x/” (Request/Response)", - "success": true - }, - { - "name": "x/x;”=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;”=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=”;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"”\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=”;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"”\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"”\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"”\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"”\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"”\\\";bonus=x\" but got \"\"" - }, - { - "name": "•/x (Blob/File)", - "success": true - }, - { - "name": "•/x (Request/Response)", - "success": true - }, - { - "name": "x/• (Blob/File)", - "success": true - }, - { - "name": "x/• (Request/Response)", - "success": true - }, - { - "name": "x/x;•=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;•=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=•;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"•\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=•;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"•\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"•\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"•\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"•\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"•\\\";bonus=x\" but got \"\"" - }, - { - "name": "–/x (Blob/File)", - "success": true - }, - { - "name": "–/x (Request/Response)", - "success": true - }, - { - "name": "x/– (Blob/File)", - "success": true - }, - { - "name": "x/– (Request/Response)", - "success": true - }, - { - "name": "x/x;–=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;–=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=–;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"–\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=–;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"–\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"–\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"–\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"–\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"–\\\";bonus=x\" but got \"\"" - }, - { - "name": "—/x (Blob/File)", - "success": true - }, - { - "name": "—/x (Request/Response)", - "success": true - }, - { - "name": "x/— (Blob/File)", - "success": true - }, - { - "name": "x/— (Request/Response)", - "success": true - }, - { - "name": "x/x;—=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;—=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=—;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"—\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=—;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"—\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"—\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"—\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"—\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"—\\\";bonus=x\" but got \"\"" - }, - { - "name": "˜/x (Blob/File)", - "success": true - }, - { - "name": "˜/x (Request/Response)", - "success": true - }, - { - "name": "x/˜ (Blob/File)", - "success": true - }, - { - "name": "x/˜ (Request/Response)", - "success": true - }, - { - "name": "x/x;˜=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;˜=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=˜;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"˜\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=˜;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"˜\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"˜\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"˜\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"˜\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"˜\\\";bonus=x\" but got \"\"" - }, - { - "name": "™/x (Blob/File)", - "success": true - }, - { - "name": "™/x (Request/Response)", - "success": true - }, - { - "name": "x/™ (Blob/File)", - "success": true - }, - { - "name": "x/™ (Request/Response)", - "success": true - }, - { - "name": "x/x;™=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;™=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=™;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"™\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=™;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"™\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"™\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"™\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"™\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"™\\\";bonus=x\" but got \"\"" - }, - { - "name": "š/x (Blob/File)", - "success": true - }, - { - "name": "š/x (Request/Response)", - "success": true - }, - { - "name": "x/š (Blob/File)", - "success": true - }, - { - "name": "x/š (Request/Response)", - "success": true - }, - { - "name": "x/x;š=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;š=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=š;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=š;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"š\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"š\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"š\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"š\\\";bonus=x\" but got \"\"" - }, - { - "name": "›/x (Blob/File)", - "success": true - }, - { - "name": "›/x (Request/Response)", - "success": true - }, - { - "name": "x/› (Blob/File)", - "success": true - }, - { - "name": "x/› (Request/Response)", - "success": true - }, - { - "name": "x/x;›=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;›=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=›;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"›\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=›;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"›\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"›\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"›\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"›\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"›\\\";bonus=x\" but got \"\"" - }, - { - "name": "œ/x (Blob/File)", - "success": true - }, - { - "name": "œ/x (Request/Response)", - "success": true - }, - { - "name": "x/œ (Blob/File)", - "success": true - }, - { - "name": "x/œ (Request/Response)", - "success": true - }, - { - "name": "x/x;œ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;œ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=œ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=œ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"œ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"œ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"œ\\\";bonus=x\" but got \"\"" - }, - { - "name": "/x (Blob/File)", - "success": true - }, - { - "name": "/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"\\\";bonus=x\" but got \"\"" - }, - { - "name": "ž/x (Blob/File)", - "success": true - }, - { - "name": "ž/x (Request/Response)", - "success": true - }, - { - "name": "x/ž (Blob/File)", - "success": true - }, - { - "name": "x/ž (Request/Response)", - "success": true - }, - { - "name": "x/x;ž=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ž=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ž;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ž;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ž\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ž\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ž\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ÿ/x (Blob/File)", - "success": true - }, - { - "name": "Ÿ/x (Request/Response)", - "success": true - }, - { - "name": "x/Ÿ (Blob/File)", - "success": true - }, - { - "name": "x/Ÿ (Request/Response)", - "success": true - }, - { - "name": "x/x;Ÿ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ÿ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ÿ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ÿ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ÿ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ÿ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ÿ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ÿ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ÿ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ÿ\\\";bonus=x\" but got \"\"" - }, - { - "name": " /x (Blob/File)", - "success": true - }, - { - "name": " /x (Request/Response)", - "success": true - }, - { - "name": "x/  (Blob/File)", - "success": true - }, - { - "name": "x/  (Request/Response)", - "success": true - }, - { - "name": "x/x; =x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x; =x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x= ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\" \\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x= ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\" \\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\" \";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\" \\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\" \";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\" \\\";bonus=x\" but got \"\"" - }, - { - "name": "¡/x (Blob/File)", - "success": true - }, - { - "name": "¡/x (Request/Response)", - "success": true - }, - { - "name": "x/¡ (Blob/File)", - "success": true - }, - { - "name": "x/¡ (Request/Response)", - "success": true - }, - { - "name": "x/x;¡=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¡=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¡;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¡;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¡\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¡\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¡\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¡\\\";bonus=x\" but got \"\"" - }, - { - "name": "¢/x (Blob/File)", - "success": true - }, - { - "name": "¢/x (Request/Response)", - "success": true - }, - { - "name": "x/¢ (Blob/File)", - "success": true - }, - { - "name": "x/¢ (Request/Response)", - "success": true - }, - { - "name": "x/x;¢=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¢=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¢;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¢\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¢;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¢\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¢\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¢\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¢\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¢\\\";bonus=x\" but got \"\"" - }, - { - "name": "£/x (Blob/File)", - "success": true - }, - { - "name": "£/x (Request/Response)", - "success": true - }, - { - "name": "x/£ (Blob/File)", - "success": true - }, - { - "name": "x/£ (Request/Response)", - "success": true - }, - { - "name": "x/x;£=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;£=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=£;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"£\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=£;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"£\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"£\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"£\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"£\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"£\\\";bonus=x\" but got \"\"" - }, - { - "name": "¤/x (Blob/File)", - "success": true - }, - { - "name": "¤/x (Request/Response)", - "success": true - }, - { - "name": "x/¤ (Blob/File)", - "success": true - }, - { - "name": "x/¤ (Request/Response)", - "success": true - }, - { - "name": "x/x;¤=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¤=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¤;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¤\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¤;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¤\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¤\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¤\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¤\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¤\\\";bonus=x\" but got \"\"" - }, - { - "name": "¥/x (Blob/File)", - "success": true - }, - { - "name": "¥/x (Request/Response)", - "success": true - }, - { - "name": "x/¥ (Blob/File)", - "success": true - }, - { - "name": "x/¥ (Request/Response)", - "success": true - }, - { - "name": "x/x;¥=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¥=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¥;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¥\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¥;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¥\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¥\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¥\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¥\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¥\\\";bonus=x\" but got \"\"" - }, - { - "name": "¦/x (Blob/File)", - "success": true - }, - { - "name": "¦/x (Request/Response)", - "success": true - }, - { - "name": "x/¦ (Blob/File)", - "success": true - }, - { - "name": "x/¦ (Request/Response)", - "success": true - }, - { - "name": "x/x;¦=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¦=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¦;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¦\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¦;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¦\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¦\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¦\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¦\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¦\\\";bonus=x\" but got \"\"" - }, - { - "name": "§/x (Blob/File)", - "success": true - }, - { - "name": "§/x (Request/Response)", - "success": true - }, - { - "name": "x/§ (Blob/File)", - "success": true - }, - { - "name": "x/§ (Request/Response)", - "success": true - }, - { - "name": "x/x;§=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;§=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=§;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"§\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=§;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"§\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"§\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"§\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"§\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"§\\\";bonus=x\" but got \"\"" - }, - { - "name": "¨/x (Blob/File)", - "success": true - }, - { - "name": "¨/x (Request/Response)", - "success": true - }, - { - "name": "x/¨ (Blob/File)", - "success": true - }, - { - "name": "x/¨ (Request/Response)", - "success": true - }, - { - "name": "x/x;¨=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¨=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¨;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¨\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¨;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¨\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¨\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¨\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¨\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¨\\\";bonus=x\" but got \"\"" - }, - { - "name": "©/x (Blob/File)", - "success": true - }, - { - "name": "©/x (Request/Response)", - "success": true - }, - { - "name": "x/© (Blob/File)", - "success": true - }, - { - "name": "x/© (Request/Response)", - "success": true - }, - { - "name": "x/x;©=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;©=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=©;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"©\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=©;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"©\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"©\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"©\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"©\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"©\\\";bonus=x\" but got \"\"" - }, - { - "name": "ª/x (Blob/File)", - "success": true - }, - { - "name": "ª/x (Request/Response)", - "success": true - }, - { - "name": "x/ª (Blob/File)", - "success": true - }, - { - "name": "x/ª (Request/Response)", - "success": true - }, - { - "name": "x/x;ª=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ª=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ª;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ª\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ª;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ª\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ª\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ª\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ª\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ª\\\";bonus=x\" but got \"\"" - }, - { - "name": "«/x (Blob/File)", - "success": true - }, - { - "name": "«/x (Request/Response)", - "success": true - }, - { - "name": "x/« (Blob/File)", - "success": true - }, - { - "name": "x/« (Request/Response)", - "success": true - }, - { - "name": "x/x;«=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;«=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=«;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"«\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=«;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"«\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"«\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"«\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"«\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"«\\\";bonus=x\" but got \"\"" - }, - { - "name": "¬/x (Blob/File)", - "success": true - }, - { - "name": "¬/x (Request/Response)", - "success": true - }, - { - "name": "x/¬ (Blob/File)", - "success": true - }, - { - "name": "x/¬ (Request/Response)", - "success": true - }, - { - "name": "x/x;¬=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¬=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¬;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¬\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¬;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¬\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¬\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¬\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¬\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¬\\\";bonus=x\" but got \"\"" - }, - { - "name": "­/x (Blob/File)", - "success": true - }, - { - "name": "­/x (Request/Response)", - "success": true - }, - { - "name": "x/­ (Blob/File)", - "success": true - }, - { - "name": "x/­ (Request/Response)", - "success": true - }, - { - "name": "x/x;­=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;­=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=­;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"­\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=­;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"­\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"­\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"­\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"­\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"­\\\";bonus=x\" but got \"\"" - }, - { - "name": "®/x (Blob/File)", - "success": true - }, - { - "name": "®/x (Request/Response)", - "success": true - }, - { - "name": "x/® (Blob/File)", - "success": true - }, - { - "name": "x/® (Request/Response)", - "success": true - }, - { - "name": "x/x;®=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;®=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=®;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"®\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=®;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"®\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"®\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"®\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"®\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"®\\\";bonus=x\" but got \"\"" - }, - { - "name": "¯/x (Blob/File)", - "success": true - }, - { - "name": "¯/x (Request/Response)", - "success": true - }, - { - "name": "x/¯ (Blob/File)", - "success": true - }, - { - "name": "x/¯ (Request/Response)", - "success": true - }, - { - "name": "x/x;¯=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¯=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¯;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¯\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¯;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¯\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¯\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¯\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¯\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¯\\\";bonus=x\" but got \"\"" - }, - { - "name": "°/x (Blob/File)", - "success": true - }, - { - "name": "°/x (Request/Response)", - "success": true - }, - { - "name": "x/° (Blob/File)", - "success": true - }, - { - "name": "x/° (Request/Response)", - "success": true - }, - { - "name": "x/x;°=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;°=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=°;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"°\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=°;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"°\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"°\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"°\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"°\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"°\\\";bonus=x\" but got \"\"" - }, - { - "name": "±/x (Blob/File)", - "success": true - }, - { - "name": "±/x (Request/Response)", - "success": true - }, - { - "name": "x/± (Blob/File)", - "success": true - }, - { - "name": "x/± (Request/Response)", - "success": true - }, - { - "name": "x/x;±=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;±=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=±;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"±\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=±;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"±\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"±\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"±\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"±\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"±\\\";bonus=x\" but got \"\"" - }, - { - "name": "²/x (Blob/File)", - "success": true - }, - { - "name": "²/x (Request/Response)", - "success": true - }, - { - "name": "x/² (Blob/File)", - "success": true - }, - { - "name": "x/² (Request/Response)", - "success": true - }, - { - "name": "x/x;²=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;²=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=²;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"²\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=²;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"²\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"²\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"²\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"²\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"²\\\";bonus=x\" but got \"\"" - }, - { - "name": "³/x (Blob/File)", - "success": true - }, - { - "name": "³/x (Request/Response)", - "success": true - }, - { - "name": "x/³ (Blob/File)", - "success": true - }, - { - "name": "x/³ (Request/Response)", - "success": true - }, - { - "name": "x/x;³=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;³=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=³;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"³\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=³;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"³\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"³\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"³\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"³\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"³\\\";bonus=x\" but got \"\"" - }, - { - "name": "´/x (Blob/File)", - "success": true - }, - { - "name": "´/x (Request/Response)", - "success": true - }, - { - "name": "x/´ (Blob/File)", - "success": true - }, - { - "name": "x/´ (Request/Response)", - "success": true - }, - { - "name": "x/x;´=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;´=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=´;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"´\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=´;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"´\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"´\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"´\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"´\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"´\\\";bonus=x\" but got \"\"" - }, - { - "name": "µ/x (Blob/File)", - "success": true - }, - { - "name": "µ/x (Request/Response)", - "success": true - }, - { - "name": "x/µ (Blob/File)", - "success": true - }, - { - "name": "x/µ (Request/Response)", - "success": true - }, - { - "name": "x/x;µ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;µ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=µ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"µ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=µ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"µ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"µ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"µ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"µ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"µ\\\";bonus=x\" but got \"\"" - }, - { - "name": "¶/x (Blob/File)", - "success": true - }, - { - "name": "¶/x (Request/Response)", - "success": true - }, - { - "name": "x/¶ (Blob/File)", - "success": true - }, - { - "name": "x/¶ (Request/Response)", - "success": true - }, - { - "name": "x/x;¶=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¶=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¶;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¶\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¶;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¶\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¶\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¶\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¶\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¶\\\";bonus=x\" but got \"\"" - }, - { - "name": "·/x (Blob/File)", - "success": true - }, - { - "name": "·/x (Request/Response)", - "success": true - }, - { - "name": "x/· (Blob/File)", - "success": true - }, - { - "name": "x/· (Request/Response)", - "success": true - }, - { - "name": "x/x;·=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;·=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=·;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"·\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=·;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"·\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"·\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"·\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"·\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"·\\\";bonus=x\" but got \"\"" - }, - { - "name": "¸/x (Blob/File)", - "success": true - }, - { - "name": "¸/x (Request/Response)", - "success": true - }, - { - "name": "x/¸ (Blob/File)", - "success": true - }, - { - "name": "x/¸ (Request/Response)", - "success": true - }, - { - "name": "x/x;¸=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¸=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¸;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¸\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¸;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¸\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¸\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¸\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¸\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¸\\\";bonus=x\" but got \"\"" - }, - { - "name": "¹/x (Blob/File)", - "success": true - }, - { - "name": "¹/x (Request/Response)", - "success": true - }, - { - "name": "x/¹ (Blob/File)", - "success": true - }, - { - "name": "x/¹ (Request/Response)", - "success": true - }, - { - "name": "x/x;¹=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¹=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¹;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¹;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¹\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¹\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¹\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¹\\\";bonus=x\" but got \"\"" - }, - { - "name": "º/x (Blob/File)", - "success": true - }, - { - "name": "º/x (Request/Response)", - "success": true - }, - { - "name": "x/º (Blob/File)", - "success": true - }, - { - "name": "x/º (Request/Response)", - "success": true - }, - { - "name": "x/x;º=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;º=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=º;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"º\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=º;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"º\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"º\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"º\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"º\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"º\\\";bonus=x\" but got \"\"" - }, - { - "name": "»/x (Blob/File)", - "success": true - }, - { - "name": "»/x (Request/Response)", - "success": true - }, - { - "name": "x/» (Blob/File)", - "success": true - }, - { - "name": "x/» (Request/Response)", - "success": true - }, - { - "name": "x/x;»=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;»=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=»;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"»\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=»;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"»\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"»\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"»\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"»\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"»\\\";bonus=x\" but got \"\"" - }, - { - "name": "¼/x (Blob/File)", - "success": true - }, - { - "name": "¼/x (Request/Response)", - "success": true - }, - { - "name": "x/¼ (Blob/File)", - "success": true - }, - { - "name": "x/¼ (Request/Response)", - "success": true - }, - { - "name": "x/x;¼=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¼=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¼;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¼\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¼;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¼\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¼\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¼\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¼\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¼\\\";bonus=x\" but got \"\"" - }, - { - "name": "½/x (Blob/File)", - "success": true - }, - { - "name": "½/x (Request/Response)", - "success": true - }, - { - "name": "x/½ (Blob/File)", - "success": true - }, - { - "name": "x/½ (Request/Response)", - "success": true - }, - { - "name": "x/x;½=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;½=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=½;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"½\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=½;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"½\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"½\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"½\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"½\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"½\\\";bonus=x\" but got \"\"" - }, - { - "name": "¾/x (Blob/File)", - "success": true - }, - { - "name": "¾/x (Request/Response)", - "success": true - }, - { - "name": "x/¾ (Blob/File)", - "success": true - }, - { - "name": "x/¾ (Request/Response)", - "success": true - }, - { - "name": "x/x;¾=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¾=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¾;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¾\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¾;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¾\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¾\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¾\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¾\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¾\\\";bonus=x\" but got \"\"" - }, - { - "name": "¿/x (Blob/File)", - "success": true - }, - { - "name": "¿/x (Request/Response)", - "success": true - }, - { - "name": "x/¿ (Blob/File)", - "success": true - }, - { - "name": "x/¿ (Request/Response)", - "success": true - }, - { - "name": "x/x;¿=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;¿=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=¿;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¿\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=¿;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¿\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¿\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"¿\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"¿\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"¿\\\";bonus=x\" but got \"\"" - }, - { - "name": "À/x (Blob/File)", - "success": true - }, - { - "name": "À/x (Request/Response)", - "success": true - }, - { - "name": "x/À (Blob/File)", - "success": true - }, - { - "name": "x/À (Request/Response)", - "success": true - }, - { - "name": "x/x;À=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;À=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=À;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"À\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=À;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"À\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"À\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"À\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"À\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"À\\\";bonus=x\" but got \"\"" - }, - { - "name": "Á/x (Blob/File)", - "success": true - }, - { - "name": "Á/x (Request/Response)", - "success": true - }, - { - "name": "x/Á (Blob/File)", - "success": true - }, - { - "name": "x/Á (Request/Response)", - "success": true - }, - { - "name": "x/x;Á=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Á=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Á;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Á;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Á\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Á\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Á\\\";bonus=x\" but got \"\"" - }, - { - "name": "Â/x (Blob/File)", - "success": true - }, - { - "name": "Â/x (Request/Response)", - "success": true - }, - { - "name": "x/ (Blob/File)", - "success": true - }, - { - "name": "x/ (Request/Response)", - "success": true - }, - { - "name": "x/x;Â=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Â=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Â;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Â;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Â\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Â\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Â\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ã/x (Blob/File)", - "success": true - }, - { - "name": "Ã/x (Request/Response)", - "success": true - }, - { - "name": "x/à (Blob/File)", - "success": true - }, - { - "name": "x/à (Request/Response)", - "success": true - }, - { - "name": "x/x;Ã=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ã=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ã;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ã;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ã\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ã\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ä/x (Blob/File)", - "success": true - }, - { - "name": "Ä/x (Request/Response)", - "success": true - }, - { - "name": "x/Ä (Blob/File)", - "success": true - }, - { - "name": "x/Ä (Request/Response)", - "success": true - }, - { - "name": "x/x;Ä=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ä=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ä;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ä;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ä\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ä\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "Å/x (Blob/File)", - "success": true - }, - { - "name": "Å/x (Request/Response)", - "success": true - }, - { - "name": "x/Å (Blob/File)", - "success": true - }, - { - "name": "x/Å (Request/Response)", - "success": true - }, - { - "name": "x/x;Å=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Å=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Å;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Å;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Å\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Å\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Å\\\";bonus=x\" but got \"\"" - }, - { - "name": "Æ/x (Blob/File)", - "success": true - }, - { - "name": "Æ/x (Request/Response)", - "success": true - }, - { - "name": "x/Æ (Blob/File)", - "success": true - }, - { - "name": "x/Æ (Request/Response)", - "success": true - }, - { - "name": "x/x;Æ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Æ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Æ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Æ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Æ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Æ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ç/x (Blob/File)", - "success": true - }, - { - "name": "Ç/x (Request/Response)", - "success": true - }, - { - "name": "x/Ç (Blob/File)", - "success": true - }, - { - "name": "x/Ç (Request/Response)", - "success": true - }, - { - "name": "x/x;Ç=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ç=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ç;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ç;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ç\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ç\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "È/x (Blob/File)", - "success": true - }, - { - "name": "È/x (Request/Response)", - "success": true - }, - { - "name": "x/È (Blob/File)", - "success": true - }, - { - "name": "x/È (Request/Response)", - "success": true - }, - { - "name": "x/x;È=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;È=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=È;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"È\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=È;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"È\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"È\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"È\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"È\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"È\\\";bonus=x\" but got \"\"" - }, - { - "name": "É/x (Blob/File)", - "success": true - }, - { - "name": "É/x (Request/Response)", - "success": true - }, - { - "name": "x/É (Blob/File)", - "success": true - }, - { - "name": "x/É (Request/Response)", - "success": true - }, - { - "name": "x/x;É=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;É=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=É;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"É\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=É;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"É\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"É\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"É\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"É\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"É\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ê/x (Blob/File)", - "success": true - }, - { - "name": "Ê/x (Request/Response)", - "success": true - }, - { - "name": "x/Ê (Blob/File)", - "success": true - }, - { - "name": "x/Ê (Request/Response)", - "success": true - }, - { - "name": "x/x;Ê=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ê=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ê;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ê;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ê\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ê\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ë/x (Blob/File)", - "success": true - }, - { - "name": "Ë/x (Request/Response)", - "success": true - }, - { - "name": "x/Ë (Blob/File)", - "success": true - }, - { - "name": "x/Ë (Request/Response)", - "success": true - }, - { - "name": "x/x;Ë=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ë=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ë;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ë;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ë\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ë\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ì/x (Blob/File)", - "success": true - }, - { - "name": "Ì/x (Request/Response)", - "success": true - }, - { - "name": "x/Ì (Blob/File)", - "success": true - }, - { - "name": "x/Ì (Request/Response)", - "success": true - }, - { - "name": "x/x;Ì=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ì=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ì;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ì;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ì\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ì\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "Í/x (Blob/File)", - "success": true - }, - { - "name": "Í/x (Request/Response)", - "success": true - }, - { - "name": "x/Í (Blob/File)", - "success": true - }, - { - "name": "x/Í (Request/Response)", - "success": true - }, - { - "name": "x/x;Í=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Í=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Í;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Í;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Í\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Í\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Í\\\";bonus=x\" but got \"\"" - }, - { - "name": "Î/x (Blob/File)", - "success": true - }, - { - "name": "Î/x (Request/Response)", - "success": true - }, - { - "name": "x/Î (Blob/File)", - "success": true - }, - { - "name": "x/Î (Request/Response)", - "success": true - }, - { - "name": "x/x;Î=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Î=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Î;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Î\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Î;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Î\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Î\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Î\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Î\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Î\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ï/x (Blob/File)", - "success": true - }, - { - "name": "Ï/x (Request/Response)", - "success": true - }, - { - "name": "x/Ï (Blob/File)", - "success": true - }, - { - "name": "x/Ï (Request/Response)", - "success": true - }, - { - "name": "x/x;Ï=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ï=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ï;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ï\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ï;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ï\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ï\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ï\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ï\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ï\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ð/x (Blob/File)", - "success": true - }, - { - "name": "Ð/x (Request/Response)", - "success": true - }, - { - "name": "x/Ð (Blob/File)", - "success": true - }, - { - "name": "x/Ð (Request/Response)", - "success": true - }, - { - "name": "x/x;Ð=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ð=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ð;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ð\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ð;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ð\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ð\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ð\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ð\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ð\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ñ/x (Blob/File)", - "success": true - }, - { - "name": "Ñ/x (Request/Response)", - "success": true - }, - { - "name": "x/Ñ (Blob/File)", - "success": true - }, - { - "name": "x/Ñ (Request/Response)", - "success": true - }, - { - "name": "x/x;Ñ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ñ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ñ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ñ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ñ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ñ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ñ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ñ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ñ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ñ\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ò/x (Blob/File)", - "success": true - }, - { - "name": "Ò/x (Request/Response)", - "success": true - }, - { - "name": "x/Ò (Blob/File)", - "success": true - }, - { - "name": "x/Ò (Request/Response)", - "success": true - }, - { - "name": "x/x;Ò=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ò=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ò;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ò\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ò;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ò\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ò\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ò\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ò\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ò\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ó/x (Blob/File)", - "success": true - }, - { - "name": "Ó/x (Request/Response)", - "success": true - }, - { - "name": "x/Ó (Blob/File)", - "success": true - }, - { - "name": "x/Ó (Request/Response)", - "success": true - }, - { - "name": "x/x;Ó=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ó=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ó;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ó\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ó;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ó\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ó\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ó\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ó\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ó\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ô/x (Blob/File)", - "success": true - }, - { - "name": "Ô/x (Request/Response)", - "success": true - }, - { - "name": "x/Ô (Blob/File)", - "success": true - }, - { - "name": "x/Ô (Request/Response)", - "success": true - }, - { - "name": "x/x;Ô=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ô=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ô;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ô\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ô;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ô\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ô\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ô\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ô\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ô\\\";bonus=x\" but got \"\"" - }, - { - "name": "Õ/x (Blob/File)", - "success": true - }, - { - "name": "Õ/x (Request/Response)", - "success": true - }, - { - "name": "x/Õ (Blob/File)", - "success": true - }, - { - "name": "x/Õ (Request/Response)", - "success": true - }, - { - "name": "x/x;Õ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Õ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Õ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Õ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Õ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Õ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Õ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Õ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Õ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Õ\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ö/x (Blob/File)", - "success": true - }, - { - "name": "Ö/x (Request/Response)", - "success": true - }, - { - "name": "x/Ö (Blob/File)", - "success": true - }, - { - "name": "x/Ö (Request/Response)", - "success": true - }, - { - "name": "x/x;Ö=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ö=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ö;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ö\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ö;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ö\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ö\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ö\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ö\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ö\\\";bonus=x\" but got \"\"" - }, - { - "name": "×/x (Blob/File)", - "success": true - }, - { - "name": "×/x (Request/Response)", - "success": true - }, - { - "name": "x/× (Blob/File)", - "success": true - }, - { - "name": "x/× (Request/Response)", - "success": true - }, - { - "name": "x/x;×=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;×=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=×;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"×\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=×;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"×\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"×\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"×\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"×\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"×\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ø/x (Blob/File)", - "success": true - }, - { - "name": "Ø/x (Request/Response)", - "success": true - }, - { - "name": "x/Ø (Blob/File)", - "success": true - }, - { - "name": "x/Ø (Request/Response)", - "success": true - }, - { - "name": "x/x;Ø=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ø=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ø;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ø\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ø;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ø\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ø\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ø\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ø\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ø\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ù/x (Blob/File)", - "success": true - }, - { - "name": "Ù/x (Request/Response)", - "success": true - }, - { - "name": "x/Ù (Blob/File)", - "success": true - }, - { - "name": "x/Ù (Request/Response)", - "success": true - }, - { - "name": "x/x;Ù=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ù=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ù;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ù\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ù;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ù\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ù\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ù\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ù\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ù\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ú/x (Blob/File)", - "success": true - }, - { - "name": "Ú/x (Request/Response)", - "success": true - }, - { - "name": "x/Ú (Blob/File)", - "success": true - }, - { - "name": "x/Ú (Request/Response)", - "success": true - }, - { - "name": "x/x;Ú=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ú=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ú;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ú\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ú;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ú\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ú\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ú\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ú\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ú\\\";bonus=x\" but got \"\"" - }, - { - "name": "Û/x (Blob/File)", - "success": true - }, - { - "name": "Û/x (Request/Response)", - "success": true - }, - { - "name": "x/Û (Blob/File)", - "success": true - }, - { - "name": "x/Û (Request/Response)", - "success": true - }, - { - "name": "x/x;Û=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Û=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Û;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Û\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Û;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Û\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Û\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Û\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Û\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Û\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ü/x (Blob/File)", - "success": true - }, - { - "name": "Ü/x (Request/Response)", - "success": true - }, - { - "name": "x/Ü (Blob/File)", - "success": true - }, - { - "name": "x/Ü (Request/Response)", - "success": true - }, - { - "name": "x/x;Ü=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ü=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ü;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ü\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ü;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ü\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ü\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ü\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ü\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ü\\\";bonus=x\" but got \"\"" - }, - { - "name": "Ý/x (Blob/File)", - "success": true - }, - { - "name": "Ý/x (Request/Response)", - "success": true - }, - { - "name": "x/Ý (Blob/File)", - "success": true - }, - { - "name": "x/Ý (Request/Response)", - "success": true - }, - { - "name": "x/x;Ý=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Ý=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Ý;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ý\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Ý;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ý\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ý\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Ý\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Ý\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Ý\\\";bonus=x\" but got \"\"" - }, - { - "name": "Þ/x (Blob/File)", - "success": true - }, - { - "name": "Þ/x (Request/Response)", - "success": true - }, - { - "name": "x/Þ (Blob/File)", - "success": true - }, - { - "name": "x/Þ (Request/Response)", - "success": true - }, - { - "name": "x/x;Þ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;Þ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=Þ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Þ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=Þ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Þ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Þ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"Þ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"Þ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"Þ\\\";bonus=x\" but got \"\"" - }, - { - "name": "ß/x (Blob/File)", - "success": true - }, - { - "name": "ß/x (Request/Response)", - "success": true - }, - { - "name": "x/ß (Blob/File)", - "success": true - }, - { - "name": "x/ß (Request/Response)", - "success": true - }, - { - "name": "x/x;ß=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ß=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ß;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ß\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ß;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ß\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ß\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ß\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ß\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ß\\\";bonus=x\" but got \"\"" - }, - { - "name": "à/x (Blob/File)", - "success": true - }, - { - "name": "à/x (Request/Response)", - "success": true - }, - { - "name": "x/à (Blob/File)", - "success": true - }, - { - "name": "x/à (Request/Response)", - "success": true - }, - { - "name": "x/x;à=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;à=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=à;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"à\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=à;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"à\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"à\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"à\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"à\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"à\\\";bonus=x\" but got \"\"" - }, - { - "name": "á/x (Blob/File)", - "success": true - }, - { - "name": "á/x (Request/Response)", - "success": true - }, - { - "name": "x/á (Blob/File)", - "success": true - }, - { - "name": "x/á (Request/Response)", - "success": true - }, - { - "name": "x/x;á=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;á=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=á;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=á;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"á\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"á\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"á\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"á\\\";bonus=x\" but got \"\"" - }, - { - "name": "â/x (Blob/File)", - "success": true - }, - { - "name": "â/x (Request/Response)", - "success": true - }, - { - "name": "x/â (Blob/File)", - "success": true - }, - { - "name": "x/â (Request/Response)", - "success": true - }, - { - "name": "x/x;â=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;â=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=â;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=â;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"â\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"â\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"â\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"â\\\";bonus=x\" but got \"\"" - }, - { - "name": "ã/x (Blob/File)", - "success": true - }, - { - "name": "ã/x (Request/Response)", - "success": true - }, - { - "name": "x/ã (Blob/File)", - "success": true - }, - { - "name": "x/ã (Request/Response)", - "success": true - }, - { - "name": "x/x;ã=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ã=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ã;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ã;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ã\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ã\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ã\\\";bonus=x\" but got \"\"" - }, - { - "name": "ä/x (Blob/File)", - "success": true - }, - { - "name": "ä/x (Request/Response)", - "success": true - }, - { - "name": "x/ä (Blob/File)", - "success": true - }, - { - "name": "x/ä (Request/Response)", - "success": true - }, - { - "name": "x/x;ä=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ä=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ä;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ä;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ä\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ä\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ä\\\";bonus=x\" but got \"\"" - }, - { - "name": "å/x (Blob/File)", - "success": true - }, - { - "name": "å/x (Request/Response)", - "success": true - }, - { - "name": "x/å (Blob/File)", - "success": true - }, - { - "name": "x/å (Request/Response)", - "success": true - }, - { - "name": "x/x;å=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;å=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=å;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=å;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"å\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"å\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"å\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"å\\\";bonus=x\" but got \"\"" - }, - { - "name": "æ/x (Blob/File)", - "success": true - }, - { - "name": "æ/x (Request/Response)", - "success": true - }, - { - "name": "x/æ (Blob/File)", - "success": true - }, - { - "name": "x/æ (Request/Response)", - "success": true - }, - { - "name": "x/x;æ=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;æ=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=æ;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=æ;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"æ\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"æ\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"æ\\\";bonus=x\" but got \"\"" - }, - { - "name": "ç/x (Blob/File)", - "success": true - }, - { - "name": "ç/x (Request/Response)", - "success": true - }, - { - "name": "x/ç (Blob/File)", - "success": true - }, - { - "name": "x/ç (Request/Response)", - "success": true - }, - { - "name": "x/x;ç=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ç=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ç;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ç;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ç\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ç\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ç\\\";bonus=x\" but got \"\"" - }, - { - "name": "è/x (Blob/File)", - "success": true - }, - { - "name": "è/x (Request/Response)", - "success": true - }, - { - "name": "x/è (Blob/File)", - "success": true - }, - { - "name": "x/è (Request/Response)", - "success": true - }, - { - "name": "x/x;è=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;è=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=è;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"è\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=è;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"è\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"è\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"è\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"è\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"è\\\";bonus=x\" but got \"\"" - }, - { - "name": "é/x (Blob/File)", - "success": true - }, - { - "name": "é/x (Request/Response)", - "success": true - }, - { - "name": "x/é (Blob/File)", - "success": true - }, - { - "name": "x/é (Request/Response)", - "success": true - }, - { - "name": "x/x;é=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;é=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=é;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"é\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=é;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"é\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"é\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"é\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"é\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"é\\\";bonus=x\" but got \"\"" - }, - { - "name": "ê/x (Blob/File)", - "success": true - }, - { - "name": "ê/x (Request/Response)", - "success": true - }, - { - "name": "x/ê (Blob/File)", - "success": true - }, - { - "name": "x/ê (Request/Response)", - "success": true - }, - { - "name": "x/x;ê=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ê=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ê;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ê;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ê\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ê\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ê\\\";bonus=x\" but got \"\"" - }, - { - "name": "ë/x (Blob/File)", - "success": true - }, - { - "name": "ë/x (Request/Response)", - "success": true - }, - { - "name": "x/ë (Blob/File)", - "success": true - }, - { - "name": "x/ë (Request/Response)", - "success": true - }, - { - "name": "x/x;ë=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ë=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ë;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ë;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ë\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ë\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ë\\\";bonus=x\" but got \"\"" - }, - { - "name": "ì/x (Blob/File)", - "success": true - }, - { - "name": "ì/x (Request/Response)", - "success": true - }, - { - "name": "x/ì (Blob/File)", - "success": true - }, - { - "name": "x/ì (Request/Response)", - "success": true - }, - { - "name": "x/x;ì=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ì=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=ì;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=ì;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ì\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"ì\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ì\\\";bonus=x\" but got \"\"" - }, - { - "name": "í/x (Blob/File)", - "success": true - }, - { - "name": "í/x (Request/Response)", - "success": true - }, - { - "name": "x/í (Blob/File)", - "success": true - }, - { - "name": "x/í (Request/Response)", - "success": true - }, - { - "name": "x/x;í=x;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;í=x;bonus=x (Request/Response)", - "success": true - }, - { - "name": "x/x;x=í;bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=í;bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"í\";bonus=x (Blob/File)", - "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"í\\\";bonus=x\" but got \"\"" - }, - { - "name": "x/x;x=\"í\";bonus=x (Request/Response)", - "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"í\\\";bonus=x\" but got \"\"" - }, - { - "name": "î/x (Blob/File)", - "success": true - }, - { - "name": "î/x (Request/Response)", - "success": true - }, - { - "name": "x/î (Blob/File)", - "success": true - }, - { - "name": "x/î (Request/Response)", - "success": true - }, + }, + "embedded-credentials.tentative.sub.html": { + "success": true, + "cases": [ { - "name": "x/x;î=x;bonus=x (Blob/File)", + "name": "Embedded credentials are treated as network errors.", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;î=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=î;bonus=x (Blob/File)", + "name": "Embedded credentials are treated as network errors in frames.", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"î\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=î;bonus=x (Request/Response)", + "name": "Embedded credentials are treated as network errors in new windows.", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"î\\\";bonus=x\" but got \"\"" + "message": "window.open is not a function" }, { - "name": "x/x;x=\"î\";bonus=x (Blob/File)", + "name": "Embedded credentials matching the top-level are not treated as network errors for relative URLs.", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"î\\\";bonus=x\" but got \"\"" + "message": "window.open is not a function" }, { - "name": "x/x;x=\"î\";bonus=x (Request/Response)", + "name": "Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"î\\\";bonus=x\" but got \"\"" - }, - { - "name": "ï/x (Blob/File)", - "success": true + "message": "window.open is not a function" }, { - "name": "ï/x (Request/Response)", - "success": true - }, + "name": "Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.", + "success": false, + "message": "window.open is not a function" + } + ] + }, + "redirect-to-url-with-credentials.https.html": { + "success": true, + "cases": [ { - "name": "x/ï (Blob/File)", + "name": "No CORS fetch after a redirect with an URL containing credentials", "success": true }, { - "name": "x/ï (Request/Response)", + "name": "CORS fetch after a redirect with a cross origin URL containing credentials", "success": true }, { - "name": "x/x;ï=x;bonus=x (Blob/File)", + "name": "CORS fetch after a redirect with a same origin URL containing credentials", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ï=x;bonus=x (Request/Response)", - "success": true + "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" }, { - "name": "x/x;x=ï;bonus=x (Blob/File)", + "name": "Image loading after a redirect with an URL containing credentials", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ï\\\";bonus=x\" but got \"\"" + "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" }, { - "name": "x/x;x=ï;bonus=x (Request/Response)", + "name": "CORS Image loading after a redirect with a cross origin URL containing credentials", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ï\\\";bonus=x\" but got \"\"" + "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" }, { - "name": "x/x;x=\"ï\";bonus=x (Blob/File)", + "name": "CORS Image loading after a redirect with a same origin URL containing credentials", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ï\\\";bonus=x\" but got \"\"" + "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: Image is not defined\"" }, { - "name": "x/x;x=\"ï\";bonus=x (Request/Response)", + "name": "Frame loading after a redirect with an URL containing credentials", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ï\\\";bonus=x\" but got \"\"" - }, - { - "name": "ð/x (Blob/File)", - "success": true - }, - { - "name": "ð/x (Request/Response)", - "success": true - }, - { - "name": "x/ð (Blob/File)", - "success": true - }, - { - "name": "x/ð (Request/Response)", - "success": true - }, + "message": "promise_test: Unhandled rejection with value: object \"ReferenceError: document is not defined\"" + } + ] + } + }, + "stale-while-revalidate": { + "fetch-sw.https.html": { + "success": true, + "cases": [ { - "name": "x/x;ð=x;bonus=x (Blob/File)", + "name": "Second fetch returns same response", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ð=x;bonus=x (Request/Response)", - "success": true - }, + "message": "promise_test: Unhandled rejection with value: object \"TypeError: Cannot read properties of undefined (reading 'register')\"" + } + ] + }, + "fetch.any.html": { + "success": true, + "cases": [ { - "name": "x/x;x=ð;bonus=x (Blob/File)", + "name": "Second fetch returns same response", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ð\\\";bonus=x\" but got \"\"" - }, + "message": "assert_equals: expected \"lwbefdpkiqfhgejhzspj\" but got \"sueymolkqyvlbejzamwn\"" + } + ] + }, + "revalidate-not-blocked-by-csp.html": { + "success": false, + "cases": [] + }, + "stale-css.html": { + "success": false, + "cases": [] + }, + "stale-image.html": { + "success": false, + "cases": [] + }, + "stale-script.html": { + "success": false, + "cases": [] + } + } + }, + "mimesniff": { + "media": { + "media-sniff.window.html": { + "success": true, + "cases": [ { - "name": "x/x;x=ð;bonus=x (Request/Response)", + "name": "mp3-raw.mp3 loads when served with Content-Type ", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ð\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ð\";bonus=x (Blob/File)", + "name": "mp3-raw.mp3 loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ð\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ð\";bonus=x (Request/Response)", + "name": "mp3-raw.mp3 loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ð\\\";bonus=x\" but got \"\"" - }, - { - "name": "ñ/x (Blob/File)", - "success": true - }, - { - "name": "ñ/x (Request/Response)", - "success": true - }, - { - "name": "x/ñ (Blob/File)", - "success": true - }, - { - "name": "x/ñ (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ñ=x;bonus=x (Blob/File)", + "name": "mp3-raw.mp3 loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ñ=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ñ;bonus=x (Blob/File)", + "name": "mp3-raw.mp3 loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ñ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ñ;bonus=x (Request/Response)", + "name": "mp3-raw.mp3 loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ñ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ñ\";bonus=x (Blob/File)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type ", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ñ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ñ\";bonus=x (Request/Response)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ñ\\\";bonus=x\" but got \"\"" - }, - { - "name": "ò/x (Blob/File)", - "success": true - }, - { - "name": "ò/x (Request/Response)", - "success": true - }, - { - "name": "x/ò (Blob/File)", - "success": true - }, - { - "name": "x/ò (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ò=x;bonus=x (Blob/File)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ò=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ò;bonus=x (Blob/File)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ò\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ò;bonus=x (Request/Response)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ò\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ò\";bonus=x (Blob/File)", + "name": "mp3-with-id3.mp3 loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ò\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ò\";bonus=x (Request/Response)", + "name": "flac.flac loads when served with Content-Type ", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ò\\\";bonus=x\" but got \"\"" - }, - { - "name": "ó/x (Blob/File)", - "success": true - }, - { - "name": "ó/x (Request/Response)", - "success": true - }, - { - "name": "x/ó (Blob/File)", - "success": true - }, - { - "name": "x/ó (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ó=x;bonus=x (Blob/File)", + "name": "flac.flac loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ó=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ó;bonus=x (Blob/File)", + "name": "flac.flac loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ó\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ó;bonus=x (Request/Response)", + "name": "flac.flac loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ó\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ó\";bonus=x (Blob/File)", + "name": "flac.flac loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ó\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ó\";bonus=x (Request/Response)", + "name": "flac.flac loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ó\\\";bonus=x\" but got \"\"" - }, - { - "name": "ô/x (Blob/File)", - "success": true - }, - { - "name": "ô/x (Request/Response)", - "success": true - }, - { - "name": "x/ô (Blob/File)", - "success": true - }, - { - "name": "x/ô (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ô=x;bonus=x (Blob/File)", + "name": "ogg.ogg loads when served with Content-Type ", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ô=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ô;bonus=x (Blob/File)", + "name": "ogg.ogg loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ô\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ô;bonus=x (Request/Response)", + "name": "ogg.ogg loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ô\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ô\";bonus=x (Blob/File)", + "name": "ogg.ogg loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ô\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ô\";bonus=x (Request/Response)", + "name": "ogg.ogg loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ô\\\";bonus=x\" but got \"\"" - }, - { - "name": "õ/x (Blob/File)", - "success": true - }, - { - "name": "õ/x (Request/Response)", - "success": true - }, - { - "name": "x/õ (Blob/File)", - "success": true - }, - { - "name": "x/õ (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;õ=x;bonus=x (Blob/File)", + "name": "ogg.ogg loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;õ=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=õ;bonus=x (Blob/File)", + "name": "mp4.mp4 loads when served with Content-Type ", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"õ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=õ;bonus=x (Request/Response)", + "name": "mp4.mp4 loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"õ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"õ\";bonus=x (Blob/File)", + "name": "mp4.mp4 loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"õ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"õ\";bonus=x (Request/Response)", + "name": "mp4.mp4 loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"õ\\\";bonus=x\" but got \"\"" - }, - { - "name": "ö/x (Blob/File)", - "success": true - }, - { - "name": "ö/x (Request/Response)", - "success": true - }, - { - "name": "x/ö (Blob/File)", - "success": true - }, - { - "name": "x/ö (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ö=x;bonus=x (Blob/File)", + "name": "mp4.mp4 loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ö=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ö;bonus=x (Blob/File)", + "name": "mp4.mp4 loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ö\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ö;bonus=x (Request/Response)", + "name": "wav.wav loads when served with Content-Type ", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ö\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ö\";bonus=x (Blob/File)", + "name": "wav.wav loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ö\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ö\";bonus=x (Request/Response)", + "name": "wav.wav loads when served with Content-Type application/octet-stream", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ö\\\";bonus=x\" but got \"\"" - }, - { - "name": "÷/x (Blob/File)", - "success": true - }, - { - "name": "÷/x (Request/Response)", - "success": true - }, - { - "name": "x/÷ (Blob/File)", - "success": true - }, - { - "name": "x/÷ (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;÷=x;bonus=x (Blob/File)", + "name": "wav.wav loads when served with Content-Type text/html", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;÷=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=÷;bonus=x (Blob/File)", + "name": "wav.wav loads when served with Content-Type audio/ogg; codec=vorbis", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"÷\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=÷;bonus=x (Request/Response)", + "name": "wav.wav loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"÷\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"÷\";bonus=x (Blob/File)", + "name": "webm.webm loads when served with Content-Type ", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"÷\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"÷\";bonus=x (Request/Response)", + "name": "webm.webm loads when served with Content-Type bogus/mime", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"÷\\\";bonus=x\" but got \"\"" - }, - { - "name": "ø/x (Blob/File)", - "success": true + "message": "document is not defined" }, { - "name": "ø/x (Request/Response)", - "success": true + "name": "webm.webm loads when served with Content-Type application/octet-stream", + "success": false, + "message": "document is not defined" }, { - "name": "x/ø (Blob/File)", - "success": true + "name": "webm.webm loads when served with Content-Type text/html", + "success": false, + "message": "document is not defined" }, { - "name": "x/ø (Request/Response)", - "success": true + "name": "webm.webm loads when served with Content-Type audio/ogg; codec=vorbis", + "success": false, + "message": "document is not defined" }, { - "name": "x/x;ø=x;bonus=x (Blob/File)", + "name": "webm.webm loads when served with Content-Type application/pdf", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, + "message": "document is not defined" + } + ] + } + }, + "mime-types": { + "charset-parameter.window.html": { + "success": true, + "cases": [ { - "name": "x/x;ø=x;bonus=x (Request/Response)", + "name": "Loading data…", "success": true }, { - "name": "x/x;x=ø;bonus=x (Blob/File)", + "name": "text/html;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ø\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ø;bonus=x (Request/Response)", + "name": "TEXT/HTML;CHARSET=GBK", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ø\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ø\";bonus=x (Blob/File)", + "name": "text/html;charset=gbk(", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ø\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ø\";bonus=x (Request/Response)", + "name": "text/html;x=(;charset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ø\\\";bonus=x\" but got \"\"" - }, - { - "name": "ù/x (Blob/File)", - "success": true - }, - { - "name": "ù/x (Request/Response)", - "success": true - }, - { - "name": "x/ù (Blob/File)", - "success": true - }, - { - "name": "x/ù (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ù=x;bonus=x (Blob/File)", + "name": "text/html;charset=gbk;charset=windows-1255", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ù=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ù;bonus=x (Blob/File)", + "name": "text/html;charset=();charset=GBK", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ù\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ù;bonus=x (Request/Response)", + "name": "text/html;charset =gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ù\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ù\";bonus=x (Blob/File)", + "name": "text/html ;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ù\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ù\";bonus=x (Request/Response)", + "name": "text/html; charset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ù\\\";bonus=x\" but got \"\"" - }, - { - "name": "ú/x (Blob/File)", - "success": true - }, - { - "name": "ú/x (Request/Response)", - "success": true - }, - { - "name": "x/ú (Blob/File)", - "success": true - }, - { - "name": "x/ú (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ú=x;bonus=x (Blob/File)", + "name": "text/html;charset= gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ú=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ú;bonus=x (Blob/File)", + "name": "text/html;charset= \"gbk\"", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ú\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ú;bonus=x (Request/Response)", + "name": "text/html;charset=\u000bgbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ú\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ú\";bonus=x (Blob/File)", + "name": "text/html;charset=\fgbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ú\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ú\";bonus=x (Request/Response)", + "name": "text/html;\u000bcharset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ú\\\";bonus=x\" but got \"\"" - }, - { - "name": "û/x (Blob/File)", - "success": true - }, - { - "name": "û/x (Request/Response)", - "success": true - }, - { - "name": "x/û (Blob/File)", - "success": true - }, - { - "name": "x/û (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;û=x;bonus=x (Blob/File)", + "name": "text/html;\fcharset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;û=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=û;bonus=x (Blob/File)", + "name": "text/html;charset='gbk'", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"û\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=û;bonus=x (Request/Response)", + "name": "text/html;charset='gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"û\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"û\";bonus=x (Blob/File)", + "name": "text/html;charset=gbk'", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"û\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"û\";bonus=x (Request/Response)", + "name": "text/html;charset=';charset=GBK", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"û\\\";bonus=x\" but got \"\"" - }, - { - "name": "ü/x (Blob/File)", - "success": true - }, - { - "name": "ü/x (Request/Response)", - "success": true - }, - { - "name": "x/ü (Blob/File)", - "success": true - }, - { - "name": "x/ü (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ü=x;bonus=x (Blob/File)", + "name": "text/html;test;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ü=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ü;bonus=x (Blob/File)", + "name": "text/html;test=;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ü\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ü;bonus=x (Request/Response)", + "name": "text/html;';charset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ü\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ü\";bonus=x (Blob/File)", + "name": "text/html;\";charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ü\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ü\";bonus=x (Request/Response)", + "name": "text/html ; ; charset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ü\\\";bonus=x\" but got \"\"" - }, - { - "name": "ý/x (Blob/File)", - "success": true - }, - { - "name": "ý/x (Request/Response)", - "success": true - }, - { - "name": "x/ý (Blob/File)", - "success": true - }, - { - "name": "x/ý (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ý=x;bonus=x (Blob/File)", + "name": "text/html;;;;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;ý=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=ý;bonus=x (Blob/File)", + "name": "text/html;charset= \";charset=GBK", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ý\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ý;bonus=x (Request/Response)", + "name": "text/html;charset=\";charset=foo\";charset=GBK", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ý\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ý\";bonus=x (Blob/File)", + "name": "text/html;charset=\"gbk\"", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ý\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ý\";bonus=x (Request/Response)", + "name": "text/html;charset=\"gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ý\\\";bonus=x\" but got \"\"" - }, - { - "name": "þ/x (Blob/File)", - "success": true - }, - { - "name": "þ/x (Request/Response)", - "success": true - }, - { - "name": "x/þ (Blob/File)", - "success": true - }, - { - "name": "x/þ (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;þ=x;bonus=x (Blob/File)", + "name": "text/html;charset=gbk\"", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" - }, - { - "name": "x/x;þ=x;bonus=x (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;x=þ;bonus=x (Blob/File)", + "name": "text/html;charset=\" gbk\"", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"þ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=þ;bonus=x (Request/Response)", + "name": "text/html;charset=\"gbk \"", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"þ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"þ\";bonus=x (Blob/File)", + "name": "text/html;charset=\"\\ gbk\"", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"þ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"þ\";bonus=x (Request/Response)", + "name": "text/html;charset=\"\\g\\b\\k\"", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"þ\\\";bonus=x\" but got \"\"" - }, - { - "name": "ÿ/x (Blob/File)", - "success": true - }, - { - "name": "ÿ/x (Request/Response)", - "success": true - }, - { - "name": "x/ÿ (Blob/File)", - "success": true - }, - { - "name": "x/ÿ (Request/Response)", - "success": true + "message": "document is not defined" }, { - "name": "x/x;ÿ=x;bonus=x (Blob/File)", + "name": "text/html;charset=\"gbk\"x", "success": false, - "message": "assert_equals: Blob expected \"x/x;bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;ÿ=x;bonus=x (Request/Response)", - "success": true + "name": "text/html;charset=\"\";charset=GBK", + "success": false, + "message": "document is not defined" }, { - "name": "x/x;x=ÿ;bonus=x (Blob/File)", + "name": "text/html;charset=\";charset=GBK", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ÿ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=ÿ;bonus=x (Request/Response)", + "name": "text/html;charset={gbk}", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ÿ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ÿ\";bonus=x (Blob/File)", + "name": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk", "success": false, - "message": "assert_equals: Blob expected \"x/x;x=\\\"ÿ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" }, { - "name": "x/x;x=\"ÿ\";bonus=x (Request/Response)", + "name": "text/html;test=ÿ;charset=gbk", "success": false, - "message": "assert_equals: expected \"x/x;x=\\\"ÿ\\\";bonus=x\" but got \"\"" + "message": "document is not defined" } ] + }, + "parsing.any.html": { + "success": "flaky", + "cases": [] } }, "sniffing": { @@ -33082,8 +24804,7 @@ "cases": [ { "name": "Create WebSocket - Close the Connection - close(1000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed", - "success": false, - "message": "assert_true: WebSocket connection should be opened expected true got false" + "success": true } ] }, @@ -35193,8 +26914,7 @@ "cases": [ { "name": "Send binary data on a WebSocket - ArrayBufferView - Float16Array - Connection should be closed", - "success": false, - "message": "Float16Array is not defined" + "success": true } ] }, @@ -35213,8 +26933,7 @@ "cases": [ { "name": "Send binary data on a WebSocket - ArrayBufferView - Float16Array - Connection should be closed", - "success": false, - "message": "Float16Array is not defined" + "success": true } ] }, @@ -38918,7 +30637,7 @@ { "name": "backpressure should be applied to received messages", "success": false, - "message": "assert_greater_than_equal: data send should have taken at least 2 seconds expected a number greater than or equal to 1.8 but got 0.03000044822692871" + "message": "assert_greater_than_equal: data send should have taken at least 2 seconds expected a number greater than or equal to 1.8 but got 0.11555743217468262" } ] }, @@ -38937,8 +30656,7 @@ "cases": [ { "name": "backpressure should be applied to sent messages", - "success": false, - "message": "assert_greater_than_equal: expected a number greater than or equal to 1800 but got 25.788400000000024" + "success": true } ] }, diff --git a/types/dispatcher.d.ts b/types/dispatcher.d.ts index 13b33ececc8..d62aa8c70c4 100644 --- a/types/dispatcher.d.ts +++ b/types/dispatcher.d.ts @@ -215,6 +215,8 @@ declare namespace Dispatcher { get aborted () : boolean get paused () : boolean get reason () : Error | null + rawHeaders?: Buffer[] | string[] | null + rawTrailers?: Buffer[] | string[] | null abort (reason: Error): void pause(): void resume(): void @@ -228,30 +230,12 @@ declare namespace Dispatcher { onResponseEnd?(controller: DispatchController, trailers: IncomingHttpHeaders): void; onResponseError?(controller: DispatchController, error: Error): void; - /** Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails. */ - /** @deprecated */ - onConnect?(abort: (err?: Error) => void): void; - /** Invoked when an error has occurred. */ - /** @deprecated */ - onError?(err: Error): void; - /** Invoked when request is upgraded either due to a `Upgrade` header or `CONNECT` method. */ - /** @deprecated */ - onUpgrade?(statusCode: number, headers: Buffer[] | string[] | null, socket: Duplex): void; /** Invoked when response is received, before headers have been read. **/ - /** @deprecated */ onResponseStarted?(): void; - /** Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. */ - /** @deprecated */ - onHeaders?(statusCode: number, headers: Buffer[], resume: () => void, statusText: string): boolean; - /** Invoked when response payload data is received. */ - /** @deprecated */ - onData?(chunk: Buffer): boolean; - /** Invoked when response payload and trailers have been received and the request has completed. */ - /** @deprecated */ - onComplete?(trailers: string[] | null): void; /** Invoked when a body chunk is sent to the server. May be invoked multiple times for chunked requests */ - /** @deprecated */ - onBodySent?(chunkSize: number, totalBytesSent: number): void; + onBodySent?(chunk: Buffer): void; + /** Invoked after the request body is fully sent. */ + onRequestSent?(): void; } export type PipelineHandler = (data: PipelineHandlerData) => Readable export type HttpMethod = Autocomplete<'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH'> From 66b08b1c234529bdaa209e77e40fc20670cf75ec Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 14 Feb 2026 17:18:08 +0100 Subject: [PATCH 02/15] fix: isolate global dispatcher v2 and add Dispatcher1Wrapper bridge (#4827) --- README.md | 6 ++ docs/docs/api/Dispatcher.md | 15 +++ index.js | 2 + lib/dispatcher/dispatcher1-wrapper.js | 101 ++++++++++++++++++++ lib/global.js | 18 +++- test/node-test/global-dispatcher-version.js | 100 +++++++++++++++++++ types/dispatcher1-wrapper.d.ts | 7 ++ types/index.d.ts | 4 +- 8 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 lib/dispatcher/dispatcher1-wrapper.js create mode 100644 test/node-test/global-dispatcher-version.js create mode 100644 types/dispatcher1-wrapper.d.ts diff --git a/README.md b/README.md index 15dcad7a3d7..0257b36f02c 100644 --- a/README.md +++ b/README.md @@ -563,6 +563,12 @@ See [Dispatcher.upgrade](./docs/docs/api/Dispatcher.md#dispatcherupgradeoptions- Sets the global dispatcher used by Common API Methods. Global dispatcher is shared among compatible undici modules, including undici that is bundled internally with node.js. +Undici stores this dispatcher under `Symbol.for('undici.globalDispatcher.2')`. + +On Node.js 22, `setGlobalDispatcher()` also mirrors the configured dispatcher to +`Symbol.for('undici.globalDispatcher.1')` using `Dispatcher1Wrapper`, so Node.js built-in `fetch` +can keep using the legacy handler contract while Undici uses the new handler API. + ### `undici.getGlobalDispatcher()` Gets the global dispatcher used by Common API Methods. diff --git a/docs/docs/api/Dispatcher.md b/docs/docs/api/Dispatcher.md index dbb99599610..7761c0f8fef 100644 --- a/docs/docs/api/Dispatcher.md +++ b/docs/docs/api/Dispatcher.md @@ -232,6 +232,21 @@ Pause/resume now uses the controller: - Call `controller.pause()` and `controller.resume()` instead of returning `false` from handlers. +#### Compatibility notes + +Undici now stores the global dispatcher under `Symbol.for('undici.globalDispatcher.2')`. +This avoids conflicts with runtimes (such as Node.js built-in `fetch`) that still rely on the legacy dispatcher handler interface. + +On Node.js 22, `setGlobalDispatcher()` also mirrors the configured dispatcher to `Symbol.for('undici.globalDispatcher.1')` using a `Dispatcher1Wrapper`, so Node's built-in `fetch` can keep using the legacy handler contract. + +If you need to expose a new dispatcher/agent to legacy v1 handler consumers (`onConnect/onHeaders/onData/onComplete/onError/onUpgrade`), use `Dispatcher1Wrapper`: + +```js +import { Agent, Dispatcher1Wrapper } from 'undici' + +const legacyCompatibleDispatcher = new Dispatcher1Wrapper(new Agent()) +``` + #### Example 1 - Dispatch GET request ```js diff --git a/index.js b/index.js index 271c64e8ec3..7c44af34372 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ const Pool = require('./lib/dispatcher/pool') const BalancedPool = require('./lib/dispatcher/balanced-pool') const RoundRobinPool = require('./lib/dispatcher/round-robin-pool') const Agent = require('./lib/dispatcher/agent') +const Dispatcher1Wrapper = require('./lib/dispatcher/dispatcher1-wrapper') const ProxyAgent = require('./lib/dispatcher/proxy-agent') const EnvHttpProxyAgent = require('./lib/dispatcher/env-http-proxy-agent') const RetryAgent = require('./lib/dispatcher/retry-agent') @@ -34,6 +35,7 @@ module.exports.Pool = Pool module.exports.BalancedPool = BalancedPool module.exports.RoundRobinPool = RoundRobinPool module.exports.Agent = Agent +module.exports.Dispatcher1Wrapper = Dispatcher1Wrapper module.exports.ProxyAgent = ProxyAgent module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent module.exports.RetryAgent = RetryAgent diff --git a/lib/dispatcher/dispatcher1-wrapper.js b/lib/dispatcher/dispatcher1-wrapper.js new file mode 100644 index 00000000000..b5b69219dd4 --- /dev/null +++ b/lib/dispatcher/dispatcher1-wrapper.js @@ -0,0 +1,101 @@ +'use strict' + +const Dispatcher = require('./dispatcher') +const { InvalidArgumentError } = require('../core/errors') +const { toRawHeaders } = require('../core/util') + +class LegacyHandlerWrapper { + #handler + + constructor (handler) { + this.#handler = handler + } + + onRequestStart (controller, context) { + this.#handler.onConnect?.((reason) => controller.abort(reason), context) + } + + onRequestUpgrade (controller, statusCode, headers, socket) { + const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {}) + this.#handler.onUpgrade?.(statusCode, rawHeaders, socket) + } + + onResponseStart (controller, statusCode, headers, statusMessage) { + const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {}) + + if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) { + controller.pause() + } + } + + onResponseData (controller, chunk) { + if (this.#handler.onData?.(chunk) === false) { + controller.pause() + } + } + + onResponseEnd (controller, trailers) { + const rawTrailers = controller?.rawTrailers ?? toRawHeaders(trailers ?? {}) + this.#handler.onComplete?.(rawTrailers) + } + + onResponseError (_controller, err) { + if (!this.#handler.onError) { + throw err + } + + this.#handler.onError(err) + } + + onBodySent (chunk) { + this.#handler.onBodySent?.(chunk) + } + + onRequestSent () { + this.#handler.onRequestSent?.() + } + + onResponseStarted () { + this.#handler.onResponseStarted?.() + } +} + +class Dispatcher1Wrapper extends Dispatcher { + #dispatcher + + constructor (dispatcher) { + super() + + if (!dispatcher || typeof dispatcher.dispatch !== 'function') { + throw new InvalidArgumentError('Argument dispatcher must implement dispatch') + } + + this.#dispatcher = dispatcher + } + + static wrapHandler (handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onRequestStart === 'function') { + return handler + } + + return new LegacyHandlerWrapper(handler) + } + + dispatch (opts, handler) { + return this.#dispatcher.dispatch(opts, Dispatcher1Wrapper.wrapHandler(handler)) + } + + close (...args) { + return this.#dispatcher.close(...args) + } + + destroy (...args) { + return this.#dispatcher.destroy(...args) + } +} + +module.exports = Dispatcher1Wrapper diff --git a/lib/global.js b/lib/global.js index b61d779e498..f518dae3127 100644 --- a/lib/global.js +++ b/lib/global.js @@ -2,9 +2,13 @@ // We include a version number for the Dispatcher API. In case of breaking changes, // this version number must be increased to avoid conflicts. -const globalDispatcher = Symbol.for('undici.globalDispatcher.1') +const globalDispatcher = Symbol.for('undici.globalDispatcher.2') +const legacyGlobalDispatcher = Symbol.for('undici.globalDispatcher.1') const { InvalidArgumentError } = require('./core/errors') const Agent = require('./dispatcher/agent') +const Dispatcher1Wrapper = require('./dispatcher/dispatcher1-wrapper') + +const nodeMajor = Number(process.versions.node.split('.', 1)[0]) if (getGlobalDispatcher() === undefined) { setGlobalDispatcher(new Agent()) @@ -14,12 +18,24 @@ function setGlobalDispatcher (agent) { if (!agent || typeof agent.dispatch !== 'function') { throw new InvalidArgumentError('Argument agent must implement Agent') } + Object.defineProperty(globalThis, globalDispatcher, { value: agent, writable: true, enumerable: false, configurable: false }) + + if (nodeMajor === 22) { + const legacyAgent = agent instanceof Dispatcher1Wrapper ? agent : new Dispatcher1Wrapper(agent) + + Object.defineProperty(globalThis, legacyGlobalDispatcher, { + value: legacyAgent, + writable: true, + enumerable: false, + configurable: false + }) + } } function getGlobalDispatcher () { diff --git a/test/node-test/global-dispatcher-version.js b/test/node-test/global-dispatcher-version.js new file mode 100644 index 00000000000..ecd9d706804 --- /dev/null +++ b/test/node-test/global-dispatcher-version.js @@ -0,0 +1,100 @@ +'use strict' + +const assert = require('node:assert') +const { test } = require('node:test') +const { spawnSync } = require('node:child_process') +const { join } = require('node:path') + +const cwd = join(__dirname, '../..') + +function runNode (source) { + return spawnSync(process.execPath, ['-e', source], { + cwd, + encoding: 'utf8' + }) +} + +test('setGlobalDispatcher does not break Node.js global fetch', () => { + const script = ` + const { Agent, setGlobalDispatcher } = require('./index.js') + const http = require('node:http') + const { once } = require('node:events') + + ;(async () => { + const server = http.createServer((req, res) => res.end('ok')) + server.listen(0) + await once(server, 'listening') + + setGlobalDispatcher(new Agent()) + const url = 'http://127.0.0.1:' + server.address().port + const res = await fetch(url) + process.stdout.write(await res.text()) + + server.close() + })().catch((err) => { + console.error(err?.cause?.stack || err?.stack || err) + process.exit(1) + }) + ` + + const result = runNode(script) + assert.strictEqual(result.status, 0, result.stderr) + assert.strictEqual(result.stdout, 'ok') +}) + +test('setGlobalDispatcher mirrors a v1-compatible dispatcher on Node.js 22', () => { + const script = ` + const { Agent, Dispatcher1Wrapper, setGlobalDispatcher } = require('./index.js') + const nodeMajor = Number(process.versions.node.split('.', 1)[0]) + + setGlobalDispatcher(new Agent()) + + if (nodeMajor !== 22) { + process.stdout.write('skipped') + } else { + const dispatcherV1 = globalThis[Symbol.for('undici.globalDispatcher.1')] + + if (!(dispatcherV1 instanceof Dispatcher1Wrapper)) { + throw new Error('expected v1 global dispatcher to be a Dispatcher1Wrapper on Node.js 22') + } + + process.stdout.write('mirrored') + } + ` + + const result = runNode(script) + assert.strictEqual(result.status, 0, result.stderr) + + const expected = Number(process.versions.node.split('.', 1)[0]) === 22 ? 'mirrored' : 'skipped' + assert.strictEqual(result.stdout, expected) +}) + +test('Dispatcher1Wrapper bridges legacy handlers to a new Agent', () => { + const script = ` + const { Agent, Dispatcher1Wrapper } = require('./index.js') + const http = require('node:http') + const { once } = require('node:events') + + ;(async () => { + const server = http.createServer((req, res) => res.end('ok')) + server.listen(0) + await once(server, 'listening') + + const dispatcherV1 = Symbol.for('undici.globalDispatcher.1') + globalThis[dispatcherV1] = new Dispatcher1Wrapper(new Agent()) + + const url = 'http://127.0.0.1:' + server.address().port + const res = await fetch(url) + process.stdout.write(await res.text()) + + server.close() + })().catch((err) => { + console.error(err?.cause?.stack || err?.stack || err) + process.exit(1) + }) + ` + + const result = runNode(script) + assert.strictEqual(result.status, 0, result.stderr) + assert.strictEqual(result.stdout, 'ok') +}) diff --git a/types/dispatcher1-wrapper.d.ts b/types/dispatcher1-wrapper.d.ts new file mode 100644 index 00000000000..f8a7d5e0d63 --- /dev/null +++ b/types/dispatcher1-wrapper.d.ts @@ -0,0 +1,7 @@ +import Dispatcher from './dispatcher' + +export default Dispatcher1Wrapper + +declare class Dispatcher1Wrapper extends Dispatcher { + constructor (dispatcher: Dispatcher) +} diff --git a/types/index.d.ts b/types/index.d.ts index 78ddeaae7b1..c21f589472e 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -11,6 +11,7 @@ import H2CClient from './h2c-client' import buildConnector from './connector' import errors from './errors' import Agent from './agent' +import Dispatcher1Wrapper from './dispatcher1-wrapper' import MockClient from './mock-client' import MockPool from './mock-pool' import MockAgent from './mock-agent' @@ -43,7 +44,7 @@ export { Interceptable } from './mock-interceptor' declare function globalThisInstall (): void -export { Dispatcher, BalancedPool, RoundRobinPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, interceptors, cacheStores, MockClient, MockPool, MockAgent, SnapshotAgent, MockCallHistory, MockCallHistoryLog, mockErrors, ProxyAgent, EnvHttpProxyAgent, RedirectHandler, DecoratorHandler, RetryHandler, RetryAgent, H2CClient, globalThisInstall as install } +export { Dispatcher, BalancedPool, RoundRobinPool, Pool, Client, buildConnector, errors, Agent, Dispatcher1Wrapper, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, interceptors, cacheStores, MockClient, MockPool, MockAgent, SnapshotAgent, MockCallHistory, MockCallHistoryLog, mockErrors, ProxyAgent, EnvHttpProxyAgent, RedirectHandler, DecoratorHandler, RetryHandler, RetryAgent, H2CClient, globalThisInstall as install } export default Undici declare namespace Undici { @@ -59,6 +60,7 @@ declare namespace Undici { const buildConnector: typeof import('./connector').default const errors: typeof import('./errors').default const Agent: typeof import('./agent').default + const Dispatcher1Wrapper: typeof import('./dispatcher1-wrapper').default const setGlobalDispatcher: typeof import('./global-dispatcher').setGlobalDispatcher const getGlobalDispatcher: typeof import('./global-dispatcher').getGlobalDispatcher const request: typeof import('./api').request From 01e771a183f0df0820b87e198eb7112dfdf9e8db Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 19 Feb 2026 23:13:25 +0100 Subject: [PATCH 03/15] fix: preserve request statusText and update h2 dispatch tests (#4830) --- .github/workflows/ci.yml | 2 ++ lib/api/api-request.js | 3 ++- test/http2-dispatcher.js | 48 +++++++++++++--------------------------- 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8109c204e2b..83b53846a3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -269,6 +269,8 @@ jobs: fail-fast: false max-parallel: 0 matrix: + # Node.js 22 is intentionally excluded here: --shared-builtin-undici/undici-path + # embedding is only validated for supported/current majors. node-version: ['24', '25'] runs-on: ['ubuntu-latest'] with: diff --git a/lib/api/api-request.js b/lib/api/api-request.js index b75a6dcae0e..dc944640332 100644 --- a/lib/api/api-request.js +++ b/lib/api/api-request.js @@ -87,7 +87,7 @@ class RequestHandler extends AsyncResource { this.context = context } - onResponseStart (controller, statusCode, headers, _statusMessage) { + onResponseStart (controller, statusCode, headers, statusText) { const { callback, opaque, context, responseHeaders, highWaterMark } = this const rawHeaders = controller?.rawHeaders @@ -126,6 +126,7 @@ class RequestHandler extends AsyncResource { try { this.runInAsyncScope(callback, null, null, { statusCode, + statusText, headers: responseHeaderData, trailers: this.trailers, opaque, diff --git a/test/http2-dispatcher.js b/test/http2-dispatcher.js index 0c85fc2afab..bef6c623e55 100644 --- a/test/http2-dispatcher.js +++ b/test/http2-dispatcher.js @@ -511,19 +511,13 @@ test('Should send http2 PING frames', async t => { method: 'PUT', body: 'hello' }, { - onConnect () { - - }, - onHeaders () { - return true - }, - onData () { - return true - }, - onComplete (trailers) { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd (_controller, trailers) { t.strictEqual(trailers['x-trailer'], 'hello') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } }) @@ -588,19 +582,13 @@ test('Should not send http2 PING frames if interval === 0', async t => { method: 'PUT', body: 'hello' }, { - onConnect () { - - }, - onHeaders () { - return true - }, - onData () { - return true - }, - onComplete (trailers) { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd (_controller, trailers) { t.strictEqual(trailers['x-trailer'], 'hello') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } }) @@ -666,19 +654,13 @@ test('Should not send http2 PING frames after connection is closed', async t => method: 'PUT', body: 'hello' }, { - onConnect () { - - }, - onHeaders () { - return true - }, - onData () { - return true - }, - onComplete (trailers) { + onRequestStart () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd (_controller, trailers) { t.strictEqual(trailers['x-trailer'], 'hello') }, - onError (err) { + onResponseError (_controller, err) { t.ifError(err) } }) From 19187313335e4054897fb54e59055c07533e1ab4 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 6 Mar 2026 16:38:08 +0100 Subject: [PATCH 04/15] feat!: enable h2 by default (#4828) (cherry picked from commit 09862a2d6c3fe2e0160748548a0d4698b9045f40) --- docs/docs/api/Client.md | 2 +- lib/core/connect.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/api/Client.md b/docs/docs/api/Client.md index 515d81964af..d2268e3b39f 100644 --- a/docs/docs/api/Client.md +++ b/docs/docs/api/Client.md @@ -29,7 +29,7 @@ Returns: `Client` * **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body. **Security Warning:** Disabling this option can expose your application to HTTP Request Smuggling attacks, where mismatched content-length headers cause servers and proxies to interpret request boundaries differently. This can lead to cache poisoning, credential hijacking, and bypassing security controls. Only disable this in controlled environments where you fully trust the request source. * **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version. * **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. -* **allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation. +* **allowH2**: `boolean` - Default: `true`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation. * **useH2c**: `boolean` - Default: `false`. Enforces h2c for non-https connections. * **maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame. * **initialWindowSize**: `number` (optional) - Default: `262144` (256KB). Sets the HTTP/2 stream-level flow-control window size (SETTINGS_INITIAL_WINDOW_SIZE). Must be a positive integer greater than 0. This default is higher than Node.js core's default (65535 bytes) to improve throughput, Node's choice is very conservative for current high-bandwith networks. See [RFC 7540 Section 6.9.2](https://datatracker.ietf.org/doc/html/rfc7540#section-6.9.2) for more details. diff --git a/lib/core/connect.js b/lib/core/connect.js index a49af91486e..605cb9fdd9b 100644 --- a/lib/core/connect.js +++ b/lib/core/connect.js @@ -51,7 +51,7 @@ function buildConnector ({ allowH2, useH2c, maxCachedSessions, socketPath, timeo const options = { path: socketPath, ...opts } const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) timeout = timeout == null ? 10e3 : timeout - allowH2 = allowH2 != null ? allowH2 : false + allowH2 = allowH2 != null ? allowH2 : true return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { let socket if (protocol === 'https:') { From 2d2c95a8c48a42c9047c17b483a9b190e3ea86a7 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 20 Mar 2026 18:27:41 +0000 Subject: [PATCH 05/15] test: stabilize WPT runner expectation updates --- test/web-platform-tests/expectation.json | 10741 ++++++++++++++-- .../web-platform-tests/runner/test-runner.mjs | 32 +- test/web-platform-tests/wpt-runner.mjs | 158 +- 3 files changed, 9872 insertions(+), 1059 deletions(-) diff --git a/test/web-platform-tests/expectation.json b/test/web-platform-tests/expectation.json index 83b2c3963e2..7bdaf787273 100644 --- a/test/web-platform-tests/expectation.json +++ b/test/web-platform-tests/expectation.json @@ -639,7 +639,7 @@ "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" }, { - "name": "Fetch http://web-platform.test:33109/fetch/api/resources/top.txt with no-cors mode", + "name": "Fetch http://web-platform.test:50771/fetch/api/resources/top.txt with no-cors mode", "success": false, "message": "assert_equals: Opaque filter: status is 0 expected 0 but got 200" } @@ -1297,14 +1297,14 @@ "success": true, "cases": [ { - "name": "Access-Control-Request-Private-Network is a forbidden request header", + "name": "Adding invalid request header \"Access-Control-Request-Private-Network: KO\"", "success": false, - "message": "assert_not_equals: Access-Control-Request-Private-Network does not have the value we defined got disallowed value \"\"" + "message": "assert_equals: expected (object) null but got (string) \"KO\"" }, { - "name": "Adding invalid request header \"Access-Control-Request-Private-Network: KO\"", + "name": "Access-Control-Request-Private-Network is a forbidden request header", "success": false, - "message": "assert_equals: expected (object) null but got (string) \"KO\"" + "message": "assert_not_equals: Access-Control-Request-Private-Network does not have the value we defined got disallowed value \"\"" } ] }, @@ -2407,11 +2407,11 @@ "success": true }, { - "name": "Testing empty Request Content-Type header", + "name": "Test that Request.headers has the [SameObject] extended attribute", "success": true }, { - "name": "Test that Request.headers has the [SameObject] extended attribute", + "name": "Testing empty Request Content-Type header", "success": true } ] @@ -3647,6 +3647,10 @@ "name": "Check creating a new request from a disturbed request", "success": true }, + { + "name": "Request construction failure should not set \"bodyUsed\"", + "success": true + }, { "name": "Check creating a new request with a new body from a disturbed request", "success": true @@ -3663,10 +3667,6 @@ { "name": "Check consuming a disturbed request", "success": true - }, - { - "name": "Request construction failure should not set \"bodyUsed\"", - "success": true } ] }, @@ -4062,10 +4062,6 @@ "name": "Default Content-Type for Request with buffer source body", "success": true }, - { - "name": "Default Content-Type for Request with FormData body", - "success": true - }, { "name": "Default Content-Type for Request with URLSearchParams body", "success": true @@ -4113,6 +4109,10 @@ { "name": "Can override Content-Type for Request with ReadableStream body", "success": true + }, + { + "name": "Default Content-Type for Request with FormData body", + "success": true } ] }, @@ -4168,10 +4168,6 @@ "name": "Constructing a Request with a stream on which read() is called", "success": true }, - { - "name": "Constructing a Request with a stream on which read() and releaseLock() are called", - "success": true - }, { "name": "Constructing a Request with a Request on which body.getReader() is called", "success": true @@ -4180,10 +4176,6 @@ "name": "Constructing a Request with a Request on which body.getReader().read() is called", "success": true }, - { - "name": "Constructing a Request with a Request on which read() and releaseLock() are called", - "success": true - }, { "name": "It is OK to omit .duplex when the body is null.", "success": true @@ -4247,6 +4239,14 @@ { "name": "It is OK to omit duplex when init.body is not given and input.body is given.", "success": true + }, + { + "name": "Constructing a Request with a stream on which read() and releaseLock() are called", + "success": true + }, + { + "name": "Constructing a Request with a Request on which read() and releaseLock() are called", + "success": true } ] }, @@ -4720,6 +4720,14 @@ "response-consume-stream.any.html": { "success": true, "cases": [ + { + "name": "Getting an error Response stream", + "success": true + }, + { + "name": "Getting a redirect Response stream", + "success": true + }, { "name": "Read empty text response's body as readableStream", "success": true @@ -4768,14 +4776,6 @@ "name": "Read form data response's body as readableStream with mode=byob", "success": true }, - { - "name": "Getting an error Response stream", - "success": true - }, - { - "name": "Getting a redirect Response stream", - "success": true - }, { "name": "Reading with offset from Response stream", "success": true @@ -4866,7 +4866,7 @@ { "name": "Consume response's body: from FormData to blob", "success": false, - "message": "assert_equals: Blob body type should be computed from the response Content-Type expected \"multipart/form-data; boundary=----formdata-undici-071939983636\" but got \"multipart/form-data;boundary=----formdata-undici-071939983636\"" + "message": "assert_equals: Blob body type should be computed from the response Content-Type expected \"multipart/form-data; boundary=----formdata-undici-063336922666\" but got \"multipart/form-data;boundary=----formdata-undici-063336922666\"" }, { "name": "Consume response's body: from FormData to text", @@ -5134,6 +5134,10 @@ "name": "Initialize Response with headers values", "success": true }, + { + "name": "Testing null Response body", + "success": true + }, { "name": "Initialize Response's body with application/octet-binary", "success": true @@ -5157,10 +5161,6 @@ { "name": "Testing empty Response Content-Type header", "success": true - }, - { - "name": "Testing null Response body", - "success": true } ] }, @@ -5187,10 +5187,6 @@ "name": "Default Content-Type for Response with buffer source body", "success": true }, - { - "name": "Default Content-Type for Response with FormData body", - "success": true - }, { "name": "Default Content-Type for Response with URLSearchParams body", "success": true @@ -5238,6 +5234,10 @@ { "name": "Can override Content-Type for Response with ReadableStream body", "success": true + }, + { + "name": "Default Content-Type for Response with FormData body", + "success": true } ] }, @@ -5258,51 +5258,51 @@ "success": true, "cases": [ { - "name": "Check response returned by static json() with init undefined", + "name": "Throws TypeError when calling static json() with a status of 204", "success": true }, { - "name": "Check response returned by static json() with init {\"status\":400}", + "name": "Throws TypeError when calling static json() with a status of 205", "success": true }, { - "name": "Check response returned by static json() with init {\"statusText\":\"foo\"}", + "name": "Throws TypeError when calling static json() with a status of 304", "success": true }, { - "name": "Check response returned by static json() with init {\"headers\":{}}", + "name": "Check static json() throws when data is not encodable", "success": true }, { - "name": "Check response returned by static json() with init {\"headers\":{\"content-type\":\"foo/bar\"}}", + "name": "Check static json() throws when data is circular", "success": true }, { - "name": "Check response returned by static json() with init {\"headers\":{\"x-foo\":\"bar\"}}", + "name": "Check response returned by static json() with init undefined", "success": true }, { - "name": "Throws TypeError when calling static json() with a status of 204", + "name": "Check response returned by static json() with init {\"status\":400}", "success": true }, { - "name": "Throws TypeError when calling static json() with a status of 205", + "name": "Check response returned by static json() with init {\"statusText\":\"foo\"}", "success": true }, { - "name": "Throws TypeError when calling static json() with a status of 304", + "name": "Check response returned by static json() with init {\"headers\":{}}", "success": true }, { - "name": "Check static json() encodes JSON objects correctly", + "name": "Check response returned by static json() with init {\"headers\":{\"content-type\":\"foo/bar\"}}", "success": true }, { - "name": "Check static json() throws when data is not encodable", + "name": "Check response returned by static json() with init {\"headers\":{\"x-foo\":\"bar\"}}", "success": true }, { - "name": "Check static json() throws when data is circular", + "name": "Check static json() encodes JSON objects correctly", "success": true }, { @@ -5314,11 +5314,11 @@ "success": true }, { - "name": "Check response returned by static json() with input U+df06U+d834", + "name": "Check response returned by static json() with input \udf06\ud834", "success": true }, { - "name": "Check response returned by static json() with input U+dead", + "name": "Check response returned by static json() with input \udead", "success": true } ] @@ -6094,10 +6094,6 @@ "headers-no-cors.any.html": { "success": true, "cases": [ - { - "name": "Loading data…", - "success": true - }, { "name": "\"no-cors\" Headers object cannot have accept set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss", "success": false, @@ -6227,6 +6223,10 @@ "name": "\"no-cors\" Headers object cannot have unknown/doesitmatter as header", "success": false, "message": "assert_false: expected false got true" + }, + { + "name": "Loading data…", + "success": true } ] }, @@ -6346,6 +6346,18 @@ "general.any.html": { "success": true, "cases": [ + { + "name": "Request objects have a signal property", + "success": true + }, + { + "name": "Signal state is cloned", + "success": true + }, + { + "name": "Clone aborts with original controller", + "success": true + }, { "name": "Aborting rejects with AbortError", "success": true @@ -6422,10 +6434,6 @@ "name": "TypeError from request constructor takes priority - Bad redirect init parameter value", "success": true }, - { - "name": "Request objects have a signal property", - "success": true - }, { "name": "Signal on request object", "success": true @@ -6557,14 +6565,6 @@ { "name": "Readable stream synchronously cancels with AbortError if aborted before reading", "success": true - }, - { - "name": "Signal state is cloned", - "success": true - }, - { - "name": "Clone aborts with original controller", - "success": true } ] }, @@ -8786,10 +8786,6 @@ "idlharness.any.html": { "success": true, "cases": [ - { - "name": "idl_test setup", - "success": true - }, { "name": "idl_test validation", "success": true @@ -8978,106 +8974,10 @@ "name": "Request interface: existence and properties of interface prototype object's @@unscopables property", "success": true }, - { - "name": "Request interface: attribute method", - "success": true - }, - { - "name": "Request interface: attribute url", - "success": true - }, - { - "name": "Request interface: attribute headers", - "success": true - }, - { - "name": "Request interface: attribute destination", - "success": true - }, - { - "name": "Request interface: attribute referrer", - "success": true - }, - { - "name": "Request interface: attribute referrerPolicy", - "success": true - }, - { - "name": "Request interface: attribute mode", - "success": true - }, - { - "name": "Request interface: attribute credentials", - "success": true - }, - { - "name": "Request interface: attribute cache", - "success": true - }, - { - "name": "Request interface: attribute redirect", - "success": true - }, - { - "name": "Request interface: attribute integrity", - "success": true - }, - { - "name": "Request interface: attribute keepalive", - "success": true - }, - { - "name": "Request interface: attribute isReloadNavigation", - "success": true - }, - { - "name": "Request interface: attribute isHistoryNavigation", - "success": true - }, - { - "name": "Request interface: attribute signal", - "success": true - }, - { - "name": "Request interface: attribute duplex", - "success": true - }, { "name": "Request interface: operation clone()", "success": true }, - { - "name": "Request interface: attribute body", - "success": true - }, - { - "name": "Request interface: attribute bodyUsed", - "success": true - }, - { - "name": "Request interface: operation arrayBuffer()", - "success": true - }, - { - "name": "Request interface: operation blob()", - "success": true - }, - { - "name": "Request interface: operation bytes()", - "success": true - }, - { - "name": "Request interface: operation formData()", - "success": true - }, - { - "name": "Request interface: operation json()", - "success": true - }, - { - "name": "Request interface: operation text()", - "success": true - }, { "name": "Request must be primary interface of new Request('about:blank')", "success": true @@ -9222,70 +9122,10 @@ "name": "Response interface: operation json(any, optional ResponseInit)", "success": true }, - { - "name": "Response interface: attribute type", - "success": true - }, - { - "name": "Response interface: attribute url", - "success": true - }, - { - "name": "Response interface: attribute redirected", - "success": true - }, - { - "name": "Response interface: attribute status", - "success": true - }, - { - "name": "Response interface: attribute ok", - "success": true - }, - { - "name": "Response interface: attribute statusText", - "success": true - }, - { - "name": "Response interface: attribute headers", - "success": true - }, { "name": "Response interface: operation clone()", "success": true }, - { - "name": "Response interface: attribute body", - "success": true - }, - { - "name": "Response interface: attribute bodyUsed", - "success": true - }, - { - "name": "Response interface: operation arrayBuffer()", - "success": true - }, - { - "name": "Response interface: operation blob()", - "success": true - }, - { - "name": "Response interface: operation bytes()", - "success": true - }, - { - "name": "Response interface: operation formData()", - "success": true - }, - { - "name": "Response interface: operation json()", - "success": true - }, - { - "name": "Response interface: operation text()", - "success": true - }, { "name": "Response must be primary interface of new Response()", "success": true @@ -9418,11 +9258,6 @@ "success": false, "message": "assert_own_property: global object missing non-static operation expected property \"fetchLater\" missing" }, - { - "name": "Window interface: operation fetch(RequestInfo, optional RequestInit)", - "success": false, - "message": "assert_unreached: Should have rejected: calling operation with this = {} didn't throw TypeError Reached unreachable code" - }, { "name": "Window interface: window must inherit property \"fetchLater(RequestInfo, optional DeferredRequestInit)\" with the proper type", "success": false, @@ -9437,10 +9272,175 @@ "name": "Window interface: window must inherit property \"fetch(RequestInfo, optional RequestInit)\" with the proper type", "success": true }, + { + "name": "Request interface: attribute method", + "success": true + }, + { + "name": "Request interface: attribute url", + "success": true + }, + { + "name": "Request interface: attribute headers", + "success": true + }, + { + "name": "Request interface: attribute destination", + "success": true + }, + { + "name": "Request interface: attribute referrer", + "success": true + }, + { + "name": "Request interface: attribute referrerPolicy", + "success": true + }, + { + "name": "Request interface: attribute mode", + "success": true + }, + { + "name": "Request interface: attribute credentials", + "success": true + }, + { + "name": "Request interface: attribute cache", + "success": true + }, + { + "name": "Request interface: attribute redirect", + "success": true + }, + { + "name": "Request interface: attribute integrity", + "success": true + }, + { + "name": "Request interface: attribute keepalive", + "success": true + }, + { + "name": "Request interface: attribute isReloadNavigation", + "success": true + }, + { + "name": "Request interface: attribute isHistoryNavigation", + "success": true + }, + { + "name": "Request interface: attribute signal", + "success": true + }, + { + "name": "Request interface: attribute duplex", + "success": true + }, + { + "name": "Request interface: attribute body", + "success": true + }, + { + "name": "Request interface: attribute bodyUsed", + "success": true + }, + { + "name": "Response interface: attribute type", + "success": true + }, + { + "name": "Response interface: attribute url", + "success": true + }, + { + "name": "Response interface: attribute redirected", + "success": true + }, + { + "name": "Response interface: attribute status", + "success": true + }, + { + "name": "Response interface: attribute ok", + "success": true + }, + { + "name": "Response interface: attribute statusText", + "success": true + }, + { + "name": "Response interface: attribute headers", + "success": true + }, + { + "name": "Response interface: attribute body", + "success": true + }, + { + "name": "Response interface: attribute bodyUsed", + "success": true + }, + { + "name": "idl_test setup", + "success": true + }, + { + "name": "Request interface: operation arrayBuffer()", + "success": true + }, + { + "name": "Request interface: operation blob()", + "success": true + }, + { + "name": "Request interface: operation bytes()", + "success": true + }, + { + "name": "Request interface: operation formData()", + "success": true + }, + { + "name": "Request interface: operation json()", + "success": true + }, + { + "name": "Request interface: operation text()", + "success": true + }, + { + "name": "Response interface: operation arrayBuffer()", + "success": true + }, + { + "name": "Response interface: operation blob()", + "success": true + }, + { + "name": "Response interface: operation bytes()", + "success": true + }, + { + "name": "Response interface: operation formData()", + "success": true + }, + { + "name": "Response interface: operation json()", + "success": true + }, + { + "name": "Response interface: operation text()", + "success": true + }, { "name": "Window interface: calling fetch(RequestInfo, optional RequestInit) on window with too few arguments must throw TypeError", "success": false, "message": "assert_unreached: Should have rejected: Called with 0 arguments Reached unreachable code" + }, + { + "name": "Window interface: operation fetch(RequestInfo, optional RequestInit)", + "success": false, + "message": "assert_unreached: Should have rejected: calling operation with this = {} didn't throw TypeError Reached unreachable code" } ] }, @@ -11638,14 +11638,14 @@ "success": true, "cases": [ { - "name": "fetch() and duplicate Content-Length/Content-Type headers", + "name": "XMLHttpRequest and duplicate Content-Length/Content-Type headers", "success": false, - "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" + "message": "XMLHttpRequest is not defined" }, { - "name": "XMLHttpRequest and duplicate Content-Length/Content-Type headers", + "name": "fetch() and duplicate Content-Length/Content-Type headers", "success": false, - "message": "XMLHttpRequest is not defined" + "message": "promise_test: Unhandled rejection with value: object \"TypeError: fetch failed\"" } ] }, @@ -11851,10 +11851,6 @@ "response.window.html": { "success": true, "cases": [ - { - "name": "Loading JSON…", - "success": true - }, { "name": "