@@ -300,7 +300,8 @@ static void sapi_lsapi_register_variables(zval *track_vars_array)
300
300
static size_t sapi_lsapi_read_post (char * buffer , size_t count_bytes )
301
301
{
302
302
if ( lsapi_mode ) {
303
- return LSAPI_ReadReqBody ( buffer , (unsigned long long )count_bytes );
303
+ ssize_t rv = LSAPI_ReadReqBody (buffer , (unsigned long long )count_bytes );
304
+ return (rv >= 0 ) ? (size_t )rv : 0 ;
304
305
} else {
305
306
return 0 ;
306
307
}
@@ -323,12 +324,165 @@ static char *sapi_lsapi_read_cookies(void)
323
324
/* }}} */
324
325
325
326
327
+ typedef struct _http_error {
328
+ int code ;
329
+ const char * msg ;
330
+ } http_error ;
331
+
332
+ static const http_error http_error_codes [] = {
333
+ {100 , "Continue" },
334
+ {101 , "Switching Protocols" },
335
+ {200 , "OK" },
336
+ {201 , "Created" },
337
+ {202 , "Accepted" },
338
+ {203 , "Non-Authoritative Information" },
339
+ {204 , "No Content" },
340
+ {205 , "Reset Content" },
341
+ {206 , "Partial Content" },
342
+ {300 , "Multiple Choices" },
343
+ {301 , "Moved Permanently" },
344
+ {302 , "Moved Temporarily" },
345
+ {303 , "See Other" },
346
+ {304 , "Not Modified" },
347
+ {305 , "Use Proxy" },
348
+ {400 , "Bad Request" },
349
+ {401 , "Unauthorized" },
350
+ {402 , "Payment Required" },
351
+ {403 , "Forbidden" },
352
+ {404 , "Not Found" },
353
+ {405 , "Method Not Allowed" },
354
+ {406 , "Not Acceptable" },
355
+ {407 , "Proxy Authentication Required" },
356
+ {408 , "Request Time-out" },
357
+ {409 , "Conflict" },
358
+ {410 , "Gone" },
359
+ {411 , "Length Required" },
360
+ {412 , "Precondition Failed" },
361
+ {413 , "Request Entity Too Large" },
362
+ {414 , "Request-URI Too Large" },
363
+ {415 , "Unsupported Media Type" },
364
+ {428 , "Precondition Required" },
365
+ {429 , "Too Many Requests" },
366
+ {431 , "Request Header Fields Too Large" },
367
+ {451 , "Unavailable For Legal Reasons" },
368
+ {500 , "Internal Server Error" },
369
+ {501 , "Not Implemented" },
370
+ {502 , "Bad Gateway" },
371
+ {503 , "Service Unavailable" },
372
+ {504 , "Gateway Time-out" },
373
+ {505 , "HTTP Version not supported" },
374
+ {511 , "Network Authentication Required" },
375
+ {0 , NULL }
376
+ };
377
+
378
+
379
+ static int sapi_lsapi_send_headers_like_cgi (sapi_headers_struct * sapi_headers )
380
+ {
381
+ char buf [SAPI_LSAPI_MAX_HEADER_LENGTH ];
382
+ sapi_header_struct * h ;
383
+ zend_llist_position pos ;
384
+ zend_bool ignore_status = 0 ;
385
+ int response_status = SG (sapi_headers ).http_response_code ;
386
+
387
+ if (SG (request_info ).no_headers == 1 ) {
388
+ LSAPI_FinalizeRespHeaders ();
389
+ return SAPI_HEADER_SENT_SUCCESSFULLY ;
390
+ }
391
+
392
+ if (SG (sapi_headers ).http_response_code != 200 )
393
+ {
394
+ int len ;
395
+ zend_bool has_status = 0 ;
396
+
397
+ char * s ;
398
+
399
+ if (SG (sapi_headers ).http_status_line &&
400
+ (s = strchr (SG (sapi_headers ).http_status_line , ' ' )) != 0 &&
401
+ (s - SG (sapi_headers ).http_status_line ) >= 5 &&
402
+ strncasecmp (SG (sapi_headers ).http_status_line , "HTTP/" , 5 ) == 0
403
+ ) {
404
+ len = slprintf (buf , sizeof (buf ), "Status:%s" , s );
405
+ response_status = atoi ((s + 1 ));
406
+ } else {
407
+ h = (sapi_header_struct * )zend_llist_get_first_ex (& sapi_headers -> headers , & pos );
408
+ while (h ) {
409
+ if (h -> header_len > sizeof ("Status:" )- 1 &&
410
+ strncasecmp (h -> header , "Status:" , sizeof ("Status:" )- 1 ) == 0
411
+ ) {
412
+ has_status = 1 ;
413
+ break ;
414
+ }
415
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
416
+ }
417
+ if (!has_status ) {
418
+ http_error * err = (http_error * )http_error_codes ;
419
+
420
+ while (err -> code != 0 ) {
421
+ if (err -> code == SG (sapi_headers ).http_response_code ) {
422
+ break ;
423
+ }
424
+ err ++ ;
425
+ }
426
+ if (err -> msg ) {
427
+ len = slprintf (buf , sizeof (buf ), "Status: %d %s" , SG (sapi_headers ).http_response_code , err -> msg );
428
+ } else {
429
+ len = slprintf (buf , sizeof (buf ), "Status: %d" , SG (sapi_headers ).http_response_code );
430
+ }
431
+ }
432
+ }
433
+
434
+ if (!has_status ) {
435
+ LSAPI_AppendRespHeader ( buf , len );
436
+ ignore_status = 1 ;
437
+ }
438
+ }
439
+
440
+ h = (sapi_header_struct * )zend_llist_get_first_ex (& sapi_headers -> headers , & pos );
441
+ while (h ) {
442
+ /* prevent CRLFCRLF */
443
+ if (h -> header_len ) {
444
+ if (h -> header_len > sizeof ("Status:" )- 1 &&
445
+ strncasecmp (h -> header , "Status:" , sizeof ("Status:" )- 1 ) == 0
446
+ ) {
447
+ if (!ignore_status ) {
448
+ ignore_status = 1 ;
449
+ LSAPI_AppendRespHeader (h -> header , h -> header_len );
450
+ }
451
+ } else if (response_status == 304 && h -> header_len > sizeof ("Content-Type:" )- 1 &&
452
+ strncasecmp (h -> header , "Content-Type:" , sizeof ("Content-Type:" )- 1 ) == 0
453
+ ) {
454
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
455
+ continue ;
456
+ } else {
457
+ LSAPI_AppendRespHeader (h -> header , h -> header_len );
458
+ }
459
+ }
460
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
461
+ }
462
+
463
+ LSAPI_FinalizeRespHeaders ();
464
+ return SAPI_HEADER_SENT_SUCCESSFULLY ;
465
+ }
466
+
467
+ /*
468
+ mod_lsapi mode or legacy LS mode
469
+ */
470
+ static int mod_lsapi_mode = 0 ;
471
+
472
+
326
473
/* {{{ sapi_lsapi_send_headers
327
474
*/
328
475
static int sapi_lsapi_send_headers (sapi_headers_struct * sapi_headers )
329
476
{
330
477
sapi_header_struct * h ;
331
478
zend_llist_position pos ;
479
+
480
+ if ( mod_lsapi_mode ) {
481
+ /* mod_lsapi mode */
482
+ return sapi_lsapi_send_headers_like_cgi (sapi_headers );
483
+ }
484
+
485
+ /* Legacy mode */
332
486
if ( lsapi_mode ) {
333
487
LSAPI_SetRespStatus ( SG (sapi_headers ).http_response_code );
334
488
@@ -455,7 +609,7 @@ static int sapi_lsapi_activate()
455
609
static sapi_module_struct lsapi_sapi_module =
456
610
{
457
611
"litespeed" ,
458
- "LiteSpeed V7.3.2 " ,
612
+ "LiteSpeed V7.4.3 " ,
459
613
460
614
php_lsapi_startup , /* startup */
461
615
php_module_shutdown_wrapper , /* shutdown */
@@ -530,6 +684,66 @@ static int lsapi_execute_script( zend_file_handle * file_handle)
530
684
531
685
}
532
686
687
+ static void lsapi_sigsegv ( int signal )
688
+ {
689
+ //fprintf(stderr, "lsapi_sigsegv: %d: Segmentation violation signal is caught during request shutdown\n", getpid());
690
+ _exit (1 );
691
+ }
692
+
693
+ static int clean_onexit = 1 ;
694
+
695
+ static void lsapi_sigterm ( int signal )
696
+ {
697
+ struct sigaction act , old_act ;
698
+ int sa_rc ;
699
+
700
+ // fprintf(stderr, "lsapi_sigterm: %d: clean_onexit %d\n", getpid(), clean_onexit );
701
+ if (!clean_onexit )
702
+ {
703
+ clean_onexit = 1 ;
704
+ act .sa_flags = 0 ;
705
+ act .sa_handler = lsapi_sigsegv ;
706
+ sa_rc = sigaction ( SIGINT , & act , & old_act );
707
+ sa_rc = sigaction ( SIGQUIT , & act , & old_act );
708
+ sa_rc = sigaction ( SIGILL , & act , & old_act );
709
+ sa_rc = sigaction ( SIGABRT , & act , & old_act );
710
+ sa_rc = sigaction ( SIGBUS , & act , & old_act );
711
+ sa_rc = sigaction ( SIGSEGV , & act , & old_act );
712
+ sa_rc = sigaction ( SIGTERM , & act , & old_act );
713
+
714
+ zend_try {
715
+ php_request_shutdown (NULL );
716
+ } zend_end_try ();
717
+ }
718
+ exit (1 );
719
+ }
720
+
721
+ static void lsapi_atexit ( void )
722
+ {
723
+ struct sigaction act , old_act ;
724
+ int sa_rc ;
725
+
726
+ //fprintf(stderr, "lsapi_atexit: %d: clean_onexit %d\n", getpid(), clean_onexit );
727
+ if (!clean_onexit )
728
+ {
729
+ clean_onexit = 1 ;
730
+ act .sa_flags = 0 ;
731
+ act .sa_handler = lsapi_sigsegv ;
732
+ sa_rc = sigaction ( SIGINT , & act , & old_act );
733
+ sa_rc = sigaction ( SIGQUIT , & act , & old_act );
734
+ sa_rc = sigaction ( SIGILL , & act , & old_act );
735
+ sa_rc = sigaction ( SIGABRT , & act , & old_act );
736
+ sa_rc = sigaction ( SIGBUS , & act , & old_act );
737
+ sa_rc = sigaction ( SIGSEGV , & act , & old_act );
738
+ sa_rc = sigaction ( SIGTERM , & act , & old_act );
739
+
740
+ //fprintf(stderr, "lsapi_atexit: %d: before php_request_shutdown\n", getpid(), clean_onexit );
741
+ zend_try {
742
+ php_request_shutdown (NULL );
743
+ } zend_end_try ();
744
+ }
745
+ }
746
+
533
747
static int lsapi_module_main (int show_source )
534
748
{
535
749
zend_file_handle file_handle ;
@@ -538,6 +752,8 @@ static int lsapi_module_main(int show_source)
538
752
return -1 ;
539
753
}
540
754
755
+ clean_onexit = 0 ;
756
+
541
757
if (show_source ) {
542
758
zend_syntax_highlighter_ini syntax_highlighter_ini ;
543
759
@@ -548,6 +764,9 @@ static int lsapi_module_main(int show_source)
548
764
}
549
765
zend_try {
550
766
php_request_shutdown (NULL );
767
+
768
+ clean_onexit = 1 ;
769
+
551
770
memset ( argv0 , 0 , 46 );
552
771
} zend_end_try ();
553
772
return 0 ;
@@ -565,7 +784,16 @@ static int alter_ini( const char * pKey, int keyLen, const char * pValue, int va
565
784
++ pKey ;
566
785
if ( * pKey == 4 ) {
567
786
type = ZEND_INI_SYSTEM ;
568
- stage = PHP_INI_STAGE_ACTIVATE ;
787
+ /*
788
+ Use ACTIVATE stage in legacy mode only.
789
+
790
+ RUNTIME stage should be used here,
791
+ as with ACTIVATE it's impossible to change the option from script with ini_set
792
+ */
793
+ if (!mod_lsapi_mode )
794
+ {
795
+ stage = PHP_INI_STAGE_ACTIVATE ;
796
+ }
569
797
}
570
798
else
571
799
{
@@ -1230,6 +1458,16 @@ int main( int argc, char * argv[] )
1230
1458
int slow_script_msec = 0 ;
1231
1459
char time_buf [40 ];
1232
1460
1461
+ struct sigaction act , old_act ;
1462
+ struct sigaction INT_act ;
1463
+ struct sigaction QUIT_act ;
1464
+ struct sigaction ILL_act ;
1465
+ struct sigaction ABRT_act ;
1466
+ struct sigaction BUS_act ;
1467
+ struct sigaction SEGV_act ;
1468
+ struct sigaction TERM_act ;
1469
+ int sa_rc ;
1470
+
1233
1471
#ifdef HAVE_SIGNAL_H
1234
1472
#if defined(SIGPIPE ) && defined(SIG_IGN )
1235
1473
signal (SIGPIPE , SIG_IGN );
@@ -1330,6 +1568,17 @@ int main( int argc, char * argv[] )
1330
1568
1331
1569
int result ;
1332
1570
1571
+ act .sa_flags = SA_NODEFER ;
1572
+ act .sa_handler = lsapi_sigterm ;
1573
+ sa_rc = sigaction ( SIGINT , & act , & INT_act );
1574
+ sa_rc = sigaction ( SIGQUIT , & act , & QUIT_act );
1575
+ sa_rc = sigaction ( SIGILL , & act , & ILL_act );
1576
+ sa_rc = sigaction ( SIGABRT , & act , & ABRT_act );
1577
+ sa_rc = sigaction ( SIGBUS , & act , & BUS_act );
1578
+ sa_rc = sigaction ( SIGSEGV , & act , & SEGV_act );
1579
+ sa_rc = sigaction ( SIGTERM , & act , & TERM_act );
1580
+ atexit (lsapi_atexit );
1581
+
1333
1582
while ( ( result = LSAPI_Prefork_Accept_r ( & g_req )) >= 0 ) {
1334
1583
#if defined(linux ) || defined(__linux ) || defined(__linux__ ) || defined(__gnu_linux__ )
1335
1584
if (is_criu && !result ) {
@@ -1359,6 +1608,15 @@ int main( int argc, char * argv[] )
1359
1608
break ;
1360
1609
}
1361
1610
}
1611
+
1612
+ sa_rc = sigaction ( SIGINT , & INT_act , & old_act );
1613
+ sa_rc = sigaction ( SIGQUIT , & QUIT_act , & old_act );
1614
+ sa_rc = sigaction ( SIGILL , & ILL_act , & old_act );
1615
+ sa_rc = sigaction ( SIGABRT , & ABRT_act , & old_act );
1616
+ sa_rc = sigaction ( SIGBUS , & BUS_act , & old_act );
1617
+ sa_rc = sigaction ( SIGSEGV , & SEGV_act , & old_act );
1618
+ sa_rc = sigaction ( SIGTERM , & TERM_act , & old_act );
1619
+
1362
1620
php_module_shutdown ();
1363
1621
1364
1622
#ifdef ZTS
@@ -1401,6 +1659,12 @@ static PHP_MINIT_FUNCTION(litespeed)
1401
1659
if (p && 0 == strcasecmp (p , "on" ))
1402
1660
parse_user_ini = 1 ;
1403
1661
1662
+ /*
1663
+ * mod_lsapi always sets this env var,
1664
+ * so we can detect mod_lsapi mode with its presense.
1665
+ */
1666
+ mod_lsapi_mode = ( getenv ("LSAPI_DISABLE_CPAN_BEHAV" ) != NULL );
1667
+
1404
1668
/* REGISTER_INI_ENTRIES(); */
1405
1669
return SUCCESS ;
1406
1670
}
0 commit comments