summaryrefslogtreecommitdiff
path: root/sapi/cli/php_cli_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cli/php_cli_server.c')
-rw-r--r--sapi/cli/php_cli_server.c201
1 files changed, 166 insertions, 35 deletions
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index 375aa25c42..6cefa2de9f 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -105,6 +105,8 @@
#include "php_http_parser.h"
#include "php_cli_server.h"
+#include "php_cli_process_title.h"
+
#define OUTPUT_NOT_CHECKED -1
#define OUTPUT_IS_TTY 1
#define OUTPUT_NOT_TTY 0
@@ -131,6 +133,7 @@ typedef struct php_cli_server_request {
char *query_string;
size_t query_string_len;
HashTable headers;
+ HashTable headers_original_case;
char *content;
size_t content_len;
const char *ext;
@@ -254,7 +257,7 @@ static php_cli_server_http_response_status_code_pair status_map[] = {
static php_cli_server_http_response_status_code_pair template_map[] = {
{ 400, "<h1>%s</h1><p>Your browser sent a request that this server could not understand.</p>" },
- { 404, "<h1>%s</h1><p>The requested resource %s was not found on this server.</p>" },
+ { 404, "<h1>%s</h1><p>The requested resource <code class=\"url\">%s</code> was not found on this server.</p>" },
{ 500, "<h1>%s</h1><p>The server is temporarily unavailable.</p>" },
{ 501, "<h1>%s</h1><p>Request method not supported.</p>" }
};
@@ -268,12 +271,52 @@ static php_cli_server_ext_mime_type_pair mime_type_map[] = {
{ "jpg", "image/jpeg" },
{ "jpeg", "image/jpeg" },
{ "jpe", "image/jpeg" },
+ { "pdf", "application/pdf" },
{ "png", "image/png" },
{ "svg", "image/svg+xml" },
{ "txt", "text/plain" },
{ "webm", "video/webm" },
{ "ogv", "video/ogg" },
{ "ogg", "audio/ogg" },
+ { "3gp", "video/3gpp" }, /* This is standard video format used for MMS in phones */
+ { "apk", "application/vnd.android.package-archive" },
+ { "avi", "video/x-msvideo" },
+ { "bmp", "image/x-ms-bmp" },
+ { "csv", "text/comma-separated-values" },
+ { "doc", "application/msword" },
+ { "docx", "application/msword" },
+ { "flac", "audio/flac" },
+ { "gz", "application/x-gzip" },
+ { "gzip", "application/x-gzip" },
+ { "ics", "text/calendar" },
+ { "kml", "application/vnd.google-earth.kml+xml" },
+ { "kmz", "application/vnd.google-earth.kmz" },
+ { "m4a", "audio/mp4" },
+ { "mp3", "audio/mpeg" },
+ { "mp4", "video/mp4" },
+ { "mpg", "video/mpeg" },
+ { "mpeg", "video/mpeg" },
+ { "mov", "video/quicktime" },
+ { "odp", "application/vnd.oasis.opendocument.presentation" },
+ { "ods", "application/vnd.oasis.opendocument.spreadsheet" },
+ { "odt", "application/vnd.oasis.opendocument.text" },
+ { "oga", "audio/ogg" },
+ { "pdf", "application/pdf" },
+ { "pptx", "application/vnd.ms-powerpoint" },
+ { "pps", "application/vnd.ms-powerpoint" },
+ { "qt", "video/quicktime" },
+ { "swf", "application/x-shockwave-flash" },
+ { "tar", "application/x-tar" },
+ { "text", "text/plain" },
+ { "tif", "image/tiff" },
+ { "wav", "audio/wav" },
+ { "wmv", "video/x-ms-wmv" },
+ { "xls", "application/vnd.ms-excel" },
+ { "xlsx", "application/vnd.ms-excel" },
+ { "zip", "application/x-zip-compressed" },
+ { "xml", "application/xml" },
+ { "xsl", "application/xml" },
+ { "xsd", "application/xml" },
{ NULL, NULL }
};
@@ -291,8 +334,10 @@ ZEND_DECLARE_MODULE_GLOBALS(cli_server);
* copied from ext/standard/info.c
*/
static const char php_cli_server_css[] = "<style>\n" \
- "body { background-color: #ffffff; color: #000000; }\n" \
- "h1 { font-family: sans-serif; font-size: 150%; background-color: #9999cc; font-weight: bold; color: #000000; margin-top: 0;}\n" \
+ "body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; }\n" \
+ "h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; }\n" \
+ "h1, p { padding-left: 10px; }\n" \
+ "code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;}\n" \
"</style>\n";
/* }}} */
@@ -432,6 +477,75 @@ static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */
return NULL;
} /* }}} */
+PHP_FUNCTION(apache_request_headers) /* {{{ */
+{
+ php_cli_server_client *client;
+ HashTable *headers;
+ char *key;
+ uint key_len;
+ char **value_pointer;
+ HashPosition pos;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ client = SG(server_context);
+ headers = &client->request.headers_original_case;
+
+ array_init_size(return_value, zend_hash_num_elements(headers));
+
+ zend_hash_internal_pointer_reset_ex(headers, &pos);
+ while (zend_hash_get_current_data_ex(headers, (void **)&value_pointer, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(headers, &key, &key_len, NULL, 0, &pos);
+ add_assoc_string_ex(return_value, key, key_len, *value_pointer, 1);
+ zend_hash_move_forward_ex(headers, &pos);
+ }
+}
+/* }}} */
+
+static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS_DC) /* {{{ */
+{
+ char *s, *p;
+ int len;
+ ALLOCA_FLAG(use_heap)
+
+ if (h->header_len > 0) {
+ p = strchr(h->header, ':');
+ len = p - h->header;
+ if (p && (len > 0)) {
+ while (len > 0 && (h->header[len-1] == ' ' || h->header[len-1] == '\t')) {
+ len--;
+ }
+ if (len) {
+ s = do_alloca(len + 1, use_heap);
+ memcpy(s, h->header, len);
+ s[len] = 0;
+ do {
+ p++;
+ } while (*p == ' ' || *p == '\t');
+ add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1);
+ free_alloca(s, use_heap);
+ }
+ }
+ }
+}
+/* }}} */
+
+PHP_FUNCTION(apache_response_headers) /* {{{ */
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ if (!&SG(sapi_headers).headers) {
+ RETURN_FALSE;
+ }
+ array_init(return_value);
+ zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t)add_response_header, return_value TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ cli_server module
*/
@@ -476,6 +590,18 @@ zend_module_entry cli_server_module_entry = {
};
/* }}} */
+ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0)
+ZEND_END_ARG_INFO()
+
+const zend_function_entry server_additional_functions[] = {
+ PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
+ PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
+ PHP_FE(apache_request_headers, arginfo_no_args)
+ PHP_FE(apache_response_headers, arginfo_no_args)
+ PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args)
+ {NULL, NULL, NULL}
+};
+
static int sapi_cli_server_startup(sapi_module_struct *sapi_module) /* {{{ */
{
if (php_module_startup(sapi_module, &cli_server_module_entry, 1) == FAILURE) {
@@ -1290,6 +1416,7 @@ static int php_cli_server_request_ctor(php_cli_server_request *req) /* {{{ */
req->query_string = NULL;
req->query_string_len = 0;
zend_hash_init(&req->headers, 0, NULL, (void(*)(void*))char_ptr_dtor_p, 1);
+ zend_hash_init(&req->headers_original_case, 0, NULL, NULL, 1);
req->content = NULL;
req->content_len = 0;
req->ext = NULL;
@@ -1315,6 +1442,7 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */
pefree(req->query_string, 1);
}
zend_hash_destroy(&req->headers);
+ zend_hash_destroy(&req->headers_original_case);
if (req->content) {
pefree(req->content, 1);
}
@@ -1557,9 +1685,14 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p
return 1;
}
{
- char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
- zend_hash_add(&client->request.headers, header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
- efree(header_name);
+ /* strip off the colon */
+ char *orig_header_name = estrndup(client->current_header_name, client->current_header_name_len);
+ char *lc_header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
+
+ zend_hash_add(&client->request.headers, lc_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
+ zend_hash_add(&client->request.headers_original_case, orig_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
+ efree(lc_header_name);
+ efree(orig_header_name);
}
if (client->current_header_name_allocated) {
@@ -1984,40 +2117,38 @@ static int php_cli_server_request_shutdown(php_cli_server *server, php_cli_serve
static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) /* {{{ */
{
int decline = 0;
- if (!php_handle_special_queries(TSRMLS_C)) {
- zend_file_handle zfd;
- char *old_cwd;
-
- ALLOCA_FLAG(use_heap)
- old_cwd = do_alloca(MAXPATHLEN, use_heap);
- old_cwd[0] = '\0';
- php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
-
- zfd.type = ZEND_HANDLE_FILENAME;
- zfd.filename = server->router;
- zfd.handle.fp = NULL;
- zfd.free_filename = 0;
- zfd.opened_path = NULL;
-
- zend_try {
- zval *retval = NULL;
- if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, &retval, 1, &zfd)) {
- if (retval) {
- decline = Z_TYPE_P(retval) == IS_BOOL && !Z_LVAL_P(retval);
- zval_ptr_dtor(&retval);
- }
- } else {
- decline = 1;
+ zend_file_handle zfd;
+ char *old_cwd;
+
+ ALLOCA_FLAG(use_heap)
+ old_cwd = do_alloca(MAXPATHLEN, use_heap);
+ old_cwd[0] = '\0';
+ php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
+
+ zfd.type = ZEND_HANDLE_FILENAME;
+ zfd.filename = server->router;
+ zfd.handle.fp = NULL;
+ zfd.free_filename = 0;
+ zfd.opened_path = NULL;
+
+ zend_try {
+ zval *retval = NULL;
+ if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, &retval, 1, &zfd)) {
+ if (retval) {
+ decline = Z_TYPE_P(retval) == IS_BOOL && !Z_LVAL_P(retval);
+ zval_ptr_dtor(&retval);
}
- } zend_end_try();
-
- if (old_cwd[0] != '\0') {
- php_ignore_value(VCWD_CHDIR(old_cwd));
+ } else {
+ decline = 1;
}
+ } zend_end_try();
- free_alloca(old_cwd, use_heap);
+ if (old_cwd[0] != '\0') {
+ php_ignore_value(VCWD_CHDIR(old_cwd));
}
+ free_alloca(old_cwd, use_heap);
+
return decline;
}
/* }}} */