|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch php-trunk-cli-server-colors3 for Built-in web server Bug #55109Patch version 2011-07-02 15:29 UTC Return to Bug #55109 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:Developer: arraypad@gmail.com
Index: sapi/cli/php_cli_server.c
===================================================================
--- sapi/cli/php_cli_server.c (revision 312777)
+++ sapi/cli/php_cli_server.c (working copy)
@@ -101,7 +101,12 @@
#include "php_network.h"
#include "php_http_parser.h"
+#include "php_cli_server.h"
+#define OUTPUT_NOT_CHECKED -1
+#define OUTPUT_IS_TTY 1
+#define OUTPUT_NOT_TTY 0
+
typedef struct php_cli_server_poller {
fd_set rfds, wfds;
struct {
@@ -259,11 +264,16 @@
{ NULL, NULL }
};
+static int php_cli_output_is_tty = OUTPUT_NOT_CHECKED;
+
static size_t php_cli_server_client_send_through(php_cli_server_client *client, const char *str, size_t str_len);
static php_cli_server_chunk *php_cli_server_chunk_heap_new_self_contained(size_t len);
static void php_cli_server_buffer_append(php_cli_server_buffer *buffer, php_cli_server_chunk *chunk);
static void php_cli_server_logf(const char *format TSRMLS_DC, ...);
+static void php_cli_server_log_response(php_cli_server_client *client, int status, const char *message TSRMLS_DC);
+ZEND_DECLARE_MODULE_GLOBALS(cli_server);
+
static void char_ptr_dtor_p(char **p) /* {{{ */
{
pefree(*p, 1);
@@ -352,12 +362,55 @@
return NULL;
} /* }}} */
+/* {{{ cli_server module
+ */
+
+static void cli_server_init_globals(zend_cli_server_globals *cg TSRMLS_DC)
+{
+ cg->color = 0;
+}
+
+PHP_INI_BEGIN()
+ STD_PHP_INI_BOOLEAN("cli_server.color", "0", PHP_INI_ALL, OnUpdateBool, color, zend_cli_server_globals, cli_server_globals)
+PHP_INI_END()
+
+static PHP_MINIT_FUNCTION(cli_server)
+{
+ ZEND_INIT_MODULE_GLOBALS(cli_server, cli_server_init_globals, NULL);
+ REGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+static PHP_MSHUTDOWN_FUNCTION(cli_server)
+{
+ UNREGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+static PHP_MINFO_FUNCTION(cli_server)
+{
+ DISPLAY_INI_ENTRIES();
+}
+
+zend_module_entry cli_server_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "cli_server",
+ NULL,
+ PHP_MINIT(cli_server),
+ PHP_MSHUTDOWN(cli_server),
+ NULL,
+ NULL,
+ PHP_MINFO(cli_server),
+ PHP_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
static int sapi_cli_server_startup(sapi_module_struct *sapi_module) /* {{{ */
{
- if (php_module_startup(sapi_module, NULL, 0) == FAILURE) {
+ if (php_module_startup(sapi_module, &cli_server_module_entry, 1) == FAILURE) {
return FAILURE;
}
-
return SUCCESS;
} /* }}} */
@@ -880,20 +933,117 @@
return 0;
} /* }}} */
+#if HAVE_UNISTD_H
+static int php_cli_is_output_tty() /* {{{ */
+{
+ if (php_cli_output_is_tty == OUTPUT_NOT_CHECKED) {
+ php_cli_output_is_tty = isatty(STDOUT_FILENO);
+ }
+ return php_cli_output_is_tty;
+} /* }}} */
+#endif
+
+static void php_cli_server_log_response(php_cli_server_client *client, int status, const char *message TSRMLS_DC) /* {{{ */
+{
+ int color = 0, effective_status = status;
+ char *basic_buf, *message_buf = "", *error_buf = "";
+ zend_bool append_error_message = 0;
+
+ if (PG(last_error_message)) {
+ switch (PG(last_error_type)) {
+ case E_ERROR:
+ case E_CORE_ERROR:
+ case E_COMPILE_ERROR:
+ case E_USER_ERROR:
+ case E_PARSE:
+ if (status == 200) {
+ /* the status code isn't changed by a fatal error, so fake it */
+ effective_status = 500;
+ }
+
+ append_error_message = 1;
+ break;
+ }
+ }
+
+#if HAVE_UNISTD_H
+ if (CLI_SERVER_G(color) && php_cli_is_output_tty() == OUTPUT_IS_TTY) {
+ if (effective_status >= 500) {
+ /* server error: red */
+ color = 1;
+ } else if (effective_status >= 400) {
+ /* client error: yellow */
+ color = 3;
+ } else if (effective_status >= 200) {
+ /* success: green */
+ color = 2;
+ }
+ }
+#endif
+
+ /* basic */
+ spprintf(&basic_buf, 0, "%s [%d]: %s", client->addr_str, status, client->request.request_uri);
+ if (!basic_buf) {
+ return;
+ }
+
+ /* message */
+ if (message) {
+ spprintf(&message_buf, 0, " - %s", message);
+ if (!message_buf) {
+ efree(basic_buf);
+ return;
+ }
+ }
+
+ /* error */
+ if (append_error_message) {
+ spprintf(&error_buf, 0, " - %s in %s on line %d", PG(last_error_message), PG(last_error_file), PG(last_error_lineno));
+ if (!error_buf) {
+ efree(basic_buf);
+ if (message) {
+ efree(message_buf);
+ }
+ return;
+ }
+ }
+
+ if (color) {
+ php_cli_server_logf("\x1b[3%dm%s%s%s\x1b[0m" TSRMLS_CC, color, basic_buf, message_buf, error_buf);
+ } else {
+ php_cli_server_logf("%s%s%s" TSRMLS_CC, basic_buf, message_buf, error_buf);
+ }
+
+ efree(basic_buf);
+ if (message) {
+ efree(message_buf);
+ }
+ if (append_error_message) {
+ efree(error_buf);
+ }
+} /* }}} */
+
static void php_cli_server_logf(const char *format TSRMLS_DC, ...) /* {{{ */
{
- char buf[1024];
+ char *buf = NULL;
va_list ap;
#ifdef ZTS
va_start(ap, tsrm_ls);
#else
va_start(ap, format);
#endif
- vsnprintf(buf, sizeof(buf), format, ap);
+ vspprintf(&buf, 0, format, ap);
va_end(ap);
+
+ if (!buf) {
+ return;
+ }
+
if (sapi_module.log_message) {
sapi_module.log_message(buf TSRMLS_CC);
}
+
+ efree(buf);
} /* }}} */
static int php_network_listen_socket(const char *host, int *port, int socktype, int *af, socklen_t *socklen, char **errstr TSRMLS_DC) /* {{{ */
@@ -1490,6 +1640,7 @@
size_t escaped_request_uri_len;
const char *status_string = get_status_string(status);
const char *content_template = get_template_string(status);
+ char *errstr = get_last_error();
assert(status_string && content_template);
php_cli_server_content_sender_ctor(&client->content_sender);
@@ -1575,7 +1726,7 @@
php_cli_server_buffer_prepend(&client->content_sender.buffer, chunk);
}
- php_cli_server_logf("%s: %s - Sending error page (%d)" TSRMLS_CC, client->addr_str, client->request.request_uri, status);
+ php_cli_server_log_response(client, status, errstr ? errstr : "?" TSRMLS_CC);
php_cli_server_poller_add(&server->poller, POLLOUT, client->sock);
efree(escaped_request_uri);
return SUCCESS;
@@ -1612,6 +1763,7 @@
} zend_end_try();
}
+ php_cli_server_log_response(client, SG(sapi_headers).http_response_code, NULL TSRMLS_CC);
php_request_shutdown(0);
php_cli_server_close_connection(server, client TSRMLS_CC);
destroy_request_info(&SG(request_info));
@@ -1625,13 +1777,6 @@
fd = client->request.path_translated ? open(client->request.path_translated, O_RDONLY): -1;
if (fd < 0) {
- char *errstr = get_last_error();
- if (errstr) {
- php_cli_server_logf("%s: %s - %s" TSRMLS_CC, client->addr_str, client->request.request_uri, errstr);
- pefree(errstr, 1);
- } else {
- php_cli_server_logf("%s: %s - ?" TSRMLS_CC, client->addr_str, client->request.request_uri);
- }
return php_cli_server_send_error_page(server, client, 404 TSRMLS_CC);
}
@@ -1650,6 +1795,7 @@
append_http_status_line(&buffer, client->request.protocol_version, status, 1);
if (!buffer.c) {
/* out of memory */
+ php_cli_server_log_response(client, 500, NULL TSRMLS_CC);
return FAILURE;
}
append_essential_headers(&buffer, client, 1);
@@ -1666,10 +1812,12 @@
chunk = php_cli_server_chunk_heap_new(buffer.c, buffer.c, buffer.len);
if (!chunk) {
smart_str_free_ex(&buffer, 1);
+ php_cli_server_log_response(client, 500, NULL TSRMLS_CC);
return FAILURE;
}
php_cli_server_buffer_append(&client->content_sender.buffer, chunk);
}
+ php_cli_server_log_response(client, 200, NULL TSRMLS_CC);
php_cli_server_poller_add(&server->poller, POLLOUT, client->sock);
return SUCCESS;
}
@@ -1885,7 +2033,6 @@
php_cli_server_close_connection(server, client TSRMLS_CC);
return FAILURE;
} else if (status == 1) {
- php_cli_server_logf("%s: %s" TSRMLS_CC, client->addr_str, client->request.request_uri);
php_cli_server_poller_remove(&server->poller, POLLIN, client->sock);
php_cli_server_dispatch(server, client TSRMLS_CC);
} else {
Index: sapi/cli/php_cli_server.h
===================================================================
--- sapi/cli/php_cli_server.h (revision 312777)
+++ sapi/cli/php_cli_server.h (working copy)
@@ -26,6 +26,16 @@
extern sapi_module_struct cli_server_sapi_module;
extern int do_cli_server(int argc, char **argv TSRMLS_DC);
+ZEND_BEGIN_MODULE_GLOBALS(cli_server)
+ short color;
+ZEND_END_MODULE_GLOBALS(cli_server)
+
+#ifdef ZTS
+#define CLI_SERVER_G(v) TSRMG(cli_server_globals_id, zend_cli_server_globals *, v)
+#else
+#define CLI_SERVER_G(v) (cli_server_globals.v)
+#endif
+
#endif /* PHP_CLI_SERVER_H */
/*
Index: php.ini-development
===================================================================
--- php.ini-development (revision 312777)
+++ php.ini-development (working copy)
@@ -931,6 +931,10 @@
; Module Settings ;
;;;;;;;;;;;;;;;;;;;
+[CLI Server]
+; Whether the CLI web server uses ANSI color coding in its terminal output.
+cli_server.color = On
+
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
Index: php.ini-production
===================================================================
--- php.ini-production (revision 312777)
+++ php.ini-production (working copy)
@@ -927,6 +927,10 @@
; Module Settings ;
;;;;;;;;;;;;;;;;;;;
+[CLI Server]
+; Whether the CLI web server uses ANSI color coding in its terminal output.
+cli_server.color = On
+
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 07 01:00:01 2025 UTC |