[tahoe-dev] [tahoe-lafs] #698: corrupted file displayed to user after failure to download followed by retry

tahoe-lafs trac at allmydata.org
Thu May 14 22:33:58 UTC 2009


#698: corrupted file displayed to user after failure to download followed by
retry
--------------------------+-------------------------------------------------
 Reporter:  zooko         |           Owner:       
     Type:  defect        |          Status:  new  
 Priority:  critical      |       Milestone:  1.5.0
Component:  code-network  |         Version:  1.4.1
 Keywords:  integrity     |   Launchpad_bug:       
--------------------------+-------------------------------------------------

Comment(by zooko):

 Okay, re topic 2 from [comment:5], I see that the corrupted page that I
 get is actually the ''complete'' contents of my wiki ''with the first 2302
 or 2306 bytes of it overwritten by the Twisted error messages''.

 That is: my wiki begins with the following 4000 bytes:

 {{{
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"><head>


 <script id="versionArea" type="text/javascript">
 //<![CDATA[
 var version = {title: "TiddlyWiki", major: 2, minor: 5, revision: 0, date:
 new Date("Mar 9, 2009"), extensions: {}};
 //]]>
 </script>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <meta name="copyright" content="TiddlyWiki created by Jeremy Ruston,
 (jeremy [at] osmosoft [dot] com)

 Copyright (c) UnaMesa Association 2004-2009

 Redistribution and use in source and binary forms, with or without
 modification,
 are permitted provided that the following conditions are met:

 Redistributions of source code must retain the above copyright notice,
 this
 list of conditions and the following disclaimer.

 Redistributions in binary form must reproduce the above copyright notice,
 this
 list of conditions and the following disclaimer in the documentation
 and/or other
 materials provided with the distribution.

 Neither the name of the UnaMesa Association nor the names of its
 contributors may be
 used to endorse or promote products derived from this software without
 specific
 prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS
 IS' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 NO EVENT
 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR
 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN
 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH
 DAMAGE.">
 <script id="jsheadArea" type="text/javascript">
 //<![CDATA[
 /*
  * jQuery JavaScript Library v1.3.2
  * http://jquery.com/
  *
  * Copyright (c) 2009 John Resig
  * Dual licensed under the MIT and GPL licenses.
  * http://docs.jquery.com/License
  *
  * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
  * Revision: 6246
  */
 (function(){var
 l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new
 o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return
 this}if(typeof E==="string"){var
 G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var
 I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var
 F=o(I||[]);F.context=document;F.selector=E;return F}}else{return
 o(H).find(E)}}else{if(o.isFunction(E)){return
 o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return
 this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return
 this.length},get:function(E){return
 E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var
 G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?"
 ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return
 G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return
 this},each:function(F,E){return o.each(this,F,E)},index:function(E){return
 o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof
 F==="string"){if(H===g){return
 this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return
 this.each(function(I){for(F in
 E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return
 this.attr(E,F,"curCSS")},text:function(F){if(typeof
 F!=="object"&&F!=null){return
 this.empty().append((this[0]&&this[0].ownerDocument||do
 }}}

 When I encountered this failure the first time, the first 4000 bytes of
 the resulting page that I got looked like this:

 {{{
 <html><head><title>Exception</title></head><body><style type="text/css">
 p.error {
   color: black;
   font-family: Verdana, Arial, helvetica, sans-serif;
   font-weight: bold;
   font-size: large;
   margin: 0.25em;
 }

 div {
   font-family: Verdana, Arial, helvetica, sans-serif;
 }

 strong.variableClass {
   font-size: small;
 }

 div.stackTrace {
 }

 div.frame {
   padding: 0.25em;
   background: white;
   border-bottom: thin black dotted;
 }

 div.firstFrame {
   padding: 0.25em;
   background: white;
   border-top: thin black dotted;
   border-bottom: thin black dotted;
 }

 div.location {
     font-size: small;
 }

 div.snippet {
   background: #FFFFDD;
   padding: 0.25em;
 }

 div.snippetHighlightLine {
   color: red;
 }

 span.lineno {
     font-size: small;
 }

 pre.code {
   margin: 0px;
   padding: 0px;
   display: inline;
   font-size: small;
   font-family: "Courier New", courier, monotype;
 }

 span.function {
   font-weight: bold;
   font-family: "Courier New", courier, monotype;
 }

 table.variables {
   border-collapse: collapse;
   width: 100%;
 }

 td.varName {
   width: 1in;
   vertical-align: top;
   font-style: italic;
   font-size: small;
   padding-right: 0.25em;
 }

 td.varValue {
   padding-left: 0.25em;
   padding-right: 0.25em;
   font-size: small;
 }

 div.variables {
   margin-top: 0.5em;
 }

 div.dict {
   background: #cccc99;
   padding: 2px;
   float: left;
 }

 td.dictKey {
   background: #ffff99;
   font-weight: bold;
 }

 td.dictValue {
   background: #ffff99;
 }

 div.list {
   background: #7777cc;
   padding: 2px;
   float: left;
 }

 div.listItem {
   background: #9999ff;
 }

 div.instance {
   width: 100%;
   background: #efefef;
   padding: 2px;
   float: left;
 }

 span.instanceName {
   font-size: small;
   display: block;
 }

 span.instanceRepr {
   font-family: "Courier New", courier, monotype;
 }

 div.function {
   background: orange;
   font-weight: bold;
   float: left;
 }
 </style><a href="#tracebackEnd"><p class="error"><class
 'twisted.internet.defer.FirstError'>:
 FirstError(<twisted.python.failure.Failure <class
 'foolscap.ipb.DeadReferenceError'>>, 2)</p></a><div
 class="stackTrace"></div><a name="tracebackEnd"><p class="error"><class
 'twisted.internet.defer.FirstError'>:
 FirstError(<twisted.python.failure.Failure <class
 'foolscap.ipb.DeadReferenceError'>>, 2)</p></a></body></html>, 19
 Feb 2009)
  * Revision: 6246
  */
 (function(){var
 l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new
 o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return
 this}if(typeof E==="string"){var
 G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var
 I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var
 F=o(I||[]);F.context=document;F.selector=E;return F}}else{return
 o(H).find(E)}}else{if(o.isFunction(E)){return
 o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return
 this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return
 this.length},get:function(E){return
 E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var
 G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?"
 ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return
 G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return
 this},each:function(F,E){return o.each(this,F,E)},index:function(E){return
 o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof
 F==="string"){if(H===g){return
 this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return
 this.each(function(I){for(F in
 E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return
 this.attr(E,F,"curCSS")},text:function(F){if(typeof
 F!=="object"&&F!=null){return
 this.empty().append((this[0]&&this[0].ownerDocument
 }}}

 See what I mean?  It looks like Firefox 3.5b4 has overwritten the first
 2302 or so bytes of the file with the twisted error message.  Note that it
 doesn't exactly line up -- the twisted error message from {{{<html>}}} to
 {{{</html>}}} inclusive is 2302 bytes, but the first bytes of the original
 file {{{, 19 Feb 2009)}}} I would expect to begin on byte 2306 rather than
 byte 2302.  Maybe there was a newline conversion or the header got subtly
 rewritten a little between the time I captured the above view of "my wiki"
 and the time the bad wiki was emitted.

 Anyway, this makes me pretty sure that Firefox-3.5b4 is doing something
 mighty funny here.  Certainly I don't think Tahoe is sending those bytes
 down in an HTTP response.  Indeed, from the "Current Uploads Downloads"
 log, we can see that Tahoe wasn't asked for the contents of the wiki at
 all (the "update in MODE_READ" and the "retrieve" operations are the get
 the ''directory'', not to get the actual {{{wiki.html}}} file from the
 directory).  Firefox-3.5b4 must have supplied the cached contents of the
 wiki itself, then overwritten the first few bytes of it with the twisted
 error message, then displayed it to the user.  Ugh.

 I suppose we should report this on the firefox issue tracker...

-- 
Ticket URL: <http://allmydata.org/trac/tahoe/ticket/698#comment:6>
tahoe-lafs <http://allmydata.org>
secure decentralized file storage grid


More information about the tahoe-dev mailing list