static PHP_METHOD(swoole_server_port, __destruct) { swoole_server_port_property *property = swoole_get_property(getThis(), 0); efree(property); swoole_set_property(getThis(), 0, NULL); swoole_set_object(getThis(), NULL); }
static PHP_METHOD(swoole_server_port, __destruct) { swoole_port_callbacks *callbacks = swoole_get_property(getThis(), 0); efree(callbacks); swoole_set_property(getThis(), 0, NULL); swoole_set_object(getThis(), NULL); }
/** * @zobject: swoole_http_client object */ static void http_client_coro_onError(swClient *cli) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zdata; zval *retval = NULL; SW_MAKE_STD_ZVAL(zdata); //return false ZVAL_BOOL(zdata, 0); zval *zobject = cli->object; php_context *sw_current_context = swoole_get_property(zobject, 1); zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); if (cli->timeout_id > 0) { php_swoole_clear_timer_coro(cli->timeout_id TSRMLS_CC); cli->timeout_id=0; } if (!cli->released) { http_client_free(zobject TSRMLS_CC); } swoole_set_object(zobject, NULL); http_client_property *hcc = swoole_get_property(zobject, 0); if(hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT){ hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; } hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; int ret = coro_resume(sw_current_context, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
static PHP_METHOD(swoole_server_port, on) { char *ha_name = NULL; zend_size_t len, i; int ret = -1; zval *cb; if (SwooleGS->start > 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server is running. Unable to set event callback now."); RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sz", &ha_name, &len, &cb) == FAILURE) { return; } swoole_port_callbacks *callbacks = swoole_get_property(getThis(), 0); swListenPort *port = swoole_get_object(getThis()); if (!port->ptr) { port->ptr = callbacks; } char *callback[PHP_SERVER_PORT_CALLBACK_NUM] = { "connect", "receive", "close", "packet", }; for (i = 0; i < PHP_SERVER_PORT_CALLBACK_NUM; i++) { if (strncasecmp(callback[i], ha_name, len) == 0) { ret = php_swoole_set_callback(callbacks->array, i, cb TSRMLS_CC); if (i == SW_SERVER_CB_onConnect && SwooleG.serv->onConnect == NULL) { SwooleG.serv->onConnect = php_swoole_onConnect; } else if (i == SW_SERVER_CB_onClose && SwooleG.serv->onClose == NULL) { SwooleG.serv->onClose = php_swoole_onClose; } break; } } if (ret < 0) { swoole_php_error(E_WARNING, "Unknown event types[%s]", ha_name); } SW_CHECK_RETURN(ret); }
static sw_inline void client_execute_callback(swClient *cli, enum client_callback_type type) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *callback = NULL; zval *retval = NULL; zval **args[1]; zval *zobject = cli->object; client_callback *cb = swoole_get_property(zobject, 0); char *callback_name; switch(type) { case SW_CLIENT_CALLBACK_onConnect: callback = cb->onConnect; callback_name = "onConnect"; break; case SW_CLIENT_CALLBACK_onError: callback = cb->onError; callback_name = "onError"; break; case SW_CLIENT_CALLBACK_onClose: callback = cb->onClose; callback_name = "onClose"; break; default: return; } if (callback == NULL || ZVAL_IS_NULL(callback)) { swoole_php_fatal_error(E_WARNING, "object have not %s callback.", callback_name); return; } args[0] = &zobject; if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "%s handler error.", callback_name); return; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } }
static void http_client_coro_onTimeout(php_context *ctx) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zdata; zval *retval = NULL; SW_MAKE_STD_ZVAL(zdata); ZVAL_BOOL(zdata, 0); //return false #if PHP_MAJOR_VERSION < 7 zval *zobject = (zval *)ctx->coro_params; #else zval _zobject = ctx->coro_params; zval *zobject = & _zobject; #endif //define time out RETURN ERROR 110 zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), 110 TSRMLS_CC); http_client *http = swoole_get_object(zobject); http->cli->released = 1; http_client_free(zobject TSRMLS_CC); swoole_set_object(zobject, NULL); http_client_property *hcc = swoole_get_property(zobject, 0); if(hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT){ hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; } hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; int ret = coro_resume(ctx, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
static sw_inline void client_free_php_context(zval *object) { //free memory php_context *context = swoole_get_property(object, 1); if (!context) { return; } if (likely(context->state == SW_CORO_CONTEXT_RUNNING)) { efree(context); } else { context->state = SW_CORO_CONTEXT_TERM; } swoole_set_property(object, 1, NULL); }
static void client_onReceive(swClient *cli, char *data, uint32_t length) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zobject = cli->object; zval *zcallback = NULL; zval **args[2]; zval *retval; zval *zdata; SW_MAKE_STD_ZVAL(zdata); SW_ZVAL_STRINGL(zdata, data, length, 1); args[0] = &zobject; args[1] = &zdata; client_callback *cb = swoole_get_property(zobject, 0); zcallback = cb->onReceive; if (zcallback == NULL || ZVAL_IS_NULL(zcallback)) { swoole_php_fatal_error(E_WARNING, "swoole_client object have not receive callback."); goto free_zdata; } if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "onReactorCallback handler error"); goto free_zdata; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
static PHP_METHOD(swoole_server_port, set) { zval *zset = NULL; HashTable *vht; zval *v; if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &zset) == FAILURE) { return; } vht = Z_ARRVAL_P(zset); swListenPort *port = swoole_get_object(getThis()); swoole_server_port_property *property = swoole_get_property(getThis(), 0); if (port == NULL || property == NULL) { swoole_php_fatal_error(E_ERROR, "Please use the swoole_server->listen method."); return; } property->setting = zset; //backlog if (php_swoole_array_get_value(vht, "backlog", v)) { convert_to_long(v); port->backlog = (int) Z_LVAL_P(v); } if (php_swoole_array_get_value(vht, "socket_buffer_size", v)) { convert_to_long(v); port->socket_buffer_size = (int) Z_LVAL_P(v); } //tcp_nodelay if (php_swoole_array_get_value(vht, "open_tcp_nodelay", v)) { convert_to_boolean(v); port->open_tcp_nodelay = Z_BVAL_P(v); } //tcp_defer_accept if (php_swoole_array_get_value(vht, "tcp_defer_accept", v)) { convert_to_long(v); port->tcp_defer_accept = (uint8_t) Z_LVAL_P(v); } //tcp_keepalive if (php_swoole_array_get_value(vht, "open_tcp_keepalive", v)) { convert_to_boolean(v); port->open_tcp_keepalive = Z_BVAL_P(v); } //buffer: split package with eof if (php_swoole_array_get_value(vht, "open_eof_split", v)) { convert_to_boolean(v); port->protocol.split_by_eof = Z_BVAL_P(v); if (port->protocol.split_by_eof) { port->open_eof_check = 1; } } //package eof if (php_swoole_array_get_value(vht, "package_eof", v)) { convert_to_string(v); port->protocol.package_eof_len = Z_STRLEN_P(v); if (port->protocol.package_eof_len > SW_DATA_EOF_MAXLEN) { swoole_php_fatal_error(E_ERROR, "pacakge_eof max length is %d", SW_DATA_EOF_MAXLEN); RETURN_FALSE; } bzero(port->protocol.package_eof, SW_DATA_EOF_MAXLEN); memcpy(port->protocol.package_eof, Z_STRVAL_P(v), Z_STRLEN_P(v)); } //http_protocol if (php_swoole_array_get_value(vht, "open_http_protocol", v)) { convert_to_boolean(v); port->open_http_protocol = Z_BVAL_P(v); } //websocket protocol if (php_swoole_array_get_value(vht, "open_websocket_protocol", v)) { convert_to_boolean(v); port->open_websocket_protocol = Z_BVAL_P(v); } #ifdef SW_USE_HTTP2 //http2 protocol if (php_swoole_array_get_value(vht, "open_http2_protocol", v)) { convert_to_boolean(v); port->open_http2_protocol = Z_BVAL_P(v); } #endif //buffer: mqtt protocol if (php_swoole_array_get_value(vht, "open_mqtt_protocol", v)) { convert_to_boolean(v); port->open_mqtt_protocol = Z_BVAL_P(v); } //tcp_keepidle if (php_swoole_array_get_value(vht, "tcp_keepidle", v)) { convert_to_long(v); port->tcp_keepidle = (uint16_t) Z_LVAL_P(v); } //tcp_keepinterval if (php_swoole_array_get_value(vht, "tcp_keepinterval", v)) { convert_to_long(v); port->tcp_keepinterval = (uint16_t) Z_LVAL_P(v); } //tcp_keepcount if (sw_zend_hash_find(vht, ZEND_STRS("tcp_keepcount"), (void **) &v) == SUCCESS) { convert_to_long(v); port->tcp_keepcount = (uint16_t) Z_LVAL_P(v); } //open length check if (php_swoole_array_get_value(vht, "open_length_check", v)) { convert_to_boolean(v); port->open_length_check = Z_BVAL_P(v); } //package length size if (php_swoole_array_get_value(vht, "package_length_type", v)) { convert_to_string(v); port->protocol.package_length_type = Z_STRVAL_P(v)[0]; port->protocol.package_length_size = swoole_type_size(port->protocol.package_length_type); if (port->protocol.package_length_size == 0) { swoole_php_fatal_error(E_ERROR, "unknow package_length_type, see pack(). Link: http://php.net/pack"); RETURN_FALSE; } } //package length offset if (php_swoole_array_get_value(vht, "package_length_offset", v)) { convert_to_long(v); port->protocol.package_length_offset = (int) Z_LVAL_P(v); } //package body start if (php_swoole_array_get_value(vht, "package_body_offset", v) || php_swoole_array_get_value(vht, "package_body_start", v)) { convert_to_long(v); port->protocol.package_body_offset = (int) Z_LVAL_P(v); } /** * package max length */ if (php_swoole_array_get_value(vht, "package_max_length", v)) { convert_to_long(v); port->protocol.package_max_length = (int) Z_LVAL_P(v); } #ifdef SW_USE_OPENSSL if (port->ssl) { if (php_swoole_array_get_value(vht, "ssl_cert_file", v)) { convert_to_string(v); if (access(Z_STRVAL_P(v), R_OK) < 0) { swoole_php_fatal_error(E_ERROR, "ssl cert file[%s] not found.", Z_STRVAL_P(v)); return; } port->ssl_cert_file = strdup(Z_STRVAL_P(v)); port->open_ssl_encrypt = 1; } if (php_swoole_array_get_value(vht, "ssl_key_file", v)) { convert_to_string(v); if (access(Z_STRVAL_P(v), R_OK) < 0) { swoole_php_fatal_error(E_ERROR, "ssl key file[%s] not found.", Z_STRVAL_P(v)); return; } port->ssl_key_file = strdup(Z_STRVAL_P(v)); } if (php_swoole_array_get_value(vht, "ssl_method", v)) { convert_to_long(v); port->ssl_method = (int) Z_LVAL_P(v); } //verify client cert if (php_swoole_array_get_value(vht, "ssl_client_cert_file", v)) { convert_to_string(v); if (access(Z_STRVAL_P(v), R_OK) < 0) { swoole_php_fatal_error(E_ERROR, "ssl cert file[%s] not found.", port->ssl_cert_file); return; } port->ssl_client_cert_file = strdup(Z_STRVAL_P(v)); } if (php_swoole_array_get_value(vht, "ssl_verify_depth", v)) { convert_to_long(v); port->ssl_verify_depth = (int) Z_LVAL_P(v); } if (php_swoole_array_get_value(vht, "ssl_prefer_server_ciphers", v)) { convert_to_boolean(v); port->ssl_config.prefer_server_ciphers = Z_BVAL_P(v); } // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_session_tickets"), (void **) &v) == SUCCESS) // { // convert_to_boolean(v); // port->ssl_config.session_tickets = Z_BVAL_P(v); // } // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_stapling"), (void **) &v) == SUCCESS) // { // convert_to_boolean(v); // port->ssl_config.stapling = Z_BVAL_P(v); // } // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_stapling_verify"), (void **) &v) == SUCCESS) // { // convert_to_boolean(v); // port->ssl_config.stapling_verify = Z_BVAL_P(v); // } if (php_swoole_array_get_value(vht, "ssl_ciphers", v)) { convert_to_string(v); port->ssl_config.ciphers = strdup(Z_STRVAL_P(v)); } if (php_swoole_array_get_value(vht, "ssl_ecdh_curve", v)) { convert_to_string(v); port->ssl_config.ecdh_curve = strdup(Z_STRVAL_P(v)); } // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_session_cache"), (void **) &v) == SUCCESS) // { // convert_to_string(v); // port->ssl_config.session_cache = strdup(Z_STRVAL_P(v)); // } if (swPort_enable_ssl_encrypt(port) < 0) { swoole_php_fatal_error(E_ERROR, "swPort_enable_ssl_encrypt() failed."); RETURN_FALSE; } } #endif zend_update_property(swoole_server_port_class_entry_ptr, getThis(), ZEND_STRL("setting"), zset TSRMLS_CC); }
static PHP_METHOD(swoole_server_port, on) { char *name = NULL; zend_size_t len, i; zval *cb; if (SwooleGS->start > 0) { swoole_php_fatal_error(E_WARNING, "Server is running. Unable to set event callback now."); RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sz", &name, &len, &cb) == FAILURE) { return; } #ifdef PHP_SWOOLE_CHECK_CALLBACK char *func_name = NULL; if (!sw_zend_is_callable(cb, 0, &func_name TSRMLS_CC)) { swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); efree(func_name); return; } efree(func_name); #endif swoole_server_port_property *property = swoole_get_property(getThis(), 0); swListenPort *port = swoole_get_object(getThis()); if (!port->ptr) { port->ptr = property; } char *callback_name[PHP_SERVER_CALLBACK_NUM] = { "Connect", "Receive", "Close", "Packet", "Start", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Request", "HandShake", "Open", "Message", }; char property_name[128]; int l_property_name = 0; memcpy(property_name, "on", 2); for (i = 0; i < PHP_SERVER_CALLBACK_NUM; i++) { if (callback_name[i] == NULL) { continue; } if (strncasecmp(callback_name[i], name, len) == 0) { memcpy(property_name + 2, callback_name[i], len); l_property_name = len + 2; property_name[l_property_name] = '\0'; zend_update_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, cb TSRMLS_CC); property->callbacks[i] = sw_zend_read_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, 0 TSRMLS_CC); sw_copy_to_stack(property->callbacks[i], property->_callbacks[i]); if (i == SW_SERVER_CB_onConnect && SwooleG.serv->onConnect == NULL) { SwooleG.serv->onConnect = php_swoole_onConnect; } else if (i == SW_SERVER_CB_onClose && SwooleG.serv->onClose == NULL) { SwooleG.serv->onClose = php_swoole_onClose; } break; } } if (l_property_name == 0) { swoole_php_error(E_WARNING, "Unknown event types[%s]", name); RETURN_FALSE; } RETURN_TRUE; }
static int http2_client_build_header(zval *zobject, http2_client_request *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; zval *zheader = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); int index = 0; int find_host = 0; nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); if (req->type == HTTP_GET) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("POST")); } http2_add_header(&nv[index++], ZEND_STRL(":path"), req->uri, req->uri_len); if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (zheader && !ZVAL_IS_NULL(zheader)) { HashTable *ht = Z_ARRVAL_P(zheader); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[3], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }
static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; int index = 0; int find_host = 0; zval *cookies = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("cookies"), 1 TSRMLS_CC); zval *method = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("method"), 1 TSRMLS_CC); zval *path = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("path"), 1 TSRMLS_CC); zval *headers = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("headers"), 1 TSRMLS_CC); nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); if (ZVAL_IS_NULL(method) || Z_TYPE_P(method) != IS_STRING || Z_STRLEN_P(method) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), Z_STRVAL_P(method), Z_STRLEN_P(method)); } if (ZVAL_IS_NULL(path) || Z_TYPE_P(path) != IS_STRING || Z_STRLEN_P(path) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":path"), "/", 1); } else { http2_add_header(&nv[index++], ZEND_STRL(":path"), Z_STRVAL_P(path), Z_STRLEN_P(path)); } if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (headers && !ZVAL_IS_NULL(headers)) { HashTable *ht = Z_ARRVAL_P(headers); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }
static void http_client_coro_onReceive(swClient *cli, char *data, uint32_t length) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zobject = cli->object; zval *retval = NULL; http_client *http = swoole_get_object(zobject); if (!http->cli) { swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); return; } //timeout if (cli->timeout_id > 0) { php_swoole_clear_timer_coro(cli->timeout_id TSRMLS_CC); cli->timeout_id=0; } long parsed_n = php_http_parser_execute(&http->parser, &http_parser_settings, data, length); http_client_property *hcc = swoole_get_property(zobject, 0); zval *zdata; SW_MAKE_STD_ZVAL(zdata); if (parsed_n < 0) { //错误情况 标志位 done defer 保存 sw_zend_call_method_with_0_params(&zobject, swoole_http_client_coro_class_entry_ptr, NULL, "close", &retval); if (retval) { sw_zval_ptr_dtor(&retval); } ZVAL_BOOL(zdata, 0); //return false if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) { //not recv yet sava data hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; //wait for recv } goto begin_resume; } //not complete if (!http->completed) { return; } // if(!hcc->defer_chunk_status){ //not recv all wait for next // return; // } ZVAL_BOOL(zdata, 1); //return false if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) { //not recv yet sava data hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 1; goto free_zdata; } begin_resume: { //if should resume /*if next cr*/ php_context *sw_current_context = swoole_get_property(zobject, 1); hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; // hcc->defer_chunk_status = 0; http->completed = 0; int ret = coro_resume(sw_current_context, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } } free_zdata: sw_zval_ptr_dtor(&zdata); }