@@ -56,6 +56,8 @@ swString *swoole_zlib_buffer = NULL;
56
56
#endif
57
57
swString * swoole_http_form_data_buffer ;
58
58
59
+ static http_context * current_ctx = NULL ;
60
+
59
61
enum http_global_flag
60
62
{
61
63
HTTP_GLOBAL_GET = 1u << 1 ,
@@ -86,6 +88,10 @@ zend_class_entry *swoole_http_response_class_entry_ptr;
86
88
static zend_class_entry swoole_http_request_ce ;
87
89
zend_class_entry * swoole_http_request_class_entry_ptr ;
88
90
91
+ static void (* old_error_handler )(int , const char * , const uint , const char * , va_list );
92
+ static void worker_error_handler (int error_num , const char * error_filename , const uint error_lineno , const char * format , va_list args );
93
+ static void http_onWorkerStart (swServer * serv , int worker_id );
94
+ static void http_onWorkerStop (swServer * serv , int worker_id );
89
95
static int http_onReceive (swServer * serv , swEventData * req );
90
96
static void http_onClose (swServer * serv , swDataHead * info );
91
97
@@ -114,6 +120,22 @@ static int http_trim_double_quote(zval **value, char **ptr);
114
120
#define http_strncasecmp (const_str , at , length ) ((length >= sizeof(const_str)-1) &&\
115
121
(strncasecmp(at, ZEND_STRL(const_str)) == 0))
116
122
123
+ #ifdef va_copy
124
+ #define call_old_error_handler (error_num , error_filename , error_lineno , format , args ) \
125
+ { \
126
+ va_list copy; \
127
+ va_copy(copy, args); \
128
+ old_error_handler(error_num, error_filename, error_lineno, format, copy); \
129
+ va_end(copy); \
130
+ }
131
+ #else
132
+ #define call_old_error_handler (error_num , error_filename , error_lineno , format , args ) \
133
+ { \
134
+ old_error_handler(error_num, error_filename, error_lineno, format, args); \
135
+ }
136
+ #endif
137
+
138
+
117
139
//header filed format,like:Content-Type
118
140
static inline void http_header_key_format (char * key , int length )
119
141
{
@@ -916,6 +938,19 @@ static int http_request_message_complete(php_http_parser *parser)
916
938
return 0 ;
917
939
}
918
940
941
+ static void http_onWorkerStart (swServer * serv , int worker_id )
942
+ {
943
+ old_error_handler = zend_error_cb ;
944
+ zend_error_cb = worker_error_handler ;
945
+ php_swoole_onWorkerStart (serv , worker_id );
946
+ }
947
+
948
+ static void http_onWorkerStop (swServer * serv , int worker_id )
949
+ {
950
+ zend_error_cb = old_error_handler ;
951
+ php_swoole_onWorkerStop (serv , worker_id );
952
+ }
953
+
919
954
static int http_onReceive (swServer * serv , swEventData * req )
920
955
{
921
956
if (swEventData_is_dgram (req -> info .type ))
@@ -1058,6 +1093,8 @@ static int http_onReceive(swServer *serv, swEventData *req)
1058
1093
}
1059
1094
}
1060
1095
1096
+ current_ctx = ctx ;
1097
+
1061
1098
if (sw_call_user_function_ex (EG (function_table ), NULL , zcallback , & retval , 2 , args , 0 , NULL TSRMLS_CC ) == FAILURE )
1062
1099
{
1063
1100
swError ("onRequest handler error" );
@@ -1068,6 +1105,8 @@ static int http_onReceive(swServer *serv, swEventData *req)
1068
1105
zend_exception_error (EG (exception ), E_ERROR TSRMLS_CC );
1069
1106
}
1070
1107
1108
+ current_ctx = NULL ;
1109
+
1071
1110
//websocket user handshake
1072
1111
if (conn -> websocket_status == WEBSOCKET_STATUS_HANDSHAKE )
1073
1112
{
@@ -1433,8 +1472,10 @@ static PHP_METHOD(swoole_http_server, start)
1433
1472
}
1434
1473
#endif
1435
1474
1436
- serv -> onReceive = http_onReceive ;
1437
- serv -> onClose = http_onClose ;
1475
+ serv -> onWorkerStart = http_onWorkerStart ;
1476
+ serv -> onWorkerStop = http_onWorkerStop ;
1477
+ serv -> onReceive = http_onReceive ;
1478
+ serv -> onClose = http_onClose ;
1438
1479
1439
1480
zval * zsetting = sw_zend_read_property (swoole_server_class_entry_ptr , getThis (), ZEND_STRL ("setting" ), 1 TSRMLS_CC );
1440
1481
int is_update = 0 ;
@@ -1464,7 +1505,7 @@ static PHP_METHOD(swoole_http_server, start)
1464
1505
if (serv -> listen_list -> open_websocket_protocol )
1465
1506
{
1466
1507
add_assoc_bool (zsetting , "open_websocket_protocol" , 1 );
1467
- }
1508
+ }
1468
1509
1469
1510
if (is_update ) {
1470
1511
zend_update_property (swoole_server_class_entry_ptr , getThis (), ZEND_STRL ("setting" ), zsetting TSRMLS_CC );
@@ -2369,3 +2410,74 @@ static PHP_METHOD(swoole_http_response, __destruct)
2369
2410
swoole_http_context_free (context TSRMLS_CC );
2370
2411
}
2371
2412
}
2413
+
2414
+ static void worker_error_handler (int error_num , const char * error_filename , const uint error_lineno , const char * format , va_list args )
2415
+ {
2416
+ SWOOLE_FETCH_TSRMLS ;
2417
+
2418
+ zend_bool _old_in_compilation ;
2419
+ zend_execute_data * _old_current_execute_data ;
2420
+
2421
+ _old_in_compilation = CG (in_compilation );
2422
+ _old_current_execute_data = EG (current_execute_data );
2423
+
2424
+ if (!PG (modules_activated ) || !EG (objects_store ).object_buckets || !current_ctx ) {
2425
+ call_old_error_handler (error_num , error_filename , error_lineno , format , args );
2426
+ return ;
2427
+ }
2428
+ if (error_num == E_USER_ERROR ||
2429
+ error_num == E_COMPILE_ERROR ||
2430
+ error_num == E_CORE_ERROR ||
2431
+ error_num == E_ERROR ||
2432
+ error_num == E_PARSE ) {
2433
+
2434
+ char buffer [1024 ] = {0 };
2435
+ size_t buffer_len ;
2436
+
2437
+ #ifdef va_copy
2438
+ va_list argcopy ;
2439
+ va_copy (argcopy , args );
2440
+ buffer_len = vslprintf (buffer , sizeof (buffer )- 1 , format , argcopy );
2441
+ va_end (argcopy );
2442
+ #else
2443
+ buffer_len = vslprintf (buffer , sizeof (buffer )- 1 , format , args );
2444
+ #endif
2445
+ if (buffer_len > sizeof (buffer ) - 1 || buffer_len == (size_t )-1 ) {
2446
+ buffer_len = sizeof (buffer ) - 1 ;
2447
+ }
2448
+
2449
+ current_ctx -> response .status = 500 ;
2450
+ zval * zresponse = current_ctx -> response .zobject ;
2451
+ zval * function = NULL ;
2452
+ SW_MAKE_STD_ZVAL (function );
2453
+ SW_ZVAL_STRING (function , "end" , 1 );
2454
+ zval * retval = NULL ;
2455
+ if (!current_ctx -> send_header ) {
2456
+ zval * * args [1 ];
2457
+ zval * buff ;
2458
+ SW_MAKE_STD_ZVAL (buff );
2459
+ SW_ZVAL_STRINGL (buff , buffer , buffer_len , 1 );
2460
+ args [0 ] = & buff ;
2461
+
2462
+ if (sw_call_user_function_ex (EG (function_table ), & zresponse , function , & retval , 1 , args , 0 , NULL TSRMLS_CC ) == FAILURE )
2463
+ {
2464
+ swError ("Write error msg failure" );
2465
+ }
2466
+ sw_zval_ptr_dtor (& buff );
2467
+ } else {
2468
+ if (sw_call_user_function_ex (EG (function_table ), & zresponse , function , & retval , 0 , NULL , 0 , NULL TSRMLS_CC ) == FAILURE )
2469
+ {
2470
+ swError ("Call response->end() failure" );
2471
+ }
2472
+ }
2473
+ if (retval ) sw_zval_ptr_dtor (& retval );
2474
+ sw_zval_ptr_dtor (& function );
2475
+ }
2476
+ zend_try {
2477
+ call_old_error_handler (error_num , error_filename , error_lineno , format , args );
2478
+ } zend_catch {
2479
+ CG (in_compilation ) = _old_in_compilation ;
2480
+ EG (current_execute_data ) = _old_current_execute_data ;
2481
+ } zend_end_try ();
2482
+ }
2483
+
0 commit comments