Skip to content

Commit 3ec8776

Browse files
author
George Wang
committed
Merge branch 'PHP-7.2' into PHP-7.3
2 parents 807c755 + 32af676 commit 3ec8776

File tree

2 files changed

+268
-4
lines changed

2 files changed

+268
-4
lines changed

sapi/litespeed/lsapi_main.c

Lines changed: 267 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ static void sapi_lsapi_register_variables(zval *track_vars_array)
300300
static size_t sapi_lsapi_read_post(char *buffer, size_t count_bytes)
301301
{
302302
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;
304305
} else {
305306
return 0;
306307
}
@@ -323,12 +324,165 @@ static char *sapi_lsapi_read_cookies(void)
323324
/* }}} */
324325

325326

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+
326473
/* {{{ sapi_lsapi_send_headers
327474
*/
328475
static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers)
329476
{
330477
sapi_header_struct *h;
331478
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 */
332486
if ( lsapi_mode ) {
333487
LSAPI_SetRespStatus( SG(sapi_headers).http_response_code );
334488

@@ -455,7 +609,7 @@ static int sapi_lsapi_activate()
455609
static sapi_module_struct lsapi_sapi_module =
456610
{
457611
"litespeed",
458-
"LiteSpeed V7.3.2",
612+
"LiteSpeed V7.4.3",
459613

460614
php_lsapi_startup, /* startup */
461615
php_module_shutdown_wrapper, /* shutdown */
@@ -530,6 +684,66 @@ static int lsapi_execute_script( zend_file_handle * file_handle)
530684

531685
}
532686

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+
533747
static int lsapi_module_main(int show_source)
534748
{
535749
zend_file_handle file_handle;
@@ -538,6 +752,8 @@ static int lsapi_module_main(int show_source)
538752
return -1;
539753
}
540754

755+
clean_onexit = 0;
756+
541757
if (show_source) {
542758
zend_syntax_highlighter_ini syntax_highlighter_ini;
543759

@@ -548,6 +764,9 @@ static int lsapi_module_main(int show_source)
548764
}
549765
zend_try {
550766
php_request_shutdown(NULL);
767+
768+
clean_onexit = 1;
769+
551770
memset( argv0, 0, 46 );
552771
} zend_end_try();
553772
return 0;
@@ -565,7 +784,16 @@ static int alter_ini( const char * pKey, int keyLen, const char * pValue, int va
565784
++pKey;
566785
if ( *pKey == 4 ) {
567786
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+
}
569797
}
570798
else
571799
{
@@ -1230,6 +1458,16 @@ int main( int argc, char * argv[] )
12301458
int slow_script_msec = 0;
12311459
char time_buf[40];
12321460

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+
12331471
#ifdef HAVE_SIGNAL_H
12341472
#if defined(SIGPIPE) && defined(SIG_IGN)
12351473
signal(SIGPIPE, SIG_IGN);
@@ -1330,6 +1568,17 @@ int main( int argc, char * argv[] )
13301568

13311569
int result;
13321570

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+
13331582
while( ( result = LSAPI_Prefork_Accept_r( &g_req )) >= 0 ) {
13341583
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
13351584
if (is_criu && !result) {
@@ -1359,6 +1608,15 @@ int main( int argc, char * argv[] )
13591608
break;
13601609
}
13611610
}
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+
13621620
php_module_shutdown();
13631621

13641622
#ifdef ZTS
@@ -1401,6 +1659,12 @@ static PHP_MINIT_FUNCTION(litespeed)
14011659
if (p && 0 == strcasecmp(p, "on"))
14021660
parse_user_ini = 1;
14031661

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+
14041668
/* REGISTER_INI_ENTRIES(); */
14051669
return SUCCESS;
14061670
}

sapi/litespeed/lsapilib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct LSAPI_key_value_pair
7171
};
7272

7373

74-
#define LSAPI_MAX_RESP_HEADERS 100
74+
#define LSAPI_MAX_RESP_HEADERS 1000
7575

7676
typedef struct lsapi_request
7777
{

0 commit comments

Comments
 (0)