summaryrefslogtreecommitdiff
path: root/sapi/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cgi')
-rw-r--r--sapi/cgi/cgi_main.c243
-rw-r--r--sapi/cgi/fastcgi.c13
-rw-r--r--sapi/cgi/tests/003.phpt2
-rw-r--r--sapi/cgi/tests/008.phpt2
4 files changed, 215 insertions, 45 deletions
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 559ea1f46..840d53f3b 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -21,7 +21,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: cgi_main.c,v 1.267.2.15.2.46 2007/08/08 23:51:57 stas Exp $ */
+/* $Id: cgi_main.c,v 1.267.2.15.2.52 2007/11/01 15:23:14 dmitry Exp $ */
#include "php.h"
#include "php_globals.h"
@@ -141,6 +141,9 @@ static const opt_struct OPTIONS[] = {
{'?', 0, "usage"},/* help alias (both '?' and 'usage') */
{'v', 0, "version"},
{'z', 1, "zend-extension"},
+#if PHP_FASTCGI
+ {'T', 1, "timing"},
+#endif
{'-', 0, NULL} /* end of args */
};
@@ -308,6 +311,52 @@ static void sapi_cgibin_flush(void *server_context)
#define SAPI_CGI_MAX_HEADER_LENGTH 1024
+typedef struct _http_error {
+ int code;
+ const char* msg;
+} http_error;
+
+static const http_error http_error_codes[] = {
+ {100, "Continue"},
+ {101, "Switching Protocols"},
+ {200, "OK"},
+ {201, "Created"},
+ {202, "Accepted"},
+ {203, "Non-Authoritative Information"},
+ {204, "No Content"},
+ {205, "Reset Content"},
+ {206, "Partial Content"},
+ {300, "Multiple Choices"},
+ {301, "Moved Permanently"},
+ {302, "Moved Temporarily"},
+ {303, "See Other"},
+ {304, "Not Modified"},
+ {305, "Use Proxy"},
+ {400, "Bad Request"},
+ {401, "Unauthorized"},
+ {402, "Payment Required"},
+ {403, "Forbidden"},
+ {404, "Not Found"},
+ {405, "Method Not Allowed"},
+ {406, "Not Acceptable"},
+ {407, "Proxy Authentication Required"},
+ {408, "Request Time-out"},
+ {409, "Conflict"},
+ {410, "Gone"},
+ {411, "Length Required"},
+ {412, "Precondition Failed"},
+ {413, "Request Entity Too Large"},
+ {414, "Request-URI Too Large"},
+ {415, "Unsupported Media Type"},
+ {500, "Internal Server Error"},
+ {501, "Not Implemented"},
+ {502, "Bad Gateway"},
+ {503, "Service Unavailable"},
+ {504, "Gateway Time-out"},
+ {505, "HTTP Version not supported"},
+ {0, NULL}
+};
+
static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
char buf[SAPI_CGI_MAX_HEADER_LENGTH];
@@ -321,6 +370,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
if (CGIG(nph) || SG(sapi_headers).http_response_code != 200)
{
int len;
+ zend_bool has_status = 0;
if (CGIG(rfc2616_headers) && SG(sapi_headers).http_status_line) {
len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH,
@@ -339,11 +389,35 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0) {
len = slprintf(buf, sizeof(buf), "Status:%s\r\n", s);
} else {
- len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code);
+ h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos);
+ while (h) {
+ if (h->header_len > sizeof("Status:")-1 &&
+ strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0) {
+ has_status = 1;
+ break;
+ }
+ h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos);
+ }
+ if (!has_status) {
+ http_error *err = (http_error*)http_error_codes;
+
+ while (err->code != 0) {
+ if (err->code == SG(sapi_headers).http_response_code) {
+ break;
+ }
+ err++;
+ }
+ if (err->msg) {
+ len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->msg);
+ } else {
+ len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code);
+ }
+ }
}
}
-
- PHPWRITE_H(buf, len);
+ if (!has_status) {
+ PHPWRITE_H(buf, len);
+ }
}
h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos);
@@ -522,29 +596,44 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
{
- char *script_name = SG(request_info).request_uri;
- unsigned int script_name_len = script_name ? strlen(script_name) : 0;
- char *path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
- unsigned int path_info_len = path_info ? strlen(path_info) : 0;
- unsigned int php_self_len = script_name_len + path_info_len;
- char *php_self = emalloc(php_self_len + 1);
-
- if (script_name) {
- memcpy(php_self, script_name, script_name_len + 1);
- }
- if (path_info) {
- memcpy(php_self + script_name_len, path_info, path_info_len + 1);
- }
+ unsigned int php_self_len;
+ char *php_self;
/* In CGI mode, we consider the environment to be a part of the server
* variables
*/
php_import_environment_variables(track_vars_array TSRMLS_CC);
- /* Build the special-case PHP_SELF variable for the CGI version */
+
+#if ENABLE_PATHINFO_CHECK
+ if (CGIG(fix_pathinfo)) {
+ char *script_name = SG(request_info).request_uri;
+ unsigned int script_name_len = script_name ? strlen(script_name) : 0;
+ char *path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
+ unsigned int path_info_len = path_info ? strlen(path_info) : 0;
+
+ php_self_len = script_name_len + path_info_len;
+ php_self = emalloc(php_self_len + 1);
+ if (script_name) {
+ memcpy(php_self, script_name, script_name_len + 1);
+ }
+ if (path_info) {
+ memcpy(php_self + script_name_len, path_info, path_info_len + 1);
+ }
+
+ /* Build the special-case PHP_SELF variable for the CGI version */
+ if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
+ php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
+ }
+ efree(php_self);
+ return;
+ }
+#endif
+
+ php_self = SG(request_info).request_uri ? SG(request_info).request_uri : "";
+ php_self_len = strlen(php_self);
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
}
- efree(php_self);
}
static void sapi_cgi_log_message(char *message)
@@ -667,7 +756,11 @@ static void php_cgi_usage(char *argv0)
" -s Display colour syntax highlighted source.\n"
" -v Version number\n"
" -w Display source with stripped comments and whitespace.\n"
- " -z <file> Load Zend extension <file>.\n",
+ " -z <file> Load Zend extension <file>.\n"
+#if PHP_FASTCGI
+ " -T <count> Measure execution time of script repeated <count> times.\n"
+#endif
+ ,
prog, prog);
}
/* }}} */
@@ -777,6 +870,22 @@ static void init_request_info(TSRMLS_D)
struct stat st;
char *env_redirect_url = sapi_cgibin_getenv("REDIRECT_URL", sizeof("REDIRECT_URL")-1 TSRMLS_CC);
char *env_document_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
+ int script_path_translated_len;
+
+ /* Hack for buggy IIS that sets incorrect PATH_INFO */
+ char *env_server_software = sapi_cgibin_getenv("SERVER_SOFTWARE", sizeof("SERVER_SOFTWARE")-1 TSRMLS_CC);
+ if (env_server_software &&
+ env_script_name &&
+ env_path_info &&
+ strncmp(env_server_software, "Microsoft-IIS", sizeof("Microsoft-IIS")-1) == 0 &&
+ strncmp(env_path_info, env_script_name, strlen(env_script_name)) == 0) {
+ env_path_info = _sapi_cgibin_putenv("ORIG_PATH_INFO", env_path_info TSRMLS_CC);
+ env_path_info += strlen(env_script_name);
+ if (*env_path_info == 0) {
+ env_path_info = NULL;
+ }
+ env_path_info = _sapi_cgibin_putenv("PATH_INFO", env_path_info TSRMLS_CC);
+ }
if (CGIG(fix_pathinfo)) {
char *real_path = NULL;
@@ -814,9 +923,11 @@ static void init_request_info(TSRMLS_D)
* this fixes url's like /info.php/test
*/
if (script_path_translated &&
- (real_path = tsrm_realpath(script_path_translated, NULL TSRMLS_CC)) == NULL) {
- char *pt = estrdup(script_path_translated);
- int len = strlen(pt);
+ (script_path_translated_len = strlen(script_path_translated)) > 0 &&
+ (script_path_translated[script_path_translated_len-1] == '/' ||
+ (real_path = tsrm_realpath(script_path_translated, NULL TSRMLS_CC)) == NULL)) {
+ char *pt = estrndup(script_path_translated, script_path_translated_len);
+ int len = script_path_translated_len;
char *ptr;
while ((ptr = strrchr(pt, '/')) || (ptr = strrchr(pt, '\\'))) {
@@ -956,9 +1067,6 @@ static void init_request_info(TSRMLS_D)
SG(request_info).path_translated = estrdup(script_path_translated);
}
} else {
- if (real_path) {
- script_path_translated = real_path;
- }
/* make sure path_info/translated are empty */
if (!orig_script_filename ||
(script_path_translated != orig_script_filename &&
@@ -991,9 +1099,7 @@ static void init_request_info(TSRMLS_D)
if (script_path_translated && !strstr(script_path_translated, "..")) {
SG(request_info).path_translated = estrdup(script_path_translated);
}
- if (real_path) {
- free(real_path);
- }
+ free(real_path);
}
} else {
#endif
@@ -1171,6 +1277,13 @@ int main(int argc, char *argv[])
char *bindpath = NULL;
int fcgi_fd = 0;
fcgi_request request;
+ int repeats = 1;
+ int benchmark = 0;
+#if HAVE_GETTIMEOFDAY
+ struct timeval start, end;
+#else
+ time_t start, end;
+#endif
#ifndef PHP_WIN32
int status = 0;
#endif
@@ -1460,6 +1573,17 @@ consult the installation file that came with this distribution, or visit \n\
zend_first_try {
while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1)) != -1) {
switch (c) {
+#if PHP_FASTCGI
+ case 'T':
+ benchmark = 1;
+ repeats = atoi(php_optarg);
+#ifdef HAVE_GETTIMEOFDAY
+ gettimeofday(&start, NULL);
+#else
+ time(&start);
+#endif
+ break;
+#endif
case 'h':
case '?':
#if PHP_FASTCGI
@@ -1471,8 +1595,8 @@ consult the installation file that came with this distribution, or visit \n\
SG(headers_sent) = 1;
php_cgi_usage(argv[0]);
php_end_ob_buffers(1 TSRMLS_CC);
- exit(1);
- break;
+ exit_status = 0;
+ goto out;
}
}
php_optind = orig_optind;
@@ -1511,7 +1635,8 @@ consult the installation file that came with this distribution, or visit \n\
SG(headers_sent) = 1;
php_printf("You cannot use both -n and -c switch. Use -h for help.\n");
php_end_ob_buffers(1 TSRMLS_CC);
- exit(1);
+ exit_status = 1;
+ goto out;
}
while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0)) != -1) {
@@ -1552,9 +1677,9 @@ consult the installation file that came with this distribution, or visit \n\
SG(request_info).no_headers = 1;
}
php_print_info(0xFFFFFFFF TSRMLS_CC);
- php_end_ob_buffers(1 TSRMLS_CC);
- exit(0);
- break;
+ php_request_shutdown((void *) 0);
+ exit_status = 0;
+ goto out;
case 'l': /* syntax check mode */
no_headers = 1;
@@ -1571,8 +1696,8 @@ consult the installation file that came with this distribution, or visit \n\
print_extensions(TSRMLS_C);
php_printf("\n");
php_end_ob_buffers(1 TSRMLS_CC);
- exit(0);
- break;
+ exit_status = 0;
+ goto out;
#if 0 /* not yet operational, see also below ... */
case '': /* generate indented source mode*/
@@ -1600,9 +1725,9 @@ consult the installation file that came with this distribution, or visit \n\
#else
php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2007 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#endif
- php_end_ob_buffers(1 TSRMLS_CC);
- exit(0);
- break;
+ php_request_shutdown((void *) 0);
+ exit_status = 0;
+ goto out;
case 'w':
behavior = PHP_MODE_STRIP;
@@ -1861,7 +1986,19 @@ fastcgi_request_done:
}
#if PHP_FASTCGI
- if (!fastcgi) break;
+ if (!fastcgi) {
+ if (benchmark) {
+ repeats--;
+ if (repeats > 0) {
+ script_file = NULL;
+ php_optind = orig_optind;
+ php_optarg = orig_optarg;
+ continue;
+ }
+ }
+ break;
+ }
+
/* only fastcgi will get here */
requests++;
if (max_requests && (requests == max_requests)) {
@@ -1890,6 +2027,30 @@ fastcgi_request_done:
exit_status = 255;
} zend_end_try();
+out:
+#if PHP_FASTCGI
+ if (benchmark) {
+ int sec;
+#ifdef HAVE_GETTIMEOFDAY
+ int usec;
+
+ gettimeofday(&end, NULL);
+ sec = (int)(end.tv_sec - start.tv_sec);
+ if (end.tv_usec >= start.tv_usec) {
+ usec = (int)(end.tv_usec - start.tv_usec);
+ } else {
+ sec -= 1;
+ usec = (int)(end.tv_usec + 1000000 - start.tv_usec);
+ }
+ fprintf(stderr, "\nElapsed time: %d.%06d sec\n", sec, usec);
+#else
+ time(&end);
+ sec = (int)(end - start);
+ fprintf(stderr, "\nElapsed time: %d sec\n", sec);
+#endif
+ }
+#endif
+
SG(server_context) = NULL;
php_module_shutdown(TSRMLS_C);
sapi_shutdown();
diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c
index 143b35e69..72610ae49 100644
--- a/sapi/cgi/fastcgi.c
+++ b/sapi/cgi/fastcgi.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: fastcgi.c,v 1.4.2.13.2.27 2007/07/09 11:48:39 dmitry Exp $ */
+/* $Id: fastcgi.c,v 1.4.2.13.2.28 2007/09/07 08:26:47 dmitry Exp $ */
#include "php.h"
#include "fastcgi.h"
@@ -620,7 +620,8 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e
val_len |= (*p++ << 8);
val_len |= *p++;
}
- if (p + name_len + val_len > end) {
+ if (name_len + val_len < 0 ||
+ name_len + val_len > end - p) {
/* Malformated request */
ret = 0;
break;
@@ -676,6 +677,10 @@ static int fcgi_read_request(fcgi_request *req)
padding = hdr.paddingLength;
}
+ if (len + padding > FCGI_MAX_LENGTH) {
+ return 0;
+ }
+
req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0;
if (hdr.type == FCGI_BEGIN_REQUEST && len == sizeof(fcgi_begin_request)) {
@@ -712,6 +717,10 @@ static int fcgi_read_request(fcgi_request *req)
padding = hdr.paddingLength;
while (hdr.type == FCGI_PARAMS && len > 0) {
+ if (len + padding > FCGI_MAX_LENGTH) {
+ return 0;
+ }
+
if (safe_read(req, buf, len+padding) != len+padding) {
req->keep = 0;
return 0;
diff --git a/sapi/cgi/tests/003.phpt b/sapi/cgi/tests/003.phpt
index 0da3ca860..ea418d104 100644
--- a/sapi/cgi/tests/003.phpt
+++ b/sapi/cgi/tests/003.phpt
@@ -48,7 +48,7 @@ Content-type: text/html
<?php
class test { public $var = "test"; private $pri; function foo() { } } ?>
"
-string(%d) "Status: 404
+string(%d) "Status: 404 Not Found
X-Powered-By: PHP/%s
Content-type: text/html
diff --git a/sapi/cgi/tests/008.phpt b/sapi/cgi/tests/008.phpt
index d541ca430..40140e879 100644
--- a/sapi/cgi/tests/008.phpt
+++ b/sapi/cgi/tests/008.phpt
@@ -45,7 +45,7 @@ Content-type: text/html
<br /><span style="color: #0000BB">&lt;?php<br />$test&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"var"</span><span style="color: #007700">;&nbsp;</span><span style="color: #FF8000">//var<br />/*&nbsp;test&nbsp;class&nbsp;*/<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">test&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">$var&nbsp;</span><span style="color: #007700">=&nbsp;array();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">Test&nbsp;$arg</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"hello"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000BB">$o&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">test</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;<br /></span>
</span>
</code>"
-string(%d) "Status: 404
+string(%d) "Status: 404 Not Found
X-Powered-By: PHP/%s
Content-type: text/html