@@ -311,7 +311,8 @@ static void sapi_lsapi_register_variables(zval *track_vars_array)
311
311
static size_t sapi_lsapi_read_post (char * buffer , size_t count_bytes )
312
312
{
313
313
if ( lsapi_mode ) {
314
- return LSAPI_ReadReqBody ( buffer , (unsigned long long )count_bytes );
314
+ ssize_t rv = LSAPI_ReadReqBody (buffer , (unsigned long long )count_bytes );
315
+ return (rv >= 0 ) ? (size_t )rv : 0 ;
315
316
} else {
316
317
return 0 ;
317
318
}
@@ -334,12 +335,165 @@ static char *sapi_lsapi_read_cookies(void)
334
335
/* }}} */
335
336
336
337
338
+ typedef struct _http_error {
339
+ int code ;
340
+ const char * msg ;
341
+ } http_error ;
342
+
343
+ static const http_error http_error_codes [] = {
344
+ {100 , "Continue" },
345
+ {101 , "Switching Protocols" },
346
+ {200 , "OK" },
347
+ {201 , "Created" },
348
+ {202 , "Accepted" },
349
+ {203 , "Non-Authoritative Information" },
350
+ {204 , "No Content" },
351
+ {205 , "Reset Content" },
352
+ {206 , "Partial Content" },
353
+ {300 , "Multiple Choices" },
354
+ {301 , "Moved Permanently" },
355
+ {302 , "Moved Temporarily" },
356
+ {303 , "See Other" },
357
+ {304 , "Not Modified" },
358
+ {305 , "Use Proxy" },
359
+ {400 , "Bad Request" },
360
+ {401 , "Unauthorized" },
361
+ {402 , "Payment Required" },
362
+ {403 , "Forbidden" },
363
+ {404 , "Not Found" },
364
+ {405 , "Method Not Allowed" },
365
+ {406 , "Not Acceptable" },
366
+ {407 , "Proxy Authentication Required" },
367
+ {408 , "Request Time-out" },
368
+ {409 , "Conflict" },
369
+ {410 , "Gone" },
370
+ {411 , "Length Required" },
371
+ {412 , "Precondition Failed" },
372
+ {413 , "Request Entity Too Large" },
373
+ {414 , "Request-URI Too Large" },
374
+ {415 , "Unsupported Media Type" },
375
+ {428 , "Precondition Required" },
376
+ {429 , "Too Many Requests" },
377
+ {431 , "Request Header Fields Too Large" },
378
+ {451 , "Unavailable For Legal Reasons" },
379
+ {500 , "Internal Server Error" },
380
+ {501 , "Not Implemented" },
381
+ {502 , "Bad Gateway" },
382
+ {503 , "Service Unavailable" },
383
+ {504 , "Gateway Time-out" },
384
+ {505 , "HTTP Version not supported" },
385
+ {511 , "Network Authentication Required" },
386
+ {0 , NULL }
387
+ };
388
+
389
+
390
+ static int sapi_lsapi_send_headers_like_cgi (sapi_headers_struct * sapi_headers )
391
+ {
392
+ char buf [SAPI_LSAPI_MAX_HEADER_LENGTH ];
393
+ sapi_header_struct * h ;
394
+ zend_llist_position pos ;
395
+ zend_bool ignore_status = 0 ;
396
+ int response_status = SG (sapi_headers ).http_response_code ;
397
+
398
+ if (SG (request_info ).no_headers == 1 ) {
399
+ LSAPI_FinalizeRespHeaders ();
400
+ return SAPI_HEADER_SENT_SUCCESSFULLY ;
401
+ }
402
+
403
+ if (SG (sapi_headers ).http_response_code != 200 )
404
+ {
405
+ int len ;
406
+ zend_bool has_status = 0 ;
407
+
408
+ char * s ;
409
+
410
+ if (SG (sapi_headers ).http_status_line &&
411
+ (s = strchr (SG (sapi_headers ).http_status_line , ' ' )) != 0 &&
412
+ (s - SG (sapi_headers ).http_status_line ) >= 5 &&
413
+ strncasecmp (SG (sapi_headers ).http_status_line , "HTTP/" , 5 ) == 0
414
+ ) {
415
+ len = slprintf (buf , sizeof (buf ), "Status:%s" , s );
416
+ response_status = atoi ((s + 1 ));
417
+ } else {
418
+ h = (sapi_header_struct * )zend_llist_get_first_ex (& sapi_headers -> headers , & pos );
419
+ while (h ) {
420
+ if (h -> header_len > sizeof ("Status:" )- 1 &&
421
+ strncasecmp (h -> header , "Status:" , sizeof ("Status:" )- 1 ) == 0
422
+ ) {
423
+ has_status = 1 ;
424
+ break ;
425
+ }
426
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
427
+ }
428
+ if (!has_status ) {
429
+ http_error * err = (http_error * )http_error_codes ;
430
+
431
+ while (err -> code != 0 ) {
432
+ if (err -> code == SG (sapi_headers ).http_response_code ) {
433
+ break ;
434
+ }
435
+ err ++ ;
436
+ }
437
+ if (err -> msg ) {
438
+ len = slprintf (buf , sizeof (buf ), "Status: %d %s" , SG (sapi_headers ).http_response_code , err -> msg );
439
+ } else {
440
+ len = slprintf (buf , sizeof (buf ), "Status: %d" , SG (sapi_headers ).http_response_code );
441
+ }
442
+ }
443
+ }
444
+
445
+ if (!has_status ) {
446
+ LSAPI_AppendRespHeader ( buf , len );
447
+ ignore_status = 1 ;
448
+ }
449
+ }
450
+
451
+ h = (sapi_header_struct * )zend_llist_get_first_ex (& sapi_headers -> headers , & pos );
452
+ while (h ) {
453
+ /* prevent CRLFCRLF */
454
+ if (h -> header_len ) {
455
+ if (h -> header_len > sizeof ("Status:" )- 1 &&
456
+ strncasecmp (h -> header , "Status:" , sizeof ("Status:" )- 1 ) == 0
457
+ ) {
458
+ if (!ignore_status ) {
459
+ ignore_status = 1 ;
460
+ LSAPI_AppendRespHeader (h -> header , h -> header_len );
461
+ }
462
+ } else if (response_status == 304 && h -> header_len > sizeof ("Content-Type:" )- 1 &&
463
+ strncasecmp (h -> header , "Content-Type:" , sizeof ("Content-Type:" )- 1 ) == 0
464
+ ) {
465
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
466
+ continue ;
467
+ } else {
468
+ LSAPI_AppendRespHeader (h -> header , h -> header_len );
469
+ }
470
+ }
471
+ h = (sapi_header_struct * )zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
472
+ }
473
+
474
+ LSAPI_FinalizeRespHeaders ();
475
+ return SAPI_HEADER_SENT_SUCCESSFULLY ;
476
+ }
477
+
478
+ /*
479
+ mod_lsapi mode or legacy LS mode
480
+ */
481
+ static int mod_lsapi_mode = 0 ;
482
+
483
+
337
484
/* {{{ sapi_lsapi_send_headers
338
485
*/
339
486
static int sapi_lsapi_send_headers (sapi_headers_struct * sapi_headers )
340
487
{
341
488
sapi_header_struct * h ;
342
489
zend_llist_position pos ;
490
+
491
+ if ( mod_lsapi_mode ) {
492
+ /* mod_lsapi mode */
493
+ return sapi_lsapi_send_headers_like_cgi (sapi_headers );
494
+ }
495
+
496
+ /* Legacy mode */
343
497
if ( lsapi_mode ) {
344
498
LSAPI_SetRespStatus ( SG (sapi_headers ).http_response_code );
345
499
@@ -466,7 +620,7 @@ static int sapi_lsapi_activate()
466
620
static sapi_module_struct lsapi_sapi_module =
467
621
{
468
622
"litespeed" ,
469
- "LiteSpeed V7.3.2 " ,
623
+ "LiteSpeed V7.4.3 " ,
470
624
471
625
php_lsapi_startup , /* startup */
472
626
php_module_shutdown_wrapper , /* shutdown */
@@ -541,6 +695,66 @@ static int lsapi_execute_script( zend_file_handle * file_handle)
541
695
542
696
}
543
697
698
+ static void lsapi_sigsegv ( int signal )
699
+ {
700
+ //fprintf(stderr, "lsapi_sigsegv: %d: Segmentation violation signal is caught during request shutdown\n", getpid());
701
+ _exit (1 );
702
+ }
703
+
704
+ static int clean_onexit = 1 ;
705
+
706
+ static void lsapi_sigterm ( int signal )
707
+ {
708
+ struct sigaction act , old_act ;
709
+ int sa_rc ;
710
+
711
+ // fprintf(stderr, "lsapi_sigterm: %d: clean_onexit %d\n", getpid(), clean_onexit );
712
+ if (!clean_onexit )
713
+ {
714
+ clean_onexit = 1 ;
715
+ act .sa_flags = 0 ;
716
+ act .sa_handler = lsapi_sigsegv ;
717
+ sa_rc = sigaction ( SIGINT , & act , & old_act );
718
+ sa_rc = sigaction ( SIGQUIT , & act , & old_act );
719
+ sa_rc = sigaction ( SIGILL , & act , & old_act );
720
+ sa_rc = sigaction ( SIGABRT , & act , & old_act );
721
+ sa_rc = sigaction ( SIGBUS , & act , & old_act );
722
+ sa_rc = sigaction ( SIGSEGV , & act , & old_act );
723
+ sa_rc = sigaction ( SIGTERM , & act , & old_act );
724
+
725
+ zend_try {
726
+ php_request_shutdown (NULL );
727
+ } zend_end_try ();
728
+ }
729
+ exit (1 );
730
+ }
731
+
732
+ static void lsapi_atexit ( void )
733
+ {
734
+ struct sigaction act , old_act ;
735
+ int sa_rc ;
736
+
737
+ //fprintf(stderr, "lsapi_atexit: %d: clean_onexit %d\n", getpid(), clean_onexit );
738
+ if (!clean_onexit )
739
+ {
740
+ clean_onexit = 1 ;
741
+ act .sa_flags = 0 ;
742
+ act .sa_handler = lsapi_sigsegv ;
743
+ sa_rc = sigaction ( SIGINT , & act , & old_act );
744
+ sa_rc = sigaction ( SIGQUIT , & act , & old_act );
745
+ sa_rc = sigaction ( SIGILL , & act , & old_act );
746
+ sa_rc = sigaction ( SIGABRT , & act , & old_act );
747
+ sa_rc = sigaction ( SIGBUS , & act , & old_act );
748
+ sa_rc = sigaction ( SIGSEGV , & act , & old_act );
749
+ sa_rc = sigaction ( SIGTERM , & act , & old_act );
750
+
751
+ //fprintf(stderr, "lsapi_atexit: %d: before php_request_shutdown\n", getpid(), clean_onexit );
752
+ zend_try {
753
+ php_request_shutdown (NULL );
754
+ } zend_end_try ();
755
+ }
756
+ }
757
+
544
758
static int lsapi_module_main (int show_source )
545
759
{
546
760
zend_file_handle file_handle ;
@@ -549,6 +763,8 @@ static int lsapi_module_main(int show_source)
549
763
return -1 ;
550
764
}
551
765
766
+ clean_onexit = 0 ;
767
+
552
768
if (show_source ) {
553
769
zend_syntax_highlighter_ini syntax_highlighter_ini ;
554
770
@@ -559,6 +775,9 @@ static int lsapi_module_main(int show_source)
559
775
}
560
776
zend_try {
561
777
php_request_shutdown (NULL );
778
+
779
+ clean_onexit = 1 ;
780
+
562
781
memset ( argv0 , 0 , 46 );
563
782
} zend_end_try ();
564
783
return 0 ;
@@ -576,7 +795,16 @@ static int alter_ini( const char * pKey, int keyLen, const char * pValue, int va
576
795
++ pKey ;
577
796
if ( * pKey == 4 ) {
578
797
type = ZEND_INI_SYSTEM ;
579
- stage = PHP_INI_STAGE_ACTIVATE ;
798
+ /*
799
+ Use ACTIVATE stage in legacy mode only.
800
+
801
+ RUNTIME stage should be used here,
802
+ as with ACTIVATE it's impossible to change the option from script with ini_set
803
+ */
804
+ if (!mod_lsapi_mode )
805
+ {
806
+ stage = PHP_INI_STAGE_ACTIVATE ;
807
+ }
580
808
}
581
809
else
582
810
{
@@ -1245,6 +1473,16 @@ int main( int argc, char * argv[] )
1245
1473
int slow_script_msec = 0 ;
1246
1474
char time_buf [40 ];
1247
1475
1476
+ struct sigaction act , old_act ;
1477
+ struct sigaction INT_act ;
1478
+ struct sigaction QUIT_act ;
1479
+ struct sigaction ILL_act ;
1480
+ struct sigaction ABRT_act ;
1481
+ struct sigaction BUS_act ;
1482
+ struct sigaction SEGV_act ;
1483
+ struct sigaction TERM_act ;
1484
+ int sa_rc ;
1485
+
1248
1486
#ifdef HAVE_SIGNAL_H
1249
1487
#if defined(SIGPIPE ) && defined(SIG_IGN )
1250
1488
signal (SIGPIPE , SIG_IGN );
@@ -1346,6 +1584,17 @@ int main( int argc, char * argv[] )
1346
1584
int iRequestsProcessed = 0 ;
1347
1585
int result ;
1348
1586
1587
+ act .sa_flags = SA_NODEFER ;
1588
+ act .sa_handler = lsapi_sigterm ;
1589
+ sa_rc = sigaction ( SIGINT , & act , & INT_act );
1590
+ sa_rc = sigaction ( SIGQUIT , & act , & QUIT_act );
1591
+ sa_rc = sigaction ( SIGILL , & act , & ILL_act );
1592
+ sa_rc = sigaction ( SIGABRT , & act , & ABRT_act );
1593
+ sa_rc = sigaction ( SIGBUS , & act , & BUS_act );
1594
+ sa_rc = sigaction ( SIGSEGV , & act , & SEGV_act );
1595
+ sa_rc = sigaction ( SIGTERM , & act , & TERM_act );
1596
+ atexit (lsapi_atexit );
1597
+
1349
1598
while ( ( result = LSAPI_Prefork_Accept_r ( & g_req )) >= 0 ) {
1350
1599
#if defined(linux ) || defined(__linux ) || defined(__linux__ ) || defined(__gnu_linux__ )
1351
1600
if (is_criu && !result ) {
@@ -1375,6 +1624,15 @@ int main( int argc, char * argv[] )
1375
1624
break ;
1376
1625
}
1377
1626
}
1627
+
1628
+ sa_rc = sigaction ( SIGINT , & INT_act , & old_act );
1629
+ sa_rc = sigaction ( SIGQUIT , & QUIT_act , & old_act );
1630
+ sa_rc = sigaction ( SIGILL , & ILL_act , & old_act );
1631
+ sa_rc = sigaction ( SIGABRT , & ABRT_act , & old_act );
1632
+ sa_rc = sigaction ( SIGBUS , & BUS_act , & old_act );
1633
+ sa_rc = sigaction ( SIGSEGV , & SEGV_act , & old_act );
1634
+ sa_rc = sigaction ( SIGTERM , & TERM_act , & old_act );
1635
+
1378
1636
php_module_shutdown ();
1379
1637
1380
1638
#ifdef ZTS
@@ -1417,6 +1675,12 @@ static PHP_MINIT_FUNCTION(litespeed)
1417
1675
if (p && 0 == strcasecmp (p , "on" ))
1418
1676
parse_user_ini = 1 ;
1419
1677
1678
+ /*
1679
+ * mod_lsapi always sets this env var,
1680
+ * so we can detect mod_lsapi mode with its presense.
1681
+ */
1682
+ mod_lsapi_mode = ( getenv ("LSAPI_DISABLE_CPAN_BEHAV" ) != NULL );
1683
+
1420
1684
/* REGISTER_INI_ENTRIES(); */
1421
1685
return SUCCESS ;
1422
1686
}
0 commit comments