1
1
<?php
2
2
3
- namespace Rcalicdan \FiberAsync \Http \Testing \Services ;
3
+ namespace Rcalicdan \FiberAsync \Http \Testing \Utilities ;
4
4
5
5
use Rcalicdan \FiberAsync \Http \Cookie ;
6
6
use Rcalicdan \FiberAsync \Http \CookieJar ;
@@ -162,16 +162,16 @@ public function mockSetCookies(MockedRequest $mock, array $cookies): void
162
162
if (is_string ($ config )) {
163
163
$ mock ->addResponseHeader ('Set-Cookie ' , "{$ name }= {$ config }; Path=/ " );
164
164
} elseif (is_array ($ config )) {
165
- $ setCookieValue = $ name. '= ' . ($ config ['value ' ] ?? '' );
165
+ $ setCookieValue = $ name . '= ' . ($ config ['value ' ] ?? '' );
166
166
167
167
if (isset ($ config ['path ' ])) {
168
- $ setCookieValue .= '; Path= ' . $ config ['path ' ];
168
+ $ setCookieValue .= '; Path= ' . $ config ['path ' ];
169
169
}
170
170
if (isset ($ config ['domain ' ])) {
171
- $ setCookieValue .= '; Domain= ' . $ config ['domain ' ];
171
+ $ setCookieValue .= '; Domain= ' . $ config ['domain ' ];
172
172
}
173
173
if (isset ($ config ['expires ' ])) {
174
- $ setCookieValue .= '; Expires= ' . gmdate ('D, d M Y H:i:s T ' , $ config ['expires ' ]);
174
+ $ setCookieValue .= '; Expires= ' . gmdate ('D, d M Y H:i:s T ' , $ config ['expires ' ]);
175
175
}
176
176
if ($ config ['secure ' ] ?? false ) {
177
177
$ setCookieValue .= '; Secure ' ;
@@ -180,7 +180,7 @@ public function mockSetCookies(MockedRequest $mock, array $cookies): void
180
180
$ setCookieValue .= '; HttpOnly ' ;
181
181
}
182
182
if (isset ($ config ['sameSite ' ])) {
183
- $ setCookieValue .= '; SameSite= ' . $ config ['sameSite ' ];
183
+ $ setCookieValue .= '; SameSite= ' . $ config ['sameSite ' ];
184
184
}
185
185
186
186
$ mock ->addResponseHeader ('Set-Cookie ' , $ setCookieValue );
@@ -260,7 +260,7 @@ public function assertCookieSent(string $name, array $curlOptions): void
260
260
}
261
261
262
262
if (! isset ($ cookies [$ name ])) {
263
- throw new MockAssertionException ("Cookie ' {$ name }' was not sent in request. Sent cookies: " . implode (', ' , array_keys ($ cookies )));
263
+ throw new MockAssertionException ("Cookie ' {$ name }' was not sent in request. Sent cookies: " . implode (', ' , array_keys ($ cookies )));
264
264
}
265
265
}
266
266
@@ -311,15 +311,15 @@ public function applyCookiesToCurlOptions(array &$curlOptions, string $url, stri
311
311
$ cookieHeaderExists = false ;
312
312
foreach ($ curlOptions [CURLOPT_HTTPHEADER ] as &$ header ) {
313
313
if (str_starts_with (strtolower ($ header ), 'cookie: ' )) {
314
- $ header .= '; ' . $ cookieHeader ;
314
+ $ header .= '; ' . $ cookieHeader ;
315
315
$ cookieHeaderExists = true ;
316
316
317
317
break ;
318
318
}
319
319
}
320
320
321
321
if (! $ cookieHeaderExists ) {
322
- $ curlOptions [CURLOPT_HTTPHEADER ][] = 'Cookie: ' . $ cookieHeader ;
322
+ $ curlOptions [CURLOPT_HTTPHEADER ][] = 'Cookie: ' . $ cookieHeader ;
323
323
}
324
324
}
325
325
}
@@ -358,7 +358,7 @@ public function processSetCookieHeaders(array $headers, string $jarName = 'defau
358
358
*/
359
359
public function createTempCookieFile (string $ prefix = 'test_cookies_ ' ): string
360
360
{
361
- $ filename = sys_get_temp_dir (). DIRECTORY_SEPARATOR . $ prefix. uniqid (). '.json ' ;
361
+ $ filename = sys_get_temp_dir () . DIRECTORY_SEPARATOR . $ prefix . uniqid () . '.json ' ;
362
362
363
363
if ($ this ->autoManage ) {
364
364
$ this ->createdCookieFiles [] = $ filename ;
@@ -415,4 +415,140 @@ public function getDebugInfo(): array
415
415
416
416
return $ info ;
417
417
}
418
+
419
+ /**
420
+ * Apply cookies to curl options, honoring a custom jar in $curlOptions['_cookie_jar'] or falling back to the default jar.
421
+ */
422
+ public function applyCookiesForRequestOptions (array &$ curlOptions , string $ url ): void
423
+ {
424
+ $ jarOption = $ curlOptions ['_cookie_jar ' ] ?? null ;
425
+
426
+ if ($ jarOption instanceof CookieJarInterface) {
427
+ $ uri = new Uri ($ url );
428
+ $ cookieHeader = $ jarOption ->getCookieHeader (
429
+ $ uri ->getHost (),
430
+ $ uri ->getPath () !== '' ? $ uri ->getPath () : '/ ' ,
431
+ $ uri ->getScheme () === 'https '
432
+ );
433
+
434
+ if ($ cookieHeader === '' ) {
435
+ return ;
436
+ }
437
+
438
+ $ curlOptions [CURLOPT_HTTPHEADER ] = $ curlOptions [CURLOPT_HTTPHEADER ] ?? [];
439
+
440
+ foreach ($ curlOptions [CURLOPT_HTTPHEADER ] as &$ header ) {
441
+ if (str_starts_with (strtolower ($ header ), 'cookie: ' )) {
442
+ $ header .= '; ' . $ cookieHeader ;
443
+ return ;
444
+ }
445
+ }
446
+
447
+ $ curlOptions [CURLOPT_HTTPHEADER ][] = 'Cookie: ' . $ cookieHeader ;
448
+ return ;
449
+ }
450
+
451
+ // If jar name provided, use stored jar if available
452
+ if (is_string ($ jarOption )) {
453
+ $ jar = $ this ->getCookieJar ($ jarOption );
454
+ if ($ jar === null ) {
455
+ return ;
456
+ }
457
+
458
+ $ uri = new Uri ($ url );
459
+ $ cookieHeader = $ jar ->getCookieHeader (
460
+ $ uri ->getHost (),
461
+ $ uri ->getPath () !== '' ? $ uri ->getPath () : '/ ' ,
462
+ $ uri ->getScheme () === 'https '
463
+ );
464
+
465
+ if ($ cookieHeader === '' ) {
466
+ return ;
467
+ }
468
+
469
+ $ curlOptions [CURLOPT_HTTPHEADER ] = $ curlOptions [CURLOPT_HTTPHEADER ] ?? [];
470
+
471
+ foreach ($ curlOptions [CURLOPT_HTTPHEADER ] as &$ header ) {
472
+ if (str_starts_with (strtolower ($ header ), 'cookie: ' )) {
473
+ $ header .= '; ' . $ cookieHeader ;
474
+ return ;
475
+ }
476
+ }
477
+
478
+ $ curlOptions [CURLOPT_HTTPHEADER ][] = 'Cookie: ' . $ cookieHeader ;
479
+ return ;
480
+ }
481
+
482
+ $ this ->applyCookiesToCurlOptions ($ curlOptions , $ url );
483
+ }
484
+
485
+ /**
486
+ * Process Set-Cookie headers and apply them to both the shared manager (default jar)
487
+ * and to a custom jar passed in $curlOptions['_cookie_jar'] (instance or jar name).
488
+ *
489
+ * Keeps the same domain-inference behavior as before: if the parsed cookie lacks a domain,
490
+ * it will be set to the request host (if available).
491
+ */
492
+ public function processResponseCookiesForOptions (array $ headers , array $ curlOptions , string $ url ): void
493
+ {
494
+ $ this ->processSetCookieHeaders ($ headers , 'default ' );
495
+
496
+ $ jarOption = $ curlOptions ['_cookie_jar ' ] ?? null ;
497
+ if ($ jarOption === null ) {
498
+ return ;
499
+ }
500
+
501
+ $ customJar = null ;
502
+ if ($ jarOption instanceof CookieJarInterface) {
503
+ $ customJar = $ jarOption ;
504
+ } elseif (is_string ($ jarOption )) {
505
+ $ customJar = $ this ->getCookieJar ($ jarOption );
506
+ }
507
+
508
+ if ($ customJar === null ) {
509
+ return ;
510
+ }
511
+
512
+ $ setCookieHeaders = [];
513
+ foreach ($ headers as $ name => $ value ) {
514
+ if (strtolower ($ name ) !== 'set-cookie ' ) {
515
+ continue ;
516
+ }
517
+ if (is_array ($ value )) {
518
+ $ setCookieHeaders = array_merge ($ setCookieHeaders , $ value );
519
+ continue ;
520
+ }
521
+ $ setCookieHeaders [] = $ value ;
522
+ }
523
+
524
+ if (empty ($ setCookieHeaders )) {
525
+ return ;
526
+ }
527
+
528
+ $ uri = new Uri ($ url );
529
+ $ requestDomain = $ uri ->getHost () ?? '' ;
530
+
531
+ foreach ($ setCookieHeaders as $ setCookieHeader ) {
532
+ $ cookie = Cookie::fromSetCookieHeader ($ setCookieHeader );
533
+ if ($ cookie === null ) {
534
+ continue ;
535
+ }
536
+
537
+ if (empty ($ cookie ->getDomain ()) && $ requestDomain !== '' ) {
538
+ $ cookie = new Cookie (
539
+ $ cookie ->getName (),
540
+ $ cookie ->getValue (),
541
+ $ cookie ->getExpires (),
542
+ $ requestDomain ,
543
+ $ cookie ->getPath (),
544
+ $ cookie ->isSecure (),
545
+ $ cookie ->isHttpOnly (),
546
+ $ cookie ->getMaxAge (),
547
+ $ cookie ->getSameSite ()
548
+ );
549
+ }
550
+
551
+ $ customJar ->setCookie ($ cookie );
552
+ }
553
+ }
418
554
}
0 commit comments