@@ -56,6 +56,8 @@ swString *swoole_zlib_buffer = NULL;
5656#endif
5757swString * swoole_http_form_data_buffer ;
5858
59+ static http_context * current_ctx = NULL ;
60+
5961enum http_global_flag
6062{
6163 HTTP_GLOBAL_GET = 1u << 1 ,
@@ -86,6 +88,10 @@ zend_class_entry *swoole_http_response_class_entry_ptr;
8688static zend_class_entry swoole_http_request_ce ;
8789zend_class_entry * swoole_http_request_class_entry_ptr ;
8890
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 );
8995static int http_onReceive (swServer * serv , swEventData * req );
9096static void http_onClose (swServer * serv , swDataHead * info );
9197
@@ -114,6 +120,22 @@ static int http_trim_double_quote(zval **value, char **ptr);
114120#define http_strncasecmp (const_str , at , length ) ((length >= sizeof(const_str)-1) &&\
115121 (strncasecmp(at, ZEND_STRL(const_str)) == 0))
116122
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+
117139//header filed format,like:Content-Type
118140static inline void http_header_key_format (char * key , int length )
119141{
@@ -916,6 +938,19 @@ static int http_request_message_complete(php_http_parser *parser)
916938 return 0 ;
917939}
918940
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+
919954static int http_onReceive (swServer * serv , swEventData * req )
920955{
921956 if (swEventData_is_dgram (req -> info .type ))
@@ -1058,6 +1093,8 @@ static int http_onReceive(swServer *serv, swEventData *req)
10581093 }
10591094 }
10601095
1096+ current_ctx = ctx ;
1097+
10611098 if (sw_call_user_function_ex (EG (function_table ), NULL , zcallback , & retval , 2 , args , 0 , NULL TSRMLS_CC ) == FAILURE )
10621099 {
10631100 swError ("onRequest handler error" );
@@ -1068,6 +1105,8 @@ static int http_onReceive(swServer *serv, swEventData *req)
10681105 zend_exception_error (EG (exception ), E_ERROR TSRMLS_CC );
10691106 }
10701107
1108+ current_ctx = NULL ;
1109+
10711110 //websocket user handshake
10721111 if (conn -> websocket_status == WEBSOCKET_STATUS_HANDSHAKE )
10731112 {
@@ -1433,8 +1472,10 @@ static PHP_METHOD(swoole_http_server, start)
14331472 }
14341473#endif
14351474
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 ;
14381479
14391480 zval * zsetting = sw_zend_read_property (swoole_server_class_entry_ptr , getThis (), ZEND_STRL ("setting" ), 1 TSRMLS_CC );
14401481 int is_update = 0 ;
@@ -1464,7 +1505,7 @@ static PHP_METHOD(swoole_http_server, start)
14641505 if (serv -> listen_list -> open_websocket_protocol )
14651506 {
14661507 add_assoc_bool (zsetting , "open_websocket_protocol" , 1 );
1467- }
1508+ }
14681509
14691510 if (is_update ) {
14701511 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)
23692410 swoole_http_context_free (context TSRMLS_CC );
23702411 }
23712412}
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