diff --git a/examples/http/server.php b/examples/http/server.php index a38f8e9d8dc..ac9dcaf2e3f 100644 --- a/examples/http/server.php +++ b/examples/http/server.php @@ -6,6 +6,7 @@ function dump($var) $key_dir = dirname(dirname(__DIR__)) . '/tests/ssl'; $http = new Swoole\Http\Server("0.0.0.0", 9501, SWOOLE_BASE); +//$http = new Swoole\Http\Server("::", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP6); //$http = new Swoole\Http\Server("0.0.0.0", 9501); //$http = new Swoole\Http\Server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); //https diff --git a/ext-src/php_swoole_cxx.h b/ext-src/php_swoole_cxx.h index cf4e1457220..992da972a52 100644 --- a/ext-src/php_swoole_cxx.h +++ b/ext-src/php_swoole_cxx.h @@ -66,6 +66,8 @@ _(SW_ZEND_STR_CLASS_NAME_RESOLVER, "Swoole\\NameResolver") \ _(SW_ZEND_STR_SOCKET, "socket") \ _(SW_ZEND_STR_CONNECTED, "connected") \ + _(SW_ZEND_STR_ADDR_LOOPBACK_V4, "127.0.0.1") \ + _(SW_ZEND_STR_ADDR_LOOPBACK_V6, "::1") \ typedef enum sw_zend_known_string_id { #define _SW_ZEND_STR_ID(id, str) id, diff --git a/ext-src/php_swoole_http.h b/ext-src/php_swoole_http.h index e690c923e53..aeb57b16a94 100644 --- a/ext-src/php_swoole_http.h +++ b/ext-src/php_swoole_http.h @@ -166,7 +166,6 @@ struct Context { size_t current_form_data_name_len; zval *current_multipart_header; String *form_data_buffer; - zend_string *addr_cache; std::string upload_tmp_dir; diff --git a/ext-src/stubs/php_swoole_http_server_coro.stub.php b/ext-src/stubs/php_swoole_http_server_coro.stub.php index fb3e0b368bc..966604fd39f 100644 --- a/ext-src/stubs/php_swoole_http_server_coro.stub.php +++ b/ext-src/stubs/php_swoole_http_server_coro.stub.php @@ -7,6 +7,6 @@ public function set(array $settings): bool {} public function handle(string $pattern, callable $callback): void {} public function start(): bool {} public function shutdown(): void {} - private function onAccept(): void {} + private function onAccept(\Swoole\Coroutine\Socket $conn): void {} } } diff --git a/ext-src/stubs/php_swoole_http_server_coro_arginfo.h b/ext-src/stubs/php_swoole_http_server_coro_arginfo.h index f48c44e5fe8..2eb6815670e 100644 --- a/ext-src/stubs/php_swoole_http_server_coro_arginfo.h +++ b/ext-src/stubs/php_swoole_http_server_coro_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 50fef9fc3f7f67d1c27a0f06cc0dbb64e1ba97bb */ + * Stub hash: 2f5ecf154780c21ccc66ba5e2fd318eb117191b0 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Coroutine_Http_Server___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) @@ -26,4 +26,6 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Coroutine_Http_Server_shutdown, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() -#define arginfo_class_Swoole_Coroutine_Http_Server_onAccept arginfo_class_Swoole_Coroutine_Http_Server_shutdown +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Coroutine_Http_Server_onAccept, 0, 1, IS_VOID, 0) + ZEND_ARG_OBJ_INFO(0, conn, Swoole\\Coroutine\\Socket, 0) +ZEND_END_ARG_INFO() diff --git a/ext-src/swoole_http_server.cc b/ext-src/swoole_http_server.cc index c3ce312b386..f978ebc2d9a 100644 --- a/ext-src/swoole_http_server.cc +++ b/ext-src/swoole_http_server.cc @@ -118,11 +118,13 @@ int php_swoole_http_server_onReceive(Server *serv, RecvData *req) { ZVAL_LONG(&tmp, conn->info.get_port()); zend_hash_str_add(ht, ZEND_STRL("remote_port"), &tmp); - if (!ctx->addr_cache) { - auto addr = conn->info.get_ip(); - ctx->addr_cache = zend_string_init(addr, strlen(addr), 0); + if (conn->info.type == SW_SOCK_TCP && IN_IS_ADDR_LOOPBACK(&conn->info.addr.inet_v4.sin_addr)) { + ZVAL_STR_COPY(&tmp, SW_ZSTR_KNOWN(SW_ZEND_STR_ADDR_LOOPBACK_V4)); + } else if (conn->info.type == SW_SOCK_TCP6 && IN6_IS_ADDR_LOOPBACK(&conn->info.addr.inet_v6.sin6_addr)) { + ZVAL_STR_COPY(&tmp, SW_ZSTR_KNOWN(SW_ZEND_STR_ADDR_LOOPBACK_V6)); + } else { + ZVAL_STRING(&tmp, conn->info.get_ip()); } - ZVAL_STR_COPY(&tmp, ctx->addr_cache); zend_hash_str_add(ht, ZEND_STRL("remote_addr"), &tmp); ZVAL_LONG(&tmp, (int) conn->last_recv_time); @@ -306,9 +308,6 @@ void HttpContext::free() { if (write_buffer) { delete write_buffer; } - if (addr_cache) { - zend_string_release(addr_cache); - } delete this; } diff --git a/ext-src/swoole_http_server_coro.cc b/ext-src/swoole_http_server_coro.cc index 0c7d38259e8..a21617c0d31 100644 --- a/ext-src/swoole_http_server_coro.cc +++ b/ext-src/swoole_http_server_coro.cc @@ -568,6 +568,9 @@ static PHP_METHOD(swoole_http_server_coro, onAccept) { std::string cid_str = std::to_string(co->get_cid()); zend::array_set(&hs->zclients, cid_str.c_str(), cid_str.length(), zconn); + auto addr = sock->get_ip(); + zend_string *remote_addr = zend_string_init(addr, strlen(addr), 0); + while (true) { _recv_request : { sock->get_socket()->recv_wait = 1; @@ -660,12 +663,8 @@ static PHP_METHOD(swoole_http_server_coro, onAccept) { add_assoc_long(zserver, "server_port", hs->socket->get_bind_port()); add_assoc_long(zserver, "remote_port", (zend_long) sock->get_port()); - if (!ctx->addr_cache) { - auto addr = sock->get_ip(); - ctx->addr_cache = zend_string_init(addr, strlen(addr), 0); - } zval tmp; - ZVAL_STR_COPY(&tmp, ctx->addr_cache); + ZVAL_STR_COPY(&tmp, remote_addr); zend_hash_str_add(Z_ARRVAL_P(zserver), ZEND_STRL("remote_addr"), &tmp); zend_fcall_info_cache *fci_cache = hs->get_handler(ctx); @@ -701,6 +700,7 @@ static PHP_METHOD(swoole_http_server_coro, onAccept) { zval_dtor(ctx->request.zobject); zval_dtor(ctx->response.zobject); } + zend_string_release(remote_addr); zend::array_unset(&hs->zclients, cid_str.c_str(), cid_str.length()); } diff --git a/include/swoole_socket.h b/include/swoole_socket.h index b330a078a84..57e22d1ce4a 100644 --- a/include/swoole_socket.h +++ b/include/swoole_socket.h @@ -47,6 +47,10 @@ #define s6_addr32 _S6_un._S6_u32 #endif +static bool IN_IS_ADDR_LOOPBACK(struct in_addr *a) { + return a->s_addr == htonl(INADDR_LOOPBACK); +} + // OS Feature #if defined(HAVE_KQUEUE) || !defined(HAVE_SENDFILE) int swoole_sendfile(int out_fd, int in_fd, off_t *offset, size_t size); @@ -110,6 +114,15 @@ struct Address { int get_port(); const char *get_addr(); + bool is_loopback_addr() { + if (type == SW_SOCK_TCP || type == SW_SOCK_UDP) { + return IN_IS_ADDR_LOOPBACK(&addr.inet_v4.sin_addr); + } else if (type == SW_SOCK_TCP6 || type == SW_SOCK_UDP6) { + return IN6_IS_ADDR_LOOPBACK(&addr.inet_v6.sin6_addr); + } + return false; + } + static bool verify_ip(int __af, const std::string &str) { char tmp_address[INET6_ADDRSTRLEN]; return inet_pton(__af, str.c_str(), tmp_address) != -1;