@@ -486,6 +486,195 @@ func TestPHPServerDirectiveDisableFileServer(t *testing.T) {
486486 tester .AssertGetResponse ("http://localhost:" + testPort + "/not-found.txt" , http .StatusOK , "I am by birth a Genevese (i not set)" )
487487}
488488
489+ func TestPHPServerGlobals (t * testing.T ) {
490+ documentRoot , _ := filepath .Abs ("../testdata" )
491+ scriptFilename := filepath .Join (documentRoot , "server-globals.php" )
492+
493+ tester := caddytest .NewTester (t )
494+ initServer (t , tester , `
495+ {
496+ skip_install_trust
497+ admin localhost:2999
498+ http_port ` + testPort + `
499+ https_port 9443
500+ }
501+
502+ localhost:` + testPort + ` {
503+ root ../testdata
504+ php_server {
505+ index server-globals.php
506+ }
507+ }
508+ ` , "caddyfile" )
509+
510+ // Request to /en: no matching file, falls through to server-globals.php worker
511+ // SCRIPT_NAME should be /server-globals.php, PHP_SELF should be /server-globals.php (no /en), PATH_INFO empty
512+ tester .AssertGetResponse (
513+ "http://localhost:" + testPort + "/en" ,
514+ http .StatusOK ,
515+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
516+ SCRIPT_FILENAME: %s
517+ PHP_SELF: /server-globals.php
518+ PATH_INFO:
519+ DOCUMENT_ROOT: %s
520+ DOCUMENT_URI: /server-globals.php
521+ REQUEST_URI: /en
522+ ` , scriptFilename , documentRoot ),
523+ )
524+
525+ // Request to /server-globals.php/en: explicit PHP file with path info
526+ // SCRIPT_NAME should be /server-globals.php, PHP_SELF should be /server-globals.php/en, PATH_INFO should be /en
527+ tester .AssertGetResponse (
528+ "http://localhost:" + testPort + "/server-globals.php/en" ,
529+ http .StatusOK ,
530+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
531+ SCRIPT_FILENAME: %s
532+ PHP_SELF: /server-globals.php/en
533+ PATH_INFO: /en
534+ DOCUMENT_ROOT: %s
535+ DOCUMENT_URI: /server-globals.php
536+ REQUEST_URI: /server-globals.php/en
537+ ` , scriptFilename , documentRoot ),
538+ )
539+ }
540+
541+ func TestWorkerPHPServerGlobals (t * testing.T ) {
542+ documentRoot , _ := filepath .Abs ("../testdata" )
543+ documentRoot2 , _ := filepath .Abs ("../caddy" )
544+ scriptFilename := documentRoot + string (filepath .Separator ) + "server-globals.php"
545+ testPortNum , _ := strconv .Atoi (testPort )
546+ testPortTwo := strconv .Itoa (testPortNum + 1 )
547+ testPortThree := strconv .Itoa (testPortNum + 2 )
548+
549+ tester := caddytest .NewTester (t )
550+ initServer (t , tester , `
551+ {
552+ skip_install_trust
553+ admin localhost:2999
554+
555+ frankenphp {
556+ worker {
557+ file ../testdata/server-globals.php
558+ num 1
559+ }
560+ }
561+ }
562+
563+ http://localhost:` + testPort + ` {
564+ php_server {
565+ root ../testdata
566+ index server-globals.php
567+ }
568+ }
569+
570+ http://localhost:` + testPortTwo + ` {
571+ php_server {
572+ root ../testdata
573+ index server-globals.php
574+ worker {
575+ file server-globals.php
576+ num 1
577+ }
578+ }
579+ }
580+
581+ http://localhost:` + testPortThree + ` {
582+ php_server {
583+ root ./
584+ index server-globals.php
585+ worker {
586+ file ../testdata/server-globals.php
587+ num 1
588+ match *
589+ }
590+ }
591+ }
592+ ` , "caddyfile" )
593+
594+ // === Site 1: global worker with php_server ===
595+ // because we don't specify a php file, PATH_INFO should be empty
596+ tester .AssertGetResponse (
597+ "http://localhost:" + testPort + "/en" ,
598+ http .StatusOK ,
599+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
600+ SCRIPT_FILENAME: %s
601+ PHP_SELF: /server-globals.php
602+ PATH_INFO:
603+ DOCUMENT_ROOT: %s
604+ DOCUMENT_URI: /server-globals.php
605+ REQUEST_URI: /en
606+ ` , scriptFilename , documentRoot ),
607+ )
608+
609+ tester .AssertGetResponse (
610+ "http://localhost:" + testPort + "/server-globals.php/en" ,
611+ http .StatusOK ,
612+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
613+ SCRIPT_FILENAME: %s
614+ PHP_SELF: /server-globals.php/en
615+ PATH_INFO: /en
616+ DOCUMENT_ROOT: %s
617+ DOCUMENT_URI: /server-globals.php
618+ REQUEST_URI: /server-globals.php/en
619+ ` , scriptFilename , documentRoot ),
620+ )
621+
622+ // === Site 2: php_server with its own worker ===
623+ // because the request does not specify a php file, PATH_INFO should be empty
624+ tester .AssertGetResponse (
625+ "http://localhost:" + testPortTwo + "/en" ,
626+ http .StatusOK ,
627+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
628+ SCRIPT_FILENAME: %s
629+ PHP_SELF: /server-globals.php
630+ PATH_INFO:
631+ DOCUMENT_ROOT: %s
632+ DOCUMENT_URI: /server-globals.php
633+ REQUEST_URI: /en
634+ ` , scriptFilename , documentRoot ),
635+ )
636+
637+ tester .AssertGetResponse (
638+ "http://localhost:" + testPortTwo + "/server-globals.php/en" ,
639+ http .StatusOK ,
640+ fmt .Sprintf (`SCRIPT_NAME: /server-globals.php
641+ SCRIPT_FILENAME: %s
642+ PHP_SELF: /server-globals.php/en
643+ PATH_INFO: /en
644+ DOCUMENT_ROOT: %s
645+ DOCUMENT_URI: /server-globals.php
646+ REQUEST_URI: /server-globals.php/en
647+ ` , scriptFilename , documentRoot ),
648+ )
649+
650+ // === Site 3: php_server with its own match worker ===
651+ tester .AssertGetResponse (
652+ "http://localhost:" + testPortThree + "/en" ,
653+ http .StatusOK ,
654+ fmt .Sprintf (`SCRIPT_NAME:
655+ SCRIPT_FILENAME: %s
656+ PHP_SELF:
657+ PATH_INFO:
658+ DOCUMENT_ROOT: %s
659+ DOCUMENT_URI:
660+ REQUEST_URI: /en
661+ ` , scriptFilename , documentRoot2 ),
662+ )
663+
664+ tester .AssertGetResponse (
665+ "http://localhost:" + testPortThree + "/server-globals.php/en" ,
666+ http .StatusOK ,
667+ fmt .Sprintf (`SCRIPT_NAME:
668+ SCRIPT_FILENAME: %s
669+ PHP_SELF:
670+ PATH_INFO:
671+ DOCUMENT_ROOT: %s
672+ DOCUMENT_URI:
673+ REQUEST_URI: /server-globals.php/en
674+ ` , scriptFilename , documentRoot2 ),
675+ )
676+ }
677+
489678func TestMetrics (t * testing.T ) {
490679 var wg sync.WaitGroup
491680 tester := caddytest .NewTester (t )
0 commit comments