Skip to content

Commit f95a04e

Browse files
committed
Support ephemeral ports in debug server
1 parent 1359a52 commit f95a04e

File tree

1 file changed

+93
-38
lines changed

1 file changed

+93
-38
lines changed

sapi/cli/php_cli_server.c

Lines changed: 93 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,81 @@ static void php_cli_server_client_dtor_wrapper(zval *zv) /* {{{ */
23532353
pefree(p, 1);
23542354
} /* }}} */
23552355

2356-
static int php_cli_server_ctor(php_cli_server *server, const char *addr, const char *document_root, const char *router) /* {{{ */
2356+
/**
2357+
* Parse the host and port portions of an address specifier in
2358+
* one of the following forms:
2359+
* - hostOrIP
2360+
* - [hostOrIp]
2361+
* - hostOrIP:port
2362+
* - [hostOrIP]:port
2363+
*/
2364+
static char *php_cli_server_parse_addr(const char *addr, int *pport) {
2365+
const char *p, *end;
2366+
long port;
2367+
2368+
if (addr[0] == '[') {
2369+
/* Encapsulated [hostOrIP]:port or just [hostOrIP] */
2370+
const char *start = addr + 1;
2371+
end = strchr(start, ']');
2372+
if (!end) {
2373+
/* No ending ] delimiter to match [ */
2374+
return NULL;
2375+
}
2376+
2377+
p = end + 1;
2378+
if (*p == '\0') {
2379+
/* host only, implied port 0 */
2380+
*pport = 0;
2381+
return pestrndup(start, end - start, 1);
2382+
}
2383+
2384+
if (*p != ':') {
2385+
/* Invalid char following address */
2386+
return NULL;
2387+
}
2388+
2389+
port = strtol(p + 1, (char**)&p, 10);
2390+
if (p && *p) {
2391+
/* Non-numeric in port */
2392+
return NULL;
2393+
}
2394+
if (port < 0 || port > 65535) {
2395+
/* Invalid port */
2396+
return NULL;
2397+
}
2398+
2399+
/* Full [hostOrIP]:port provided */
2400+
*pport = (int)port;
2401+
return pestrndup(start, end - start, 1);
2402+
}
2403+
2404+
end = strchr(addr, ':');
2405+
if (!end) {
2406+
/* host only, implied port 0 */
2407+
*pport = 0;
2408+
return pestrdup(addr, 1);
2409+
}
2410+
2411+
if (strchr(end + 1, ':')) {
2412+
/* Probably a bare IPv6 */
2413+
*pport = 0;
2414+
return pestrdup(addr, 1);
2415+
}
2416+
2417+
port = strtol(end + 1, (char**)&p, 10);
2418+
if (p && *p) {
2419+
/* Non-numeric port */
2420+
return NULL;
2421+
}
2422+
if (port < 0 || port > 65535) {
2423+
/* Invalid port */
2424+
return NULL;
2425+
}
2426+
*pport = (int)port;
2427+
return pestrndup(addr, end - addr, 1);
2428+
}
2429+
2430+
static int php_cli_server_ctor(php_cli_server *server, const char *addr, const char *document_root, const char *router, const char **phost, int *pport) /* {{{ */
23572431
{
23582432
int retval = SUCCESS;
23592433
char *host = NULL;
@@ -2363,40 +2437,9 @@ static int php_cli_server_ctor(php_cli_server *server, const char *addr, const c
23632437
int err = 0;
23642438
int port = 3000;
23652439
php_socket_t server_sock = SOCK_ERR;
2366-
char *p = NULL;
23672440

2368-
if (addr[0] == '[') {
2369-
host = pestrdup(addr + 1, 1);
2370-
if (!host) {
2371-
return FAILURE;
2372-
}
2373-
p = strchr(host, ']');
2374-
if (p) {
2375-
*p++ = '\0';
2376-
if (*p == ':') {
2377-
port = strtol(p + 1, &p, 10);
2378-
if (port <= 0 || port > 65535) {
2379-
p = NULL;
2380-
}
2381-
} else if (*p != '\0') {
2382-
p = NULL;
2383-
}
2384-
}
2385-
} else {
2386-
host = pestrdup(addr, 1);
2387-
if (!host) {
2388-
return FAILURE;
2389-
}
2390-
p = strchr(host, ':');
2391-
if (p) {
2392-
*p++ = '\0';
2393-
port = strtol(p, &p, 10);
2394-
if (port <= 0 || port > 65535) {
2395-
p = NULL;
2396-
}
2397-
}
2398-
}
2399-
if (!p) {
2441+
host = php_cli_server_parse_addr(addr, &port);
2442+
if (!host) {
24002443
fprintf(stderr, "Invalid address: %s\n", addr);
24012444
retval = FAILURE;
24022445
goto out;
@@ -2457,7 +2500,14 @@ static int php_cli_server_ctor(php_cli_server *server, const char *addr, const c
24572500

24582501
server->is_running = 1;
24592502
out:
2460-
if (retval != SUCCESS) {
2503+
if (retval == SUCCESS) {
2504+
if (phost) {
2505+
*phost = host;
2506+
}
2507+
if (pport) {
2508+
*pport = port;
2509+
}
2510+
} else {
24612511
if (host) {
24622512
pefree(host, 1);
24632513
}
@@ -2644,6 +2694,8 @@ int do_cli_server(int argc, char **argv) /* {{{ */
26442694
int php_optind = 1;
26452695
int c;
26462696
const char *server_bind_address = NULL;
2697+
const char *server_bound_host = NULL;
2698+
int server_bound_port = 0;
26472699
extern const opt_struct OPTIONS[];
26482700
const char *document_root = NULL;
26492701
#ifdef PHP_WIN32
@@ -2714,16 +2766,19 @@ int do_cli_server(int argc, char **argv) /* {{{ */
27142766
router = argv[php_optind];
27152767
}
27162768

2717-
if (FAILURE == php_cli_server_ctor(&server, server_bind_address, document_root, router)) {
2769+
if (FAILURE == php_cli_server_ctor(&server, server_bind_address, document_root, router,
2770+
&server_bound_host, &server_bound_port)) {
27182771
return 1;
27192772
}
27202773
sapi_module.phpinfo_as_text = 0;
27212774

27222775
{
2776+
zend_bool ipv6 = strchr(server_bound_host, ':');
27232777
php_cli_server_logf(
27242778
PHP_CLI_SERVER_LOG_PROCESS,
2725-
"PHP %s Development Server (http://%s) started",
2726-
PHP_VERSION, server_bind_address);
2779+
"PHP %s Development Server (http://%s%s%s:%d) started",
2780+
PHP_VERSION, ipv6 ? "[" : "", server_bound_host,
2781+
ipv6 ? "]" : "", server_bound_port);
27272782
}
27282783

27292784
#if defined(SIGINT)

0 commit comments

Comments
 (0)