summary refs log tree commit
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-08-28 07:43:00 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2015-08-28 07:43:00 -0700
commit8653e7ad4182b3dacae247d24086e19e3d4f72d3 (patch)
treecaadb83b23ca442ee2229c72546e523a08ff9856
parent53d9351b36a560a816db0b8d132b9665e81e3420 (diff)
parent48e0da23ca00dcfd350426a18e6db4bd6a44fe32 (diff)
downloadrack-8653e7ad4182b3dacae247d24086e19e3d4f72d3.tar.gz
Merge pull request #922 from mcantor/showexceptions-lazy-erb-template
Lazily instantiate ERB template object
-rw-r--r--lib/rack/show_exceptions.rb541
1 files changed, 270 insertions, 271 deletions
diff --git a/lib/rack/show_exceptions.rb b/lib/rack/show_exceptions.rb
index 50913c17..ca86b2b2 100644
--- a/lib/rack/show_exceptions.rb
+++ b/lib/rack/show_exceptions.rb
@@ -17,7 +17,6 @@ module Rack
 
     def initialize(app)
       @app = app
-      @template = ERB.new(TEMPLATE)
     end
 
     def call(env)
@@ -94,7 +93,7 @@ module Rack
         end
       }.compact
 
-      @template.result(binding)
+      TEMPLATE.result(binding)
     end
 
     def h(obj)                  # :nodoc:
@@ -108,279 +107,279 @@ module Rack
 
     # :stopdoc:
 
