Example #1
0
void swoole_process_init(int module_number TSRMLS_DC)
{
    INIT_CLASS_ENTRY(swoole_process_ce, "swoole_process", swoole_process_methods);
    swoole_process_class_entry_ptr = zend_register_internal_class(&swoole_process_ce TSRMLS_CC);

    /**
     * 31 signal constants
     */
   zval *zpcntl;
   if (sw_zend_hash_find(&module_registry, ZEND_STRS("pcntl"), (void **) &zpcntl) == FAILURE)
   {
       REGISTER_LONG_CONSTANT("SIGHUP", (long) SIGHUP, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGINT", (long) SIGINT, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGQUIT", (long) SIGQUIT, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGILL", (long) SIGILL, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGTRAP", (long) SIGTRAP, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGABRT", (long) SIGABRT, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGBUS", (long) SIGBUS, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGFPE", (long) SIGFPE, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGKILL", (long) SIGKILL, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGUSR1", (long) SIGUSR1, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGSEGV", (long) SIGSEGV, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGUSR2", (long) SIGUSR2, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGPIPE", (long) SIGPIPE, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGALRM", (long) SIGALRM, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGTERM", (long) SIGTERM, CONST_CS | CONST_PERSISTENT);
#ifdef SIGSTKFLT
       REGISTER_LONG_CONSTANT("SIGSTKFLT", (long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT);
#endif
       REGISTER_LONG_CONSTANT("SIGCHLD", (long) SIGCHLD, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGCONT", (long) SIGCONT, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGSTOP", (long) SIGSTOP, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGTSTP", (long) SIGTSTP, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGTTIN", (long) SIGTTIN, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGTTOU", (long) SIGTTOU, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGURG", (long) SIGURG, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGXCPU", (long) SIGXCPU, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGXFSZ", (long) SIGXFSZ, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGVTALRM", (long) SIGVTALRM, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGPROF", (long) SIGPROF, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGWINCH", (long) SIGWINCH, CONST_CS | CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("SIGIO", (long) SIGIO, CONST_CS | CONST_PERSISTENT);
#ifdef SIGPWR
       REGISTER_LONG_CONSTANT("SIGPWR", (long) SIGPWR, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef SIGSYS
       REGISTER_LONG_CONSTANT("SIGSYS", (long) SIGSYS, CONST_CS | CONST_PERSISTENT);
#endif
   }
}
static int websocket_handshake(swListenPort *port, http_context *ctx)
{
#if PHP_MAJOR_VERSION < 7
    TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL);
#endif

    zval *header = ctx->request.zheader;
    HashTable *ht = Z_ARRVAL_P(header);
    zval *pData;

    if (sw_zend_hash_find(ht, ZEND_STRS("sec-websocket-key"), (void **) &pData) == FAILURE)
    {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "header no sec-websocket-key");
        return SW_ERR;
    }
    convert_to_string(pData);

    swString_clear(swoole_http_buffer);
    swString_append_ptr(swoole_http_buffer, ZEND_STRL("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n"));

    int n;
    char sec_websocket_accept[128];
    memcpy(sec_websocket_accept, Z_STRVAL_P(pData), Z_STRLEN_P(pData));
    memcpy(sec_websocket_accept + Z_STRLEN_P(pData), SW_WEBSOCKET_GUID, sizeof(SW_WEBSOCKET_GUID) - 1);

    char sha1_str[20];
    bzero(sha1_str, sizeof(sha1_str));
    php_swoole_sha1(sec_websocket_accept, Z_STRLEN_P(pData) + sizeof(SW_WEBSOCKET_GUID) - 1, (unsigned char *) sha1_str);

    char encoded_str[50];
    bzero(encoded_str, sizeof(encoded_str));
    n = swBase64_encode((unsigned char *) sha1_str, sizeof(sha1_str), encoded_str);

    char _buf[128];
    n = snprintf(_buf, sizeof(_buf), "Sec-WebSocket-Accept: %*s\r\n", n, encoded_str);

    swString_append_ptr(swoole_http_buffer, _buf, n);
    swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Version: "SW_WEBSOCKET_VERSION"\r\n"));
    if (port->websocket_subprotocol)
    {
        swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Protocol: "));
        swString_append_ptr(swoole_http_buffer, port->websocket_subprotocol, port->websocket_subprotocol_length);
        swString_append_ptr(swoole_http_buffer, ZEND_STRL("\r\n"));
    }
    swString_append_ptr(swoole_http_buffer, ZEND_STRL("Server: "SW_WEBSOCKET_SERVER_SOFTWARE"\r\n\r\n"));

    swTrace("websocket header len:%ld\n%s \n", swoole_http_buffer->length, swoole_http_buffer->str);

    return swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length);
}
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);
}
Example #4
0
static void php_swoole_aio_onComplete(swAio_event *event)
{
	int isEOF = SW_FALSE;
	int64_t ret;

	zval *retval = NULL, *zcallback = NULL, *zwriten = NULL;
	zval *zcontent = NULL;
	zval **args[2];
	file_request *file_req = NULL;
	dns_request *dns_req = NULL;

#if PHP_MAJOR_VERSION < 7
    TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL);
