@@ -3,8 +3,12 @@ declare const self: ServiceWorkerGlobalScope;
3
3
4
4
import { awaitReply , getNextRequestId } from './messaging' ;
5
5
import { getURLScope , isURLScoped , setURLScope } from '@php-wasm/scopes' ;
6
+ import { HttpCookieStore } from '@php-wasm/universal' ;
6
7
7
- export async function convertFetchEventToPHPRequest ( event : FetchEvent ) {
8
+ export async function convertFetchEventToPHPRequest (
9
+ event : FetchEvent ,
10
+ cookieStore : HttpCookieStore
11
+ ) {
8
12
let url = new URL ( event . request . url ) ;
9
13
10
14
if ( ! isURLScoped ( url ) ) {
@@ -22,8 +26,28 @@ export async function convertFetchEventToPHPRequest(event: FetchEvent) {
22
26
? new Uint8Array ( await event . request . clone ( ) . arrayBuffer ( ) )
23
27
: undefined ;
24
28
const requestHeaders : Record < string , string > = { } ;
29
+
30
+ let providedCookies = '' ;
31
+ // @TODO : Why don't our types properly include Headers#entries()?
25
32
for ( const pair of ( event . request . headers as any ) . entries ( ) ) {
26
- requestHeaders [ pair [ 0 ] ] = pair [ 1 ] ;
33
+ const [ name , value ] = pair as [ string , string ] ;
34
+ if ( name . toLowerCase ( ) === 'cookie' ) {
35
+ providedCookies = value ;
36
+ } else {
37
+ requestHeaders [ name ] = value ;
38
+ }
39
+ }
40
+
41
+ const credentialsAllowed =
42
+ event . request . credentials === 'include' ||
43
+ event . request . credentials === 'same-origin' ;
44
+ if ( credentialsAllowed ) {
45
+ const storedCookies = cookieStore . getCookieRequestHeader ( ) ;
46
+ const effectiveCookies = [ storedCookies ] ;
47
+ if ( providedCookies ) {
48
+ effectiveCookies . push ( providedCookies ) ;
49
+ }
50
+ requestHeaders [ 'Cookie' ] = effectiveCookies . join ( '; ' ) ;
27
51
}
28
52
29
53
let phpResponse ;
@@ -63,6 +87,23 @@ export async function convertFetchEventToPHPRequest(event: FetchEvent) {
63
87
throw e ;
64
88
}
65
89
90
+ /**
91
+ * We should not consider Set-Cookie headers unless credentials are allowed.
92
+ * From https://fetch.spec.whatwg.org/#concept-request-credentials-mode :
93
+ * > "omit"
94
+ * > Excludes credentials from this request, and causes any credentials
95
+ * > sent back in the response to be ignored.
96
+ */
97
+ if ( credentialsAllowed ) {
98
+ // @TODO : Make way to relay non-HttpOnly cookies from PHP to the client.
99
+ // Those would be available to client JS in a classic WP setup.
100
+ cookieStore . rememberCookiesFromResponseHeaders ( phpResponse . headers ) ;
101
+ }
102
+ // Explicitly remove the Set-Cookie header because:
103
+ // - The browser is forbidden from relaying it via custom Response objects.
104
+ // - We can be sure it is not relayed by removing it ourselves.
105
+ delete phpResponse . headers [ 'set-cookie' ] ;
106
+
66
107
/**
67
108
* Safari has a bug that prevents Service Workers from redirecting relative URLs.
68
109
* When attempting to redirect to a relative URL, the network request will return an error.
0 commit comments