-# adapted from Django <djangoproject.com>
-# Copyright (c) 2005, the Lawrence Journal-World
-# Used under the modified BSD license:
-# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
-TEMPLATE = <<'HTML'
-<!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><%=h exception.class %> at <%=h path %></title>
-  <style type="text/css">
-    html * { padding:0; margin:0; }
-    body * { padding:10px 20px; }
-    body * * { padding:0; }
-    body { font:small sans-serif; }
-    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; }
-    h3 { margin:1em 0 .5em 0; }
-    h4 { margin:0 0 .5em 0; font-weight: normal; }
-    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:#fefefe; text-align:left;
-        font-weight:normal; 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.code { width:100%;}
-    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: 10px 0; }
-    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 ol.context-line li { color:black; background-color:#ccc; }
-    div.context ol.context-line li span { float: right; }
-    div.commands { margin-left: 40px; }
-    div.commands a { color:black; text-decoration:none; }
-    #summary { background: #ffc; }
-    #summary h2 { font-weight: normal; color: #666; }
-    #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
-    #summary ul#quicklinks li { float: left; padding: 0 1em; }
-    #summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
-    #explanation { background:#eee; }
-    #template, #template-not-exist { background:#f6f6f6; }
-    #template-not-exist ul { margin: 0 0 0 20px; }
-    #traceback { background:#eee; }
-    #requestinfo { background:#f6f6f6; padding-left:120px; }
-    #summary table { border:none; background:transparent; }
-    #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
-    #requestinfo h3 { margin-bottom:-1em; }
-    .error { background: #ffc; }
-    .specific { color:#cc3300; font-weight:bold; }
-  </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);
+    # adapted from Django <djangoproject.com>
+    # Copyright (c) 2005, the Lawrence Journal-World
+    # Used under the modified BSD license:
+    # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
+    TEMPLATE = ERB.new(<<-'HTML'.gsub(/^      /, ''))
+      <!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><%=h exception.class %> at <%=h path %></title>
+        <style type="text/css">
+          html * { padding:0; margin:0; }
+          body * { padding:10px 20px; }
+          body * * { padding:0; }
+          body { font:small sans-serif; }
+          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; }
+          h3 { margin:1em 0 .5em 0; }
+          h4 { margin:0 0 .5em 0; font-weight: normal; }
+          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:#fefefe; text-align:left;
+              font-weight:normal; 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.code { width:100%;}
+          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: 10px 0; }
+          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 ol.context-line li { color:black; background-color:#ccc; }
+          div.context ol.context-line li span { float: right; }
+          div.commands { margin-left: 40px; }
+          div.commands a { color:black; text-decoration:none; }
+          #summary { background: #ffc; }
+          #summary h2 { font-weight: normal; color: #666; }
+          #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
+          #summary ul#quicklinks li { float: left; padding: 0 1em; }
+          #summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
+          #explanation { background:#eee; }
+          #template, #template-not-exist { background:#f6f6f6; }
+          #template-not-exist ul { margin: 0 0 0 20px; }
+          #traceback { background:#eee; }
+          #requestinfo { background:#f6f6f6; padding-left:120px; }
+          #summary table { border:none; background:transparent; }
+          #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
+          #requestinfo h3 { margin-bottom:-1em; }
+          .error { background: #ffc; }
+          .specific { color:#cc3300; font-weight:bold; }
+        </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';
             }
-        }
-        return (arrReturnElements)
-    }
-    function hideAll(elems) {
-      for (var e = 0; e < elems.length; e++) {
-        elems[e].style.display = 'none';
-      }
-    }
-    window.onload = function() {
-      hideAll(getElementsByClassName(document, 'table', 'vars'));
-      hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
-      hideAll(getElementsByClassName(document, 'ol', 'post-context'));
-    }
-    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) {
-      toggle('v' + 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;
-    }
-    //-->
-  </script>
-</head>
-<body>
-
-<div id="summary">
-  <h1><%=h exception.class %> at <%=h path %></h1>
-  <h2><%=h exception.message %></h2>
-  <table><tr>
-    <th>Ruby</th>
-    <td>
-<% if first = frames.first %>
-      <code><%=h first.filename %></code>: in <code><%=h first.function %></code>, line <%=h frames.first.lineno %>
-<% else %>
-      unknown location
-<% end %>
-    </td>
-  </tr><tr>
-    <th>Web</th>
-    <td><code><%=h req.request_method %> <%=h(req.host + path)%></code></td>
-  </tr></table>
-
-  <h3>Jump to:</h3>
-  <ul id="quicklinks">
-    <li><a href="#get-info">GET</a></li>
-    <li><a href="#post-info">POST</a></li>
-    <li><a href="#cookie-info">Cookies</a></li>
-    <li><a href="#env-info">ENV</a></li>
-  </ul>
-</div>
-
-<div id="traceback">
-  <h2>Traceback <span>(innermost first)</span></h2>
-  <ul class="traceback">
-<% frames.each { |frame| %>
-      <li class="frame">
-        <code><%=h frame.filename %></code>: in <code><%=h frame.function %></code>
-
-          <% if frame.context_line %>
-          <div class="context" id="c<%=h frame.object_id %>">
-              <% if frame.pre_context %>
-              <ol start="<%=h frame.pre_context_lineno+1 %>" class="pre-context" id="pre<%=h frame.object_id %>">
-                <% frame.pre_context.each { |line| %>
-                <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
+          }
+          window.onload = function() {
+            hideAll(getElementsByClassName(document, 'table', 'vars'));
+            hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
+            hideAll(getElementsByClassName(document, 'ol', 'post-context'));
+          }
+          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) {
+            toggle('v' + 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;
+          }
+          //-->
+        </script>
+      </head>
+      <body>
+
+      <div id="summary">
+        <h1><%=h exception.class %> at <%=h path %></h1>
+        <h2><%=h exception.message %></h2>
+        <table><tr>
+          <th>Ruby</th>
+          <td>
+      <% if first = frames.first %>
+            <code><%=h first.filename %></code>: in <code><%=h first.function %></code>, line <%=h frames.first.lineno %>
+      <% else %>
+            unknown location
+      <% end %>
+          </td>
+        </tr><tr>
+          <th>Web</th>
+          <td><code><%=h req.request_method %> <%=h(req.host + path)%></code></td>
+        </tr></table>
+
+        <h3>Jump to:</h3>
+        <ul id="quicklinks">
+          <li><a href="#get-info">GET</a></li>
+          <li><a href="#post-info">POST</a></li>
+          <li><a href="#cookie-info">Cookies</a></li>
+          <li><a href="#env-info">ENV</a></li>
+        </ul>
+      </div>
+
+      <div id="traceback">
+        <h2>Traceback <span>(innermost first)</span></h2>
+        <ul class="traceback">
+      <% frames.each { |frame| %>
+            <li class="frame">
+              <code><%=h frame.filename %></code>: in <code><%=h frame.function %></code>
+
+                <% if frame.context_line %>
+                <div class="context" id="c<%=h frame.object_id %>">
+                    <% if frame.pre_context %>
+                    <ol start="<%=h frame.pre_context_lineno+1 %>" class="pre-context" id="pre<%=h frame.object_id %>">
+                      <% frame.pre_context.each { |line| %>
+                      <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
+                      <% } %>
+                    </ol>
+                    <% end %>
+
+                  <ol start="<%=h frame.lineno %>" class="context-line">
+                    <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h frame.context_line %><span>...</span></li></ol>
+
+                    <% if frame.post_context %>
+                    <ol start='<%=h frame.lineno+1 %>' class="post-context" id="post<%=h frame.object_id %>">
+                      <% frame.post_context.each { |line| %>
+                      <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
+                      <% } %>
+                    </ol>
+                    <% end %>
+                </div>
+                <% end %>
+            </li>
+      <% } %>
+        </ul>
+      </div>
+
+      <div id="requestinfo">
+        <h2>Request information</h2>
+
+        <h3 id="get-info">GET</h3>
+        <% if req.GET and not req.GET.empty? %>
+          <table class="req">
+            <thead>
+              <tr>
+                <th>Variable</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+                <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
+                <tr>
+                  <td><%=h key %></td>
+                  <td class="code"><div><%=h val.inspect %></div></td>
+                </tr>
+                <% } %>
+            </tbody>
+          </table>
+        <% else %>
+          <p>No GET data.</p>
+        <% end %>
+
+        <h3 id="post-info">POST</h3>
+        <% if req.POST and not req.POST.empty? %>
+          <table class="req">
+            <thead>
+              <tr>
+                <th>Variable</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+                <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
+                <tr>
+                  <td><%=h key %></td>
+                  <td class="code"><div><%=h val.inspect %></div></td>
+                </tr>
+                <% } %>
+            </tbody>
+          </table>
+        <% else %>
+          <p>No POST data.</p>
+        <% end %>
+
+
+        <h3 id="cookie-info">COOKIES</h3>
+        <% unless req.cookies.empty? %>
+          <table class="req">
+            <thead>
+              <tr>
+                <th>Variable</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+              <% req.cookies.each { |key, val| %>
+                <tr>
+                  <td><%=h key %></td>
+                  <td class="code"><div><%=h val.inspect %></div></td>
+                </tr>
+              <% } %>
+            </tbody>
+          </table>
+        <% else %>
+          <p>No cookie data.</p>
+        <% end %>
+
+        <h3 id="env-info">Rack ENV</h3>
+          <table class="req">
+            <thead>
+              <tr>
+                <th>Variable</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+                <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
+                <tr>
+                  <td><%=h key %></td>
+                  <td class="code"><div><%=h val %></div></td>
+                </tr>
                 <% } %>
