diff --git a/lib/web/fetch/index.js b/lib/web/fetch/index.js index 5fbef495ad6..784e0c2cdbb 100644 --- a/lib/web/fetch/index.js +++ b/lib/web/fetch/index.js @@ -444,8 +444,7 @@ function fetching ({ // 9. If request’s origin is "client", then set request’s origin to request’s // client’s origin. if (request.origin === 'client') { - // TODO: What if request.client is null? - request.origin = request.client?.origin + request.origin = request.client.origin } // 10. If all of the following conditions are true: diff --git a/lib/web/fetch/util.js b/lib/web/fetch/util.js index 299f4e64c81..e533ac957ca 100644 --- a/lib/web/fetch/util.js +++ b/lib/web/fetch/util.js @@ -255,16 +255,23 @@ function appendFetchMetadata (httpRequest) { // https://fetch.spec.whatwg.org/#append-a-request-origin-header function appendRequestOriginHeader (request) { - // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. + // 1. Let serializedOrigin be the result of byte-serializing a request origin + // with request. + // TODO: implement "byte-serializing a request origin" let serializedOrigin = request.origin - // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. - if (request.responseTainting === 'cors' || request.mode === 'websocket') { - if (serializedOrigin) { - request.headersList.append('origin', serializedOrigin, true) - } + // "'client' is changed to an origin during fetching." + // This doesn't happen in undici (in most cases) because undici, by default, + // has no concept of origin. + if (serializedOrigin === 'client') { + return + } + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", + // then append (`Origin`, serializedOrigin) to request’s header list. // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + if (request.responseTainting === 'cors' || request.mode === 'websocket') { + request.headersList.append('origin', serializedOrigin, true) } else if (request.method !== 'GET' && request.method !== 'HEAD') { // 1. Switch on request’s referrer policy: switch (request.referrerPolicy) { @@ -275,13 +282,16 @@ function appendRequestOriginHeader (request) { case 'no-referrer-when-downgrade': case 'strict-origin': case 'strict-origin-when-cross-origin': - // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. + // If request’s origin is a tuple origin, its scheme is "https", and + // request’s current URL’s scheme is not "https", then set + // serializedOrigin to `null`. if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { serializedOrigin = null } break case 'same-origin': - // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. + // If request’s origin is not same origin with request’s current URL’s + // origin, then set serializedOrigin to `null`. if (!sameOrigin(request, requestCurrentURL(request))) { serializedOrigin = null } @@ -290,10 +300,8 @@ function appendRequestOriginHeader (request) { // Do nothing. } - if (serializedOrigin) { - // 2. Append (`Origin`, serializedOrigin) to request’s header list. - request.headersList.append('origin', serializedOrigin, true) - } + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin, true) } } diff --git a/lib/web/websocket/connection.js b/lib/web/websocket/connection.js index a434e45ac82..5058fc58095 100644 --- a/lib/web/websocket/connection.js +++ b/lib/web/websocket/connection.js @@ -35,7 +35,7 @@ try { * @param {(response: any) => void} onEstablish * @param {Partial} options */ -function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { +function establishWebSocketConnection (url, protocols, client, ws, onEstablish, options) { // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s // scheme is "ws", and to "https" otherwise. const requestURL = url @@ -48,6 +48,7 @@ function establishWebSocketConnection (url, protocols, ws, onEstablish, options) // and redirect mode is "error". const request = makeRequest({ urlList: [requestURL], + client, serviceWorkers: 'none', referrer: 'no-referrer', mode: 'websocket', diff --git a/lib/web/websocket/websocket.js b/lib/web/websocket/websocket.js index 892ce78c2db..97e86c3801e 100644 --- a/lib/web/websocket/websocket.js +++ b/lib/web/websocket/websocket.js @@ -124,6 +124,7 @@ class WebSocket extends EventTarget { this[kWebSocketURL] = new URL(urlRecord.href) // 11. Let client be this's relevant settings object. + const client = environmentSettingsObject.settingsObject // 12. Run this step in parallel: @@ -132,6 +133,7 @@ class WebSocket extends EventTarget { this[kController] = establishWebSocketConnection( urlRecord, protocols, + client, this, (response) => this.#onConnectionEstablished(response), options diff --git a/test/fetch/issue-rsshub-15532.js b/test/fetch/issue-rsshub-15532.js new file mode 100644 index 00000000000..11491337de5 --- /dev/null +++ b/test/fetch/issue-rsshub-15532.js @@ -0,0 +1,25 @@ +'use strict' + +const { once } = require('node:events') +const { createServer } = require('node:http') +const { test } = require('node:test') +const { fetch } = require('../..') +const { tspl } = require('@matteo.collina/tspl') + +// https://github.com/DIYgod/RSSHub/issues/15532 +test('An invalid Origin header is not set', async (t) => { + const { deepStrictEqual } = tspl(t, { plan: 1 }) + + const server = createServer((req, res) => { + deepStrictEqual(req.headers.origin, undefined) + + res.end() + }).listen(0) + + await once(server, 'listening') + t.after(server.close.bind(server)) + + await fetch(`http://localhost:${server.address().port}`, { + method: 'POST' + }) +})