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.comIndex: 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-2024 The PHP Group All rights reserved. |
Last updated: Fri Apr 19 02:01:29 2024 UTC |