-              </ol>
-              <% end %>
+            </tbody>
+          </table>
 
-            <ol start="<%=h frame.lineno %>" class="context-line">
-              <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h frame.context_line %><span>...</span></li></ol>
+      </div>
 
-              <% if frame.post_context %>
-              <ol start='<%=h frame.lineno+1 %>' class="post-context" id="post<%=h frame.object_id %>">
-                <% frame.post_context.each { |line| %>
-                <li onclick="toggle('pre<%=h frame.object_id %>', 'post<%=h frame.object_id %>')"><%=h line %></li>
-                <% } %>
-              </ol>
-              <% end %>
-          </div>
-          <% end %>
-      </li>
-<% } %>
-  </ul>
-</div>
-
-<div id="requestinfo">
-  <h2>Request information</h2>
-
-  <h3 id="get-info">GET</h3>
-  <% if req.GET and not req.GET.empty? %>
-    <table class="req">
-      <thead>
-        <tr>
-          <th>Variable</th>
-          <th>Value</th>
-        </tr>
-      </thead>
-      <tbody>
-          <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
-          <tr>
-            <td><%=h key %></td>
-            <td class="code"><div><%=h val.inspect %></div></td>
-          </tr>
-          <% } %>
-      </tbody>
-    </table>
-  <% else %>
-    <p>No GET data.</p>
-  <% end %>
-
-  <h3 id="post-info">POST</h3>
-  <% if req.POST and not req.POST.empty? %>
-    <table class="req">
-      <thead>
-        <tr>
-          <th>Variable</th>
-          <th>Value</th>
-        </tr>
-      </thead>
-      <tbody>
-          <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
-          <tr>
-            <td><%=h key %></td>
-            <td class="code"><div><%=h val.inspect %></div></td>
-          </tr>
-          <% } %>
-      </tbody>
-    </table>
-  <% else %>
-    <p>No POST data.</p>
-  <% end %>
-
-
-  <h3 id="cookie-info">COOKIES</h3>
-  <% unless req.cookies.empty? %>
-    <table class="req">
-      <thead>
-        <tr>
-          <th>Variable</th>
-          <th>Value</th>
-        </tr>
-      </thead>
-      <tbody>
-        <% req.cookies.each { |key, val| %>
-          <tr>
-            <td><%=h key %></td>
-            <td class="code"><div><%=h val.inspect %></div></td>
-          </tr>
-        <% } %>
-      </tbody>
-    </table>
-  <% else %>
-    <p>No cookie data.</p>
-  <% end %>
-
-  <h3 id="env-info">Rack ENV</h3>
-    <table class="req">
-      <thead>
-        <tr>
-          <th>Variable</th>
-          <th>Value</th>
-        </tr>
-      </thead>
-      <tbody>
-          <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
-          <tr>
-            <td><%=h key %></td>
-            <td class="code"><div><%=h val %></div></td>
-          </tr>
-          <% } %>
-      </tbody>
-    </table>
-
-</div>
-
-<div id="explanation">
-  <p>
-    You're seeing this error because you use <code>Rack::ShowExceptions</code>.
-  </p>
-</div>
-
-</body>
-</html>
-HTML
+      <div id="explanation">
+        <p>
+          You're seeing this error because you use <code>Rack::ShowExceptions</code>.
+        </p>
+      </div>
+
+      </body>
+      </html>
+    HTML
 
     # :startdoc:
   end