377 lines
13 KiB
PHP
377 lines
13 KiB
PHP
<?php
|
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
# ***** BEGIN LICENSE BLOCK *****
|
|
# This file is part of Plume Framework, a simple PHP Application Framework.
|
|
# Copyright (C) 2001-2007 Loic d'Anterroches and contributors.
|
|
#
|
|
# Plume Framework is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
# the Free Software Foundation; either version 2.1 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Plume Framework is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
#
|
|
# ***** END LICENSE BLOCK ***** */
|
|
|
|
class Pluf_HTTP_Response_ServerErrorDebug extends Pluf_HTTP_Response
|
|
{
|
|
/**
|
|
* Debug version of a server error.
|
|
*
|
|
* @param Exception The exception being raised.
|
|
* @param string Mime type
|
|
*/
|
|
function __construct($e, $mimetype=null)
|
|
{
|
|
$this->status_code = 500;
|
|
$this->content = Pluf_HTTP_Response_ServerErrorDebug_Pretty($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @credits http://www.sitepoint.com/blogs/2006/04/04/pretty-blue-screen/
|
|
*/
|
|
function Pluf_HTTP_Response_ServerErrorDebug_Pretty($e)
|
|
{
|
|
$o = create_function('$in','return htmlspecialchars($in);');
|
|
$sub = create_function('$f','$loc="";if(isset($f["class"])){
|
|
$loc.=$f["class"].$f["type"];}
|
|
if(isset($f["function"])){$loc.=$f["function"];}
|
|
if(!empty($loc)){$loc=htmlspecialchars($loc);
|
|
$loc="<strong>$loc</strong>";}return $loc;');
|
|
$parms = create_function('$f','$params=array();if(isset($f["function"])){
|
|
try{if(isset($f["class"])){
|
|
$r=new ReflectionMethod($f["class"]."::".$f["function"]);}
|
|
else{$r=new ReflectionFunction($f["function"]);}
|
|
return $r->getParameters();}catch(Exception $e){}}
|
|
return $params;');
|
|
$src2lines = create_function('$file','$src=nl2br(highlight_file($file,TRUE));
|
|
return explode("<br />",$src);');
|
|
$clean = create_function('$line','return trim(strip_tags($line));');
|
|
$desc = get_class($e)." making ".$_SERVER['REQUEST_METHOD']." request to ".
|
|
$_SERVER['REQUEST_URI'];
|
|
$out = '
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
<html lang="en">
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
|
<meta name="robots" content="NONE,NOARCHIVE" />
|
|
<title>'.$o($desc).'</title>
|
|
<style type="text/css">
|
|
html * { padding:0; margin:0; }
|
|
body * { padding:10px 20px; }
|
|
body * * { padding:0; }
|
|
body { font:small sans-serif; background: #70DBFF; }
|
|
body>div { border-bottom:1px solid #ddd; }
|
|
h1 { font-weight:normal; }
|
|
h2 { margin-bottom:.8em; }
|
|
h2 span { font-size:80%; color:#666; font-weight:normal; }
|
|
h2 a { text-decoration:none; }
|
|
h3 { margin:1em 0 .5em 0; }
|
|
h4 { margin:0.5em 0 .5em 0; font-weight: normal; font-style: italic; }
|
|
table {
|
|
border:1px solid #ccc; border-collapse: collapse; background:white; }
|
|
tbody td, tbody th { vertical-align:top; padding:2px 3px; }
|
|
thead th {
|
|
padding:1px 6px 1px 3px; background:#70FF94; text-align:left;
|
|
font-weight:bold; font-size:11px; border:1px solid #ddd; }
|
|
tbody th { text-align:right; color:#666; padding-right:.5em; }
|
|
table.vars { margin:5px 0 2px 40px; }
|
|
table.vars td, table.req td { font-family:monospace; }
|
|
table td { background: #70FFDB; }
|
|
table td.code { width:95%;}
|
|
table td.code div { overflow:hidden; }
|
|
table.source th { color:#666; }
|
|
table.source td {
|
|
font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
|
|
ul.traceback { list-style-type:none; }
|
|
ul.traceback li.frame { margin-bottom:1em; }
|
|
div.context { margin:5px 0 2px 40px; background-color:#70FFDB; }
|
|
div.context ol {
|
|
padding-left:30px; margin:0 10px; list-style-position: inside; }
|
|
div.context ol li {
|
|
font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
|
|
div.context li.current-line { color:black; background-color:#70FF94; }
|
|
div.commands { margin-left: 40px; }
|
|
div.commands a { color:black; text-decoration:none; }
|
|
p.headers { background: #70FFDB; font-family:monospace; }
|
|
#summary { background: #00B8F5; }
|
|
#summary h2 { font-weight: normal; color: #666; }
|
|
#traceback { background:#eee; }
|
|
#request { background:#f6f6f6; }
|
|
#response { background:#eee; }
|
|
#summary table { border:none; background:#00B8F5; }
|
|
#summary td { background:#00B8F5; }
|
|
.switch { text-decoration: none; }
|
|
.whitemsg { background:white; color:black;}
|
|
</style>
|
|
<script type="text/javascript">
|
|
//<!--
|
|
function getElementsByClassName(oElm, strTagName, strClassName){
|
|
// Written by Jonathan Snook, http://www.snook.ca/jon;
|
|
// Add-ons by Robert Nyman, http://www.robertnyman.com
|
|
var arrElements = (strTagName == "*" && document.all)? document.all :
|
|
oElm.getElementsByTagName(strTagName);
|
|
var arrReturnElements = new Array();
|
|
strClassName = strClassName.replace(/\-/g, "\\-");
|
|
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
|
|
var oElement;
|
|
for(var i=0; i<arrElements.length; i++){
|
|
oElement = arrElements[i];
|
|
if(oRegExp.test(oElement.className)){
|
|
arrReturnElements.push(oElement);
|
|
}
|
|
}
|
|
return (arrReturnElements)
|
|
}
|
|
function hideAll(elems) {
|
|
for (var e = 0; e < elems.length; e++) {
|
|
elems[e].style.display = \'none\';
|
|
}
|
|
}
|
|
function toggle() {
|
|
for (var i = 0; i < arguments.length; i++) {
|
|
var e = document.getElementById(arguments[i]);
|
|
if (e) {
|
|
e.style.display = e.style.display == \'none\' ? \'block\' : \'none\';
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function varToggle(link, id, prefix) {
|
|
toggle(prefix + id);
|
|
var s = link.getElementsByTagName(\'span\')[0];
|
|
var uarr = String.fromCharCode(0x25b6);
|
|
var darr = String.fromCharCode(0x25bc);
|
|
s.innerHTML = s.innerHTML == uarr ? darr : uarr;
|
|
return false;
|
|
}
|
|
function sectionToggle(span, section) {
|
|
toggle(section);
|
|
var span = document.getElementById(span);
|
|
var uarr = String.fromCharCode(0x25b6);
|
|
var darr = String.fromCharCode(0x25bc);
|
|
span.innerHTML = span.innerHTML == uarr ? darr : uarr;
|
|
return false;
|
|
}
|
|
|
|
window.onload = function() {
|
|
hideAll(getElementsByClassName(document, \'table\', \'vars\'));
|
|
hideAll(getElementsByClassName(document, \'div\', \'context\'));
|
|
hideAll(getElementsByClassName(document, \'ul\', \'traceback\'));
|
|
hideAll(getElementsByClassName(document, \'div\', \'section\'));
|
|
}
|
|
//-->
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="summary">
|
|
<h1>'.$o($desc).'</h1>
|
|
<h2>';
|
|
if ($e->getCode()) {
|
|
$out .= $o($e->getCode()). ' : ';
|
|
}
|
|
$out .= ' '.$o($e->getMessage()).'</h2>
|
|
<table>
|
|
<tr>
|
|
<th>PHP</th>
|
|
<td>'.$o($e->getFile()).', line '.$o($e->getLine()).'</td>
|
|
</tr>
|
|
<tr>
|
|
<th>URI</th>
|
|
<td>'.$o($_SERVER['REQUEST_METHOD'].' '.
|
|
$_SERVER['REQUEST_URI']).'</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div id="traceback">
|
|
<h2>Stacktrace
|
|
<a href=\'#\' onclick="return sectionToggle(\'tb_switch\',\'tb_list\')">
|
|
<span id="tb_switch">▶</span></a></h2>
|
|
<ul id="tb_list" class="traceback">';
|
|
$frames = $e->getTrace();
|
|
foreach ($frames as $frame_id=>$frame) {
|
|
if (!isset($frame['file'])) {
|
|
$frame['file'] = 'No File';
|
|
$frame['line'] = '0';
|
|
}
|
|
$out .= '<li class="frame">'.$sub($frame).'
|
|
['.$o($frame['file']).', line '.$o($frame['line']).']';
|
|
if (isset($frame['args']) && count($frame['args']) > 0) {
|
|
$params = $parms($frame);
|
|
$out .= '
|
|
<div class="commands">
|
|
<a href=\'#\' onclick="return varToggle(this, \''.
|
|
$o($frame_id).'\',\'v\')"><span>▶</span> Args</a>
|
|
</div>
|
|
<table class="vars" id="v'.$o($frame_id).'">
|
|
<thead>
|
|
<tr>
|
|
<th>Arg</th>
|
|
<th>Name</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
foreach ($frame['args'] as $k => $v) {
|
|
$name = (isset($params[$k]) and isset($params[$k]->name)) ? '$'.$params[$k]->name : '?';
|
|
$out .= '
|
|
<tr>
|
|
<td>'.$o($k).'</td>
|
|
<td>'.$o($name).'</td>
|
|
<td class="code">
|
|
<pre>'.Pluf_esc(print_r($v, true)).'</pre>
|
|
</td>
|
|
</tr>';
|
|
}
|
|
$out .= '</tbody></table>';
|
|
}
|
|
if (is_readable($frame['file']) ) {
|
|
$out .= '
|
|
<div class="commands">
|
|
<a href=\'#\' onclick="return varToggle(this, \''
|
|
.$o($frame_id).'\',\'c\')"><span>▶</span> Src</a>
|
|
</div>
|
|
<div class="context" id="c'.$o($frame_id).'">';
|
|
$lines = $src2lines($frame['file']);
|
|
$start = $frame['line'] < 5 ?
|
|
0 : $frame['line'] -5; $end = $start + 10;
|
|
$out2 = '';
|
|
foreach ( $lines as $k => $line ) {
|
|
if ( $k > $end ) { break; }
|
|
$line = trim(strip_tags($line));
|
|
if ( $k < $start && isset($frames[$frame_id+1]["function"])
|
|
&& preg_match('/function( )*'.preg_quote($frames[$frame_id+1]["function"]).'/',
|
|
$line) ) {
|
|
$start = $k;
|
|
}
|
|
if ( $k >= $start ) {
|
|
if ( $k != $frame['line'] ) {
|
|
$out2 .= '<li><code>'.$clean($line).'</code></li>'."\n"; }
|
|
else {
|
|
$out2 .= '<li class="current-line"><code>'.
|
|
$clean($line).'</code></li>'."\n"; }
|
|
}
|
|
}
|
|
$out .= "<ol start=\"$start\">\n".$out2. "</ol>\n";
|
|
$out .= '</div>';
|
|
} else {
|
|
$out .= '<div class="commands">No src available</div>';
|
|
}
|
|
$out .= '</li>';
|
|
} // End of foreach $frames
|
|
$out .= '
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div id="request">
|
|
<h2>Request
|
|
<a href=\'#\' onclick="return sectionToggle(\'req_switch\',\'req_list\')">
|
|
<span id="req_switch">▶</span></a></h2>
|
|
<div id="req_list" class="section">';
|
|
if ( function_exists('apache_request_headers') ) {
|
|
$out .= '<h3>Request <span>(raw)</span></h3>';
|
|
$req_headers = apache_request_headers();
|
|
$out .= '<h4>HEADERS</h4>';
|
|
if ( count($req_headers) > 0 ) {
|
|
$out .= '<p class="headers">';
|
|
foreach ($req_headers as $req_h_name => $req_h_val) {
|
|
$out .= $o($req_h_name.': '.$req_h_val);
|
|
$out .= '<br>';
|
|
}
|
|
$out .= '</p>';
|
|
} else {
|
|
$out .= '<p>No headers.</p>';
|
|
}
|
|
$req_body = file_get_contents('php://input');
|
|
if ( strlen( $req_body ) > 0 ) {
|
|
$out .='
|
|
<h4>Body</h4>
|
|
<p class="req" style="padding-bottom: 2em"><code>
|
|
'.$o($req_body).'
|
|
</code></p>';
|
|
}
|
|
}
|
|
$out .= '
|
|
<h3>Request <span>(parsed)</span></h3>';
|
|
$superglobals = array('$_GET','$_POST','$_COOKIE','$_SERVER','$_ENV');
|
|
foreach ( $superglobals as $sglobal ) {
|
|
$sfn = create_function('','return '.$sglobal.';');
|
|
$out .= '<h4>'.$sglobal.'</h4>';
|
|
if ( count($sfn()) > 0 ) {
|
|
$out .= '
|
|
<table class="req">
|
|
<thead>
|
|
<tr>
|
|
<th>Variable</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
foreach ( $sfn() as $k => $v ) {
|
|
$out .= '<tr>
|
|
<td>'.$o($k).'</td>
|
|
<td class="code">
|
|
<div>'.$o(print_r($v,TRUE)).'</div>
|
|
</td>
|
|
</tr>';
|
|
}
|
|
$out .= '
|
|
</tbody>
|
|
</table>';
|
|
} else {
|
|
$out .= '
|
|
<p class="whitemsg">No data</p>';
|
|
}
|
|
}
|
|
$out .= '
|
|
|
|
</div>
|
|
</div>';
|
|
if ( function_exists('headers_list') ) {
|
|
$out .= '
|
|
<div id="response">
|
|
|
|
<h2>Response
|
|
<a href=\'#\' onclick="return sectionToggle(\'resp_switch\',\'resp_list\')">
|
|
<span id="resp_switch">▶</span></a></h2>
|
|
|
|
<div id="resp_list" class="section">
|
|
|
|
<h3>Headers</h3>';
|
|
$resp_headers = headers_list();
|
|
if (count($resp_headers) > 0) {
|
|
$out .= '
|
|
<p class="headers">';
|
|
foreach ( $resp_headers as $resp_h ) {
|
|
$out .= $o($resp_h);
|
|
$out .= '<br>';
|
|
}
|
|
$out .= ' </p>';
|
|
} else {
|
|
$out .= '
|
|
<p>No headers.</p>';
|
|
}
|
|
$out .= '
|
|
</div>';
|
|
}
|
|
$out .= '
|
|
</body>
|
|
</html>
|
|
';
|
|
return $out;
|
|
}
|
|
|