#endif

	if (event->type == SW_AIO_DNS_LOOKUP)
	{
		dns_req = (dns_request *) event->req;
		if (dns_req->callback == NULL)
		{
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]");
			return;
		}
		zcallback = dns_req->callback;
	}
	else
	{
		if (sw_zend_hash_find(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd), (void**) &file_req) != SUCCESS)
		{
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[1]");
			return;
		}
		if (file_req->callback == NULL && file_req->type == SW_AIO_READ)
		{
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]");
			return;
		}
		zcallback = file_req->callback;
	}

	ret = event->ret;
	if (ret < 0)
	{
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: Aio Error: %s[%d]", strerror(event->error), event->error);
	}
    else if (file_req != NULL)
    {
        if (ret == 0)
        {
            bzero(event->buf, event->nbytes);
            isEOF = SW_TRUE;
        }
        else if (file_req->once == 1 && ret < file_req->content_length)
        {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: ret_length[%d] < req->length[%d].", (int) ret, file_req->content_length);
        }
        else if (event->type == SW_AIO_READ)
        {
            file_req->offset += event->ret;
        }
    }

    if (event->type == SW_AIO_READ)
    {
        SW_MAKE_STD_ZVAL(zcontent,0);
        args[0] = &file_req->filename;
        args[1] = &zcontent;
        SW_ZVAL_STRINGL(zcontent, event->buf, ret, 0);
    }
    else if (event->type == SW_AIO_WRITE)
    {
        SW_MAKE_STD_ZVAL(zwriten,0);
        args[0] = &file_req->filename;
        args[1] = &zwriten;
        ZVAL_LONG(zwriten, ret);

        if (file_req->once != 1)
        {
            if (SwooleAIO.mode == SW_AIO_LINUX)
            {
                free(event->buf);
            }
            else
            {
                efree(event->buf);
            }
        }
    }
	else if(event->type == SW_AIO_DNS_LOOKUP)
	{
		SW_MAKE_STD_ZVAL(zcontent,0);
		args[0] = &dns_req->domain;
		if (ret < 0)
		{
			SW_ZVAL_STRING(zcontent, "", 0);
		}
		else
		{
			SW_ZVAL_STRING(zcontent, event->buf, 0);
		}
		args[1] = &zcontent;
	}
	else
	{
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete unknow event type");
		return;
	}

    if (zcallback)
    {
        if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE)
        {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete handler error");
            return;
        }
    }

	//readfile/writefile
	if (file_req != NULL)
	{
		//只操作一次,完成后释放缓存区并关闭文件
		if (file_req->once == 1)
		{
			close_file:
			sw_zval_ptr_dtor(&file_req->callback);
			sw_zval_ptr_dtor(&file_req->filename);

			if (SwooleAIO.mode == SW_AIO_LINUX)
			{
			    free(event->buf);
			}
			else
			{
			    efree(event->buf);
			}
			close(event->fd);
			//remove from hashtable
			sw_zend_hash_del(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd));
		}
		else if(file_req->type == SW_AIO_WRITE)
		{
			if (retval != NULL && !Z_BVAL_P(retval))
			{
				swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename));
				goto close_file;
			}
		}
        else
        {
            if (!Z_BVAL_P(retval) || isEOF)
            {
                goto close_file;
            }
            else if (SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset) < 0)
            {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error);
            }
        }
	}
    else if (dns_req != NULL)
    {
        sw_zval_ptr_dtor(&dns_req->callback);
        sw_zval_ptr_dtor(&dns_req->domain);

        efree(dns_req);
        efree(event->buf);
    }
    if (zcontent != NULL)
    {
        efree(zcontent);
    }
    if (zwriten != NULL)
    {
        sw_zval_ptr_dtor(&zwriten);
    }
    if (retval != NULL)
    {
        sw_zval_ptr_dtor(&retval);
    }
    if (SwooleWG.in_client && SwooleG.main_reactor->event_num == 1 && SwooleAIO.task_num == 1)
    {
        SwooleG.main_reactor->running = 0;
    }
}
static PHP_METHOD(swoole_server_port, set)
{
    zval *zset = NULL;
    HashTable *vht;
    zval *v;
    vht = Z_ARRVAL_P(zset);

    if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &zset) == FAILURE)
    {
        return;
    }

    swListenPort *port = swoole_get_object(getThis());
    if (port == NULL)
    {
        swoole_php_fatal_error(E_ERROR, "Please use the swoole_server->listen method.");
        return;
    }

    //backlog
    if (sw_zend_hash_find(vht, ZEND_STRS("backlog"), (void **) &v) == SUCCESS)
    {
        convert_to_long(v);
        port->backlog = (int) Z_LVAL_P(v);
    }
    //tcp_nodelay
    if (sw_zend_hash_find(vht, ZEND_STRS("open_tcp_nodelay"), (void **) &v) == SUCCESS)
    {
        convert_to_boolean(v);
        port->open_tcp_nodelay = Z_BVAL_P(v);
    }
    //tcp_defer_accept
    if (sw_zend_hash_find(vht, ZEND_STRS("tcp_defer_accept"), (void **) &v) == SUCCESS)
    {
        convert_to_long(v);
        port->tcp_defer_accept = (uint8_t) Z_LVAL_P(v);
    }
   //port reuse
   if (sw_zend_hash_find(vht, ZEND_STRS("enable_port_reuse"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       SwooleG.reuse_port = Z_BVAL_P(v);
   }
   //tcp_keepalive
   if (sw_zend_hash_find(vht, ZEND_STRS("open_tcp_keepalive"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       port->open_tcp_keepalive = Z_BVAL_P(v);
   }
   //buffer: split package with eof
   if (sw_zend_hash_find(vht, ZEND_STRS("open_eof_split"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       port->protocol.split_by_eof = Z_BVAL_P(v);
       port->open_eof_check = 1;
   }
   //package eof
   if (sw_zend_hash_find(vht, ZEND_STRS("package_eof"), (void **) &v) == SUCCESS)
   {
       convert_to_string(v);
       port->protocol.package_eof_len = Z_STRLEN_P(v);
       if (port->protocol.package_eof_len > SW_DATA_EOF_MAXLEN)
       {
           php_error_docref(NULL TSRMLS_CC, 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));
   }
   //buffer: http_protocol
   if (sw_zend_hash_find(vht, ZEND_STRS("open_http_protocol"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       port->open_http_protocol = Z_BVAL_P(v);
   }
   //buffer: mqtt protocol
   if (sw_zend_hash_find(vht, ZEND_STRS("open_mqtt_protocol"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       port->open_mqtt_protocol = Z_BVAL_P(v);
   }
   //tcp_keepidle
   if (sw_zend_hash_find(vht, ZEND_STRS("tcp_keepidle"), (void **) &v) == SUCCESS)
   {
       convert_to_long(v);
       port->tcp_keepidle = (uint16_t) Z_LVAL_P(v);
   }
   //tcp_keepinterval
   if (sw_zend_hash_find(vht, ZEND_STRS("tcp_keepinterval"), (void **) &v) == SUCCESS)
   {
       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 (sw_zend_hash_find(vht, ZEND_STRS("open_length_check"), (void **) &v) == SUCCESS)
   {
       convert_to_boolean(v);
       port->open_length_check = Z_BVAL_P(v);
   }
   //package length size
   if (sw_zend_hash_find(vht, ZEND_STRS("package_length_type"), (void **)&v) == SUCCESS)
   {
       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)
       {
           php_error_docref(NULL TSRMLS_CC, E_ERROR, "unknow package_length_type, see pack(). Link: http://php.net/pack");
           RETURN_FALSE;
       }
   }
   //package length offset
   if (sw_zend_hash_find(vht, ZEND_STRS("package_length_offset"), (void **)&v) == SUCCESS)
   {
       convert_to_long(v);
       port->protocol.package_length_offset = (int)Z_LVAL_P(v);
   }
   //package body start
   if (sw_zend_hash_find(vht, ZEND_STRS("package_body_offset"), (void **) &v) == SUCCESS
           || sw_zend_hash_find(vht, ZEND_STRS("package_body_start"), (void **) &v) == SUCCESS)
   {
       convert_to_long(v);
       port->protocol.package_body_offset = (int) Z_LVAL_P(v);
   }
   /**
    * package max length
    */
   if (sw_zend_hash_find(vht, ZEND_STRS("package_max_length"), (void **) &v) == SUCCESS)
   {
       convert_to_long(v);
       port->protocol.package_max_length = (int) Z_LVAL_P(v);
   }
    /**
     * swoole_packet_mode
     */
    if (SwooleG.serv->packet_mode == 1)
    {
        port->protocol.package_max_length = 64 * 1024 * 1024;
        port->open_length_check = 1;
        port->protocol.package_length_offset = 0;
        port->protocol.package_body_offset = 4;
        port->protocol.package_length_type = 'N';
        port->open_eof_check = 0;
    }

#ifdef SW_USE_OPENSSL
    if (sw_zend_hash_find(vht, ZEND_STRS("ssl_cert_file"), (void **) &v) == SUCCESS)
    {
        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 (sw_zend_hash_find(vht, ZEND_STRS("ssl_key_file"), (void **) &v) == SUCCESS)
    {
        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 (sw_zend_hash_find(vht, ZEND_STRS("ssl_method"), (void **) &v) == SUCCESS)
    {
        convert_to_long(v);
        port->ssl_method = (int) Z_LVAL_P(v);
    }
    //verify client cert
    if (sw_zend_hash_find(vht, ZEND_STRS("ssl_client_cert_file"), (void **) &v) == SUCCESS)
    {
        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 (sw_zend_hash_find(vht, ZEND_STRS("ssl_verify_depth"), (void **) &v) == SUCCESS)
    {
        convert_to_long(v);
        port->ssl_verify_depth = (int) Z_LVAL_P(v);
    }
    if (port->open_ssl_encrypt && !port->ssl_key_file)
    {
        php_error_docref(NULL TSRMLS_CC, E_ERROR, "ssl require key file.");
        return;
    }
#endif
}