<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[14120] CalendarServer/trunk/txweb2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/14120">14120</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2014-10-29 09:28:01 -0700 (Wed, 29 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Whitespace.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunktxweb2authdigestpy">CalendarServer/trunk/txweb2/auth/digest.py</a></li>
<li><a href="#CalendarServertrunktxweb2authinterfacespy">CalendarServer/trunk/txweb2/auth/interfaces.py</a></li>
<li><a href="#CalendarServertrunktxweb2authwrapperpy">CalendarServer/trunk/txweb2/auth/wrapper.py</a></li>
<li><a href="#CalendarServertrunktxweb2channelhttppy">CalendarServer/trunk/txweb2/channel/http.py</a></li>
<li><a href="#CalendarServertrunktxweb2clienthttppy">CalendarServer/trunk/txweb2/client/http.py</a></li>
<li><a href="#CalendarServertrunktxweb2clientinterfacespy">CalendarServer/trunk/txweb2/client/interfaces.py</a></li>
<li><a href="#CalendarServertrunktxweb2davauthpy">CalendarServer/trunk/txweb2/dav/auth.py</a></li>
<li><a href="#CalendarServertrunktxweb2davfileoppy">CalendarServer/trunk/txweb2/dav/fileop.py</a></li>
<li><a href="#CalendarServertrunktxweb2davhttppy">CalendarServer/trunk/txweb2/dav/http.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethod__init__py">CalendarServer/trunk/txweb2/dav/method/__init__.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodaclpy">CalendarServer/trunk/txweb2/dav/method/acl.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodcopymovepy">CalendarServer/trunk/txweb2/dav/method/copymove.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethoddeletepy">CalendarServer/trunk/txweb2/dav/method/delete.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethoddelete_commonpy">CalendarServer/trunk/txweb2/dav/method/delete_common.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodgetpy">CalendarServer/trunk/txweb2/dav/method/get.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodlockpy">CalendarServer/trunk/txweb2/dav/method/lock.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodmkcolpy">CalendarServer/trunk/txweb2/dav/method/mkcol.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodprop_commonpy">CalendarServer/trunk/txweb2/dav/method/prop_common.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodputpy">CalendarServer/trunk/txweb2/dav/method/put.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodput_commonpy">CalendarServer/trunk/txweb2/dav/method/put_common.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodreportpy">CalendarServer/trunk/txweb2/dav/method/report.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodreport_acl_principal_prop_setpy">CalendarServer/trunk/txweb2/dav/method/report_acl_principal_prop_set.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodreport_principal_matchpy">CalendarServer/trunk/txweb2/dav/method/report_principal_match.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodreport_principal_property_searchpy">CalendarServer/trunk/txweb2/dav/method/report_principal_property_search.py</a></li>
<li><a href="#CalendarServertrunktxweb2davmethodreport_principal_search_property_setpy">CalendarServer/trunk/txweb2/dav/method/report_principal_search_property_set.py</a></li>
<li><a href="#CalendarServertrunktxweb2davnonepropspy">CalendarServer/trunk/txweb2/dav/noneprops.py</a></li>
<li><a href="#CalendarServertrunktxweb2davresourcepy">CalendarServer/trunk/txweb2/dav/resource.py</a></li>
<li><a href="#CalendarServertrunktxweb2davstaticpy">CalendarServer/trunk/txweb2/dav/static.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtest__init__py">CalendarServer/trunk/txweb2/dav/test/__init__.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_aclpy">CalendarServer/trunk/txweb2/dav/test/test_acl.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_authpy">CalendarServer/trunk/txweb2/dav/test/test_auth.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_copypy">CalendarServer/trunk/txweb2/dav/test/test_copy.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_deletepy">CalendarServer/trunk/txweb2/dav/test/test_delete.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_httppy">CalendarServer/trunk/txweb2/dav/test/test_http.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_lockpy">CalendarServer/trunk/txweb2/dav/test/test_lock.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_mkcolpy">CalendarServer/trunk/txweb2/dav/test/test_mkcol.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_movepy">CalendarServer/trunk/txweb2/dav/test/test_move.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_optionspy">CalendarServer/trunk/txweb2/dav/test/test_options.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_proppy">CalendarServer/trunk/txweb2/dav/test/test_prop.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_putpy">CalendarServer/trunk/txweb2/dav/test/test_put.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_quotapy">CalendarServer/trunk/txweb2/dav/test/test_quota.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_reportpy">CalendarServer/trunk/txweb2/dav/test/test_report.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_report_expandpy">CalendarServer/trunk/txweb2/dav/test/test_report_expand.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_resourcepy">CalendarServer/trunk/txweb2/dav/test/test_resource.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_staticpy">CalendarServer/trunk/txweb2/dav/test/test_static.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_xattrpropspy">CalendarServer/trunk/txweb2/dav/test/test_xattrprops.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttworequest_clientpy">CalendarServer/trunk/txweb2/dav/test/tworequest_client.py</a></li>
<li><a href="#CalendarServertrunktxweb2davxattrpropspy">CalendarServer/trunk/txweb2/dav/xattrprops.py</a></li>
<li><a href="#CalendarServertrunktxweb2errorpy">CalendarServer/trunk/txweb2/error.py</a></li>
<li><a href="#CalendarServertrunktxweb2fileuploadpy">CalendarServer/trunk/txweb2/fileupload.py</a></li>
<li><a href="#CalendarServertrunktxweb2filtergzippy">CalendarServer/trunk/txweb2/filter/gzip.py</a></li>
<li><a href="#CalendarServertrunktxweb2filterlocationpy">CalendarServer/trunk/txweb2/filter/location.py</a></li>
<li><a href="#CalendarServertrunktxweb2filterrangepy">CalendarServer/trunk/txweb2/filter/range.py</a></li>
<li><a href="#CalendarServertrunktxweb2httppy">CalendarServer/trunk/txweb2/http.py</a></li>
<li><a href="#CalendarServertrunktxweb2http_headerspy">CalendarServer/trunk/txweb2/http_headers.py</a></li>
<li><a href="#CalendarServertrunktxweb2iwebpy">CalendarServer/trunk/txweb2/iweb.py</a></li>
<li><a href="#CalendarServertrunktxweb2logpy">CalendarServer/trunk/txweb2/log.py</a></li>
<li><a href="#CalendarServertrunktxweb2resourcepy">CalendarServer/trunk/txweb2/resource.py</a></li>
<li><a href="#CalendarServertrunktxweb2responsecodepy">CalendarServer/trunk/txweb2/responsecode.py</a></li>
<li><a href="#CalendarServertrunktxweb2serverpy">CalendarServer/trunk/txweb2/server.py</a></li>
<li><a href="#CalendarServertrunktxweb2staticpy">CalendarServer/trunk/txweb2/static.py</a></li>
<li><a href="#CalendarServertrunktxweb2streampy">CalendarServer/trunk/txweb2/stream.py</a></li>
<li><a href="#CalendarServertrunktxweb2test__init__py">CalendarServer/trunk/txweb2/test/__init__.py</a></li>
<li><a href="#CalendarServertrunktxweb2testsimple_clientpy">CalendarServer/trunk/txweb2/test/simple_client.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_clientpy">CalendarServer/trunk/txweb2/test/test_client.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_fileuploadpy">CalendarServer/trunk/txweb2/test/test_fileupload.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_httppy">CalendarServer/trunk/txweb2/test/test_http.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_http_headerspy">CalendarServer/trunk/txweb2/test/test_http_headers.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_httpauthpy">CalendarServer/trunk/txweb2/test/test_httpauth.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_logpy">CalendarServer/trunk/txweb2/test/test_log.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_resourcepy">CalendarServer/trunk/txweb2/test/test_resource.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_serverpy">CalendarServer/trunk/txweb2/test/test_server.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_staticpy">CalendarServer/trunk/txweb2/test/test_static.py</a></li>
<li><a href="#CalendarServertrunktxweb2testtest_streampy">CalendarServer/trunk/txweb2/test/test_stream.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunktxweb2authdigestpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/auth/digest.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/auth/digest.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/auth/digest.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -81,6 +81,8 @@
</span><span class="cx">     return _origCalcHA1(pszAlg, pszUserName, pszRealm, pszPassword, pszNonce,
</span><span class="cx">                         pszCNonce, preHA1)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> # DigestCalcResponse
</span><span class="cx"> def calcResponse(
</span><span class="cx">     HA1,
</span></span></pre></div>
<a id="CalendarServertrunktxweb2authinterfacespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/auth/interfaces.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/auth/interfaces.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/auth/interfaces.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IAuthenticatedRequest(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A request that has been authenticated with the use of Cred,
</span><span class="lines">@@ -73,6 +74,7 @@
</span><span class="cx">                        &quot;the application's realm&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IHTTPUser(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A generic interface that can implemented by an avatar to provide
</span></span></pre></div>
<a id="CalendarServertrunktxweb2authwrapperpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/auth/wrapper.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/auth/wrapper.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/auth/wrapper.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx">             responsecode.UNAUTHORIZED,
</span><span class="cx">             &quot;You are not authorized to access this resource.&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _generateHeaders(self, factories, remoteAddr=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Set up the response's headers.
</span><span class="lines">@@ -76,7 +77,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         response = UnauthorizedResponse()
</span><span class="cx">         d = response._generateHeaders(factories, remoteAddr)
</span><del>-        d.addCallback(lambda _:response)
</del><ins>+        d.addCallback(lambda _: response)
</ins><span class="cx">         return d
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -115,6 +116,7 @@
</span><span class="cx">         self.portal = portal
</span><span class="cx">         self.interfaces = interfaces
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _loginSucceeded(self, avatar, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Callback for successful login.
</span><span class="lines">@@ -239,6 +241,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return self.authenticate(request), seg
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def renderHTTP(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Authenticate the request then return the result of calling renderHTTP
</span></span></pre></div>
<a id="CalendarServertrunktxweb2channelhttppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/channel/http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/channel/http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/channel/http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx">         self.retryAfter = retryAfter
</span><span class="cx">         self.outstandingRequests = outstandingRequests
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionMade(self):
</span><span class="cx">         log.info(overloaded=self)
</span><span class="cx"> 
</span><span class="lines">@@ -76,6 +77,7 @@
</span><span class="cx">         self.transport.loseConnection()
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class SSLRedirectRequest(Request):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     An L{SSLRedirectRequest} prevents processing if the request is over plain
</span><span class="lines">@@ -103,7 +105,7 @@
</span><span class="cx"> 
</span><span class="cx"> # &gt;%
</span><span class="cx"> 
</span><del>-PERSIST_NO_PIPELINE, PERSIST_PIPELINE = (1,2)
</del><ins>+PERSIST_NO_PIPELINE, PERSIST_PIPELINE = (1, 2)
</ins><span class="cx"> 
</span><span class="cx"> _cachedHostNames = {}
</span><span class="cx"> def _cachedGetHostByAddr(hostaddr):
</span><span class="lines">@@ -113,9 +115,11 @@
</span><span class="cx">             hostname = socket.gethostbyaddr(hostaddr)[0]
</span><span class="cx">         except socket.herror:
</span><span class="cx">             hostname = hostaddr
</span><del>-        _cachedHostNames[hostaddr]=hostname
</del><ins>+        _cachedHostNames[hostaddr] = hostname
</ins><span class="cx">     return hostname
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class StringTransport(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     I am a StringIO wrapper that conforms for the transport API. I support
</span><span class="lines">@@ -123,15 +127,22 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def __init__(self):
</span><span class="cx">         self.s = StringIO()
</span><ins>+
+
</ins><span class="cx">     def writeSequence(self, seq):
</span><span class="cx">         self.s.write(''.join(seq))
</span><ins>+
+
</ins><span class="cx">     def __getattr__(self, attr):
</span><span class="cx">         return getattr(self.__dict__['s'], attr)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class AbortedException(Exception):
</span><span class="cx">     pass
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class HTTPParser(object):
</span><span class="cx">     &quot;&quot;&quot;This class handles the parsing side of HTTP processing. With a suitable
</span><span class="cx">     subclass, it can parse either the client side or the server side of the
</span><span class="lines">@@ -179,6 +190,7 @@
</span><span class="cx">         self.inHeaders = http_headers.Headers()
</span><span class="cx">         self.channel = channel
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineReceived(self, line):
</span><span class="cx">         if self.chunkedIn:
</span><span class="cx">             # Parsing a chunked input
</span><span class="lines">@@ -246,6 +258,7 @@
</span><span class="cx">                     self.headerReceived(self.partialHeader)
</span><span class="cx">                 self.partialHeader = line
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def rawDataReceived(self, data):
</span><span class="cx">         &quot;&quot;&quot;Handle incoming content.&quot;&quot;&quot;
</span><span class="cx">         datalen = len(data)
</span><span class="lines">@@ -294,6 +307,7 @@
</span><span class="cx">         self.setConnectionParams(connHeaders)
</span><span class="cx">         self.connHeaders = connHeaders
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def allContentReceived(self):
</span><span class="cx">         self.finishedReading = True
</span><span class="cx">         self.channel.requestReadFinished(self)
</span><span class="lines">@@ -342,7 +356,7 @@
</span><span class="cx">         connHeaders = http_headers.Headers()
</span><span class="cx"> 
</span><span class="cx">         move('connection')
</span><del>-        if self.version &lt; (1,1):
</del><ins>+        if self.version &lt; (1, 1):
</ins><span class="cx">             # Remove all headers mentioned in Connection, because a HTTP 1.0
</span><span class="cx">             # proxy might have erroneously forwarded it from a 1.1 client.
</span><span class="cx">             for name in connHeaders.getHeader('connection', ()):
</span><span class="lines">@@ -366,9 +380,10 @@
</span><span class="cx"> 
</span><span class="cx">         return connHeaders
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setConnectionParams(self, connHeaders):
</span><span class="cx">         # Figure out persistent connection stuff
</span><del>-        if self.version &gt;= (1,1):
</del><ins>+        if self.version &gt;= (1, 1):
</ins><span class="cx">             if 'close' in connHeaders.getHeader('connection', ()):
</span><span class="cx">                 readPersistent = False
</span><span class="cx">             else:
</span><span class="lines">@@ -424,6 +439,7 @@
</span><span class="cx">         # Set the calculated persistence
</span><span class="cx">         self.channel.setReadPersistent(readPersistent)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def abortParse(self):
</span><span class="cx">         # If we're erroring out while still reading the request
</span><span class="cx">         if not self.finishedReading:
</span><span class="lines">@@ -431,19 +447,24 @@
</span><span class="cx">             self.channel.setReadPersistent(False)
</span><span class="cx">             self.channel.requestReadFinished(self)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     # producer interface
</span><span class="cx">     def pauseProducing(self):
</span><span class="cx">         if not self.finishedReading:
</span><span class="cx">             self.channel.pauseProducing()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def resumeProducing(self):
</span><span class="cx">         if not self.finishedReading:
</span><span class="cx">             self.channel.resumeProducing()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def stopProducing(self):
</span><span class="cx">         if not self.finishedReading:
</span><span class="cx">             self.channel.stopProducing()
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class HTTPChannelRequest(HTTPParser):
</span><span class="cx">     &quot;&quot;&quot;This class handles the state and parsing for one HTTP request.
</span><span class="cx">     It is responsible for all the low-level connection oriented behavior.
</span><span class="lines">@@ -458,7 +479,7 @@
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, channel, queued=0):
</span><span class="cx">         HTTPParser.__init__(self, channel)
</span><del>-        self.queued=queued
</del><ins>+        self.queued = queued
</ins><span class="cx"> 
</span><span class="cx">         # Buffer writes to a string until we're first in line
</span><span class="cx">         # to write a response
</span><span class="lines">@@ -468,7 +489,7 @@
</span><span class="cx">             self.transport = self.channel.transport
</span><span class="cx"> 
</span><span class="cx">         # set the version to a fallback for error generation
</span><del>-        self.version = (1,0)
</del><ins>+        self.version = (1, 0)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def gotInitialLine(self, initialLine):
</span><span class="lines">@@ -501,36 +522,44 @@
</span><span class="cx">             # simulate end of headers, as HTTP 0 doesn't have headers.
</span><span class="cx">             self.lineReceived('')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineLengthExceeded(self, line, wasFirst=False):
</span><span class="cx">         code = wasFirst and responsecode.REQUEST_URI_TOO_LONG or responsecode.BAD_REQUEST
</span><span class="cx">         self._abortWithError(code, 'Header line too long.')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def createRequest(self):
</span><span class="cx">         self.request = self.channel.requestFactory(self, self.command, self.path, self.version, self.length, self.inHeaders)
</span><span class="cx">         del self.inHeaders
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def processRequest(self):
</span><span class="cx">         self.request.process()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentChunk(self, data):
</span><span class="cx">         self.request.handleContentChunk(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentComplete(self):
</span><span class="cx">         self.request.handleContentComplete()
</span><span class="cx"> 
</span><del>-############## HTTPChannelRequest *RESPONSE* methods #############
</del><ins>+    #  HTTPChannelRequest *RESPONSE* methods #
</ins><span class="cx">     producer = None
</span><span class="cx">     chunkedOut = False
</span><span class="cx">     finished = False
</span><span class="cx"> 
</span><del>-    ##### Request Callbacks #####
</del><ins>+
+    # Request Callbacks #
</ins><span class="cx">     def writeIntermediateResponse(self, code, headers=None):
</span><del>-        if self.version &gt;= (1,1):
</del><ins>+        if self.version &gt;= (1, 1):
</ins><span class="cx">             self._writeHeaders(code, headers, False)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeHeaders(self, code, headers):
</span><span class="cx">         self._writeHeaders(code, headers, True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _writeHeaders(self, code, headers, addConnectionHeaders):
</span><span class="cx">         # HTTP 0.9 doesn't have headers.
</span><span class="cx">         if self.version[0] == 0:
</span><span class="lines">@@ -549,9 +578,11 @@
</span><span class="cx">         if addConnectionHeaders:
</span><span class="cx">             # if we don't have a content length, we send data in
</span><span class="cx">             # chunked mode, so that we can support persistent connections.
</span><del>-            if (headers.getHeader('content-length') is None and
-                self.command != &quot;HEAD&quot; and code not in http.NO_BODY_CODES):
-                if self.version &gt;= (1,1):
</del><ins>+            if (
+                headers.getHeader('content-length') is None and
+                self.command != &quot;HEAD&quot; and code not in http.NO_BODY_CODES
+            ):
+                if self.version &gt;= (1, 1):
</ins><span class="cx">                     l.append(&quot;%s: %s\r\n&quot; % ('Transfer-Encoding', 'chunked'))
</span><span class="cx">                     self.chunkedOut = True
</span><span class="cx">                 else:
</span><span class="lines">@@ -560,7 +591,7 @@
</span><span class="cx"> 
</span><span class="cx">             if self.channel.isLastRequest(self):
</span><span class="cx">                 l.append(&quot;%s: %s\r\n&quot; % ('Connection', 'close'))
</span><del>-            elif self.version &lt; (1,1):
</del><ins>+            elif self.version &lt; (1, 1):
</ins><span class="cx">                 l.append(&quot;%s: %s\r\n&quot; % ('Connection', 'Keep-Alive'))
</span><span class="cx"> 
</span><span class="cx">         l.append(&quot;\r\n&quot;)
</span><span class="lines">@@ -575,6 +606,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.transport.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def finish(self):
</span><span class="cx">         &quot;&quot;&quot;We are finished writing data.&quot;&quot;&quot;
</span><span class="cx">         if self.finished:
</span><span class="lines">@@ -612,18 +644,21 @@
</span><span class="cx">             else:
</span><span class="cx">                 self._cleanup()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getHostInfo(self):
</span><span class="cx">         return self.channel._host, self.channel._secure
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getRemoteHost(self):
</span><span class="cx">         return self.channel.transport.getPeer()
</span><span class="cx"> 
</span><del>-    ##### End Request Callbacks #####
</del><ins>+    # End Request Callbacks #
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _abortWithError(self, errorcode, text=''):
</span><span class="cx">         &quot;&quot;&quot;Handle low level protocol errors.&quot;&quot;&quot;
</span><span class="cx">         headers = http_headers.Headers()
</span><del>-        headers.setHeader('content-length', len(text)+1)
</del><ins>+        headers.setHeader('content-length', len(text) + 1)
</ins><span class="cx"> 
</span><span class="cx">         self.abortConnection(closeWrite=False)
</span><span class="cx">         self.writeHeaders(errorcode, headers)
</span><span class="lines">@@ -633,6 +668,7 @@
</span><span class="cx">         log.warn(&quot;Aborted request (%d) %s&quot; % (errorcode, text))
</span><span class="cx">         raise AbortedException
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _cleanup(self):
</span><span class="cx">         &quot;&quot;&quot;Called when have finished responding and are no longer queued.&quot;&quot;&quot;
</span><span class="cx">         if self.producer:
</span><span class="lines">@@ -641,6 +677,7 @@
</span><span class="cx">         self.channel.requestWriteFinished(self)
</span><span class="cx">         del self.transport
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     # methods for channel - end users should not use these
</span><span class="cx"> 
</span><span class="cx">     def noLongerQueued(self):
</span><span class="lines">@@ -685,12 +722,14 @@
</span><span class="cx">         else:
</span><span class="cx">             self.transport.registerProducer(producer, streaming)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def unregisterProducer(self):
</span><span class="cx">         &quot;&quot;&quot;Unregister the producer.&quot;&quot;&quot;
</span><span class="cx">         if not self.queued:
</span><span class="cx">             self.transport.unregisterProducer()
</span><span class="cx">         self.producer = None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         &quot;&quot;&quot;connection was lost&quot;&quot;&quot;
</span><span class="cx">         if self.queued and self.producer:
</span><span class="lines">@@ -699,6 +738,8 @@
</span><span class="cx">         if self.request:
</span><span class="cx">             self.request.connectionLost(reason)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class HTTPChannel(basic.LineReceiver, policies.TimeoutMixin, object):
</span><span class="cx">     &quot;&quot;&quot;A receiver for HTTP requests. Handles splitting up the connection
</span><span class="cx">     for the multiple HTTPChannelRequests that may be in progress on this
</span><span class="lines">@@ -717,7 +758,7 @@
</span><span class="cx"> 
</span><span class="cx">     implements(interfaces.IHalfCloseableProtocol)
</span><span class="cx"> 
</span><del>-    ## Configuration parameters. Set in instances or subclasses.
</del><ins>+    # Configuration parameters. Set in instances or subclasses.
</ins><span class="cx"> 
</span><span class="cx">     # How many simultaneous requests to handle.
</span><span class="cx">     maxPipeline = 4
</span><span class="lines">@@ -754,10 +795,12 @@
</span><span class="cx">     def _callLater(self, secs, fun):
</span><span class="cx">         reactor.callLater(secs, fun)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __init__(self):
</span><span class="cx">         # the request queue
</span><span class="cx">         self.requests = []
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionMade(self):
</span><span class="cx">         self._secure = interfaces.ISSLTransport(self.transport, None) is not None
</span><span class="cx">         address = self.transport.getHost()
</span><span class="lines">@@ -765,6 +808,7 @@
</span><span class="cx">         self.setTimeout(self.inputTimeOut)
</span><span class="cx">         self.factory.addConnectedChannel(self)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineReceived(self, line):
</span><span class="cx">         if self._first_line:
</span><span class="cx">             self.setTimeout(self.inputTimeOut)
</span><span class="lines">@@ -798,6 +842,7 @@
</span><span class="cx">             except AbortedException:
</span><span class="cx">                 pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineLengthExceeded(self, line):
</span><span class="cx">         if self._first_line:
</span><span class="cx">             # Fabricate a request object to respond to the line length violation.
</span><span class="lines">@@ -810,6 +855,7 @@
</span><span class="cx">         except AbortedException:
</span><span class="cx">             pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def rawDataReceived(self, data):
</span><span class="cx">         self.setTimeout(self.inputTimeOut)
</span><span class="cx">         try:
</span><span class="lines">@@ -817,6 +863,7 @@
</span><span class="cx">         except AbortedException:
</span><span class="cx">             pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def requestReadFinished(self, request):
</span><span class="cx">         if(self.readPersistent is PERSIST_NO_PIPELINE or
</span><span class="cx">            len(self.requests) &gt;= self.maxPipeline):
</span><span class="lines">@@ -832,6 +879,7 @@
</span><span class="cx">         if len(self.requests) &gt; 0:
</span><span class="cx">             self.setTimeout(self.idleTimeOut)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _startNextRequest(self):
</span><span class="cx">         # notify next request, if present, it can start writing
</span><span class="cx">         del self.requests[0]
</span><span class="lines">@@ -854,11 +902,13 @@
</span><span class="cx">             self.setTimeout(self.betweenRequestsTimeOut)
</span><span class="cx">             self.resumeProducing()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setReadPersistent(self, persistent):
</span><span class="cx">         if self.readPersistent:
</span><span class="cx">             # only allow it to be set if it's not currently False
</span><span class="cx">             self.readPersistent = persistent
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def dropQueuedRequests(self):
</span><span class="cx">         &quot;&quot;&quot;Called when a response is written that forces a connection close.&quot;&quot;&quot;
</span><span class="cx">         self.readPersistent = False
</span><span class="lines">@@ -867,13 +917,16 @@
</span><span class="cx">             request.connectionLost(None)
</span><span class="cx">         del self.requests[1:]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def isLastRequest(self, request):
</span><span class="cx">         # Is this channel handling the last possible request
</span><span class="cx">         return not self.readPersistent and self.requests[-1] == request
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def requestWriteFinished(self, request):
</span><span class="cx">         &quot;&quot;&quot;Called by first request in queue when it is done.&quot;&quot;&quot;
</span><del>-        if request != self.requests[0]: raise TypeError
</del><ins>+        if request != self.requests[0]:
+            raise TypeError
</ins><span class="cx"> 
</span><span class="cx">         # Don't del because we haven't finished cleanup, so,
</span><span class="cx">         # don't want queue len to be 0 yet.
</span><span class="lines">@@ -888,20 +941,23 @@
</span><span class="cx">             # Set an abort timer in case an orderly close hangs
</span><span class="cx">             self.setTimeout(None)
</span><span class="cx">             self._abortTimer = reactor.callLater(self.closeTimeOut, self._abortTimeout)
</span><del>-            #reactor.callLater(0.1, self.transport.loseConnection)
</del><ins>+            # eactor.callLater(0.1, self.transport.loseConnection)
</ins><span class="cx">             self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def timeoutConnection(self):
</span><del>-        #log.info(&quot;Timing out client: %s&quot; % str(self.transport.getPeer()))
</del><ins>+        # log.info(&quot;Timing out client: %s&quot; % str(self.transport.getPeer()))
</ins><span class="cx">         # Set an abort timer in case an orderly close hangs
</span><span class="cx">         self._abortTimer = reactor.callLater(self.closeTimeOut, self._abortTimeout)
</span><span class="cx">         policies.TimeoutMixin.timeoutConnection(self)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _abortTimeout(self):
</span><span class="cx">         log.error(&quot;Connection aborted - took too long to close: {c}&quot;, c=str(self.transport.getPeer()))
</span><span class="cx">         self._abortTimer = None
</span><span class="cx">         self.transport.abortConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def readConnectionLost(self):
</span><span class="cx">         &quot;&quot;&quot;Read connection lost&quot;&quot;&quot;
</span><span class="cx">         # If in the lingering-close state, lose the socket.
</span><span class="lines">@@ -923,6 +979,7 @@
</span><span class="cx">         if self.chanRequest:
</span><span class="cx">             self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self.factory.removeConnectedChannel(self)
</span><span class="cx"> 
</span><span class="lines">@@ -935,6 +992,8 @@
</span><span class="cx">             if request is not None:
</span><span class="cx">                 request.connectionLost(reason)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class OverloadedServerProtocol(protocol.Protocol):
</span><span class="cx">     def connectionMade(self):
</span><span class="cx">         self.transport.write(&quot;HTTP/1.0 503 Service Unavailable\r\n&quot;
</span><span class="lines">@@ -980,7 +1039,7 @@
</span><span class="cx"> 
</span><span class="cx">         p = protocol.ServerFactory.buildProtocol(self, addr)
</span><span class="cx"> 
</span><del>-        for arg,value in self.protocolArgs.iteritems():
</del><ins>+        for arg, value in self.protocolArgs.iteritems():
</ins><span class="cx">             setattr(p, arg, value)
</span><span class="cx">         return p
</span><span class="cx"> 
</span><span class="lines">@@ -1007,6 +1066,7 @@
</span><span class="cx">             if self.outstandingRequests == 0:
</span><span class="cx">                 self.allConnectionsClosedDeferred.callback(None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     @property
</span><span class="cx">     def outstandingRequests(self):
</span><span class="cx">         return len(self.connectedChannels)
</span><span class="lines">@@ -1033,9 +1093,10 @@
</span><span class="cx">         self.vary = vary
</span><span class="cx">         HTTPFactory.__init__(self, requestFactory, maxRequests, **kwargs)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def buildProtocol(self, addr):
</span><span class="cx">         if self.vary:
</span><del>-            retryAfter = randint(int(self.retryAfter * 1/2), int(self.retryAfter * 3/2))
</del><ins>+            retryAfter = randint(int(self.retryAfter * 1 / 2), int(self.retryAfter * 3 / 2))
</ins><span class="cx">         else:
</span><span class="cx">             retryAfter = self.retryAfter
</span><span class="cx"> 
</span><span class="lines">@@ -1044,11 +1105,13 @@
</span><span class="cx"> 
</span><span class="cx">         p = protocol.ServerFactory.buildProtocol(self, addr)
</span><span class="cx"> 
</span><del>-        for arg,value in self.protocolArgs.iteritems():
</del><ins>+        for arg, value in self.protocolArgs.iteritems():
</ins><span class="cx">             setattr(p, arg, value)
</span><span class="cx"> 
</span><span class="cx">         return p
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class HTTPLoggingChannelRequest(HTTPChannelRequest):
</span><span class="cx"> 
</span><span class="cx">     class TransportLoggingWrapper(object):
</span><span class="lines">@@ -1071,11 +1134,13 @@
</span><span class="cx">         def __getattr__(self, attr):
</span><span class="cx">             return getattr(self.__dict__['transport'], attr)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     class LogData(object):
</span><span class="cx">         def __init__(self):
</span><span class="cx">             self.request = []
</span><span class="cx">             self.response = []
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __init__(self, channel, queued=0):
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).__init__(channel, queued)
</span><span class="cx"> 
</span><span class="lines">@@ -1085,6 +1150,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.logData = None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def gotInitialLine(self, initialLine):
</span><span class="cx">         if self.logData is not None:
</span><span class="cx">             self.startTime = time.time()
</span><span class="lines">@@ -1092,6 +1158,7 @@
</span><span class="cx">             self.logData.request.append(&quot;%s\r\n&quot; % (initialLine,))
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).gotInitialLine(initialLine)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineReceived(self, line):
</span><span class="cx"> 
</span><span class="cx">         if self.logData is not None:
</span><span class="lines">@@ -1104,12 +1171,14 @@
</span><span class="cx">             self.logData.request.append(&quot;%s\r\n&quot; % (loggedLine,))
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).lineReceived(line)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentChunk(self, data):
</span><span class="cx"> 
</span><span class="cx">         if self.logData is not None:
</span><span class="cx">             self.logData.request.append(data)
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).handleContentChunk(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentComplete(self):
</span><span class="cx"> 
</span><span class="cx">         if self.logData is not None:
</span><span class="lines">@@ -1117,12 +1186,14 @@
</span><span class="cx">             self.logData.request.append(&quot;\r\n\r\n&gt;&gt;&gt;&gt; Request complete at: %.3f (elapsed: %.1f ms)&quot; % (doneTime, 1000 * (doneTime - self.startTime),))
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).handleContentComplete()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeHeaders(self, code, headers):
</span><span class="cx">         if self.logData is not None:
</span><span class="cx">             doneTime = time.time()
</span><span class="cx">             self.logData.response.append(&quot;\r\n\r\n&lt;&lt;&lt;&lt; Response sending at: %.3f (elapsed: %.1f ms)\r\n\r\n&quot; % (doneTime, 1000 * (doneTime - self.startTime),))
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).writeHeaders(code, headers)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def finish(self):
</span><span class="cx"> 
</span><span class="cx">         super(HTTPLoggingChannelRequest, self).finish()
</span><span class="lines">@@ -1144,11 +1215,11 @@
</span><span class="cx">         L{LimitingHTTPFactory} will limit.  This must be set externally.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    def __init__(self, requestFactory, maxRequests=600, maxAccepts=100,
-        **kwargs):
</del><ins>+    def __init__(self, requestFactory, maxRequests=600, maxAccepts=100, **kwargs):
</ins><span class="cx">         HTTPFactory.__init__(self, requestFactory, maxRequests, **kwargs)
</span><span class="cx">         self.maxAccepts = maxAccepts
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def buildProtocol(self, addr):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Override L{HTTPFactory.buildProtocol} in order to avoid ever returning
</span><span class="lines">@@ -1159,6 +1230,7 @@
</span><span class="cx">             setattr(p, arg, value)
</span><span class="cx">         return p
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def addConnectedChannel(self, channel):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Override L{HTTPFactory.addConnectedChannel} to pause listening on the
</span></span></pre></div>
<a id="CalendarServertrunktxweb2clienthttppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/client/http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/client/http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/client/http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -104,6 +104,7 @@
</span><span class="cx">         self.transport = self.channel.transport
</span><span class="cx">         self.responseDefer = Deferred()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def submit(self):
</span><span class="cx">         l = []
</span><span class="cx">         request = self.request
</span><span class="lines">@@ -138,15 +139,18 @@
</span><span class="cx">         d = StreamProducer(request.stream).beginProducing(self)
</span><span class="cx">         d.addCallback(self._finish).addErrback(self._error)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def registerProducer(self, producer, streaming):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Register a producer.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.transport.registerProducer(producer, streaming)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def unregisterProducer(self):
</span><span class="cx">         self.transport.unregisterProducer()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def write(self, data):
</span><span class="cx">         if not data:
</span><span class="cx">             return
</span><span class="lines">@@ -155,6 +159,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.transport.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _finish(self, x):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         We are finished writing data.
</span><span class="lines">@@ -167,6 +172,7 @@
</span><span class="cx">         self.channel.requestWriteFinished(self)
</span><span class="cx">         del self.transport
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _error(self, err):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Abort parsing, and depending of the status of the request, either fire
</span><span class="lines">@@ -179,15 +185,18 @@
</span><span class="cx">         else:
</span><span class="cx">             self.responseDefer.errback(err)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _abortWithError(self, errcode, text):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Abort parsing by forwarding a C{ProtocolError} to C{_error}.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self._error(ProtocolError(text))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self._error(reason)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def gotInitialLine(self, initialLine):
</span><span class="cx">         parts = initialLine.split(' ', 2)
</span><span class="cx"> 
</span><span class="lines">@@ -197,7 +206,7 @@
</span><span class="cx">                                  &quot;Bad response line: %s&quot; % (initialLine,))
</span><span class="cx">             return
</span><span class="cx"> 
</span><del>-        strversion, self.code, message = parts
</del><ins>+        strversion, self.code, _ignore_message = parts
</ins><span class="cx"> 
</span><span class="cx">         try:
</span><span class="cx">             protovers = parseVersion(strversion)
</span><span class="lines">@@ -216,7 +225,8 @@
</span><span class="cx">                                  'Only HTTP 1.x is supported.')
</span><span class="cx">             return
</span><span class="cx"> 
</span><del>-    ## FIXME: Actually creates Response, function is badly named!
</del><ins>+
+    # FIXME: Actually creates Response, function is badly named!
</ins><span class="cx">     def createRequest(self):
</span><span class="cx">         self.stream = ProducerStream(self.length)
</span><span class="cx">         self.response = Response(self.code, self.inHeaders, self.stream)
</span><span class="lines">@@ -224,13 +234,16 @@
</span><span class="cx"> 
</span><span class="cx">         del self.inHeaders
</span><span class="cx"> 
</span><del>-    ## FIXME: Actually processes Response, function is badly named!
</del><ins>+
+    # FIXME: Actually processes Response, function is badly named!
</ins><span class="cx">     def processRequest(self):
</span><span class="cx">         self.responseDefer.callback(self.response)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentChunk(self, data):
</span><span class="cx">         self.stream.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentComplete(self):
</span><span class="cx">         self.stream.finish()
</span><span class="cx"> 
</span><span class="lines">@@ -247,12 +260,15 @@
</span><span class="cx">     def clientBusy(self, proto):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def clientIdle(self, proto):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def clientPipelining(self, proto):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def clientGone(self, proto):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><span class="lines">@@ -285,6 +301,7 @@
</span><span class="cx">             manager = EmptyHTTPClientManager()
</span><span class="cx">         self.manager = manager
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lineReceived(self, line):
</span><span class="cx">         if not self.inRequests:
</span><span class="cx">             # server sending random unrequested data.
</span><span class="lines">@@ -301,6 +318,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.inRequests[0].lineReceived(line)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def rawDataReceived(self, data):
</span><span class="cx">         if not self.inRequests:
</span><span class="cx">             # Server sending random unrequested data.
</span><span class="lines">@@ -313,6 +331,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.inRequests[0].rawDataReceived(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def submitRequest(self, request, closeAfter=True):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @param request: The request to send to a remote server.
</span><span class="lines">@@ -337,13 +356,13 @@
</span><span class="cx">         if closeAfter:
</span><span class="cx">             self.readPersistent = False
</span><span class="cx"> 
</span><del>-        self.outRequest = chanRequest = HTTPClientChannelRequest(self,
-                                            request, closeAfter)
</del><ins>+        self.outRequest = chanRequest = HTTPClientChannelRequest(self, request, closeAfter)
</ins><span class="cx">         self.inRequests.append(chanRequest)
</span><span class="cx"> 
</span><span class="cx">         chanRequest.submit()
</span><span class="cx">         return chanRequest.responseDefer
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def requestWriteFinished(self, request):
</span><span class="cx">         assert request is self.outRequest
</span><span class="cx"> 
</span><span class="lines">@@ -353,6 +372,7 @@
</span><span class="cx">         if self.readPersistent is PERSIST_PIPELINE:
</span><span class="cx">             self.manager.clientPipelining(self)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def requestReadFinished(self, request):
</span><span class="cx">         assert self.inRequests[0] is request
</span><span class="cx"> 
</span><span class="lines">@@ -366,6 +386,7 @@
</span><span class="cx">             else:
</span><span class="cx">                 self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setReadPersistent(self, persist):
</span><span class="cx">         self.readPersistent = persist
</span><span class="cx">         if not persist:
</span><span class="lines">@@ -374,6 +395,7 @@
</span><span class="cx">                 request.connectionLost(None)
</span><span class="cx">             del self.inRequests[1:]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self.readPersistent = False
</span><span class="cx">         self.setTimeout(None)
</span><span class="lines">@@ -382,4 +404,3 @@
</span><span class="cx">         for request in self.inRequests:
</span><span class="cx">             if request is not None:
</span><span class="cx">                 request.connectionLost(reason)
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2clientinterfacespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/client/interfaces.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/client/interfaces.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/client/interfaces.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> from zope.interface import Interface
</span><span class="cx"> 
</span><span class="cx"> class IHTTPClientManager(Interface):
</span><del>-    &quot;&quot;&quot;I coordinate between multiple L{HTTPClientProtocol} objects connected to a 
</del><ins>+    &quot;&quot;&quot;I coordinate between multiple L{HTTPClientProtocol} objects connected to a
</ins><span class="cx">     single server to facilite request queuing and pipelining.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -35,27 +35,30 @@
</span><span class="cx">         requests.
</span><span class="cx"> 
</span><span class="cx">         @param proto: The L{HTTPClientProtocol} that is changing state.
</span><del>-        @type proto: L{HTTPClientProtocol}        
</del><ins>+        @type proto: L{HTTPClientProtocol}
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         pass
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def clientIdle(proto):
</span><span class="cx">         &quot;&quot;&quot;Called when an L{HTTPClientProtocol} is able to accept more requests.
</span><del>-    
</del><ins>+
</ins><span class="cx">         @param proto: The L{HTTPClientProtocol} that is changing state.
</span><span class="cx">         @type proto: L{HTTPClientProtocol}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def clientPipelining(proto):
</span><span class="cx">         &quot;&quot;&quot;Called when the L{HTTPClientProtocol} determines that it is able to
</span><span class="cx">         support request pipelining.
</span><del>-    
</del><ins>+
</ins><span class="cx">         @param proto: The L{HTTPClientProtocol} that is changing state.
</span><span class="cx">         @type proto: L{HTTPClientProtocol}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         pass
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def clientGone(proto):
</span><span class="cx">         &quot;&quot;&quot;Called when the L{HTTPClientProtocol} disconnects from the server.
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davauthpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/auth.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/auth.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/auth.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -37,9 +37,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class AuthenticationWrapper(WrapperResource):
</span><del>-    def __init__(self, resource, portal,
</del><ins>+    def __init__(
+        self, resource, portal,
</ins><span class="cx">         wireEncryptedCredentialFactories, wireUnencryptedCredentialFactories,
</span><del>-        loginInterfaces):
</del><ins>+        loginInterfaces
+    ):
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Wrap the given resource and use the parameters to set up the request
</span><span class="cx">         to allow anyone to challenge and handle authentication.
</span><span class="lines">@@ -58,10 +60,14 @@
</span><span class="cx">         super(AuthenticationWrapper, self).__init__(resource)
</span><span class="cx"> 
</span><span class="cx">         self.portal = portal
</span><del>-        self.wireEncryptedCredentialFactories = dict([(factory.scheme, factory)
-                                         for factory in wireEncryptedCredentialFactories])
-        self.wireUnencryptedCredentialFactories = dict([(factory.scheme, factory)
-                                         for factory in wireUnencryptedCredentialFactories])
</del><ins>+        self.wireEncryptedCredentialFactories = dict([
+            (factory.scheme, factory)
+            for factory in wireEncryptedCredentialFactories
+        ])
+        self.wireUnencryptedCredentialFactories = dict([
+            (factory.scheme, factory)
+            for factory in wireUnencryptedCredentialFactories
+        ])
</ins><span class="cx">         self.loginInterfaces = loginInterfaces
</span><span class="cx"> 
</span><span class="cx">         # FIXME: some unit tests access self.credentialFactories, so assigning here
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davfileoppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/fileop.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/fileop.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/fileop.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -170,6 +170,8 @@
</span><span class="cx"> 
</span><span class="cx">     return succeed(response)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def copy(source_filepath, destination_filepath, destination_uri, depth):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Perform a X{COPY} from the given source and destination filepaths.
</span><span class="lines">@@ -203,7 +205,7 @@
</span><span class="cx">                 Failure(),
</span><span class="cx">                 &quot;opening file for reading: %s&quot; % (source_filepath.path,)
</span><span class="cx">             ))
</span><del>-    
</del><ins>+
</ins><span class="cx">         source_stream = FileStream(source_file)
</span><span class="cx">         response = waitForDeferred(put(source_stream, destination_filepath, destination_uri))
</span><span class="cx">         yield response
</span><span class="lines">@@ -257,7 +259,7 @@
</span><span class="cx">                         &quot;creating directory %s&quot; % (destination_basename,)
</span><span class="cx">                     ))
</span><span class="cx"> 
</span><del>-                if depth == &quot;0&quot;: 
</del><ins>+                if depth == &quot;0&quot;:
</ins><span class="cx">                     yield success_code
</span><span class="cx">                     return
</span><span class="cx">         else:
</span><span class="lines">@@ -279,7 +281,7 @@
</span><span class="cx">         def paths(basepath, subpath):
</span><span class="cx">             source_path = os.path.join(basepath, subpath)
</span><span class="cx">             assert source_path.startswith(source_basename)
</span><del>-            destination_path = os.path.join(destination_basename, source_path[source_basename_len+1:])
</del><ins>+            destination_path = os.path.join(destination_basename, source_path[source_basename_len + 1:])
</ins><span class="cx">             return source_path, destination_path
</span><span class="cx"> 
</span><span class="cx">         for dir, subdirs, files in os.walk(source_filepath.path, topdown=True):
</span><span class="lines">@@ -493,6 +495,8 @@
</span><span class="cx"> 
</span><span class="cx">     return succeed(responsecode.CREATED)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def rmdir(dirname):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Removes the directory with the given name, as well as its contents.
</span><span class="lines">@@ -510,6 +514,8 @@
</span><span class="cx"> 
</span><span class="cx">     os.rmdir(dirname)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def checkResponse(response, method, *codes):
</span><del>-    assert  response in codes, \
</del><ins>+    assert response in codes, \
</ins><span class="cx">         &quot;%s() returned %r, but should have returned one of %r instead&quot; % (method, response, codes)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davhttppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -162,12 +162,13 @@
</span><span class="cx">         @param success_response: the response to return in lieu of a
</span><span class="cx">             L{MultiStatusResponse} if no responses are added to this queue.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        self.responses         = []
-        self.path_basename     = path_basename
</del><ins>+        self.responses = []
+        self.path_basename = path_basename
</ins><span class="cx">         self.path_basename_len = len(path_basename)
</span><del>-        self.method            = method
-        self.success_response  = success_response
</del><ins>+        self.method = method
+        self.success_response = success_response
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def add(self, path, what):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Add a response.
</span><span class="lines">@@ -178,12 +179,12 @@
</span><span class="cx">         assert path.startswith(self.path_basename), &quot;%s does not start with %s&quot; % (path, self.path_basename)
</span><span class="cx"> 
</span><span class="cx">         if type(what) is int:
</span><del>-            code    = what
-            error   = None
</del><ins>+            code = what
+            error = None
</ins><span class="cx">             message = responsecode.RESPONSES[code]
</span><span class="cx">         elif isinstance(what, Failure):
</span><del>-            code    = statusForFailure(what)
-            error   = errorForFailure(what)
</del><ins>+            code = statusForFailure(what)
+            error = errorForFailure(what)
</ins><span class="cx">             message = messageForFailure(what)
</span><span class="cx">         else:
</span><span class="cx">             raise AssertionError(&quot;Unknown data type: %r&quot; % (what,))
</span><span class="lines">@@ -205,6 +206,7 @@
</span><span class="cx">             children.append(element.ResponseDescription(message))
</span><span class="cx">         self.responses.append(element.StatusResponse(*children))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def response(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Generate a L{MultiStatusResponse} with the responses contained in the
</span><span class="lines">@@ -231,11 +233,12 @@
</span><span class="cx">         @param success_response: the status to return if no
</span><span class="cx">             L{PropertyStatus} are added to this queue.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        self.method            = method
-        self.uri               = uri
-        self.propstats         = []
-        self.success_response  = success_response
</del><ins>+        self.method = method
+        self.uri = uri
+        self.propstats = []
+        self.success_response = success_response
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def add(self, what, property):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Add a response.
</span><span class="lines">@@ -243,12 +246,12 @@
</span><span class="cx">         @param property: the property whose status is being reported.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         if type(what) is int:
</span><del>-            code    = what
-            error   = None
</del><ins>+            code = what
+            error = None
</ins><span class="cx">             message = responsecode.RESPONSES[code]
</span><span class="cx">         elif isinstance(what, Failure):
</span><del>-            code    = statusForFailure(what)
-            error   = errorForFailure(what)
</del><ins>+            code = statusForFailure(what)
+            error = errorForFailure(what)
</ins><span class="cx">             message = messageForFailure(what)
</span><span class="cx">         else:
</span><span class="cx">             raise AssertionError(&quot;Unknown data type: %r&quot; % (what,))
</span><span class="lines">@@ -274,6 +277,7 @@
</span><span class="cx">             children.append(element.ResponseDescription(message))
</span><span class="cx">         self.propstats.append(element.PropertyStatus(*children))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def error(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Convert any 2xx codes in the propstat responses to 424 Failed
</span><span class="lines">@@ -294,6 +298,7 @@
</span><span class="cx">                     newchildren.append(child)
</span><span class="cx">             self.propstats[index] = element.PropertyStatus(*newchildren)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def response(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Generate a response from the responses contained in the queue or, if
</span><span class="lines">@@ -313,6 +318,7 @@
</span><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Exceptions and response codes
</span><span class="cx"> ##
</span><span class="lines">@@ -355,6 +361,7 @@
</span><span class="cx">         failure.raiseException()
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> def errorForFailure(failure):
</span><span class="cx">     if failure.check(HTTPError) and isinstance(failure.value.response, ErrorResponse):
</span><span class="cx">         return element.Error(failure.value.response.error)
</span><span class="lines">@@ -362,6 +369,7 @@
</span><span class="cx">         return None
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> def messageForFailure(failure):
</span><span class="cx">     if failure.check(HTTPError):
</span><span class="cx">         if isinstance(failure.value.response, ErrorResponse):
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethod__init__py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/__init__.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/__init__.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/__init__.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodaclpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/acl.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/acl.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/acl.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodcopymovepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/copymove.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/copymove.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/copymove.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx">         # May need to add a location header
</span><span class="cx">         addLocation(request, destination_uri)
</span><span class="cx"> 
</span><del>-    #x = waitForDeferred(copy(self.fp, destination.fp, destination_uri, depth))
</del><ins>+    # x = waitForDeferred(copy(self.fp, destination.fp, destination_uri, depth))
</ins><span class="cx">     x = waitForDeferred(put_common.storeResource(request,
</span><span class="cx">                                                  source=self,
</span><span class="cx">                                                  source_uri=request.uri,
</span><span class="lines">@@ -214,6 +214,8 @@
</span><span class="cx"> 
</span><span class="cx">     return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def _prepareForCopy(destination, destination_uri, request, depth):
</span><span class="cx">     #
</span><span class="cx">     # Destination must be a DAV resource
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethoddeletepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/delete.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/delete.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/delete.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethoddelete_commonpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/delete_common.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/delete_common.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/delete_common.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">         d = waitForDeferred(resource.quotaSizeAdjust(request, -old_size))
</span><span class="cx">         yield d
</span><span class="cx">         d.getResult()
</span><del>-    
</del><ins>+
</ins><span class="cx">     yield result
</span><span class="cx"> 
</span><span class="cx"> deleteResource = deferredGenerator(deleteResource)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodgetpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/get.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/get.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/get.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -39,16 +39,22 @@
</span><span class="cx">     d.addCallback(lambda _: super(txweb2.dav.resource.DAVResource, self).http_OPTIONS(request))
</span><span class="cx">     return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def http_HEAD(self, request):
</span><span class="cx">     d = authorize(self, request)
</span><span class="cx">     d.addCallback(lambda _: super(txweb2.dav.resource.DAVResource, self).http_HEAD(request))
</span><span class="cx">     return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def http_GET(self, request):
</span><span class="cx">     d = authorize(self, request)
</span><span class="cx">     d.addCallback(lambda _: super(txweb2.dav.resource.DAVResource, self).http_GET(request))
</span><span class="cx">     return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def authorize(self, request):
</span><span class="cx">     if self.exists():
</span><span class="cx">         d = self.authorize(request, (davxml.Read(),))
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodlockpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/lock.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/lock.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/lock.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     return responsecode.NOT_IMPLEMENTED
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def http_UNLOCK(self, request):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Respond to a UNLOCK request. (RFC 2518, section 8.11)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodmkcolpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/mkcol.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/mkcol.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/mkcol.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodprop_commonpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/prop_common.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/prop_common.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/prop_common.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -59,9 +59,11 @@
</span><span class="cx">     @param resource: the L{DAVFile} for the targetted resource.
</span><span class="cx">     @return: a map of OK and NOT FOUND property values.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     return _namedPropertiesForResource(request, prop.children, resource)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def _namedPropertiesForResource(request, props, resource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Return the specified properties on the specified resource.
</span><span class="lines">@@ -74,13 +76,13 @@
</span><span class="cx">         responsecode.OK        : [],
</span><span class="cx">         responsecode.NOT_FOUND : [],
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     for property in props:
</span><span class="cx">         if isinstance(property, element.WebDAVElement):
</span><span class="cx">             qname = property.qname()
</span><span class="cx">         else:
</span><span class="cx">             qname = property
</span><del>-    
</del><ins>+
</ins><span class="cx">         props = waitForDeferred(resource.listProperties(request))
</span><span class="cx">         yield props
</span><span class="cx">         props = props.getResult()
</span><span class="lines">@@ -96,11 +98,12 @@
</span><span class="cx">                 if status != responsecode.NOT_FOUND:
</span><span class="cx">                     log.error(&quot;Error reading property %r for resource %s: %s&quot; %
</span><span class="cx">                               (qname, request.uri, f.value))
</span><del>-                if status not in properties_by_status: properties_by_status[status] = []
</del><ins>+                if status not in properties_by_status:
+                    properties_by_status[status] = []
</ins><span class="cx">                 properties_by_status[status].append(propertyName(qname))
</span><span class="cx">         else:
</span><span class="cx">             properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
</span><del>-    
</del><ins>+
</ins><span class="cx">     yield properties_by_status
</span><span class="cx"> 
</span><span class="cx"> _namedPropertiesForResource = deferredGenerator(_namedPropertiesForResource)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodputpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/put.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/put.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/put.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -69,15 +69,15 @@
</span><span class="cx">     # Implemented error if we get a Content-* header which we don't
</span><span class="cx">     # recognize and handle properly.
</span><span class="cx">     #
</span><del>-    for header, value in request.headers.getAllRawHeaders():
</del><ins>+    for header, _ignore_value in request.headers.getAllRawHeaders():
</ins><span class="cx">         if header.startswith(&quot;Content-&quot;) and header not in (
</span><del>-           #&quot;Content-Base&quot;,     # Doesn't make sense in PUT?
-           #&quot;Content-Encoding&quot;, # Requires that we decode it?
</del><ins>+            # &quot;Content-Base&quot;,     # Doesn't make sense in PUT?
+            # &quot;Content-Encoding&quot;, # Requires that we decode it?
</ins><span class="cx">             &quot;Content-Language&quot;,
</span><span class="cx">             &quot;Content-Length&quot;,
</span><del>-           #&quot;Content-Location&quot;, # Doesn't make sense in PUT?
</del><ins>+            # &quot;Content-Location&quot;, # Doesn't make sense in PUT?
</ins><span class="cx">             &quot;Content-MD5&quot;,
</span><del>-           #&quot;Content-Range&quot;,    # FIXME: Need to implement this
</del><ins>+            # &quot;Content-Range&quot;,    # FIXME: Need to implement this
</ins><span class="cx">             &quot;Content-Type&quot;,
</span><span class="cx">         ):
</span><span class="cx">             log.error(&quot;Client sent unrecognized content header in PUT request: %s&quot;
</span><span class="lines">@@ -100,5 +100,5 @@
</span><span class="cx">     # to return a MULTI_STATUS response, which is WebDAV-specific (and PUT is
</span><span class="cx">     # not).
</span><span class="cx">     #
</span><del>-    #return put(request.stream, self.fp)
</del><ins>+    # return put(request.stream, self.fp)
</ins><span class="cx">     return put_common.storeResource(request, destination=self, destination_uri=request.uri)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodput_commonpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/put_common.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/put_common.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/put_common.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -55,7 +55,7 @@
</span><span class="cx"> ):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Function that does common PUT/COPY/MOVE behaviour.
</span><del>-    
</del><ins>+
</ins><span class="cx">     @param request:           the L{txweb2.server.Request} for the current HTTP request.
</span><span class="cx">     @param source:            the L{DAVFile} for the source resource to copy from, or None if source data
</span><span class="cx">                               is to be read from the request.
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">     @param depth:             a C{str} containing the COPY/MOVE Depth header value.
</span><span class="cx">     @return:                  status response.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     try:
</span><span class="cx">         assert request is not None and destination is not None and destination_uri is not None
</span><span class="cx">         assert (source is None) or (source is not None and source_uri is not None)
</span><span class="lines">@@ -84,20 +84,22 @@
</span><span class="cx">         log.error(&quot;depth=%s\n&quot; % (depth,))
</span><span class="cx">         raise
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     class RollbackState(object):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         This class encapsulates the state needed to rollback the entire PUT/COPY/MOVE
</span><span class="cx">         transaction, leaving the server state the same as it was before the request was
</span><span class="cx">         processed. The DoRollback method will actually execute the rollback operations.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         def __init__(self):
</span><span class="cx">             self.active = True
</span><span class="cx">             self.source_copy = None
</span><span class="cx">             self.destination_copy = None
</span><span class="cx">             self.destination_created = False
</span><span class="cx">             self.source_deleted = False
</span><del>-        
</del><ins>+
+
</ins><span class="cx">         def Rollback(self):
</span><span class="cx">             &quot;&quot;&quot;
</span><span class="cx">             Rollback the server state. Do not allow this to raise another exception. If
</span><span class="lines">@@ -142,7 +144,7 @@
</span><span class="cx">                     self.destination_copy = None
</span><span class="cx">                 self.destination_created = False
</span><span class="cx">                 self.source_deleted = False
</span><del>-    
</del><ins>+
</ins><span class="cx">     rollback = RollbackState()
</span><span class="cx"> 
</span><span class="cx">     try:
</span><span class="lines">@@ -164,7 +166,7 @@
</span><span class="cx">             old_dest_size = old_dest_size.getResult()
</span><span class="cx">         else:
</span><span class="cx">             old_dest_size = 0
</span><del>-            
</del><ins>+
</ins><span class="cx">         if source is not None:
</span><span class="cx">             sourcequota = waitForDeferred(source.quota(request))
</span><span class="cx">             yield sourcequota
</span><span class="lines">@@ -193,7 +195,7 @@
</span><span class="cx">             rollback.source_copy = FilePath(source.fp.path)
</span><span class="cx">             rollback.source_copy.path += &quot;.rollback&quot;
</span><span class="cx">             source.fp.copyTo(rollback.source_copy)
</span><del>-    
</del><ins>+
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Handle actual store operations here.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -231,7 +233,7 @@
</span><span class="cx">                 destination.writeDeadProperty(davxml.GETContentType.fromString(generateContentType(content_type)))
</span><span class="cx"> 
</span><span class="cx">         response = IResponse(response)
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Do quota check on destination
</span><span class="cx">         if destquota is not None:
</span><span class="cx">             # Get size of new/old resources
</span><span class="lines">@@ -265,7 +267,7 @@
</span><span class="cx"> 
</span><span class="cx">         yield response
</span><span class="cx">         return
</span><del>-        
</del><ins>+
</ins><span class="cx">     except:
</span><span class="cx">         # Roll back changes to original server state. Note this may do nothing
</span><span class="cx">         # if the rollback has already ocurred or changes already committed.
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodreportpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/report.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/report.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/report.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -52,15 +52,18 @@
</span><span class="cx"> max_number_of_matches = 500
</span><span class="cx"> 
</span><span class="cx"> class NumberOfMatchesWithinLimits(Exception):
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, limit):
</span><del>-        
</del><ins>+
</ins><span class="cx">         super(NumberOfMatchesWithinLimits, self).__init__()
</span><span class="cx">         self.limit = limit
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def maxLimit(self):
</span><span class="cx">         return self.limit
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def http_REPORT(self, request):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Respond to a REPORT request. (RFC 3253, section 3.6)
</span><span class="lines">@@ -124,7 +127,7 @@
</span><span class="cx"> 
</span><span class="cx">     try:
</span><span class="cx">         method = getattr(self, method_name)
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Also double-check via supported-reports property
</span><span class="cx">         reports = self.supportedReports()
</span><span class="cx">         test = lookupElement((namespace, name))
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodreport_acl_principal_prop_setpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/report_acl_principal_prop_set.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/report_acl_principal_prop_set.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/report_acl_principal_prop_set.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">     if depth != &quot;0&quot;:
</span><span class="cx">         log.error(&quot;Error in prinicpal-prop-set REPORT, Depth set to %s&quot; % (depth,))
</span><span class="cx">         raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, &quot;Depth %s not allowed&quot; % (depth,)))
</span><del>-    
</del><ins>+
</ins><span class="cx">     #
</span><span class="cx">     # Check authentication and access controls
</span><span class="cx">     #
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodreport_principal_matchpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/report_principal_match.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/report_principal_match.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/report_principal_match.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx">     if depth != &quot;0&quot;:
</span><span class="cx">         log.error(&quot;Non-zero depth is not allowed: %s&quot; % (depth,))
</span><span class="cx">         raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, &quot;Depth %s not allowed&quot; % (depth,)))
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Get a single DAV:prop element from the REPORT request body
</span><span class="cx">     propertiesForResource = None
</span><span class="cx">     propElement = None
</span><span class="lines">@@ -98,19 +98,19 @@
</span><span class="cx">         if lookForPrincipals:
</span><span class="cx"> 
</span><span class="cx">             # Find the set of principals that represent &quot;self&quot;.
</span><del>-            
</del><ins>+
</ins><span class="cx">             # First add &quot;self&quot;
</span><span class="cx">             principal = waitForDeferred(request.locateResource(str(myPrincipalURL)))
</span><span class="cx">             yield principal
</span><span class="cx">             principal = principal.getResult()
</span><del>-            selfItems = [principal,]
-            
</del><ins>+            selfItems = [principal, ]
+
</ins><span class="cx">             # Get group memberships for &quot;self&quot; and add each of those
</span><span class="cx">             d = waitForDeferred(principal.groupMemberships())
</span><span class="cx">             yield d
</span><span class="cx">             memberships = d.getResult()
</span><span class="cx">             selfItems.extend(memberships)
</span><del>-            
</del><ins>+
</ins><span class="cx">             # Now add each principal found to the response provided the principal resource is a child of
</span><span class="cx">             # the current resource.
</span><span class="cx">             for principal in selfItems:
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">                 # FIXME: making the assumption that the principalURL() is the URL of the resource we found
</span><span class="cx">                 principal_uris = [principal.principalURL()]
</span><span class="cx">                 principal_uris.extend(principal.alternateURIs())
</span><del>-                
</del><ins>+
</ins><span class="cx">                 # Compare each one to the request URI and return at most one that matches
</span><span class="cx">                 for uri in principal_uris:
</span><span class="cx">                     if uri.startswith(request.uri):
</span><span class="lines">@@ -126,7 +126,7 @@
</span><span class="cx">                         matchcount += 1
</span><span class="cx">                         if matchcount &gt; max_number_of_matches:
</span><span class="cx">                             raise NumberOfMatchesWithinLimits(max_number_of_matches)
</span><del>-        
</del><ins>+
</ins><span class="cx">                         d = waitForDeferred(prop_common.responseForHref(
</span><span class="cx">                             request,
</span><span class="cx">                             responses,
</span><span class="lines">@@ -144,9 +144,9 @@
</span><span class="cx">             filteredaces = waitForDeferred(self.inheritedACEsforChildren(request))
</span><span class="cx">             yield filteredaces
</span><span class="cx">             filteredaces = filteredaces.getResult()
</span><del>-        
</del><ins>+
</ins><span class="cx">             children = []
</span><del>-            d = waitForDeferred(self.findChildren(&quot;infinity&quot;, request, lambda x, y: children.append((x,y)),
</del><ins>+            d = waitForDeferred(self.findChildren(&quot;infinity&quot;, request, lambda x, y: children.append((x, y)),
</ins><span class="cx">                                                   privileges=(element.Read(),), inherited_aces=filteredaces))
</span><span class="cx">             yield d
</span><span class="cx">             d.getResult()
</span><span class="lines">@@ -157,7 +157,8 @@
</span><span class="cx">                     prop = waitForDeferred(child.readProperty(principalPropElement.qname(), request))
</span><span class="cx">                     yield prop
</span><span class="cx">                     prop = prop.getResult()
</span><del>-                    if prop: prop.removeWhitespaceNodes()
</del><ins>+                    if prop:
+                        prop.removeWhitespaceNodes()
</ins><span class="cx"> 
</span><span class="cx">                     if prop and len(prop.children) == 1 and isinstance(prop.children[0], element.HRef):
</span><span class="cx">                         # Find principal associated with this property and test it
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodreport_principal_property_searchpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/report_principal_property_search.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/report_principal_property_search.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/report_principal_property_search.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">     if depth != &quot;0&quot;:
</span><span class="cx">         log.error(&quot;Error in prinicpal-property-search REPORT, Depth set to %s&quot; % (depth,))
</span><span class="cx">         raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, &quot;Depth %s not allowed&quot; % (depth,)))
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Get a single DAV:prop element from the REPORT request body
</span><span class="cx">     propertiesForResource = None
</span><span class="cx">     propElement = None
</span><span class="lines">@@ -78,7 +78,8 @@
</span><span class="cx">             props.removeWhitespaceNodes()
</span><span class="cx">             match = child.childOfType(element.Match)
</span><span class="cx">             propertySearches.append((props.children, str(match).lower()))
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def nodeMatch(node, match):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         See if the content of the supplied node matches the supplied text.
</span><span class="lines">@@ -97,7 +98,8 @@
</span><span class="cx">                 return nodeMatch(child, match)
</span><span class="cx">         else:
</span><span class="cx">             return False
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def propertySearch(resource, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test the resource to see if it contains properties matching the
</span><span class="lines">@@ -120,7 +122,7 @@
</span><span class="cx">                     # No property =&gt; no match
</span><span class="cx">                     yield False
</span><span class="cx">                     return
</span><del>-        
</del><ins>+
</ins><span class="cx">         yield True
</span><span class="cx"> 
</span><span class="cx">     propertySearch = deferredGenerator(propertySearch)
</span><span class="lines">@@ -143,7 +145,7 @@
</span><span class="cx">             resources.append((self, request.uri))
</span><span class="cx"> 
</span><span class="cx">         # Loop over all collections and principal resources within
</span><del>-        for resource, ruri in resources:
</del><ins>+        for resource, _ignore_ruri in resources:
</ins><span class="cx"> 
</span><span class="cx">             # Do some optimisation of access control calculation by determining any inherited ACLs outside of
</span><span class="cx">             # the child resource loop and supply those to the checkPrivileges on each child.
</span><span class="lines">@@ -152,7 +154,7 @@
</span><span class="cx">             filteredaces = filteredaces.getResult()
</span><span class="cx"> 
</span><span class="cx">             children = []
</span><del>-            d = waitForDeferred(resource.findChildren(&quot;infinity&quot;, request, lambda x, y: children.append((x,y)),
</del><ins>+            d = waitForDeferred(resource.findChildren(&quot;infinity&quot;, request, lambda x, y: children.append((x, y)),
</ins><span class="cx">                                                       privileges=(element.Read(),), inherited_aces=filteredaces))
</span><span class="cx">             yield d
</span><span class="cx">             d.getResult()
</span><span class="lines">@@ -167,7 +169,7 @@
</span><span class="cx">                         matchcount += 1
</span><span class="cx">                         if matchcount &gt; max_number_of_matches:
</span><span class="cx">                             raise NumberOfMatchesWithinLimits(max_number_of_matches)
</span><del>-    
</del><ins>+
</ins><span class="cx">                         d = waitForDeferred(prop_common.responseForHref(
</span><span class="cx">                             request,
</span><span class="cx">                             responses,
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davmethodreport_principal_search_property_setpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/method/report_principal_search_property_set.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/method/report_principal_search_property_set.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/method/report_principal_search_property_set.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -54,13 +54,13 @@
</span><span class="cx">     if depth != &quot;0&quot;:
</span><span class="cx">         log.error(&quot;Error in principal-search-property-set REPORT, Depth set to %s&quot; % (depth,))
</span><span class="cx">         raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, &quot;Depth %s not allowed&quot; % (depth,)))
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Get details from the resource
</span><span class="cx">     result = self.principalSearchPropertySet()
</span><span class="cx">     if result is None:
</span><span class="cx">         log.error(&quot;Error in principal-search-property-set REPORT not supported on: %s&quot; % (self,))
</span><span class="cx">         raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, &quot;Not allowed on this resource&quot;))
</span><del>-        
</del><ins>+
</ins><span class="cx">     yield Response(code=responsecode.OK, stream=MemoryStream(result.toxml()))
</span><span class="cx"> 
</span><span class="cx"> report_DAV__principal_search_property_set = deferredGenerator(report_DAV__principal_search_property_set)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davnonepropspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/noneprops.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/noneprops.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/noneprops.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -48,28 +48,34 @@
</span><span class="cx">             NonePropertyStore.__singleton = object.__new__(clazz)
</span><span class="cx">         return NonePropertyStore.__singleton
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __init__(self, resource):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def get(self, qname, uid=None):
</span><span class="cx">         raise HTTPError(StatusResponse(
</span><span class="cx">             responsecode.NOT_FOUND,
</span><span class="cx">             &quot;No such property: %s&quot; % (encodeXMLName(*qname),)
</span><span class="cx">         ))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def set(self, property, uid=None):
</span><span class="cx">         raise HTTPError(StatusResponse(
</span><span class="cx">             responsecode.FORBIDDEN,
</span><span class="cx">             &quot;Permission denied for setting property: %s&quot; % (property,)
</span><span class="cx">         ))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def delete(self, qname, uid=None):
</span><span class="cx">         # RFC 2518 Section 12.13.1 says that removal of
</span><span class="cx">         # non-existing property is not an error.
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contains(self, qname, uid=None):
</span><span class="cx">         return False
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def list(self, uid=None):
</span><span class="cx">         return ()
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/resource.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/resource.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/resource.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -148,8 +148,8 @@
</span><span class="cx">             (dav_namespace, &quot;displayname&quot;),
</span><span class="cx">             (dav_namespace, &quot;supportedlock&quot;),
</span><span class="cx">             (dav_namespace, &quot;supported-report-set&quot;), # RFC 3253, section 3.1.5
</span><del>-           #(dav_namespace, &quot;owner&quot;                     ), # RFC 3744, section 5.1
-           #(dav_namespace, &quot;group&quot;                     ), # RFC 3744, section 5.2
</del><ins>+            # (dav_namespace, &quot;owner&quot;                     ), # RFC 3744, section 5.1
+            # (dav_namespace, &quot;group&quot;                     ), # RFC 3744, section 5.2
</ins><span class="cx">             (dav_namespace, &quot;supported-privilege-set&quot;), # RFC 3744, section 5.3
</span><span class="cx">             (dav_namespace, &quot;current-user-privilege-set&quot;), # RFC 3744, section 5.4
</span><span class="cx">             (dav_namespace, &quot;current-user-principal&quot;), # RFC 5397, Section 3
</span><span class="lines">@@ -752,8 +752,8 @@
</span><span class="cx">             for name in names:
</span><span class="cx">                 (names1 if name.rstrip(&quot;/&quot;).find(&quot;/&quot;) == -1 else namesDeep).append(name.rstrip(&quot;/&quot;))
</span><span class="cx"> 
</span><del>-        #children = []
-        #yield self.findChildren(&quot;1&quot;, request, lambda x, y: children.append((x, y)), privileges=None, inherited_aces=None)
</del><ins>+        # children = []
+        # yield self.findChildren(&quot;1&quot;, request, lambda x, y: children.append((x, y)), privileges=None, inherited_aces=None)
</ins><span class="cx"> 
</span><span class="cx">         children = []
</span><span class="cx">         basepath = request.urlForResource(self)
</span><span class="lines">@@ -794,7 +794,7 @@
</span><span class="cx">             )[2].append((resource, url))
</span><span class="cx"> 
</span><span class="cx">         # Now determine whether each ace satisfies privileges
</span><del>-        #print(aclmap)
</del><ins>+        # print(aclmap)
</ins><span class="cx">         for items in aclmap.itervalues():
</span><span class="cx">             checked = (yield self.checkACLPrivilege(
</span><span class="cx">                 request, items[0], items[1], privileges, inherited_aces
</span><span class="lines">@@ -1237,7 +1237,7 @@
</span><span class="cx">                     #
</span><span class="cx">                     # Otherwise, we'd use this logic:
</span><span class="cx">                     #
</span><del>-                    #elif old_ace.inherited:
</del><ins>+                    # elif old_ace.inherited:
</ins><span class="cx">                     #    log.error(&quot;Attempt to overwrite inherited ace %r &quot;
</span><span class="cx">                     #              &quot;on resource %r&quot; % (old_ace, self))
</span><span class="cx">                     #    returnValue((
</span><span class="lines">@@ -1273,8 +1273,7 @@
</span><span class="cx">                 returnValue((element.dav_namespace, &quot;no-ace-conflict&quot;))
</span><span class="cx"> 
</span><span class="cx">             if ace.inherited:
</span><del>-                log.error(&quot;Attempt to create inherited ace %r on resource %r&quot;
-                        % (ace, self))
</del><ins>+                log.error(&quot;Attempt to create inherited ace %r on resource %r&quot; % (ace, self))
</ins><span class="cx">                 returnValue((element.dav_namespace, &quot;no-ace-conflict&quot;))
</span><span class="cx"> 
</span><span class="cx">             # Step 6
</span><span class="lines">@@ -1381,8 +1380,8 @@
</span><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx">         for resource, uri in resources:
</span><del>-            acl = (yield
-                resource.accessControlList(
</del><ins>+            acl = (
+                yield resource.accessControlList(
</ins><span class="cx">                     request,
</span><span class="cx">                     inherited_aces=inherited_aces
</span><span class="cx">                 )
</span><span class="lines">@@ -1404,8 +1403,8 @@
</span><span class="cx">                     ):
</span><span class="cx">                         continue
</span><span class="cx"> 
</span><del>-                    match = (yield
-                        self.matchPrincipal(principal, ace.principal, request)
</del><ins>+                    match = (
+                        yield self.matchPrincipal(principal, ace.principal, request)
</ins><span class="cx">                     )
</span><span class="cx"> 
</span><span class="cx">                     if match:
</span><span class="lines">@@ -1525,8 +1524,8 @@
</span><span class="cx">                     parent = (yield request.locateResource(parentURL))
</span><span class="cx"> 
</span><span class="cx">                     if parent:
</span><del>-                        parent_acl = (yield
-                            parent.accessControlList(
</del><ins>+                        parent_acl = (
+                            yield parent.accessControlList(
</ins><span class="cx">                                 request, inheritance=True, expanding=True
</span><span class="cx">                             )
</span><span class="cx">                         )
</span><span class="lines">@@ -1989,15 +1988,15 @@
</span><span class="cx">             # First see if the ace's principal affects the principal
</span><span class="cx">             # being tested.  FIXME: support the DAV:invert operation
</span><span class="cx"> 
</span><del>-            match = (yield
-                self.matchPrincipal(principal, ace.principal, request)
</del><ins>+            match = (
+                yield self.matchPrincipal(principal, ace.principal, request)
</ins><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx">             if match:
</span><span class="cx">                 # Expand aggregate privileges
</span><span class="cx">                 ps = []
</span><del>-                supportedPrivs = (yield
-                    self.supportedPrivileges(request)
</del><ins>+                supportedPrivs = (
+                    yield self.supportedPrivileges(request)
</ins><span class="cx">                 )
</span><span class="cx">                 for p in ace.privileges:
</span><span class="cx">                     ps.extend(p.expandAggregate(supportedPrivs))
</span><span class="lines">@@ -2319,8 +2318,8 @@
</span><span class="cx"> 
</span><span class="cx">     def renderHTTP(self, request):
</span><span class="cx">         # FIXME: This is for testing with litmus; comment out when not in use
</span><del>-        #litmus = request.headers.getRawHeaders(&quot;x-litmus&quot;)
-        #if litmus: log.info(&quot;*** Litmus test: %s ***&quot; % (litmus,))
</del><ins>+        # litmus = request.headers.getRawHeaders(&quot;x-litmus&quot;)
+        # if litmus: log.info(&quot;*** Litmus test: %s ***&quot; % (litmus,))
</ins><span class="cx"> 
</span><span class="cx">         #
</span><span class="cx">         # If this is a collection and the URI doesn't end in &quot;/&quot;, redirect.
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davstaticpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/static.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/static.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/static.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -8,10 +8,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -51,6 +51,8 @@
</span><span class="cx">     log.info(&quot;Setting of dead properties will not be allowed.&quot;)
</span><span class="cx">     from txweb2.dav.noneprops import NonePropertyStore as DeadPropertyStore
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class DAVFile (DAVResource, File):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     WebDAV-accessible File resource.
</span><span class="lines">@@ -71,41 +73,48 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         File.__init__(
</span><span class="cx">             self, path,
</span><del>-            defaultType = defaultType,
-            ignoredExts = (),
-            processors = None,
-            indexNames = indexNames,
</del><ins>+            defaultType=defaultType,
+            ignoredExts=(),
+            processors=None,
+            indexNames=indexNames,
</ins><span class="cx">         )
</span><span class="cx">         DAVResource.__init__(self, principalCollections=principalCollections)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __repr__(self):
</span><span class="cx">         return &quot;&lt;%s: %s&gt;&quot; % (self.__class__.__name__, self.fp.path)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     ##
</span><span class="cx">     # WebDAV
</span><span class="cx">     ##
</span><span class="cx"> 
</span><span class="cx">     def etag(self):
</span><del>-        if not self.fp.exists(): return succeed(None)
</del><ins>+        if not self.fp.exists():
+            return succeed(None)
</ins><span class="cx">         if self.hasDeadProperty(TwistedGETContentMD5):
</span><span class="cx">             return succeed(http_headers.ETag(str(self.readDeadProperty(TwistedGETContentMD5))))
</span><span class="cx">         else:
</span><span class="cx">             return super(DAVFile, self).etag()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def davComplianceClasses(self):
</span><span class="cx">         return (&quot;1&quot;, &quot;access-control&quot;) # Add &quot;2&quot; when we have locking
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def deadProperties(self):
</span><span class="cx">         if not hasattr(self, &quot;_dead_properties&quot;):
</span><span class="cx">             self._dead_properties = DeadPropertyStore(self)
</span><span class="cx">         return self._dead_properties
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def isCollection(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         See L{IDAVResource.isCollection}.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return self.fp.isdir()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     ##
</span><span class="cx">     # ACL
</span><span class="cx">     ##
</span><span class="lines">@@ -113,6 +122,7 @@
</span><span class="cx">     def supportedPrivileges(self, request):
</span><span class="cx">         return succeed(davPrivilegeSet)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     ##
</span><span class="cx">     # Quota
</span><span class="cx">     ##
</span><span class="lines">@@ -130,10 +140,10 @@
</span><span class="cx">                 &quot;&quot;&quot;
</span><span class="cx">                 Recursively descend the directory tree rooted at top,
</span><span class="cx">                 calling the callback function for each regular file
</span><del>-                
</del><ins>+
</ins><span class="cx">                 @param top: L{FilePath} for the directory to walk.
</span><span class="cx">                 &quot;&quot;&quot;
</span><del>-            
</del><ins>+
</ins><span class="cx">                 total = 0
</span><span class="cx">                 for f in top.listdir():
</span><span class="cx">                     child = top.child(f)
</span><span class="lines">@@ -148,15 +158,16 @@
</span><span class="cx">                     else:
</span><span class="cx">                         # Unknown file type, print a message
</span><span class="cx">                         pass
</span><del>-            
</del><ins>+
</ins><span class="cx">                 yield total
</span><del>-            
</del><ins>+
</ins><span class="cx">             walktree = deferredGenerator(walktree)
</span><del>-    
</del><ins>+
</ins><span class="cx">             return walktree(self.fp)
</span><span class="cx">         else:
</span><span class="cx">             return succeed(self.fp.getsize())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     ##
</span><span class="cx">     # Workarounds for issues with File
</span><span class="cx">     ##
</span><span class="lines">@@ -167,6 +178,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateChild(self, req, segments):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         See L{IResource}C{.locateChild}.
</span><span class="lines">@@ -178,7 +190,7 @@
</span><span class="cx">                 return (child, segments[1:])
</span><span class="cx">         except InsecurePath:
</span><span class="cx">             raise HTTPError(StatusResponse(responsecode.FORBIDDEN, &quot;Invalid URL path&quot;))
</span><del>-        
</del><ins>+
</ins><span class="cx">         # If we're not backed by a directory, we have no children.
</span><span class="cx">         # But check for existance first; we might be a collection resource
</span><span class="cx">         # that the request wants created.
</span><span class="lines">@@ -188,13 +200,14 @@
</span><span class="cx"> 
</span><span class="cx">         # OK, we need to return a child corresponding to the first segment
</span><span class="cx">         path = segments[0]
</span><del>-        
</del><ins>+
</ins><span class="cx">         if path == &quot;&quot;:
</span><span class="cx">             # Request is for a directory (collection) resource
</span><span class="cx">             return (self, ())
</span><span class="cx"> 
</span><span class="cx">         return (self.createSimilarFile(self.fp.child(path).path), segments[1:])
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def createSimilarFile(self, path):
</span><span class="cx">         return self.__class__(
</span><span class="cx">             path, defaultType=self.defaultType, indexNames=self.indexNames[:],
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtest__init__py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/__init__.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/__init__.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/__init__.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_aclpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_acl.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_acl.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_acl.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -54,9 +54,13 @@
</span><span class="cx"> 
</span><span class="cx">         principalCollection = TestPrincipalsCollection(
</span><span class="cx">             &quot;/principals/&quot;,
</span><del>-            children={&quot;users&quot;: TestPrincipalsCollection(
</del><ins>+            children={
+                &quot;users&quot;: TestPrincipalsCollection(
</ins><span class="cx">                     &quot;/principals/users/&quot;,
</span><del>-                    children={&quot;user01&quot;: userResource})})
</del><ins>+                    children={&quot;user01&quot;: userResource}
+                )
+            }
+        )
</ins><span class="cx"> 
</span><span class="cx">         rootResource = self.resource_class(
</span><span class="cx">             docroot, principalCollections=(principalCollection,))
</span><span class="lines">@@ -112,6 +116,7 @@
</span><span class="cx">             rmdir(self._docroot)
</span><span class="cx">             del self._docroot
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_COPY_MOVE_source(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify source access controls during COPY and MOVE.
</span><span class="lines">@@ -122,7 +127,7 @@
</span><span class="cx"> 
</span><span class="cx">             for src, status in (
</span><span class="cx">                 (&quot;nobind&quot;, responsecode.FORBIDDEN),
</span><del>-                (&quot;bind&quot;,   responsecode.FORBIDDEN),
</del><ins>+                (&quot;bind&quot;, responsecode.FORBIDDEN),
</ins><span class="cx">                 (&quot;unbind&quot;, responsecode.CREATED),
</span><span class="cx">             ):
</span><span class="cx">                 src_path = os.path.join(self.docroot, &quot;src_&quot; + src)
</span><span class="lines">@@ -149,30 +154,31 @@
</span><span class="cx"> 
</span><span class="cx">                 for method in (&quot;COPY&quot;, &quot;MOVE&quot;):
</span><span class="cx">                     for name, code in (
</span><del>-                        (&quot;none&quot;       , {&quot;COPY&quot;: responsecode.FORBIDDEN, &quot;MOVE&quot;: status}[method]),
-                        (&quot;read&quot;       , {&quot;COPY&quot;: responsecode.CREATED,   &quot;MOVE&quot;: status}[method]),
-                        (&quot;read-write&quot; , {&quot;COPY&quot;: responsecode.CREATED,   &quot;MOVE&quot;: status}[method]),
-                        (&quot;unlock&quot;     , {&quot;COPY&quot;: responsecode.FORBIDDEN, &quot;MOVE&quot;: status}[method]),
-                        (&quot;all&quot;        , {&quot;COPY&quot;: responsecode.CREATED,   &quot;MOVE&quot;: status}[method]),
</del><ins>+                        (&quot;none&quot;, {&quot;COPY&quot;: responsecode.FORBIDDEN, &quot;MOVE&quot;: status}[method]),
+                        (&quot;read&quot;, {&quot;COPY&quot;: responsecode.CREATED, &quot;MOVE&quot;: status}[method]),
+                        (&quot;read-write&quot; , {&quot;COPY&quot;: responsecode.CREATED, &quot;MOVE&quot;: status}[method]),
+                        (&quot;unlock&quot;, {&quot;COPY&quot;: responsecode.FORBIDDEN, &quot;MOVE&quot;: status}[method]),
+                        (&quot;all&quot;, {&quot;COPY&quot;: responsecode.CREATED, &quot;MOVE&quot;: status}[method]),
</ins><span class="cx">                     ):
</span><span class="cx">                         path = os.path.join(src_path, name)
</span><span class="cx">                         uri = src_uri + &quot;/&quot; + name
</span><del>-    
</del><ins>+
</ins><span class="cx">                         request = SimpleRequest(self.site, method, uri)
</span><span class="cx">                         request.headers.setHeader(&quot;destination&quot;, dst_uri)
</span><span class="cx">                         _add_auth_header(request)
</span><del>-    
</del><ins>+
</ins><span class="cx">                         def test(response, code=code, path=path):
</span><span class="cx">                             if os.path.isfile(dst_path):
</span><span class="cx">                                 os.remove(dst_path)
</span><del>-    
</del><ins>+
</ins><span class="cx">                             if response.code != code:
</span><span class="cx">                                 return self.oops(request, response, code, method, name)
</span><del>-    
</del><ins>+
</ins><span class="cx">                         yield (request, test)
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_COPY_MOVE_dest(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify destination access controls during COPY and MOVE.
</span><span class="lines">@@ -206,6 +212,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_DELETE(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify access controls during DELETE.
</span><span class="lines">@@ -232,6 +239,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_UNLOCK(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify access controls during UNLOCK of unowned lock.
</span><span class="lines">@@ -270,6 +278,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PUT_exists(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify access controls during PUT of existing file.
</span><span class="lines">@@ -295,6 +304,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPFIND(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify access controls during PROPFIND.
</span><span class="lines">@@ -331,6 +341,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_GET_REPORT(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify access controls during GET and REPORT.
</span><span class="lines">@@ -367,13 +378,14 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def oops(self, request, response, code, method, name):
</span><span class="cx">         def gotResponseData(doc):
</span><span class="cx">             if doc is None:
</span><span class="cx">                 doc_xml = None
</span><span class="cx">             else:
</span><span class="cx">                 doc_xml = doc.toxml()
</span><del>-    
</del><ins>+
</ins><span class="cx">             def fail(acl):
</span><span class="cx">                 self.fail(&quot;Incorrect status code %s (!= %s) for %s of resource %s with %s ACL: %s\nACL: %s&quot;
</span><span class="cx">                           % (response.code, code, method, request.uri, name, doc_xml, acl.toxml()))
</span><span class="lines">@@ -391,6 +403,8 @@
</span><span class="cx">         d.addCallback(gotResponseData)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def _add_auth_header(request):
</span><span class="cx">     request.headers.setHeader(
</span><span class="cx">         &quot;authorization&quot;,
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_authpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_auth.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_auth.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_auth.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -51,8 +51,7 @@
</span><span class="cx">                 self.credentialFactories = None
</span><span class="cx">                 self.chanRequest = FakeChannel(secure)
</span><span class="cx"> 
</span><del>-        wrapper = AuthenticationWrapper(None, None,
-            wireEncryptedfactories, wireUnencryptedfactories, None)
</del><ins>+        wrapper = AuthenticationWrapper(None, None, wireEncryptedfactories, wireUnencryptedfactories, None)
</ins><span class="cx">         req = FakeRequest(True) # Connection is over SSL
</span><span class="cx">         wrapper.hook(req)
</span><span class="cx">         self.assertEquals(
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_copypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_copy.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_copy.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_copy.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -70,7 +70,8 @@
</span><span class="cx">                     for filename in os.listdir(dst_path):
</span><span class="cx">                         self.fail(&quot;COPY %s (depth=%r) shouldn't copy directory contents (eg. %s)&quot; % (uri, depth, filename))
</span><span class="cx"> 
</span><del>-                else: raise AssertionError(&quot;Unknown depth: %r&quot; % (depth,))
</del><ins>+                else:
+                    raise AssertionError(&quot;Unknown depth: %r&quot; % (depth,))
</ins><span class="cx"> 
</span><span class="cx">                 rmdir(dst_path)
</span><span class="cx"> 
</span><span class="lines">@@ -80,6 +81,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_COPY_exists(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         COPY to existing resource.
</span><span class="lines">@@ -94,6 +96,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, overwrite=False))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_COPY_overwrite(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         COPY to existing resource with overwrite header.
</span><span class="lines">@@ -110,6 +113,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, overwrite=True))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_COPY_no_parent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         COPY to resource with no parent.
</span><span class="lines">@@ -124,13 +128,16 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, dst=os.path.join(self.docroot, &quot;elvislives!&quot;)))
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def work(self, test, overwrite=None, dst=None, depths=(&quot;0&quot;, &quot;infinity&quot;, None)):
</span><span class="cx">     if dst is None:
</span><span class="cx">         dst = os.path.join(self.docroot, &quot;dst&quot;)
</span><span class="cx">         os.mkdir(dst)
</span><span class="cx"> 
</span><span class="cx">     for basename in os.listdir(self.docroot):
</span><del>-        if basename == &quot;dst&quot;: continue
</del><ins>+        if basename == &quot;dst&quot;:
+            continue
</ins><span class="cx"> 
</span><span class="cx">         uri = urllib.quote(&quot;/&quot; + basename)
</span><span class="cx">         path = os.path.join(self.docroot, basename)
</span><span class="lines">@@ -160,6 +167,8 @@
</span><span class="cx"> 
</span><span class="cx">             yield (request, do_test)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def sumFile(path):
</span><span class="cx">     m = md5()
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_deletepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_delete.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_delete.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_delete.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -58,7 +58,8 @@
</span><span class="cx">                 path = os.path.join(self.docroot, filename)
</span><span class="cx">                 uri = urllib.quote(&quot;/&quot; + filename)
</span><span class="cx"> 
</span><del>-                if os.path.isdir(path): uri = uri + &quot;/&quot;
</del><ins>+                if os.path.isdir(path):
+                    uri = uri + &quot;/&quot;
</ins><span class="cx"> 
</span><span class="cx">                 def do_test(response, path=path):
</span><span class="cx">                     return check_result(response, path)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_httppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -40,13 +40,14 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         for ex_class in (IOError, OSError):
</span><span class="cx">             for exception, result in (
</span><del>-                (ex_class(errno.EACCES, &quot;Permission denied&quot; ), responsecode.FORBIDDEN),
-                (ex_class(errno.EPERM , &quot;Permission denied&quot; ), responsecode.FORBIDDEN),
</del><ins>+                (ex_class(errno.EACCES, &quot;Permission denied&quot;), responsecode.FORBIDDEN),
+                (ex_class(errno.EPERM , &quot;Permission denied&quot;), responsecode.FORBIDDEN),
</ins><span class="cx">                 (ex_class(errno.ENOSPC, &quot;No space available&quot;), responsecode.INSUFFICIENT_STORAGE_SPACE),
</span><del>-                (ex_class(errno.ENOENT, &quot;No such file&quot;      ), responsecode.NOT_FOUND),
</del><ins>+                (ex_class(errno.ENOENT, &quot;No such file&quot;), responsecode.NOT_FOUND),
</ins><span class="cx">             ):
</span><span class="cx">                 self._check_exception(exception, result)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_statusForFailure_HTTPError(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         statusForFailure() for HTTPErrors
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx">             self._check_exception(HTTPError(code), code)
</span><span class="cx">             self._check_exception(HTTPError(ErrorResponse(code, (&quot;http://twistedmatrix.com/&quot;, &quot;bar&quot;))), code)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_statusForFailure_exception(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         statusForFailure() for known/unknown exceptions
</span><span class="lines">@@ -74,6 +76,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.fail(&quot;Unknown exception should have re-raised.&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _check_exception(self, exception, result):
</span><span class="cx">         try:
</span><span class="cx">             raise exception
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_lockpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_lock.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_lock.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_lock.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_mkcolpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_mkcol.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_mkcol.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_mkcol.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self.send(request, check_result)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_MKCOL_invalid_body(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         MKCOL request with invalid request body
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_movepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_move.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_move.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_move.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -62,6 +62,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_MOVE_exists(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         MOVE to existing resource.
</span><span class="lines">@@ -76,6 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, overwrite=False))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_MOVE_overwrite(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         MOVE to existing resource with overwrite header.
</span><span class="lines">@@ -90,6 +92,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, overwrite=True))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_MOVE_no_parent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         MOVE to resource with no parent.
</span><span class="lines">@@ -104,5 +107,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work(self, test, dst=os.path.join(self.docroot, &quot;elvislives!&quot;)))
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def work(self, test, overwrite=None, dst=None):
</span><span class="cx">     return txweb2.dav.test.test_copy.work(self, test, overwrite, dst, depths=(None,))
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_optionspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_options.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_options.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_options.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return self._test_level(&quot;1&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_DAV2(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         DAV level 2
</span><span class="lines">@@ -51,12 +52,14 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return self._test_level(&quot;access-control&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _test_level(self, level):
</span><span class="cx">         def doTest(response):
</span><span class="cx">             response = IResponse(response)
</span><span class="cx"> 
</span><span class="cx">             dav = response.headers.getHeader(&quot;dav&quot;)
</span><del>-            if not dav: self.fail(&quot;no DAV header: %s&quot; % (response.headers,))
</del><ins>+            if not dav:
+                self.fail(&quot;no DAV header: %s&quot; % (response.headers,))
</ins><span class="cx">             self.assertIn(level, dav, &quot;no DAV level %s header&quot; % (level,))
</span><span class="cx"> 
</span><span class="cx">             return response
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_proppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_prop.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_prop.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_prop.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -37,8 +37,8 @@
</span><span class="cx"> 
</span><span class="cx"> # Remove dynamic live properties that exist
</span><span class="cx"> dynamicLiveProperties = (
</span><del>-    (dav_namespace, &quot;quota-available-bytes&quot;     ),
-    (dav_namespace, &quot;quota-used-bytes&quot;          ),
</del><ins>+    (dav_namespace, &quot;quota-available-bytes&quot;),
+    (dav_namespace, &quot;quota-used-bytes&quot;),
</ins><span class="cx"> )
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     def liveProperties(self):
</span><span class="cx">         return [lookupElement(qname)() for qname in self.site.resource.liveProperties() if (qname[0] == dav_namespace) and qname not in dynamicLiveProperties]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPFIND_basic(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PROPFIND request
</span><span class="lines">@@ -115,6 +116,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self.send(request, check_result)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPFIND_list(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PROPFIND with allprop, propname
</span><span class="lines">@@ -196,6 +198,7 @@
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPPATCH_basic(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PROPPATCH
</span><span class="lines">@@ -268,6 +271,7 @@
</span><span class="cx">         request.stream = MemoryStream(patch.toxml())
</span><span class="cx">         return self.send(request, check_patch_response)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPPATCH_liveprop(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PROPPATCH on a live property
</span><span class="lines">@@ -277,6 +281,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self._simple_PROPPATCH(patch, prop, responsecode.FORBIDDEN, &quot;edit of live property&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PROPPATCH_exists_not(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PROPPATCH remove a non-existant property
</span><span class="lines">@@ -286,6 +291,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self._simple_PROPPATCH(patch, prop, responsecode.OK, &quot;remove of non-existant property&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _simple_PROPPATCH(self, patch, prop, expected_code, what):
</span><span class="cx">         def check_result(response):
</span><span class="cx">             response = IResponse(response)
</span><span class="lines">@@ -320,6 +326,8 @@
</span><span class="cx">         request.stream = MemoryStream(patch.toxml())
</span><span class="cx">         return self.send(request, check_result)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class SpiffyProperty (davxml.WebDAVTextElement):
</span><span class="cx">     namespace = &quot;http://twistedmatrix.com/ns/private/tests&quot;
</span><span class="cx">     name = &quot;spiffyproperty&quot;
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_putpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_put.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_put.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_put.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -77,17 +77,20 @@
</span><span class="cx">                 path = os.path.join(self.docroot, name)
</span><span class="cx"> 
</span><span class="cx">                 # Can't really PUT something you can't read
</span><del>-                if not os.path.isfile(path): continue
-    
-                def do_test(response): checkResult(response, path)
-    
</del><ins>+                if not os.path.isfile(path):
+                    continue
+
+                def do_test(response):
+                    checkResult(response, path)
+
</ins><span class="cx">                 request = SimpleRequest(self.site, &quot;PUT&quot;, dst_uri)
</span><span class="cx">                 request.stream = FileStream(file(path, &quot;rb&quot;))
</span><del>-    
</del><ins>+
</ins><span class="cx">                 yield (request, do_test)
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PUT_again(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PUT on existing resource with If-None-Match header
</span><span class="lines">@@ -117,18 +120,19 @@
</span><span class="cx"> 
</span><span class="cx">                 request = SimpleRequest(self.site, &quot;PUT&quot;, dst_uri)
</span><span class="cx">                 request.stream = FileStream(file(__file__, &quot;rb&quot;))
</span><del>-    
</del><ins>+
</ins><span class="cx">                 if code == responsecode.CREATED:
</span><span class="cx">                     if os.path.isfile(dst_path):
</span><span class="cx">                         os.remove(dst_path)
</span><span class="cx">                     request.headers.setHeader(&quot;if-none-match&quot;, (&quot;*&quot;,))
</span><span class="cx">                 elif code == responsecode.PRECONDITION_FAILED:
</span><span class="cx">                     request.headers.setHeader(&quot;if-none-match&quot;, (&quot;*&quot;,))
</span><del>-    
</del><ins>+
</ins><span class="cx">                 yield (request, (checkResult, onError))
</span><span class="cx"> 
</span><span class="cx">         return serialize(self.send, work())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_PUT_no_parent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         PUT with no parent
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_quotapy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_quota.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_quota.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_quota.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -52,12 +52,16 @@
</span><span class="cx">         d.addCallback(_defer)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class QuotaEmpty(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Empty_Quota(self):
</span><span class="cx"> 
</span><span class="cx">         return self.checkQuota(0)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class QuotaPUT(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Quota_PUT(self):
</span><span class="lines">@@ -79,6 +83,8 @@
</span><span class="cx">         request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), &quot;data&quot;, &quot;quota_100.txt&quot;), &quot;rb&quot;))
</span><span class="cx">         return self.send(request, checkResult)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class QuotaDELETE(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Quota_DELETE(self):
</span><span class="lines">@@ -115,6 +121,8 @@
</span><span class="cx">         request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), &quot;data&quot;, &quot;quota_100.txt&quot;), &quot;rb&quot;))
</span><span class="cx">         return self.send(request, checkPUTResult)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class OverQuotaPUT(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Quota_PUT(self):
</span><span class="lines">@@ -138,6 +146,8 @@
</span><span class="cx">         request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), &quot;data&quot;, &quot;quota_100.txt&quot;), &quot;rb&quot;))
</span><span class="cx">         return self.send(request, checkResult)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class QuotaOKAdjustment(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Quota_OK_Adjustment(self):
</span><span class="lines">@@ -169,6 +179,8 @@
</span><span class="cx">         request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), &quot;data&quot;, &quot;quota_100.txt&quot;), &quot;rb&quot;))
</span><span class="cx">         return self.send(request, checkPUTResult)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class QuotaBadAdjustment(QuotaBase):
</span><span class="cx"> 
</span><span class="cx">     def test_Quota_Bad_Adjustment(self):
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_reportpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_report.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_report.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_report.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self.send(request, do_test)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_REPORT_unknown(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Unknown/bogus report type
</span><span class="lines">@@ -62,8 +63,9 @@
</span><span class="cx">                           % (response.code,))
</span><span class="cx">         class GoofyReport (davxml.WebDAVUnknownElement):
</span><span class="cx">             namespace = &quot;GOOFY:&quot;
</span><del>-            name      = &quot;goofy-report&quot;
-            def __init__(self): super(GoofyReport, self).__init__()
</del><ins>+            name = &quot;goofy-report&quot;
+            def __init__(self):
+                super(GoofyReport, self).__init__()
</ins><span class="cx"> 
</span><span class="cx">         request = SimpleRequest(self.site, &quot;REPORT&quot;, &quot;/&quot;)
</span><span class="cx">         request.stream = MemoryStream(GoofyReport().toxml())
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_report_expandpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_report_expand.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_report_expand.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_report_expand.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_resource.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_resource.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_resource.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -215,10 +215,11 @@
</span><span class="cx">         baduser.writeDeadProperty(TwistedPasswordProperty(&quot;badpass&quot;))
</span><span class="cx"> 
</span><span class="cx">         rootresource = TestPrincipalsCollection(&quot;/&quot;, {
</span><del>-                &quot;users&quot;: TestResource(&quot;/users/&quot;,
-                                      {&quot;gooduser&quot;: gooduser,
-                                       &quot;baduser&quot;: baduser})
-            })
</del><ins>+            &quot;users&quot;: TestResource(
+                &quot;/users/&quot;,
+                {&quot;gooduser&quot;: gooduser,
+                 &quot;baduser&quot;: baduser})
+        })
</ins><span class="cx"> 
</span><span class="cx">         protected = TestResource(
</span><span class="cx">             &quot;/protected&quot;, principalCollections=[rootresource])
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_staticpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_static.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_static.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_static.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_xattrpropspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_xattrprops.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_xattrprops.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/test_xattrprops.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -24,6 +24,8 @@
</span><span class="cx"> else:
</span><span class="cx">     from xattr import xattr
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class ExtendedAttributesPropertyStoreTests(TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Tests for L{xattrPropertyStore}.
</span><span class="lines">@@ -31,6 +33,7 @@
</span><span class="cx">     if xattrPropertyStore is None:
</span><span class="cx">         skip = &quot;xattr package missing, cannot test xattr property store&quot;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Create a resource and a xattr property store for it.
</span><span class="lines">@@ -71,6 +74,7 @@
</span><span class="cx">         # of the EPERM failure.
</span><span class="cx">         self.assertEquals(error.response.code, FORBIDDEN)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _missingTest(self, method):
</span><span class="cx">         # Remove access to the directory containing the file so that getting
</span><span class="cx">         # extended attributes from it fails with EPERM.
</span><span class="lines">@@ -99,6 +103,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self._forbiddenTest('get')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_getMissing(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test missing file.
</span><span class="lines">@@ -118,6 +123,7 @@
</span><span class="cx">         # Make sure that the status is NOT FOUND.
</span><span class="cx">         self.assertEquals(error.response.code, NOT_FOUND)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _makeValue(self, uid=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Create and return any old WebDAVDocument for use by the get tests.
</span><span class="lines">@@ -324,6 +330,7 @@
</span><span class="cx">         document = self._makeValue()
</span><span class="cx">         self.assertFalse(propertyStore.contains(document.root_element.qname()))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_list(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{xattrPropertyStore.list} returns a C{list} of property names
</span><span class="lines">@@ -359,6 +366,7 @@
</span><span class="cx">         # of the EPERM failure.
</span><span class="cx">         self.assertEquals(error.response.code, FORBIDDEN)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_listMissing(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test missing file.
</span><span class="lines">@@ -371,12 +379,13 @@
</span><span class="cx">         # Try to get a property from it - and fail.
</span><span class="cx">         self.assertEqual(propertyStore.list(), [])
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_get_uids(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{xattrPropertyStore.get} accepts a L{WebDAVElement} and stores a
</span><span class="cx">         compressed XML document representing it in an extended attribute.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         for uid in (None, &quot;123&quot;, &quot;456&quot;,):
</span><span class="cx">             document = self._makeValue(uid)
</span><span class="cx">             self._setValue(document, document.toxml(), uid=uid)
</span><span class="lines">@@ -391,19 +400,20 @@
</span><span class="cx">         L{xattrPropertyStore.set} accepts a L{WebDAVElement} and stores a
</span><span class="cx">         compressed XML document representing it in an extended attribute.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         for uid in (None, &quot;123&quot;, &quot;456&quot;,):
</span><span class="cx">             document = self._makeValue(uid)
</span><span class="cx">             self.propertyStore.set(document.root_element, uid=uid)
</span><span class="cx">             self.assertEquals(
</span><span class="cx">                 decompress(self._getValue(document, uid)), document.root_element.toxml(pretty=False))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_delete_uids(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{xattrPropertyStore.set} accepts a L{WebDAVElement} and stores a
</span><span class="cx">         compressed XML document representing it in an extended attribute.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         for delete_uid in (None, &quot;123&quot;, &quot;456&quot;,):
</span><span class="cx">             for uid in (None, &quot;123&quot;, &quot;456&quot;,):
</span><span class="cx">                 document = self._makeValue(uid)
</span><span class="lines">@@ -416,7 +426,8 @@
</span><span class="cx">                 document = self._makeValue(uid)
</span><span class="cx">                 self.assertEquals(
</span><span class="cx">                     decompress(self._getValue(document, uid)), document.root_element.toxml(pretty=False))
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def test_contains_uids(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{xattrPropertyStore.contains} returns C{True} if the given property
</span><span class="lines">@@ -430,6 +441,7 @@
</span><span class="cx">             self.assertTrue(
</span><span class="cx">                 self.propertyStore.contains(document.root_element.qname(), uid=uid))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_list_uids(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{xattrPropertyStore.list} returns a C{list} of property names
</span><span class="lines">@@ -465,4 +477,3 @@
</span><span class="cx">                 (u'bar', u'baz', &quot;456&quot;),
</span><span class="cx">                 (u'moo', u'mar456', &quot;456&quot;),
</span><span class="cx">             ]))
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttworequest_clientpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/tworequest_client.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/tworequest_client.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/test/tworequest_client.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -33,8 +33,8 @@
</span><span class="cx"> send(&quot;Content-Length: 100\r\n\r\n&quot;)
</span><span class="cx"> send(&quot;X&quot; * 100)
</span><span class="cx"> 
</span><del>-#import time
-#time.sleep(5)
</del><ins>+# import time
+# time.sleep(5)
</ins><span class="cx"> print &gt;&gt; sys.stderr, &quot;&gt;&gt; Getting data&quot;
</span><span class="cx"> data = ''
</span><span class="cx"> while len(data) &lt; 299999:
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davxattrpropspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/xattrprops.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/xattrprops.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/dav/xattrprops.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -64,6 +64,8 @@
</span><span class="cx"> if hasattr(errno, &quot;ENODATA&quot;):
</span><span class="cx">     _ATTR_MISSING += (errno.ENODATA,)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class xattrPropertyStore (object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -86,6 +88,7 @@
</span><span class="cx">     if sys.platform == &quot;linux2&quot;:
</span><span class="cx">         deadPropertyXattrPrefix = &quot;user.&quot;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _encode(clazz, name, uid=None):
</span><span class="cx">         result = urllib.quote(encodeXMLName(*name), safe='{}:')
</span><span class="cx">         if uid:
</span><span class="lines">@@ -93,6 +96,7 @@
</span><span class="cx">         r = clazz.deadPropertyXattrPrefix + result
</span><span class="cx">         return r
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _decode(clazz, name):
</span><span class="cx">         name = urllib.unquote(name[len(clazz.deadPropertyXattrPrefix):])
</span><span class="cx"> 
</span><span class="lines">@@ -105,8 +109,8 @@
</span><span class="cx">             uid = None
</span><span class="cx">         else:
</span><span class="cx">             uid = name[:index1]
</span><del>-        propnamespace = name[index1+1:index2]
-        propname = name[index2+1:]
</del><ins>+        propnamespace = name[index1 + 1:index2]
+        propname = name[index2 + 1:]
</ins><span class="cx"> 
</span><span class="cx">         return (propnamespace, propname, uid)
</span><span class="cx"> 
</span><span class="lines">@@ -134,7 +138,7 @@
</span><span class="cx">         @return: A L{WebDAVDocument} representing the value associated with the
</span><span class="cx">             given property.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         try:
</span><span class="cx">             data = self.attrs.get(self._encode(qname, uid))
</span><span class="cx">         except KeyError:
</span><span class="lines">@@ -247,7 +251,7 @@
</span><span class="cx"> 
</span><span class="cx">         @return: C{True} if the property exists, C{False} otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-            
</del><ins>+
</ins><span class="cx">         key = self._encode(qname, uid)
</span><span class="cx">         try:
</span><span class="cx">             self.attrs.get(key)
</span><span class="lines">@@ -274,7 +278,7 @@
</span><span class="cx">         @return: A C{list} of property names as two-tuples of namespace URI and
</span><span class="cx">             local name.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-            
</del><ins>+
</ins><span class="cx">         prefix = self.deadPropertyXattrPrefix
</span><span class="cx">         try:
</span><span class="cx">             attrs = iter(self.attrs)
</span><span class="lines">@@ -292,7 +296,7 @@
</span><span class="cx">                 if name.startswith(prefix)
</span><span class="cx">             ]
</span><span class="cx">             if filterByUID:
</span><del>-                return [ 
</del><ins>+                return [
</ins><span class="cx">                     (namespace, name)
</span><span class="cx">                     for namespace, name, propuid in results
</span><span class="cx">                     if propuid == uid
</span></span></pre></div>
<a id="CalendarServertrunktxweb2errorpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/error.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/error.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/error.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -186,10 +186,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def loadMessage(self, code):
</span><del>-        tag = XMLString(('&lt;t:transparent xmlns:t=&quot;http://twistedmatrix.com/'
-                   'ns/twisted.web.template/0.1&quot;&gt;') +
-                  ERROR_MESSAGES.get(code, &quot;&quot;) +
-                    '&lt;/t:transparent&gt;').load()[0]
</del><ins>+        tag = XMLString(
+            ('&lt;t:transparent xmlns:t=&quot;http://twistedmatrix.com/'
+             'ns/twisted.web.template/0.1&quot;&gt;') +
+            ERROR_MESSAGES.get(code, &quot;&quot;) +
+            '&lt;/t:transparent&gt;').load()[0]
</ins><span class="cx">         return tag
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -234,7 +235,7 @@
</span><span class="cx">         subtype = 'error'
</span><span class="cx">         body = 'Error in default error handler:\n' + error[0].getTraceback()
</span><span class="cx"> 
</span><del>-    ctype = http_headers.MimeType('text', subtype, {'charset':'utf-8'})
</del><ins>+    ctype = http_headers.MimeType('text', subtype, {'charset': 'utf-8'})
</ins><span class="cx">     response.headers.setHeader(&quot;content-type&quot;, ctype)
</span><span class="cx">     response.stream = stream.MemoryStream(body)
</span><span class="cx">     return response
</span><span class="lines">@@ -242,5 +243,4 @@
</span><span class="cx"> defaultErrorHandler.handleErrors = True
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-__all__ = ['defaultErrorHandler',]
-
</del><ins>+__all__ = ['defaultErrorHandler', ]
</ins></span></pre></div>
<a id="CalendarServertrunktxweb2fileuploadpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/fileupload.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/fileupload.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/fileupload.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -34,9 +34,9 @@
</span><span class="cx"> from txweb2 import http_headers
</span><span class="cx"> from cStringIO import StringIO
</span><span class="cx"> 
</span><del>-###################################
-#####  Multipart MIME Reader  #####
-###################################
</del><ins>+#
+# Multipart MIME Reader
+#
</ins><span class="cx"> 
</span><span class="cx"> class MimeFormatError(Exception):
</span><span class="cx">     pass
</span><span class="lines">@@ -52,21 +52,22 @@
</span><span class="cx"> def parseContentDispositionFormData(value):
</span><span class="cx">     match = cd_regexp.match(value)
</span><span class="cx">     if not match:
</span><del>-        # Error parsing. 
</del><ins>+        # Error parsing.
</ins><span class="cx">         raise ValueError(&quot;Unknown content-disposition format.&quot;)
</span><del>-    name=match.group(1)
-    filename=match.group(2)
</del><ins>+    name = match.group(1)
+    filename = match.group(2)
</ins><span class="cx">     return name, filename
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-#@defer.deferredGenerator
</del><ins>+
+# @defer.deferredGenerator
</ins><span class="cx"> def _readHeaders(stream):
</span><span class="cx">     &quot;&quot;&quot;Read the MIME headers. Assumes we've just finished reading in the
</span><span class="cx">     boundary string.&quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">     ctype = fieldname = filename = None
</span><span class="cx">     headers = []
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Now read headers
</span><span class="cx">     while 1:
</span><span class="cx">         line = stream.readline(size=1024)
</span><span class="lines">@@ -74,7 +75,7 @@
</span><span class="cx">             line = defer.waitForDeferred(line)
</span><span class="cx">             yield line
</span><span class="cx">             line = line.getResult()
</span><del>-        #print(&quot;GOT&quot;, line)
</del><ins>+        # print(&quot;GOT&quot;, line)
</ins><span class="cx">         if not line.endswith('\r\n'):
</span><span class="cx">             if line == &quot;&quot;:
</span><span class="cx">                 raise MimeFormatError(&quot;Unexpected end of stream.&quot;)
</span><span class="lines">@@ -84,21 +85,21 @@
</span><span class="cx">         line = line[:-2] # strip \r\n
</span><span class="cx">         if line == &quot;&quot;:
</span><span class="cx">             break # End of headers
</span><del>-        
</del><ins>+
</ins><span class="cx">         parts = line.split(':', 1)
</span><span class="cx">         if len(parts) != 2:
</span><span class="cx">             raise MimeFormatError(&quot;Header did not have a :&quot;)
</span><span class="cx">         name, value = parts
</span><span class="cx">         name = name.lower()
</span><span class="cx">         headers.append((name, value))
</span><del>-        
</del><ins>+
</ins><span class="cx">         if name == &quot;content-type&quot;:
</span><span class="cx">             ctype = http_headers.parseContentType(http_headers.tokenize((value,), foldCase=False))
</span><span class="cx">         elif name == &quot;content-disposition&quot;:
</span><span class="cx">             fieldname, filename = parseContentDispositionFormData(value)
</span><del>-        
</del><ins>+
</ins><span class="cx">     if ctype is None:
</span><del>-        ctype == http_headers.MimeType('application', 'octet-stream')
</del><ins>+        ctype = http_headers.MimeType('application', 'octet-stream')
</ins><span class="cx">     if fieldname is None:
</span><span class="cx">         raise MimeFormatError('Content-disposition invalid or omitted.')
</span><span class="cx"> 
</span><span class="lines">@@ -114,7 +115,7 @@
</span><span class="cx">         self.boundary = boundary
</span><span class="cx">         self.data = ''
</span><span class="cx">         self.deferred = defer.Deferred()
</span><del>-        
</del><ins>+
</ins><span class="cx">     length = None # unknown
</span><span class="cx">     def read(self):
</span><span class="cx">         if self.stream is None:
</span><span class="lines">@@ -128,6 +129,7 @@
</span><span class="cx">             return newdata.addCallbacks(self._gotRead, self._gotError)
</span><span class="cx">         return self._gotRead(newdata)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _gotRead(self, newdata):
</span><span class="cx">         if not newdata:
</span><span class="cx">             raise MimeFormatError(&quot;Unexpected EOF&quot;)
</span><span class="lines">@@ -136,10 +138,10 @@
</span><span class="cx">         data = self.data
</span><span class="cx">         boundary = self.boundary
</span><span class="cx">         off = data.find(boundary)
</span><del>-        
</del><ins>+
</ins><span class="cx">         if off == -1:
</span><span class="cx">             # No full boundary, check for the first character
</span><del>-            off = data.rfind(boundary[0], max(0, len(data)-len(boundary)))
</del><ins>+            off = data.rfind(boundary[0], max(0, len(data) - len(boundary)))
</ins><span class="cx">             if off != -1:
</span><span class="cx">                 # We could have a partial boundary, store it for next time
</span><span class="cx">                 self.data = data[off:]
</span><span class="lines">@@ -148,10 +150,11 @@
</span><span class="cx">                 self.data = ''
</span><span class="cx">                 return data
</span><span class="cx">         else:
</span><del>-            self.stream.pushback(data[off+len(boundary):])
</del><ins>+            self.stream.pushback(data[off + len(boundary):])
</ins><span class="cx">             self.stream = None
</span><span class="cx">             return data[:off]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _gotError(self, err):
</span><span class="cx">         # Propogate error back to MultipartMimeStream also
</span><span class="cx">         if self.deferred is not None:
</span><span class="lines">@@ -159,26 +162,30 @@
</span><span class="cx">             self.deferred = None
</span><span class="cx">             deferred.errback(err)
</span><span class="cx">         return err
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         # Assume error will be raised again and handled by MMS?
</span><span class="cx">         readAndDiscard(self).addErrback(lambda _: None)
</span><del>-        
</del><ins>+
+
+
</ins><span class="cx"> class MultipartMimeStream(object):
</span><span class="cx">     implements(IStream)
</span><span class="cx">     def __init__(self, stream, boundary):
</span><span class="cx">         self.stream = BufferedStream(stream)
</span><del>-        self.boundary = &quot;--&quot;+boundary
</del><ins>+        self.boundary = &quot;--&quot; + boundary
</ins><span class="cx">         self.first = True
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def read(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Return a deferred which will fire with a tuple of:
</span><span class="cx">         (fieldname, filename, ctype, dataStream)
</span><span class="cx">         or None when all done.
</span><del>-        
</del><ins>+
</ins><span class="cx">         Format errors will be sent to the errback.
</span><del>-        
</del><ins>+
</ins><span class="cx">         Returns None when all done.
</span><span class="cx"> 
</span><span class="cx">         IMPORTANT: you *must* exhaust dataStream returned by this call
</span><span class="lines">@@ -193,8 +200,9 @@
</span><span class="cx">         d.addCallback(self._gotHeaders)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _readFirstBoundary(self):
</span><del>-        #print(&quot;_readFirstBoundary&quot;)
</del><ins>+        # print(&quot;_readFirstBoundary&quot;)
</ins><span class="cx">         line = self.stream.readline(size=1024)
</span><span class="cx">         if isinstance(line, defer.Deferred):
</span><span class="cx">             line = defer.waitForDeferred(line)
</span><span class="lines">@@ -202,20 +210,21 @@
</span><span class="cx">             line = line.getResult()
</span><span class="cx">         if line != self.boundary + '\r\n':
</span><span class="cx">             raise MimeFormatError(&quot;Extra data before first boundary: %r looking for: %r&quot; % (line, self.boundary + '\r\n'))
</span><del>-        
-        self.boundary = &quot;\r\n&quot;+self.boundary
</del><ins>+
+        self.boundary = &quot;\r\n&quot; + self.boundary
</ins><span class="cx">         yield True
</span><span class="cx">         return
</span><span class="cx">     _readFirstBoundary = defer.deferredGenerator(_readFirstBoundary)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _readBoundaryLine(self):
</span><del>-        #print(&quot;_readBoundaryLine&quot;)
</del><ins>+        # print(&quot;_readBoundaryLine&quot;)
</ins><span class="cx">         line = self.stream.readline(size=1024)
</span><span class="cx">         if isinstance(line, defer.Deferred):
</span><span class="cx">             line = defer.waitForDeferred(line)
</span><span class="cx">             yield line
</span><span class="cx">             line = line.getResult()
</span><del>-        
</del><ins>+
</ins><span class="cx">         if line == &quot;--\r\n&quot;:
</span><span class="cx">             # THE END!
</span><span class="cx">             yield False
</span><span class="lines">@@ -226,22 +235,25 @@
</span><span class="cx">         return
</span><span class="cx">     _readBoundaryLine = defer.deferredGenerator(_readBoundaryLine)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _doReadHeaders(self, morefields):
</span><del>-        #print(&quot;_doReadHeaders&quot;, morefields)
</del><ins>+        # print(&quot;_doReadHeaders&quot;, morefields)
</ins><span class="cx">         if not morefields:
</span><span class="cx">             return None
</span><span class="cx">         return _readHeaders(self.stream)
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def _gotHeaders(self, headers):
</span><span class="cx">         if headers is None:
</span><span class="cx">             return None
</span><span class="cx">         bws = _BoundaryWatchingStream(self.stream, self.boundary)
</span><span class="cx">         self.deferred = bws.deferred
</span><del>-        ret=list(headers)
</del><ins>+        ret = list(headers)
</ins><span class="cx">         ret.append(bws)
</span><span class="cx">         return tuple(ret)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> def readIntoFile(stream, outFile, maxlen):
</span><span class="cx">     &quot;&quot;&quot;Read the stream into a file, but not if it's longer than maxlen.
</span><span class="cx">     Returns Deferred which will be triggered on finish.
</span><span class="lines">@@ -249,29 +261,32 @@
</span><span class="cx">     curlen = [0]
</span><span class="cx">     def done(_):
</span><span class="cx">         return _
</span><ins>+
+
</ins><span class="cx">     def write(data):
</span><span class="cx">         curlen[0] += len(data)
</span><span class="cx">         if curlen[0] &gt; maxlen:
</span><span class="cx">             raise MimeFormatError(&quot;Maximum length of %d bytes exceeded.&quot; %
</span><span class="cx">                                   maxlen)
</span><del>-        
</del><ins>+
</ins><span class="cx">         outFile.write(data)
</span><span class="cx">     return readStream(stream, write).addBoth(done)
</span><span class="cx"> 
</span><del>-#@defer.deferredGenerator
</del><ins>+
+
+# @defer.deferredGenerator
</ins><span class="cx"> def parseMultipartFormData(stream, boundary,
</span><del>-                           maxMem=100*1024, maxFields=1024, maxSize=10*1024*1024):
</del><ins>+                           maxMem=100 * 1024, maxFields=1024, maxSize=10 * 1024 * 1024):
</ins><span class="cx">     # If the stream length is known to be too large upfront, abort immediately
</span><del>-    
</del><ins>+
</ins><span class="cx">     if stream.length is not None and stream.length &gt; maxSize:
</span><del>-        raise MimeFormatError(&quot;Maximum length of %d bytes exceeded.&quot; %
-                                  maxSize)
-    
</del><ins>+        raise MimeFormatError(&quot;Maximum length of %d bytes exceeded.&quot; % maxSize)
+
</ins><span class="cx">     mms = MultipartMimeStream(stream, boundary)
</span><span class="cx">     numFields = 0
</span><span class="cx">     args = {}
</span><span class="cx">     files = {}
</span><del>-    
</del><ins>+
</ins><span class="cx">     while 1:
</span><span class="cx">         datas = mms.read()
</span><span class="cx">         if isinstance(datas, defer.Deferred):
</span><span class="lines">@@ -280,11 +295,11 @@
</span><span class="cx">             datas = datas.getResult()
</span><span class="cx">         if datas is None:
</span><span class="cx">             break
</span><del>-        
-        numFields+=1
</del><ins>+
+        numFields += 1
</ins><span class="cx">         if numFields == maxFields:
</span><del>-            raise MimeFormatError(&quot;Maximum number of fields %d exceeded&quot;%maxFields)
-        
</del><ins>+            raise MimeFormatError(&quot;Maximum number of fields %d exceeded&quot; % maxFields)
+
</ins><span class="cx">         # Parse data
</span><span class="cx">         fieldname, filename, ctype, stream = datas
</span><span class="cx">         if filename is None:
</span><span class="lines">@@ -311,29 +326,32 @@
</span><span class="cx">             maxSize -= outfile.tell()
</span><span class="cx">             outfile.seek(0)
</span><span class="cx">             files.setdefault(fieldname, []).append((filename, ctype, outfile))
</span><del>-        
-        
</del><ins>+
+
</ins><span class="cx">     yield args, files
</span><span class="cx">     return
</span><span class="cx"> parseMultipartFormData = defer.deferredGenerator(parseMultipartFormData)
</span><span class="cx"> 
</span><del>-###################################
-##### x-www-urlencoded reader #####
-###################################
</del><ins>+#
+# x-www-urlencoded reader
+#
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-def parse_urlencoded_stream(input, maxMem=100*1024,
-                     keep_blank_values=False, strict_parsing=False):
</del><ins>+def parse_urlencoded_stream(
+    input, maxMem=100 * 1024,
+    keep_blank_values=False, strict_parsing=False
+):
+
</ins><span class="cx">     lastdata = ''
</span><del>-    still_going=1
-    
</del><ins>+    still_going = 1
+
</ins><span class="cx">     while still_going:
</span><span class="cx">         try:
</span><span class="cx">             yield input.wait
</span><span class="cx">             data = input.next()
</span><span class="cx">         except StopIteration:
</span><span class="cx">             pairs = [lastdata]
</span><del>-            still_going=0
</del><ins>+            still_going = 0
</ins><span class="cx">         else:
</span><span class="cx">             maxMem -= len(data)
</span><span class="cx">             if maxMem &lt; 0:
</span><span class="lines">@@ -341,13 +359,13 @@
</span><span class="cx">                                       maxMem)
</span><span class="cx">             pairs = str(data).split('&amp;')
</span><span class="cx">             pairs[0] = lastdata + pairs[0]
</span><del>-            lastdata=pairs.pop()
-        
</del><ins>+            lastdata = pairs.pop()
+
</ins><span class="cx">         for name_value in pairs:
</span><span class="cx">             nv = name_value.split('=', 1)
</span><span class="cx">             if len(nv) != 2:
</span><span class="cx">                 if strict_parsing:
</span><del>-                    raise MimeFormatError(&quot;bad query field: %s&quot;) % `name_value`
</del><ins>+                    raise MimeFormatError(&quot;bad query field: %s&quot;) % repr(name_value)
</ins><span class="cx">                 continue
</span><span class="cx">             if len(nv[1]) or keep_blank_values:
</span><span class="cx">                 name = urllib.unquote(nv[0].replace('+', ' '))
</span><span class="lines">@@ -355,13 +373,13 @@
</span><span class="cx">                 yield name, value
</span><span class="cx"> parse_urlencoded_stream = generatorToStream(parse_urlencoded_stream)
</span><span class="cx"> 
</span><del>-def parse_urlencoded(stream, maxMem=100*1024, maxFields=1024,
</del><ins>+def parse_urlencoded(stream, maxMem=100 * 1024, maxFields=1024,
</ins><span class="cx">                      keep_blank_values=False, strict_parsing=False):
</span><span class="cx">     d = {}
</span><span class="cx">     numFields = 0
</span><span class="cx"> 
</span><del>-    s=parse_urlencoded_stream(stream, maxMem, keep_blank_values, strict_parsing)
-    
</del><ins>+    s = parse_urlencoded_stream(stream, maxMem, keep_blank_values, strict_parsing)
+
</ins><span class="cx">     while 1:
</span><span class="cx">         datas = s.read()
</span><span class="cx">         if isinstance(datas, defer.Deferred):
</span><span class="lines">@@ -371,11 +389,11 @@
</span><span class="cx">         if datas is None:
</span><span class="cx">             break
</span><span class="cx">         name, value = datas
</span><del>-        
</del><ins>+
</ins><span class="cx">         numFields += 1
</span><span class="cx">         if numFields == maxFields:
</span><del>-            raise MimeFormatError(&quot;Maximum number of fields %d exceeded&quot;%maxFields)
-        
</del><ins>+            raise MimeFormatError(&quot;Maximum number of fields %d exceeded&quot; % maxFields)
+
</ins><span class="cx">         if name in d:
</span><span class="cx">             d[name].append(value)
</span><span class="cx">         else:
</span></span></pre></div>
<a id="CalendarServertrunktxweb2filtergzippy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/filter/gzip.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/filter/gzip.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/filter/gzip.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -15,11 +15,11 @@
</span><span class="cx">     # uh.. stuff
</span><span class="cx">     header += '\002\377'
</span><span class="cx">     yield header
</span><del>-    
</del><ins>+
</ins><span class="cx">     compress = zlib.compressobj(compressLevel, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
</span><span class="cx">     _compress = compress.compress
</span><span class="cx">     _crc32 = zlib.crc32
</span><del>-    
</del><ins>+
</ins><span class="cx">     yield input.wait
</span><span class="cx">     for buf in input:
</span><span class="cx">         if len(buf) != 0:
</span><span class="lines">@@ -27,16 +27,16 @@
</span><span class="cx">             size += len(buf)
</span><span class="cx">             yield _compress(buf)
</span><span class="cx">         yield input.wait
</span><del>-    
</del><ins>+
</ins><span class="cx">     yield compress.flush()
</span><span class="cx">     yield struct.pack('&lt;LL', crc &amp; 0xFFFFFFFFL, size &amp; 0xFFFFFFFFL)
</span><del>-gzipStream=stream.generatorToStream(gzipStream)
</del><ins>+gzipStream = stream.generatorToStream(gzipStream)
</ins><span class="cx"> 
</span><span class="cx"> def deflateStream(input, compressLevel=6):
</span><span class="cx">     # NOTE: this produces RFC-conformant but some-browser-incompatible output.
</span><span class="cx">     # The RFC says that you're supposed to output zlib-format data, but many
</span><span class="cx">     # browsers expect raw deflate output. Luckily all those browsers support
</span><del>-    # gzip, also, so they won't even see deflate output. 
</del><ins>+    # gzip, also, so they won't even see deflate output.
</ins><span class="cx">     compress = zlib.compressobj(compressLevel, zlib.DEFLATED, zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
</span><span class="cx">     _compress = compress.compress
</span><span class="cx">     yield input.wait
</span><span class="lines">@@ -46,24 +46,24 @@
</span><span class="cx">         yield input.wait
</span><span class="cx"> 
</span><span class="cx">     yield compress.flush()
</span><del>-deflateStream=stream.generatorToStream(deflateStream)
</del><ins>+deflateStream = stream.generatorToStream(deflateStream)
</ins><span class="cx"> 
</span><span class="cx"> def gzipfilter(request, response):
</span><span class="cx">     if response.stream is None or response.headers.getHeader('content-encoding'):
</span><span class="cx">         # Empty stream, or already compressed.
</span><span class="cx">         return response
</span><del>-    
</del><ins>+
</ins><span class="cx">     # FIXME: make this a more flexible matching scheme
</span><span class="cx">     mimetype = response.headers.getHeader('content-type')
</span><span class="cx">     if not mimetype or mimetype.mediaType != 'text':
</span><span class="cx">         return response
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Make sure to note we're going to return different content depending on
</span><span class="cx">     # the accept-encoding header.
</span><span class="cx">     vary = response.headers.getHeader('vary', [])
</span><span class="cx">     if 'accept-encoding' not in vary:
</span><del>-        response.headers.setHeader('vary', vary+['accept-encoding'])
-    
</del><ins>+        response.headers.setHeader('vary', vary + ['accept-encoding'])
+
</ins><span class="cx">     ae = request.headers.getHeader('accept-encoding', {})
</span><span class="cx">     # Always prefer gzip over deflate no matter what their q-values are.
</span><span class="cx">     if ae.get('gzip', 0):
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">     elif ae.get('deflate', 0):
</span><span class="cx">         response.stream = deflateStream(response.stream)
</span><span class="cx">         response.headers.setHeader('content-encoding', ['deflate'])
</span><del>-    
</del><ins>+
</ins><span class="cx">     return response
</span><span class="cx"> 
</span><span class="cx"> __all__ = ['gzipfilter']
</span></span></pre></div>
<a id="CalendarServertrunktxweb2filterlocationpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/filter/location.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/filter/location.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/filter/location.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -16,13 +16,13 @@
</span><span class="cx">             # Check to see whether we have an absolute URI or not.
</span><span class="cx">             # If not, have the request turn it into an absolute URI.
</span><span class="cx">             #
</span><del>-            (scheme, host, path, params, querystring, fragment) = urlparse.urlparse(location)
</del><ins>+            (scheme, _ignore_host, _ignore_path, _ignore_params, _ignore_querystring, _ignore_fragment) = urlparse.urlparse(location)
</ins><span class="cx"> 
</span><span class="cx">             if scheme == &quot;&quot;:
</span><span class="cx">                 uri = request.unparseURL(path=location)
</span><span class="cx">             else:
</span><span class="cx">                 uri = location
</span><del>-        
</del><ins>+
</ins><span class="cx">             response.headers.setHeader(&quot;location&quot;, uri)
</span><span class="cx"> 
</span><span class="cx">         return response
</span></span></pre></div>
<a id="CalendarServertrunktxweb2filterrangepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/filter/range.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/filter/range.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/filter/range.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> # -*- test-case-name: txweb2.test.test_stream -*-
</span><span class="cx"> 
</span><del>-import time, os
</del><ins>+import os
+import time
</ins><span class="cx"> 
</span><span class="cx"> from txweb2 import http, http_headers, responsecode, stream
</span><span class="cx"> 
</span><span class="lines">@@ -9,26 +10,30 @@
</span><span class="cx"> class UnsatisfiableRangeRequest(Exception):
</span><span class="cx">     pass
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def canonicalizeRange((start, end), size):
</span><span class="cx">     &quot;&quot;&quot;Return canonicalized (start, end) or raises UnsatisfiableRangeRequest
</span><span class="cx">     exception.
</span><span class="cx"> 
</span><span class="cx">     NOTE: end is the last byte *inclusive*, which is not the usual convention
</span><span class="cx">     in python! Be very careful! A range of 0,1 should return 2 bytes.&quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     # handle &quot;-500&quot; ranges
</span><span class="cx">     if start is None:
</span><del>-        start = max(0, size-end)
</del><ins>+        start = max(0, size - end)
</ins><span class="cx">         end = None
</span><del>-    
</del><ins>+
</ins><span class="cx">     if end is None or end &gt;= size:
</span><span class="cx">         end = size - 1
</span><del>-        
</del><ins>+
</ins><span class="cx">     if start &gt;= size:
</span><span class="cx">         raise UnsatisfiableRangeRequest
</span><del>-    
-    return start,end
</del><span class="cx"> 
</span><ins>+    return start, end
+
+
+
</ins><span class="cx"> def makeUnsatisfiable(request, oldresponse):
</span><span class="cx">     if request.headers.hasHeader('if-range'):
</span><span class="cx">         return oldresponse # Return resource instead of error
</span><span class="lines">@@ -36,15 +41,19 @@
</span><span class="cx">     response.headers.setHeader(&quot;content-range&quot;, ('bytes', None, None, oldresponse.stream.length))
</span><span class="cx">     return response
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def makeSegment(inputStream, lastOffset, start, end):
</span><span class="cx">     offset = start - lastOffset
</span><span class="cx">     length = end + 1 - start
</span><del>-    
</del><ins>+
</ins><span class="cx">     if offset != 0:
</span><span class="cx">         before, inputStream = inputStream.split(offset)
</span><span class="cx">         before.close()
</span><span class="cx">     return inputStream.split(length)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def rangefilter(request, oldresponse):
</span><span class="cx">     if oldresponse.stream is None:
</span><span class="cx">         return oldresponse
</span><span class="lines">@@ -53,24 +62,26 @@
</span><span class="cx">         # Does not deal with indeterminate length outputs
</span><span class="cx">         return oldresponse
</span><span class="cx"> 
</span><del>-    oldresponse.headers.setHeader('accept-ranges',('bytes',))
-    
</del><ins>+    oldresponse.headers.setHeader('accept-ranges', ('bytes',))
+
</ins><span class="cx">     rangespec = request.headers.getHeader('range')
</span><del>-    
</del><ins>+
</ins><span class="cx">     # If we've got a range header and the If-Range header check passes, and
</span><span class="cx">     # the range type is bytes, do a partial response.
</span><del>-    if (rangespec is not None and http.checkIfRange(request, oldresponse) and
-        rangespec[0] == 'bytes'):
</del><ins>+    if (
+        rangespec is not None and http.checkIfRange(request, oldresponse) and
+        rangespec[0] == 'bytes'
+    ):
</ins><span class="cx">         # If it's a single range, return a simple response
</span><span class="cx">         if len(rangespec[1]) == 1:
</span><span class="cx">             try:
</span><del>-                start,end = canonicalizeRange(rangespec[1][0], size)
</del><ins>+                start, end = canonicalizeRange(rangespec[1][0], size)
</ins><span class="cx">             except UnsatisfiableRangeRequest:
</span><span class="cx">                 return makeUnsatisfiable(request, oldresponse)
</span><span class="cx"> 
</span><span class="cx">             response = http.Response(responsecode.PARTIAL_CONTENT, oldresponse.headers)
</span><del>-            response.headers.setHeader('content-range',('bytes',start, end, size))
-            
</del><ins>+            response.headers.setHeader('content-range', ('bytes', start, end, size))
+
</ins><span class="cx">             content, after = makeSegment(oldresponse.stream, 0, start, end)
</span><span class="cx">             after.close()
</span><span class="cx">             response.stream = content
</span><span class="lines">@@ -81,40 +92,44 @@
</span><span class="cx">             offsetList = []
</span><span class="cx">             for arange in rangespec[1]:
</span><span class="cx">                 try:
</span><del>-                    start,end = canonicalizeRange(arange, size)
</del><ins>+                    start, end = canonicalizeRange(arange, size)
</ins><span class="cx">                 except UnsatisfiableRangeRequest:
</span><span class="cx">                     continue
</span><span class="cx">                 if start &lt;= lastOffset:
</span><span class="cx">                     # Stupid client asking for out-of-order or overlapping ranges, PUNT!
</span><span class="cx">                     return oldresponse
</span><del>-                offsetList.append((start,end))
</del><ins>+                offsetList.append((start, end))
</ins><span class="cx">                 lastOffset = end
</span><span class="cx"> 
</span><span class="cx">             if not offsetList:
</span><span class="cx">                 return makeUnsatisfiable(request, oldresponse)
</span><del>-            
</del><ins>+
</ins><span class="cx">             content_type = oldresponse.headers.getRawHeaders('content-type')
</span><del>-            boundary = &quot;%x%x&quot; % (int(time.time()*1000000), os.getpid())
</del><ins>+            boundary = &quot;%x%x&quot; % (int(time.time() * 1000000), os.getpid())
</ins><span class="cx">             response = http.Response(responsecode.PARTIAL_CONTENT, oldresponse.headers)
</span><del>-            
-            response.headers.setHeader('content-type',
</del><ins>+
+            response.headers.setHeader(
+                'content-type',
</ins><span class="cx">                 http_headers.MimeType('multipart', 'byteranges',
</span><del>-                                      [('boundary', boundary)]))
</del><ins>+                                      [('boundary', boundary)])
+            )
</ins><span class="cx">             response.stream = out = stream.CompoundStream()
</span><del>-            
-            
</del><ins>+
+
</ins><span class="cx">             lastOffset = 0
</span><span class="cx">             origStream = oldresponse.stream
</span><span class="cx"> 
</span><span class="cx">             headerString = &quot;\r\n--%s&quot; % boundary
</span><span class="cx">             if len(content_type) == 1:
</span><del>-                headerString+='\r\nContent-Type: %s' % content_type[0]
-            headerString+=&quot;\r\nContent-Range: %s\r\n\r\n&quot;
-            
-            for start,end in offsetList:
-                out.addStream(headerString % 
-                    http_headers.generateContentRange(('bytes', start, end, size)))
</del><ins>+                headerString += '\r\nContent-Type: %s' % content_type[0]
+            headerString += &quot;\r\nContent-Range: %s\r\n\r\n&quot;
</ins><span class="cx"> 
</span><ins>+            for start, end in offsetList:
+                out.addStream(
+                    headerString %
+                    http_headers.generateContentRange(('bytes', start, end, size))
+                )
+
</ins><span class="cx">                 content, origStream = makeSegment(origStream, lastOffset, start, end)
</span><span class="cx">                 lastOffset = end + 1
</span><span class="cx">                 out.addStream(content)
</span><span class="lines">@@ -124,5 +139,5 @@
</span><span class="cx">     else:
</span><span class="cx">         return oldresponse
</span><span class="cx"> 
</span><del>-    
</del><ins>+
</ins><span class="cx"> __all__ = ['rangefilter']
</span></span></pre></div>
<a id="CalendarServertrunktxweb2httppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -236,7 +236,8 @@
</span><span class="cx">             'date', 'etag', 'content-location', 'expires',
</span><span class="cx">             'cache-control', 'vary',
</span><span class="cx">             # Others:
</span><del>-            'server', 'proxy-authenticate', 'www-authenticate', 'warning'):
</del><ins>+            'server', 'proxy-authenticate', 'www-authenticate', 'warning'
+        ):
</ins><span class="cx">             value = oldResponse.headers.getRawHeaders(header)
</span><span class="cx">             if value is not None:
</span><span class="cx">                 headers.setRawHeaders(header, value)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2http_headerspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/http_headers.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/http_headers.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/http_headers.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -243,7 +243,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##### HTTP tokenizer
</del><ins>+# HTTP tokenizer
</ins><span class="cx"> class Token(str):
</span><span class="cx">     __slots__ = []
</span><span class="cx">     tokens = {}
</span><span class="lines">@@ -385,7 +385,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##### parser utilities:
</del><ins>+# parser utilities:
</ins><span class="cx"> def checkSingleToken(tokens):
</span><span class="cx">     if len(tokens) != 1:
</span><span class="cx">         raise ValueError(&quot;Expected single token, not %s.&quot; % (tokens,))
</span><span class="lines">@@ -430,7 +430,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##### Generation utilities
</del><ins>+# Generation utilities
</ins><span class="cx"> def quoteString(s):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Quote a string according to the rules for the I{quoted-string} production
</span><span class="lines">@@ -589,7 +589,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##### Specific header parsers.
</del><ins>+# Specific header parsers.
</ins><span class="cx"> def parseAccept(field):
</span><span class="cx">     atype, args = parseArgs(field)
</span><span class="cx"> 
</span><span class="lines">@@ -863,7 +863,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-#### Header generators
</del><ins>+# Header generators
</ins><span class="cx"> def generateAccept(accept):
</span><span class="cx">     mimeType, q = accept
</span><span class="cx"> 
</span><span class="lines">@@ -1126,7 +1126,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-#### Cookies. Blech!
</del><ins>+# Cookies. Blech!
</ins><span class="cx"> class Cookie(object):
</span><span class="cx">     # __slots__ = ['name', 'value', 'path', 'domain', 'ports', 'expires', 'discard', 'secure', 'comment', 'commenturl', 'version']
</span><span class="cx"> 
</span><span class="lines">@@ -1501,7 +1501,7 @@
</span><span class="cx">     # MS definition uses lower case
</span><span class="cx">     return &quot;t&quot; if brief else &quot;f&quot;
</span><span class="cx"> 
</span><del>-##### Random stuff that looks useful.
</del><ins>+# Random stuff that looks useful.
</ins><span class="cx"> # def sortMimeQuality(s):
</span><span class="cx"> #     def sorter(item1, item2):
</span><span class="cx"> #         if item1[0] == '*':
</span><span class="lines">@@ -1716,24 +1716,24 @@
</span><span class="cx">     'Cache-Control': (tokenize, listParser(parseCacheControl), dict),
</span><span class="cx">     'Connection': (tokenize, filterTokens),
</span><span class="cx">     'Date': (last, parseDateTime),
</span><del>-#    'Pragma': tokenize
-#    'Trailer': tokenize
</del><ins>+    # 'Pragma': tokenize
+    # 'Trailer': tokenize
</ins><span class="cx">     'Transfer-Encoding': (tokenize, filterTokens),
</span><del>-#    'Upgrade': tokenize
-#    'Via': tokenize,stripComment
-#    'Warning': tokenize
</del><ins>+    # 'Upgrade': tokenize
+    # 'Via': tokenize,stripComment
+    # 'Warning': tokenize
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> generator_general_headers = {
</span><span class="cx">     'Cache-Control': (iteritems, listGenerator(generateCacheControl), singleHeader),
</span><span class="cx">     'Connection': (generateList, singleHeader),
</span><span class="cx">     'Date': (generateDateTime, singleHeader),
</span><del>-#    'Pragma':
-#    'Trailer':
</del><ins>+    # 'Pragma':
+    # 'Trailer':
</ins><span class="cx">     'Transfer-Encoding': (generateList, singleHeader),
</span><del>-#    'Upgrade':
-#    'Via':
-#    'Warning':
</del><ins>+    # 'Upgrade':
+    # 'Via':
+    # 'Warning':
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> parser_request_headers = {
</span><span class="lines">@@ -1753,7 +1753,7 @@
</span><span class="cx">     'If-Unmodified-Since': (last, parseDateTime),
</span><span class="cx">     'Max-Forwards': (last, int),
</span><span class="cx">     'Prefer': (tokenize, listParser(parsePrefer), list),
</span><del>-#    'Proxy-Authorization': str, # what is &quot;credentials&quot;
</del><ins>+    # 'Proxy-Authorization': str, # what is &quot;credentials&quot;
</ins><span class="cx">     'Range': (tokenize, parseRange),
</span><span class="cx">     'Referer': (last, str), # TODO: URI object?
</span><span class="cx">     'TE': (tokenize, listParser(parseAcceptQvalue), dict),
</span><span class="lines">@@ -1777,7 +1777,7 @@
</span><span class="cx">     'If-Unmodified-Since': (generateDateTime, singleHeader),
</span><span class="cx">     'Max-Forwards': (str, singleHeader),
</span><span class="cx">     'Prefer': (listGenerator(generatePrefer), singleHeader),
</span><del>-#    'Proxy-Authorization': str, # what is &quot;credentials&quot;
</del><ins>+    # 'Proxy-Authorization': str, # what is &quot;credentials&quot;
</ins><span class="cx">     'Range': (generateRange, singleHeader),
</span><span class="cx">     'Referer': (str, singleHeader),
</span><span class="cx">     'TE': (iteritems, listGenerator(generateAcceptQvalue), singleHeader),
</span><span class="lines">@@ -1789,7 +1789,7 @@
</span><span class="cx">     'Age': (last, int),
</span><span class="cx">     'ETag': (tokenize, ETag.parse),
</span><span class="cx">     'Location': (last,), # TODO: URI object?
</span><del>-#    'Proxy-Authenticate'
</del><ins>+    # 'Proxy-Authenticate'
</ins><span class="cx">     'Retry-After': (last, parseRetryAfter),
</span><span class="cx">     'Server': (last,),
</span><span class="cx">     'Set-Cookie': (parseSetCookie,),
</span><span class="lines">@@ -1804,7 +1804,7 @@
</span><span class="cx">     'Age': (str, singleHeader),
</span><span class="cx">     'ETag': (ETag.generate, singleHeader),
</span><span class="cx">     'Location': (str, singleHeader),
</span><del>-#    'Proxy-Authenticate'
</del><ins>+    # 'Proxy-Authenticate'
</ins><span class="cx">     'Retry-After': (generateRetryAfter, singleHeader),
</span><span class="cx">     'Server': (str, singleHeader),
</span><span class="cx">     'Set-Cookie': (generateSetCookie,),
</span><span class="lines">@@ -1825,7 +1825,7 @@
</span><span class="cx">     'Content-Type': (lambda hdr: tokenize(hdr, foldCase=False), parseContentType),
</span><span class="cx">     'Expires': (last, parseExpires),
</span><span class="cx">     'Last-Modified': (last, parseDateTime),
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> generator_entity_headers = {
</span><span class="cx">     'Allow': (generateList, singleHeader),
</span><span class="lines">@@ -1839,18 +1839,18 @@
</span><span class="cx">     'Content-Type': (generateContentType, singleHeader),
</span><span class="cx">     'Expires': (generateDateTime, singleHeader),
</span><span class="cx">     'Last-Modified': (generateDateTime, singleHeader),
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> parser_dav_headers = {
</span><span class="cx">     'Brief'       : (last, parseBrief),
</span><span class="cx">     'DAV'         : (tokenize, list),
</span><span class="cx">     'Depth'       : (last, parseDepth),
</span><span class="cx">     'Destination' : (last,), # TODO: URI object?
</span><del>-   # 'If'          : (),
-   # 'Lock-Token'  : (),
</del><ins>+    # 'If'          : (),
+    # 'Lock-Token'  : (),
</ins><span class="cx">     'Overwrite'   : (last, parseOverWrite),
</span><del>-   # 'Status-URI'  : (),
-   # 'Timeout'     : (),
</del><ins>+    # 'Status-URI'  : (),
+    # 'Timeout'     : (),
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> generator_dav_headers = {
</span><span class="lines">@@ -1858,11 +1858,11 @@
</span><span class="cx">     'DAV'         : (generateList, singleHeader),
</span><span class="cx">     'Depth'       : (singleHeader),
</span><span class="cx">     'Destination' : (singleHeader),
</span><del>-   # 'If'          : (),
-   # 'Lock-Token'  : (),
</del><ins>+    # 'If'          : (),
+    # 'Lock-Token'  : (),
</ins><span class="cx">     'Overwrite'   : (),
</span><del>-   # 'Status-URI'  : (),
-   # 'Timeout'     : (),
</del><ins>+    # 'Status-URI'  : (),
+    # 'Timeout'     : (),
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> DefaultHTTPHandler.updateParsers(parser_general_headers)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2iwebpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/iweb.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/iweb.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/iweb.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -46,11 +46,11 @@
</span><span class="cx"> 
</span><span class="cx">         @return: A 2-tuple of (resource, remaining-path-segments),
</span><span class="cx">                  or a deferred which will fire the above.
</span><del>-                 
</del><ins>+
</ins><span class="cx">                  Causes the object publishing machinery to continue on
</span><span class="cx">                  with specified resource and segments, calling the
</span><span class="cx">                  appropriate method on the specified resource.
</span><del>-                 
</del><ins>+
</ins><span class="cx">                  If you return (self, L{server.StopTraversal}), this
</span><span class="cx">                  instructs web2 to immediately stop the lookup stage,
</span><span class="cx">                  and switch to the rendering stage, leaving the
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx">         result = super(SpecialAdaptInterfaceClass, self).__call__(other, alternate)
</span><span class="cx">         if result is not alternate:
</span><span class="cx">             return result
</span><del>-        
</del><ins>+
</ins><span class="cx">         result = IOldNevowResource(other, alternate)
</span><span class="cx">         if result is not alternate:
</span><span class="cx">             result = IResource(result)
</span><span class="lines">@@ -106,8 +106,10 @@
</span><span class="cx">         string instead of a response object.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class ICanHandleException(Interface):
</span><del>-    
</del><ins>+
</ins><span class="cx">     # Shared interface with inevow.ICanHandleException
</span><span class="cx">     def renderHTTP_exception(request, failure):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -120,6 +122,7 @@
</span><span class="cx">         not replacing the page.&quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> # http.py interfaces
</span><span class="cx"> class IResponse(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="lines">@@ -129,6 +132,8 @@
</span><span class="cx">     headers = Attribute(&quot;A http_headers.Headers instance of headers to send&quot;)
</span><span class="cx">     stream = Attribute(&quot;A stream.IByteStream of outgoing data, or else None.&quot;)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class IRequest(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     I'm a request for a web resource.
</span><span class="lines">@@ -137,21 +142,22 @@
</span><span class="cx">     method = Attribute(&quot;The HTTP method from the request line, e.g. GET&quot;)
</span><span class="cx">     uri = Attribute(&quot;The raw URI from the request line. May or may not include host.&quot;)
</span><span class="cx">     clientproto = Attribute(&quot;Protocol from the request line, e.g. HTTP/1.1&quot;)
</span><del>-    
</del><ins>+
</ins><span class="cx">     headers = Attribute(&quot;A http_headers.Headers instance of incoming headers.&quot;)
</span><span class="cx">     stream = Attribute(&quot;A stream.IByteStream of incoming data.&quot;)
</span><del>-    
</del><ins>+
</ins><span class="cx">     def writeResponse(response):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Write an IResponse object to the client.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     chanRequest = Attribute(&quot;The ChannelRequest. I wonder if this is public really?&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-from twisted.web.iweb import IRequest as IOldRequest
</del><span class="cx"> 
</span><ins>+# from twisted.web.iweb import IRequest as IOldRequest
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IChanRequestCallbacks(Interface):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     The bits that are required of a Request for interfacing with a
</span><span class="lines">@@ -161,7 +167,7 @@
</span><span class="cx">     def __init__(chanRequest, command, path, version, contentLength, inHeaders):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Create a new Request object.
</span><del>-        
</del><ins>+
</ins><span class="cx">         @param chanRequest: the IChanRequest object creating this request
</span><span class="cx">         @param command: the HTTP command e.g. GET
</span><span class="cx">         @param path: the HTTP path e.g. /foo/bar.html
</span><span class="lines">@@ -175,38 +181,39 @@
</span><span class="cx">         to return a response. L{handleContentComplete} may or may not
</span><span class="cx">         have been called already.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def handleContentChunk(data):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Called when a piece of incoming data has been received.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def handleContentComplete():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Called when the incoming data stream is finished.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def connectionLost(reason):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Called if the connection was lost.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
-    
</del><ins>+
+
+
</ins><span class="cx"> class IChanRequest(Interface):
</span><del>-    
</del><ins>+
</ins><span class="cx">     def writeIntermediateResponse(code, headers=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Write a non-terminating response.
</span><del>-        
</del><ins>+
</ins><span class="cx">         Intermediate responses cannot contain data.
</span><span class="cx">         If the channel does not support intermediate responses, do nothing.
</span><del>-        
</del><ins>+
</ins><span class="cx">         @param code: The response code. Should be in the 1xx range.
</span><span class="cx">         @type code: int
</span><span class="cx">         @param headers: the headers to send in the response
</span><span class="cx">         @type headers: C{twisted.web.http_headers.Headers}
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def writeHeaders(code, headers):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Write a final response.
</span><span class="lines">@@ -218,7 +225,7 @@
</span><span class="cx">             necessary for the protocol.
</span><span class="cx">         @type headers: C{twisted.web.http_headers.Headers}
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def write(data):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Write some data.
</span><span class="lines">@@ -226,16 +233,16 @@
</span><span class="cx">         @param data: the data bytes
</span><span class="cx">         @type data: str
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def finish():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Finish the request, and clean up the connection if necessary.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def abortConnection():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Forcibly abort the connection without cleanly closing.
</span><del>-        
</del><ins>+
</ins><span class="cx">         Use if, for example, you can't write all the data you promised.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -243,7 +250,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Register a producer with the standard API.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def unregisterProducer():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Unregister a producer.
</span><span class="lines">@@ -270,6 +277,7 @@
</span><span class="cx">     persistent = Attribute(&quot;&quot;&quot;Whether this request supports HTTP connection persistence. May be set to False. Should not be set to other values.&quot;&quot;&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ISite(Interface):
</span><span class="cx">     pass
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2logpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/log.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/log.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/log.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -39,65 +39,73 @@
</span><span class="cx"> 
</span><span class="cx"> class _LogByteCounter(object):
</span><span class="cx">     implements(stream.IByteStream)
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, stream, done):
</span><del>-        self.stream=stream
-        self.done=done
-        self.len=0
-        
-    length=property(lambda self: self.stream.length)
-    
</del><ins>+        self.stream = stream
+        self.done = done
+        self.len = 0
+
+    length = property(lambda self: self.stream.length)
+
</ins><span class="cx">     def _callback(self, data):
</span><span class="cx">         if data is None:
</span><span class="cx">             if self.done:
</span><del>-                done=self.done; self.done=None
</del><ins>+                done = self.done
+                self.done = None
</ins><span class="cx">                 done(True, self.len)
</span><span class="cx">         else:
</span><span class="cx">             self.len += len(data)
</span><span class="cx">         return data
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def read(self):
</span><span class="cx">         data = self.stream.read()
</span><span class="cx">         if isinstance(data, defer.Deferred):
</span><span class="cx">             return data.addCallback(self._callback)
</span><span class="cx">         return self._callback(data)
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         if self.done:
</span><del>-            done=self.done; self.done=None
</del><ins>+            done = self.done
+            self.done = None
</ins><span class="cx">             done(False, self.len)
</span><span class="cx">         self.stream.close()
</span><span class="cx"> 
</span><del>-    
</del><ins>+
+
</ins><span class="cx"> class ILogInfo(Interface):
</span><span class="cx">     &quot;&quot;&quot;Auxilliary information about the response useful for logging.&quot;&quot;&quot;
</span><del>-    
-    bytesSent=Attribute(&quot;Number of bytes sent.&quot;)
-    responseCompleted=Attribute(&quot;Whether or not the response was completed.&quot;)
-    secondsTaken=Attribute(&quot;Number of seconds taken to serve the request.&quot;)
-    startTime=Attribute(&quot;Time at which the request started&quot;)
</del><span class="cx"> 
</span><del>-    
</del><ins>+    bytesSent = Attribute(&quot;Number of bytes sent.&quot;)
+    responseCompleted = Attribute(&quot;Whether or not the response was completed.&quot;)
+    secondsTaken = Attribute(&quot;Number of seconds taken to serve the request.&quot;)
+    startTime = Attribute(&quot;Time at which the request started&quot;)
+
+
+
</ins><span class="cx"> class LogInfo(object):
</span><span class="cx">     implements(ILogInfo)
</span><span class="cx"> 
</span><del>-    responseCompleted=None
-    secondsTaken=None
-    bytesSent=None
-    startTime=None
</del><ins>+    responseCompleted = None
+    secondsTaken = None
+    bytesSent = None
+    startTime = None
</ins><span class="cx"> 
</span><del>-    
</del><ins>+
+
</ins><span class="cx"> def logFilter(request, response, startTime=None):
</span><span class="cx">     if startTime is None:
</span><span class="cx">         startTime = time.time()
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def _log(success, length):
</span><del>-        loginfo=LogInfo()
-        loginfo.bytesSent=length
-        loginfo.responseCompleted=success
-        loginfo.secondsTaken=time.time()-startTime
</del><ins>+        loginfo = LogInfo()
+        loginfo.bytesSent = length
+        loginfo.responseCompleted = success
+        loginfo.secondsTaken = time.time() - startTime
</ins><span class="cx"> 
</span><del>-        if length:        
</del><ins>+        if length:
</ins><span class="cx">             request.timeStamp(&quot;t-resp-wr&quot;)
</span><span class="cx">         log.info(interface=iweb.IRequest, request=request, response=response,
</span><span class="cx">                  loginfo=loginfo)
</span><span class="lines">@@ -106,7 +114,7 @@
</span><span class="cx"> 
</span><span class="cx">     request.timeStamp(&quot;t-resp-gen&quot;)
</span><span class="cx">     if response.stream:
</span><del>-        response.stream=_LogByteCounter(response.stream, _log)
</del><ins>+        response.stream = _LogByteCounter(response.stream, _log)
</ins><span class="cx">     else:
</span><span class="cx">         _log(True, 0)
</span><span class="cx"> 
</span><span class="lines">@@ -137,6 +145,7 @@
</span><span class="cx">     def logMessage(self, message):
</span><span class="cx">         raise NotImplemented, 'You must provide an implementation.'
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def computeTimezoneForLog(self, tz):
</span><span class="cx">         if tz &gt; 0:
</span><span class="cx">             neg = 1
</span><span class="lines">@@ -156,7 +165,7 @@
</span><span class="cx">     def logDateString(self, when):
</span><span class="cx">         logtime = time.localtime(when)
</span><span class="cx">         Y, M, D, h, m, s = logtime[:6]
</span><del>-        
</del><ins>+
</ins><span class="cx">         if not time.daylight:
</span><span class="cx">             tz = self.tzForLog
</span><span class="cx">             if tz is None:
</span><span class="lines">@@ -171,6 +180,7 @@
</span><span class="cx">         return '%02d/%s/%02d:%02d:%02d:%02d %s' % (
</span><span class="cx">             D, monthname[M], Y, h, m, s, tz)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def emit(self, eventDict):
</span><span class="cx">         if eventDict.get('interface') is not iweb.IRequest:
</span><span class="cx">             return
</span><span class="lines">@@ -178,11 +188,11 @@
</span><span class="cx">         request = eventDict['request']
</span><span class="cx">         response = eventDict['response']
</span><span class="cx">         loginfo = eventDict['loginfo']
</span><del>-        firstLine = '%s %s HTTP/%s' %(
</del><ins>+        firstLine = '%s %s HTTP/%s' % (
</ins><span class="cx">             request.method,
</span><span class="cx">             request.uri,
</span><span class="cx">             '.'.join([str(x) for x in request.clientproto]))
</span><del>-        
</del><ins>+
</ins><span class="cx">         self.logMessage(
</span><span class="cx">             '%s - %s [%s] &quot;%s&quot; %s %d &quot;%s&quot; &quot;%s&quot;' % (
</span><span class="cx">                 request.remoteAddr.host,
</span><span class="lines">@@ -195,38 +205,45 @@
</span><span class="cx">                 loginfo.bytesSent,
</span><span class="cx">                 request.headers.getHeader('referer', '-'),
</span><span class="cx">                 request.headers.getHeader('user-agent', '-')
</span><del>-                )
</del><span class="cx">             )
</span><ins>+        )
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def start(self):
</span><span class="cx">         &quot;&quot;&quot;Start observing log events.&quot;&quot;&quot;
</span><span class="cx">         # Use the root publisher to bypass log level filtering
</span><span class="cx">         log.publisher.addObserver(self.emit, filtered=False)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def stop(self):
</span><span class="cx">         &quot;&quot;&quot;Stop observing log events.&quot;&quot;&quot;
</span><span class="cx">         log.publisher.removeObserver(self.emit)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class FileAccessLoggingObserver(BaseCommonAccessLoggingObserver):
</span><span class="cx">     &quot;&quot;&quot;I log requests to a single logfile
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, logpath):
</span><span class="cx">         self.logpath = logpath
</span><del>-                
</del><ins>+
+
</ins><span class="cx">     def logMessage(self, message):
</span><span class="cx">         self.f.write(message + '\n')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def start(self):
</span><span class="cx">         super(FileAccessLoggingObserver, self).start()
</span><span class="cx">         self.f = open(self.logpath, 'a', 1)
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def stop(self):
</span><span class="cx">         super(FileAccessLoggingObserver, self).stop()
</span><span class="cx">         self.f.close()
</span><span class="cx"> 
</span><del>-                
</del><ins>+
+
</ins><span class="cx"> class DefaultCommonAccessLoggingObserver(BaseCommonAccessLoggingObserver):
</span><span class="cx">     &quot;&quot;&quot;Log requests to default twisted logfile.&quot;&quot;&quot;
</span><span class="cx">     def logMessage(self, message):
</span></span></pre></div>
<a id="CalendarServertrunktxweb2resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/resource.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/resource.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/resource.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx">             )
</span><span class="cx">         return self._allowed_methods
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkPreconditions(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Checks all preconditions imposed by this resource upon a request made
</span><span class="lines">@@ -148,6 +149,7 @@
</span><span class="cx"> #        &quot;&quot;&quot;
</span><span class="cx"> #        return server.doTrace(request)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def http_HEAD(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Respond to a HEAD request.
</span><span class="lines">@@ -156,6 +158,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return self.http_GET(request)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def http_GET(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Respond to a GET request.
</span><span class="lines">@@ -171,6 +174,7 @@
</span><span class="cx"> 
</span><span class="cx">         return self.render(request)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Subclasses should implement this method to do page rendering.
</span><span class="lines">@@ -216,6 +220,7 @@
</span><span class="cx"> 
</span><span class="cx">         return None, []
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def child_(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         This method locates a child with a trailing C{&quot;/&quot;} in the URL.
</span><span class="lines">@@ -225,6 +230,7 @@
</span><span class="cx">             return self
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getChild(self, path):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Get a static child - when registered using L{putChild}.
</span><span class="lines">@@ -253,6 +259,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         setattr(self, 'child_%s' % (path,), child)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def http_GET(self, request):
</span><span class="cx">         if self.addSlash and request.prepath[-1] != '':
</span><span class="cx">             # If this is a directory-ish resource...
</span><span class="lines">@@ -320,6 +327,7 @@
</span><span class="cx">         self._args = args
</span><span class="cx">         self._kwargs = kwargs
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def renderHTTP(self, request):
</span><span class="cx">         return http.RedirectResponse(
</span><span class="cx">             request.unparseURL(*self._args, **self._kwargs)
</span><span class="lines">@@ -338,6 +346,7 @@
</span><span class="cx">     def __init__(self, resource):
</span><span class="cx">         self.resource = resource
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def hook(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Override this method in order to do something before passing control on
</span><span class="lines">@@ -348,18 +357,21 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         raise NotImplementedError()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateChild(self, request, segments):
</span><span class="cx">         x = self.hook(request)
</span><span class="cx">         if x is not None:
</span><span class="cx">             return x.addCallback(lambda data: (self.resource, segments))
</span><span class="cx">         return self.resource, segments
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def renderHTTP(self, request):
</span><span class="cx">         x = self.hook(request)
</span><span class="cx">         if x is not None:
</span><span class="cx">             return x.addCallback(lambda data: self.resource)
</span><span class="cx">         return self.resource
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getChild(self, name):
</span><span class="cx">         return self.resource.getChild(name)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2responsecodepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/responsecode.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/responsecode.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/responsecode.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -23,57 +23,57 @@
</span><span class="cx"> #
</span><span class="cx"> ##
</span><span class="cx"> 
</span><del>-CONTINUE                        = 100
-SWITCHING                       = 101
</del><ins>+CONTINUE = 100
+SWITCHING = 101
</ins><span class="cx"> 
</span><del>-OK                              = 200
-CREATED                         = 201
-ACCEPTED                        = 202
-NON_AUTHORITATIVE_INFORMATION   = 203
-NO_CONTENT                      = 204
-RESET_CONTENT                   = 205
-PARTIAL_CONTENT                 = 206
-MULTI_STATUS                    = 207
</del><ins>+OK = 200
+CREATED = 201
+ACCEPTED = 202
+NON_AUTHORITATIVE_INFORMATION = 203
+NO_CONTENT = 204
+RESET_CONTENT = 205
+PARTIAL_CONTENT = 206
+MULTI_STATUS = 207
</ins><span class="cx"> 
</span><del>-MULTIPLE_CHOICE                 = 300
-MOVED_PERMANENTLY               = 301
-FOUND                           = 302
-SEE_OTHER                       = 303
-NOT_MODIFIED                    = 304
-USE_PROXY                       = 305
-TEMPORARY_REDIRECT              = 307
</del><ins>+MULTIPLE_CHOICE = 300
+MOVED_PERMANENTLY = 301
+FOUND = 302
+SEE_OTHER = 303
+NOT_MODIFIED = 304
+USE_PROXY = 305
+TEMPORARY_REDIRECT = 307
</ins><span class="cx"> 
</span><del>-BAD_REQUEST                     = 400
-UNAUTHORIZED                    = 401
-PAYMENT_REQUIRED                = 402
-FORBIDDEN                       = 403
-NOT_FOUND                       = 404
-NOT_ALLOWED                     = 405
-NOT_ACCEPTABLE                  = 406
-PROXY_AUTH_REQUIRED             = 407
-REQUEST_TIMEOUT                 = 408
-CONFLICT                        = 409
-GONE                            = 410
-LENGTH_REQUIRED                 = 411
-PRECONDITION_FAILED             = 412
-REQUEST_ENTITY_TOO_LARGE        = 413
-REQUEST_URI_TOO_LONG            = 414
-UNSUPPORTED_MEDIA_TYPE          = 415
</del><ins>+BAD_REQUEST = 400
+UNAUTHORIZED = 401
+PAYMENT_REQUIRED = 402
+FORBIDDEN = 403
+NOT_FOUND = 404
+NOT_ALLOWED = 405
+NOT_ACCEPTABLE = 406
+PROXY_AUTH_REQUIRED = 407
+REQUEST_TIMEOUT = 408
+CONFLICT = 409
+GONE = 410
+LENGTH_REQUIRED = 411
+PRECONDITION_FAILED = 412
+REQUEST_ENTITY_TOO_LARGE = 413
+REQUEST_URI_TOO_LONG = 414
+UNSUPPORTED_MEDIA_TYPE = 415
</ins><span class="cx"> REQUESTED_RANGE_NOT_SATISFIABLE = 416
</span><del>-EXPECTATION_FAILED              = 417
-UNPROCESSABLE_ENTITY            = 422 # RFC 2518
-LOCKED                          = 423 # RFC 2518
-FAILED_DEPENDENCY               = 424 # RFC 2518
</del><ins>+EXPECTATION_FAILED = 417
+UNPROCESSABLE_ENTITY = 422 # RFC 2518
+LOCKED = 423 # RFC 2518
+FAILED_DEPENDENCY = 424 # RFC 2518
</ins><span class="cx"> 
</span><del>-INTERNAL_SERVER_ERROR           = 500
-NOT_IMPLEMENTED                 = 501
-BAD_GATEWAY                     = 502
-SERVICE_UNAVAILABLE             = 503
-GATEWAY_TIMEOUT                 = 504
-HTTP_VERSION_NOT_SUPPORTED      = 505
-LOOP_DETECTED                   = 506
-INSUFFICIENT_STORAGE_SPACE      = 507
-NOT_EXTENDED                    = 510
</del><ins>+INTERNAL_SERVER_ERROR = 500
+NOT_IMPLEMENTED = 501
+BAD_GATEWAY = 502
+SERVICE_UNAVAILABLE = 503
+GATEWAY_TIMEOUT = 504
+HTTP_VERSION_NOT_SUPPORTED = 505
+LOOP_DETECTED = 506
+INSUFFICIENT_STORAGE_SPACE = 507
+NOT_EXTENDED = 510
</ins><span class="cx"> 
</span><span class="cx"> RESPONSES = {
</span><span class="cx">     # 100
</span><span class="lines">@@ -133,6 +133,6 @@
</span><span class="cx">     LOOP_DETECTED: &quot;Loop In Linked or Bound Resource&quot;,
</span><span class="cx">     INSUFFICIENT_STORAGE_SPACE: &quot;Insufficient Storage Space&quot;,
</span><span class="cx">     NOT_EXTENDED: &quot;Not Extended&quot;
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> # No __all__ necessary -- everything is exported
</span></span></pre></div>
<a id="CalendarServertrunktxweb2serverpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/server.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/server.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/server.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -29,7 +29,9 @@
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> from __future__ import print_function
</span><span class="cx"> 
</span><del>-import cgi, time, urlparse
</del><ins>+import cgi
+import time
+import urlparse
</ins><span class="cx"> from urllib import quote, unquote
</span><span class="cx"> from urlparse import urlsplit
</span><span class="cx"> import weakref
</span><span class="lines">@@ -67,12 +69,14 @@
</span><span class="cx">         http.checkPreconditions(request, response)
</span><span class="cx">     return response
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def doTrace(request):
</span><span class="cx">     request = iweb.IRequest(request)
</span><span class="cx">     txt = &quot;%s %s HTTP/%d.%d\r\n&quot; % (request.method, request.uri,
</span><span class="cx">                                     request.clientproto[0], request.clientproto[1])
</span><span class="cx"> 
</span><del>-    l=[]
</del><ins>+    l = []
</ins><span class="cx">     for name, valuelist in request.headers.getAllRawHeaders():
</span><span class="cx">         for value in valuelist:
</span><span class="cx">             l.append(&quot;%s: %s\r\n&quot; % (name, value))
</span><span class="lines">@@ -84,8 +88,9 @@
</span><span class="cx">         txt)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-def parsePOSTData(request, maxMem=100*1024, maxFields=1024,
-                  maxSize=10*1024*1024):
</del><ins>+
+def parsePOSTData(request, maxMem=100 * 1024, maxFields=1024,
+                  maxSize=10 * 1024 * 1024):
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Parse data of a POST request.
</span><span class="cx"> 
</span><span class="lines">@@ -110,22 +115,27 @@
</span><span class="cx">     if ctype is None:
</span><span class="cx">         return defer.succeed(None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def updateArgs(data):
</span><span class="cx">         args = data
</span><span class="cx">         request.args.update(args)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def updateArgsAndFiles(data):
</span><span class="cx">         args, files = data
</span><span class="cx">         request.args.update(args)
</span><span class="cx">         request.files.update(files)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def error(f):
</span><span class="cx">         f.trap(fileupload.MimeFormatError)
</span><span class="cx">         raise http.HTTPError(
</span><span class="cx">             http.StatusResponse(responsecode.BAD_REQUEST, str(f.value)))
</span><span class="cx"> 
</span><del>-    if (ctype.mediaType == 'application'
-        and ctype.mediaSubtype == 'x-www-form-urlencoded'):
</del><ins>+    if (
+        ctype.mediaType == 'application'
+        and ctype.mediaSubtype == 'x-www-form-urlencoded'
+    ):
</ins><span class="cx">         d = fileupload.parse_urlencoded(request.stream)
</span><span class="cx">         d.addCallbacks(updateArgs, error)
</span><span class="cx">         return d
</span><span class="lines">@@ -134,9 +144,9 @@
</span><span class="cx">         boundary = ctype.params.get('boundary')
</span><span class="cx">         if boundary is None:
</span><span class="cx">             return defer.fail(http.HTTPError(
</span><del>-                    http.StatusResponse(
-                        responsecode.BAD_REQUEST,
-                        &quot;Boundary not specified in Content-Type.&quot;)))
</del><ins>+                http.StatusResponse(
+                    responsecode.BAD_REQUEST,
+                    &quot;Boundary not specified in Content-Type.&quot;)))
</ins><span class="cx">         d = fileupload.parseMultipartFormData(request.stream, boundary,
</span><span class="cx">                                               maxMem, maxFields, maxSize)
</span><span class="cx">         d.addCallbacks(updateArgsAndFiles, error)
</span><span class="lines">@@ -149,6 +159,7 @@
</span><span class="cx">                     ctype.mediaType, ctype.mediaSubtype))))
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class StopTraversal(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Indicates to Request._handleSegment that it should stop handling
</span><span class="lines">@@ -157,6 +168,7 @@
</span><span class="cx">     pass
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class Request(http.Request):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     vars:
</span><span class="lines">@@ -195,10 +207,10 @@
</span><span class="cx"> 
</span><span class="cx">         self.timeStamps = [(&quot;t&quot;, time.time(),)]
</span><span class="cx"> 
</span><del>-        if kw.has_key('site'):
</del><ins>+        if 'site' in kw:
</ins><span class="cx">             self.site = kw['site']
</span><span class="cx">             del kw['site']
</span><del>-        if kw.has_key('prepathuri'):
</del><ins>+        if 'prepathuri' in kw:
</ins><span class="cx">             self._initialprepath = kw['prepathuri']
</span><span class="cx">             del kw['prepathuri']
</span><span class="cx"> 
</span><span class="lines">@@ -215,9 +227,11 @@
</span><span class="cx">         except AttributeError:
</span><span class="cx">             self.serverInstance = &quot;Unknown&quot;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def timeStamp(self, tag):
</span><span class="cx">         self.timeStamps.append((tag, time.time(),))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def addResponseFilter(self, filter, atEnd=False, onlyOnce=False):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Add a response filter to this request.
</span><span class="lines">@@ -236,6 +250,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.responseFilters.insert(0, filter)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def unparseURL(self, scheme=None, host=None, port=None,
</span><span class="cx">                    path=None, params=None, querystring=None, fragment=None):
</span><span class="cx">         &quot;&quot;&quot;Turn the request path into a url string. For any pieces of
</span><span class="lines">@@ -243,13 +258,20 @@
</span><span class="cx">         request. The arguments have the same meaning as the same named
</span><span class="cx">         attributes of Request.&quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        if scheme is None: scheme = self.scheme
-        if host is None: host = self.host
-        if port is None: port = self.port
-        if path is None: path = self.path
-        if params is None: params = self.params
-        if querystring is None: querystring = self.querystring
-        if fragment is None: fragment = ''
</del><ins>+        if scheme is None:
+            scheme = self.scheme
+        if host is None:
+            host = self.host
+        if port is None:
+            port = self.port
+        if path is None:
+            path = self.path
+        if params is None:
+            params = self.params
+        if querystring is None:
+            querystring = self.querystring
+        if fragment is None:
+            fragment = ''
</ins><span class="cx"> 
</span><span class="cx">         if port == http.defaultPortForScheme.get(scheme, 0):
</span><span class="cx">             hostport = host
</span><span class="lines">@@ -260,6 +282,7 @@
</span><span class="cx">             scheme, hostport, path,
</span><span class="cx">             params, querystring, fragment))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _parseURL(self):
</span><span class="cx">         if self.uri[0] == '/':
</span><span class="cx">             # Can't use urlparse for request_uri because urlparse
</span><span class="lines">@@ -275,7 +298,7 @@
</span><span class="cx">         else:
</span><span class="cx">             # It is an absolute uri, use standard urlparse
</span><span class="cx">             (self.scheme, self.host, self.path,
</span><del>-             self.params, self.querystring, fragment) = urlparse.urlparse(self.uri)
</del><ins>+             self.params, self.querystring, _ignore_fragment) = urlparse.urlparse(self.uri)
</ins><span class="cx"> 
</span><span class="cx">         if self.querystring:
</span><span class="cx">             self.args = cgi.parse_qs(self.querystring, True)
</span><span class="lines">@@ -298,8 +321,9 @@
</span><span class="cx">         else:
</span><span class="cx">             self.prepath = []
</span><span class="cx">             self.postpath = path
</span><del>-        #print(&quot;_parseURL&quot;, self.uri, (self.uri, self.scheme, self.host, self.path, self.params, self.querystring))
</del><ins>+        # print(&quot;_parseURL&quot;, self.uri, (self.uri, self.scheme, self.host, self.path, self.params, self.querystring))
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _schemeFromPort(self, port):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Try to determine the scheme matching the supplied server port. This is needed in case
</span><span class="lines">@@ -316,7 +340,7 @@
</span><span class="cx">         @rtype: C{bool}
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        #from twistedcaldav.config import config
</del><ins>+        # from twistedcaldav.config import config
</ins><span class="cx">         if hasattr(self.site, &quot;EnableSSL&quot;) and self.site.EnableSSL:
</span><span class="cx">             if port == self.site.SSLPort:
</span><span class="cx">                 return True
</span><span class="lines">@@ -325,6 +349,7 @@
</span><span class="cx"> 
</span><span class="cx">         return False
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _fixupURLParts(self):
</span><span class="cx">         hostaddr, secure = self.chanRequest.getHostInfo()
</span><span class="cx">         if not self.scheme:
</span><span class="lines">@@ -343,7 +368,7 @@
</span><span class="cx">                 # When no hostname specified anywhere, either raise an
</span><span class="cx">                 # error, or use the interface hostname, depending on
</span><span class="cx">                 # protocol version
</span><del>-                if self.clientproto &gt;= (1,1):
</del><ins>+                if self.clientproto &gt;= (1, 1):
</ins><span class="cx">                     raise http.HTTPError(responsecode.BAD_REQUEST)
</span><span class="cx">                 self.host = hostaddr.host
</span><span class="cx">                 self.port = hostaddr.port
</span><span class="lines">@@ -380,10 +405,12 @@
</span><span class="cx">         d.callback(None)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _processTimeStamp(self, res):
</span><span class="cx">         self.timeStamp(&quot;t-req-proc&quot;)
</span><span class="cx">         return res
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def preprocessRequest(self):
</span><span class="cx">         &quot;&quot;&quot;Do any request processing that doesn't follow the normal
</span><span class="cx">         resource lookup procedure. &quot;OPTIONS *&quot; is handled here, for
</span><span class="lines">@@ -399,7 +426,7 @@
</span><span class="cx">             # Allow other methods to tunnel through using POST and a request header.
</span><span class="cx">             # See http://code.google.com/apis/gdata/docs/2.0/basics.html
</span><span class="cx">             if self.headers.hasHeader(&quot;X-HTTP-Method-Override&quot;):
</span><del>-                intendedMethod = self.headers.getRawHeaders(&quot;X-HTTP-Method-Override&quot;)[0];
</del><ins>+                intendedMethod = self.headers.getRawHeaders(&quot;X-HTTP-Method-Override&quot;)[0]
</ins><span class="cx">                 if intendedMethod:
</span><span class="cx">                     self.originalMethod = self.method
</span><span class="cx">                     self.method = intendedMethod
</span><span class="lines">@@ -407,6 +434,7 @@
</span><span class="cx">         # This is where CONNECT would go if we wanted it
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _getChild(self, _, res, path, updatepaths=True):
</span><span class="cx">         &quot;&quot;&quot;Call res.locateChild, and pass the result on to _handleSegment.&quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -421,6 +449,7 @@
</span><span class="cx">         else:
</span><span class="cx">             return self._handleSegment(result, res, path, updatepaths)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _handleSegment(self, result, res, path, updatepaths):
</span><span class="cx">         &quot;&quot;&quot;Handle the result of a locateChild call done in _getChild.&quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -435,7 +464,7 @@
</span><span class="cx">             return newres.addCallback(
</span><span class="cx">                 lambda actualRes: self._handleSegment(
</span><span class="cx">                     (actualRes, newpath), res, path, updatepaths)
</span><del>-                )
</del><ins>+            )
</ins><span class="cx"> 
</span><span class="cx">         if path:
</span><span class="cx">             url = quote(&quot;/&quot; + &quot;/&quot;.join(path))
</span><span class="lines">@@ -444,19 +473,19 @@
</span><span class="cx"> 
</span><span class="cx">         if newpath is StopTraversal:
</span><span class="cx">             # We need to rethink how to do this.
</span><del>-            #if newres is res:
</del><ins>+            # if newres is res:
</ins><span class="cx">                 return res
</span><del>-            #else:
</del><ins>+            # else:
</ins><span class="cx">             #    raise ValueError(&quot;locateChild must not return StopTraversal with a resource other than self.&quot;)
</span><span class="cx"> 
</span><span class="cx">         newres = iweb.IResource(newres)
</span><span class="cx">         if newres is res:
</span><del>-            assert not newpath is path, &quot;URL traversal cycle detected when attempting to locateChild %r from resource %r.&quot; % (path, res)
</del><ins>+            assert newpath is not path, &quot;URL traversal cycle detected when attempting to locateChild %r from resource %r.&quot; % (path, res)
</ins><span class="cx">             assert len(newpath) &lt; len(path), &quot;Infinite loop impending...&quot;
</span><span class="cx"> 
</span><span class="cx">         if updatepaths:
</span><span class="cx">             # We found a Resource... update the request.prepath and postpath
</span><del>-            for x in xrange(len(path) - len(newpath)):
</del><ins>+            for _ in xrange(len(path) - len(newpath)):
</ins><span class="cx">                 self.prepath.append(self.postpath.pop(0))
</span><span class="cx">             url = quote(&quot;/&quot; + &quot;/&quot;.join(self.prepath) + (&quot;/&quot; if self.prepath and self.prepath[-1] else &quot;&quot;))
</span><span class="cx">             self._rememberResource(newres, url)
</span><span class="lines">@@ -474,6 +503,7 @@
</span><span class="cx"> 
</span><span class="cx">     _urlsByResource = weakref.WeakKeyDictionary()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _rememberResource(self, resource, url):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Remember the URL of a visited resource.
</span><span class="lines">@@ -482,6 +512,7 @@
</span><span class="cx">         self._urlsByResource[resource] = url
</span><span class="cx">         return resource
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _forgetResource(self, resource, url):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Remember the URL of a visited resource.
</span><span class="lines">@@ -489,6 +520,7 @@
</span><span class="cx">         del self._resourcesByURL[url]
</span><span class="cx">         del self._urlsByResource[resource]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def urlForResource(self, resource):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Looks up the URL of the given resource if this resource was found while
</span><span class="lines">@@ -512,6 +544,7 @@
</span><span class="cx">             raise NoURLForResourceError(resource)
</span><span class="cx">         return url
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateResource(self, url):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Looks up the resource with the given URL.
</span><span class="lines">@@ -531,7 +564,7 @@
</span><span class="cx">         #
</span><span class="cx">         # Parse the URL
</span><span class="cx">         #
</span><del>-        (scheme, host, path, query, fragment) = urlsplit(url)
</del><ins>+        (_ignore_scheme, _ignore_host, path, query, fragment) = urlsplit(url)
</ins><span class="cx"> 
</span><span class="cx">         if query or fragment:
</span><span class="cx">             raise http.HTTPError(http.StatusResponse(
</span><span class="lines">@@ -574,6 +607,7 @@
</span><span class="cx">         d.addErrback(notFound)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateChildResource(self, parent, childName):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Looks up the child resource with the given name given the parent
</span><span class="lines">@@ -612,6 +646,7 @@
</span><span class="cx">         d.addErrback(notFound)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _processingFailed(self, reason):
</span><span class="cx">         if reason.check(http.HTTPError) is not None:
</span><span class="cx">             # If the exception was an HTTPError, leave it alone
</span><span class="lines">@@ -647,7 +682,7 @@
</span><span class="cx">             )
</span><span class="cx">             response = http.Response(
</span><span class="cx">                 responsecode.INTERNAL_SERVER_ERROR,
</span><del>-                {'content-type': http_headers.MimeType('text','html')},
</del><ins>+                {'content-type': http_headers.MimeType('text', 'html')},
</ins><span class="cx">                 body
</span><span class="cx">             )
</span><span class="cx">             self.writeResponse(response)
</span><span class="lines">@@ -664,8 +699,10 @@
</span><span class="cx"> 
</span><span class="cx">     def _cbFinishRender(self, result):
</span><span class="cx">         def filterit(response, f):
</span><del>-            if (hasattr(f, 'handleErrors') or
-                (response.code &gt;= 200 and response.code &lt; 300)):
</del><ins>+            if (
+                hasattr(f, 'handleErrors') or
+                (response.code &gt;= 200 and response.code &lt; 300)
+            ):
</ins><span class="cx">                 return f(self, response)
</span><span class="cx">             else:
</span><span class="cx">                 return response
</span><span class="lines">@@ -688,6 +725,7 @@
</span><span class="cx"> 
</span><span class="cx">         raise TypeError(&quot;html is not a resource or a response&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def renderHTTP_exception(self, req, reason):
</span><span class="cx">         log.failure(&quot;Exception rendering request: {request}&quot;, reason, request=req)
</span><span class="cx"> 
</span><span class="lines">@@ -696,19 +734,23 @@
</span><span class="cx"> 
</span><span class="cx">         return http.Response(
</span><span class="cx">             responsecode.INTERNAL_SERVER_ERROR,
</span><del>-            {'content-type': http_headers.MimeType('text','html')},
</del><ins>+            {'content-type': http_headers.MimeType('text', 'html')},
</ins><span class="cx">             body)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class Site(object):
</span><span class="cx">     def __init__(self, resource):
</span><span class="cx">         &quot;&quot;&quot;Initialize.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.resource = iweb.IResource(resource)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __call__(self, *args, **kwargs):
</span><span class="cx">         return Request(site=self, *args, **kwargs)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class NoURLForResourceError(RuntimeError):
</span><span class="cx">     def __init__(self, resource):
</span><span class="cx">         RuntimeError.__init__(self, &quot;Resource %r has no URL in this request.&quot; % (resource,))
</span></span></pre></div>
<a id="CalendarServertrunktxweb2staticpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/static.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/static.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/static.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -29,8 +29,9 @@
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> # System Imports
</span><del>-import os, time
</del><ins>+import os
</ins><span class="cx"> import tempfile
</span><ins>+import time
</ins><span class="cx"> 
</span><span class="cx"> # Sibling Imports
</span><span class="cx"> from txweb2 import http_headers, resource
</span><span class="lines">@@ -53,48 +54,57 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return succeed(None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lastModified(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The last modified time of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def creationDate(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The creation date of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentLength(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The size in bytes of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentType(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The MIME type of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentEncoding(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The encoding of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def displayName(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: The display name of the resource if available, None otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def exists(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: True if the resource exists on the server, False otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return True
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class StaticRenderMixin(resource.RenderMixin, MetaDataMixin):
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -105,9 +115,9 @@
</span><span class="cx">             etag = (yield self.etag())
</span><span class="cx">             http.checkPreconditions(
</span><span class="cx">                 request,
</span><del>-                entityExists = self.exists(),
-                etag = etag,
-                lastModified = self.lastModified(),
</del><ins>+                entityExists=self.exists(),
+                etag=etag,
+                lastModified=self.lastModified(),
</ins><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx">         # Check per-method preconditions
</span><span class="lines">@@ -155,23 +165,30 @@
</span><span class="cx">         self.type = http_headers.MimeType.fromString(type)
</span><span class="cx">         self.created_time = time.time()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def etag(self):
</span><span class="cx">         lastModified = self.lastModified()
</span><del>-        return succeed(http_headers.ETag(&quot;%X-%X&quot; % (lastModified, hash(self.data)),
-                                            weak=(time.time() - lastModified &lt;= 1)))
</del><ins>+        return succeed(http_headers.ETag(
+            &quot;%X-%X&quot; % (lastModified, hash(self.data)),
+            weak=(time.time() - lastModified &lt;= 1)))
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lastModified(self):
</span><span class="cx">         return self.creationDate()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def creationDate(self):
</span><span class="cx">         return self.created_time
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentLength(self):
</span><span class="cx">         return len(self.data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentType(self):
</span><span class="cx">         return self.type
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, req):
</span><span class="cx">         return http.Response(
</span><span class="cx">             responsecode.OK,
</span><span class="lines">@@ -179,6 +196,7 @@
</span><span class="cx">             stream=self.data)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class File(StaticRenderMixin):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     File is a resource that represents a plain non-interpreted file
</span><span class="lines">@@ -207,7 +225,7 @@
</span><span class="cx">     contentEncodings = {
</span><span class="cx">         &quot;.gz&quot; : &quot;gzip&quot;,
</span><span class="cx">         &quot;.bz2&quot;: &quot;bzip2&quot;
</span><del>-        }
</del><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     processors = {}
</span><span class="cx"> 
</span><span class="lines">@@ -233,23 +251,27 @@
</span><span class="cx">             self.processors = dict([
</span><span class="cx">                 (key.lower(), value)
</span><span class="cx">                 for key, value in processors.items()
</span><del>-                ])
</del><ins>+            ])
</ins><span class="cx"> 
</span><span class="cx">         if indexNames is not None:
</span><span class="cx">             self.indexNames = indexNames
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def comparePath(self, path):
</span><del>-        
</del><ins>+
</ins><span class="cx">         if isinstance(path, FilePath):
</span><span class="cx">             return path.path == self.fp.path
</span><span class="cx">         else:
</span><span class="cx">             return path == self.fp.path
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def exists(self):
</span><span class="cx">         return self.fp.exists()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def etag(self):
</span><del>-        if not self.fp.exists(): return succeed(None)
</del><ins>+        if not self.fp.exists():
+            return succeed(None)
</ins><span class="cx"> 
</span><span class="cx">         st = self.fp.statinfo
</span><span class="cx"> 
</span><span class="lines">@@ -265,18 +287,21 @@
</span><span class="cx">             weak=weak
</span><span class="cx">         ))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def lastModified(self):
</span><span class="cx">         if self.fp.exists():
</span><span class="cx">             return self.fp.getmtime()
</span><span class="cx">         else:
</span><span class="cx">             return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def creationDate(self):
</span><span class="cx">         if self.fp.exists():
</span><span class="cx">             return self.fp.getmtime()
</span><span class="cx">         else:
</span><span class="cx">             return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentLength(self):
</span><span class="cx">         if self.fp.exists():
</span><span class="cx">             if self.fp.isfile():
</span><span class="lines">@@ -288,6 +313,7 @@
</span><span class="cx">         else:
</span><span class="cx">             return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _initTypeAndEncoding(self):
</span><span class="cx">         self._type, self._encoding = getTypeAndEncoding(
</span><span class="cx">             self.fp.basename(),
</span><span class="lines">@@ -297,24 +323,29 @@
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         # Handle cases not covered by getTypeAndEncoding()
</span><del>-        if self.fp.isdir(): self._type = &quot;httpd/unix-directory&quot;
</del><ins>+        if self.fp.isdir():
+            self._type = &quot;httpd/unix-directory&quot;
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentType(self):
</span><span class="cx">         if not hasattr(self, &quot;_type&quot;):
</span><span class="cx">             self._initTypeAndEncoding()
</span><span class="cx">         return http_headers.MimeType.fromString(self._type)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def contentEncoding(self):
</span><span class="cx">         if not hasattr(self, &quot;_encoding&quot;):
</span><span class="cx">             self._initTypeAndEncoding()
</span><span class="cx">         return self._encoding
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def displayName(self):
</span><span class="cx">         if self.fp.exists():
</span><span class="cx">             return self.fp.basename()
</span><span class="cx">         else:
</span><span class="cx">             return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def ignoreExt(self, ext):
</span><span class="cx">         &quot;&quot;&quot;Ignore the given extension.
</span><span class="cx"> 
</span><span class="lines">@@ -331,6 +362,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.putChildren[name] = child
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getChild(self, name):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Look up a child resource.
</span><span class="lines">@@ -340,7 +372,8 @@
</span><span class="cx">             return self
</span><span class="cx"> 
</span><span class="cx">         child = self.putChildren.get(name, None)
</span><del>-        if child: return child
</del><ins>+        if child:
+            return child
</ins><span class="cx"> 
</span><span class="cx">         child_fp = self.fp.child(name)
</span><span class="cx">         if hasattr(self, &quot;knownChildren&quot;):
</span><span class="lines">@@ -351,6 +384,7 @@
</span><span class="cx">         else:
</span><span class="cx">             return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def listChildren(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: a sequence of the names of all known children of this resource.
</span><span class="lines">@@ -361,19 +395,22 @@
</span><span class="cx">             self.knownChildren = set(children)
</span><span class="cx">         return children
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateChild(self, req, segments):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         See L{IResource}C{.locateChild}.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         # If getChild() finds a child resource, return it
</span><span class="cx">         child = self.getChild(segments[0])
</span><del>-        if child is not None: return (child, segments[1:])
</del><ins>+        if child is not None:
+            return (child, segments[1:])
</ins><span class="cx"> 
</span><span class="cx">         # If we're not backed by a directory, we have no children.
</span><span class="cx">         # But check for existance first; we might be a collection resource
</span><span class="cx">         # that the request wants created.
</span><span class="cx">         self.fp.restat(False)
</span><del>-        if self.fp.exists() and not self.fp.isdir(): return (None, ())
</del><ins>+        if self.fp.exists() and not self.fp.isdir():
+            return (None, ())
</ins><span class="cx"> 
</span><span class="cx">         # OK, we need to return a child corresponding to the first segment
</span><span class="cx">         path = segments[0]
</span><span class="lines">@@ -400,10 +437,12 @@
</span><span class="cx"> 
</span><span class="cx">         return self.createSimilarFile(fpath.path), segments[1:]
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def renderHTTP(self, req):
</span><span class="cx">         self.fp.changed()
</span><span class="cx">         return super(File, self).renderHTTP(req)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, req):
</span><span class="cx">         &quot;&quot;&quot;You know what you doing.&quot;&quot;&quot;
</span><span class="cx">         if not self.fp.exists():
</span><span class="lines">@@ -412,7 +451,7 @@
</span><span class="cx">         if self.fp.isdir():
</span><span class="cx">             if req.path[-1] != &quot;/&quot;:
</span><span class="cx">                 # Redirect to include trailing '/' in URI
</span><del>-                return http.RedirectResponse(req.unparseURL(path=req.path+'/'))
</del><ins>+                return http.RedirectResponse(req.unparseURL(path=req.path + '/'))
</ins><span class="cx">             else:
</span><span class="cx">                 ifp = self.fp.childSearchPreauth(*self.indexNames)
</span><span class="cx">                 if ifp:
</span><span class="lines">@@ -450,11 +489,13 @@
</span><span class="cx"> 
</span><span class="cx">         return response
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def createSimilarFile(self, path):
</span><span class="cx">         return self.__class__(path, self.defaultType, self.ignoredExts,
</span><span class="cx">                               self.processors, self.indexNames[:])
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class FileSaver(resource.PostableResource):
</span><span class="cx">     allowedTypes = (http_headers.MimeType('text', 'plain'),
</span><span class="cx">                     http_headers.MimeType('text', 'html'),
</span><span class="lines">@@ -467,6 +508,7 @@
</span><span class="cx">         self.expectedFields = expectedFields
</span><span class="cx">         self.permissions = permissions
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def makeUniqueName(self, filename):
</span><span class="cx">         &quot;&quot;&quot;Called when a unique filename is needed.
</span><span class="cx"> 
</span><span class="lines">@@ -478,6 +520,7 @@
</span><span class="cx"> 
</span><span class="cx">         return tempfile.mktemp(suffix=os.path.splitext(filename)[1], dir=self.destination)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def isSafeToWrite(self, filename, mimetype, filestream):
</span><span class="cx">         &quot;&quot;&quot;Returns True if it's &quot;safe&quot; to write this file,
</span><span class="cx">         otherwise it raises an exception.
</span><span class="lines">@@ -493,6 +536,7 @@
</span><span class="cx"> 
</span><span class="cx">         return True
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeFile(self, filename, mimetype, fileobject):
</span><span class="cx">         &quot;&quot;&quot;Does the I/O dirty work after it calls isSafeToWrite to make
</span><span class="cx">         sure it's safe to write this file.
</span><span class="lines">@@ -505,11 +549,12 @@
</span><span class="cx">             flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, &quot;O_BINARY&quot;, 0)
</span><span class="cx"> 
</span><span class="cx">             fileobject = os.fdopen(os.open(outname, flags, self.permissions), 'wb', 0)
</span><del>-                
</del><ins>+
</ins><span class="cx">             stream.readIntoFile(filestream, fileobject)
</span><span class="cx"> 
</span><span class="cx">         return outname
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, req):
</span><span class="cx">         content = [&quot;&lt;html&gt;&lt;body&gt;&quot;]
</span><span class="cx"> 
</span><span class="lines">@@ -560,12 +605,16 @@
</span><span class="cx"> def isDangerous(path):
</span><span class="cx">     return path == '..' or '/' in path or os.sep in path
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def addSlash(request):
</span><span class="cx">     return &quot;http%s://%s%s/&quot; % (
</span><span class="cx">         request.isSecure() and 's' or '',
</span><span class="cx">         request.getHeader(&quot;host&quot;),
</span><span class="cx">         (request.uri.split('?')[0]))
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def loadMimeTypes(mimetype_locations=['/etc/mime.types']):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Multiple file locations containing mime-types can be passed as a list.
</span><span class="lines">@@ -580,18 +629,18 @@
</span><span class="cx">     # usual suspects.
</span><span class="cx">     contentTypes.update(
</span><span class="cx">         {
</span><del>-            '.conf':  'text/plain',
-            '.diff':  'text/plain',
-            '.exe':   'application/x-executable',
-            '.flac':  'audio/x-flac',
-            '.java':  'text/plain',
-            '.ogg':   'application/ogg',
-            '.oz':    'text/x-oz',
-            '.swf':   'application/x-shockwave-flash',
-            '.tgz':   'application/x-gtar',
-            '.wml':   'text/vnd.wap.wml',
-            '.xul':   'application/vnd.mozilla.xul+xml',
-            '.py':    'text/plain',
</del><ins>+            '.conf': 'text/plain',
+            '.diff': 'text/plain',
+            '.exe': 'application/x-executable',
+            '.flac': 'audio/x-flac',
+            '.java': 'text/plain',
+            '.ogg': 'application/ogg',
+            '.oz': 'text/x-oz',
+            '.swf': 'application/x-shockwave-flash',
+            '.tgz': 'application/x-gtar',
+            '.wml': 'text/vnd.wap.wml',
+            '.xul': 'application/vnd.mozilla.xul+xml',
+            '.py': 'text/plain',
</ins><span class="cx">             '.patch': 'text/plain',
</span><span class="cx">         }
</span><span class="cx">     )
</span><span class="lines">@@ -603,10 +652,12 @@
</span><span class="cx"> 
</span><span class="cx">     return contentTypes
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def getTypeAndEncoding(filename, types, encodings, defaultType):
</span><span class="cx">     p, ext = os.path.splitext(filename)
</span><span class="cx">     ext = ext.lower()
</span><del>-    if encodings.has_key(ext):
</del><ins>+    if ext in encodings:
</ins><span class="cx">         enc = encodings[ext]
</span><span class="cx">         ext = os.path.splitext(p)[1].lower()
</span><span class="cx">     else:
</span></span></pre></div>
<a id="CalendarServertrunktxweb2streampy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/stream.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/stream.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/stream.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -36,12 +36,12 @@
</span><span class="cx"> underlying resources and causes read to return None forevermore.
</span><span class="cx"> 
</span><span class="cx"> IByteStream adds a bit more to the API:
</span><del>-1) read is required to return objects conforming to the buffer interface.  
</del><ins>+1) read is required to return objects conforming to the buffer interface.
</ins><span class="cx"> 2) .length, which may either an integer number of bytes remaining, or
</span><span class="cx"> None if unknown
</span><span class="cx"> 3) .split(position). Split takes a position, and splits the
</span><span class="cx"> stream in two pieces, returning the two new streams. Using the
</span><del>-original stream after calling split is not allowed. 
</del><ins>+original stream after calling split is not allowed.
</ins><span class="cx"> 
</span><span class="cx"> There are two builtin source stream classes: FileStream and
</span><span class="cx"> MemoryStream. The first produces data from a file object, the second
</span><span class="lines">@@ -55,7 +55,10 @@
</span><span class="cx"> 
</span><span class="cx"> from __future__ import generators
</span><span class="cx"> 
</span><del>-import copy, os, types, sys
</del><ins>+import copy
+import os
+import types
+import sys
</ins><span class="cx"> from zope.interface import Interface, Attribute, implements
</span><span class="cx"> from twisted.internet.defer import Deferred
</span><span class="cx"> from twisted.internet import interfaces as ti_interfaces, defer, reactor, protocol, error as ti_error
</span><span class="lines">@@ -70,21 +73,23 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> # Python 2.4.2 (only) has a broken mmap that leaks a fd every time you call it.
</span><del>-if sys.version_info[0:3] != (2,4,2):
</del><ins>+if sys.version_info[0:3] != (2, 4, 2):
</ins><span class="cx">     try:
</span><span class="cx">         import mmap
</span><span class="cx">     except ImportError:
</span><span class="cx">         mmap = None
</span><span class="cx"> else:
</span><span class="cx">     mmap = None
</span><del>-    
-##############################
-####      Interfaces      ####
-##############################
</del><span class="cx"> 
</span><ins>+
+
+#
+# Interfaces
+#
+
</ins><span class="cx"> class IStream(Interface):
</span><span class="cx">     &quot;&quot;&quot;A stream of arbitrary data.&quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def read():
</span><span class="cx">         &quot;&quot;&quot;Read some data.
</span><span class="cx"> 
</span><span class="lines">@@ -94,19 +99,21 @@
</span><span class="cx"> 
</span><span class="cx">         Errors may be indicated by exception or by a Deferred of a Failure.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def close():
</span><span class="cx">         &quot;&quot;&quot;Prematurely close. Should also cause further reads to
</span><span class="cx">         return None.&quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class IByteStream(IStream):
</span><span class="cx">     &quot;&quot;&quot;A stream which is of bytes.&quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     length = Attribute(&quot;&quot;&quot;How much data is in this stream. Can be None if unknown.&quot;&quot;&quot;)
</span><del>-    
</del><ins>+
</ins><span class="cx">     def read():
</span><span class="cx">         &quot;&quot;&quot;Read some data.
</span><del>-        
</del><ins>+
</ins><span class="cx">         Returns an object conforming to the buffer interface, or
</span><span class="cx">         if there is no more data available, returns None.
</span><span class="cx">         Can also return a Deferred resulting in one of the above.
</span><span class="lines">@@ -130,6 +137,8 @@
</span><span class="cx">         return None. Additionally, .length should be set to 0.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class ISendfileableStream(Interface):
</span><span class="cx">     def read(sendfile=False):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -139,21 +148,25 @@
</span><span class="cx"> 
</span><span class="cx">         If sendfile == True, returns either the above, or a SendfileBuffer.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
+
+
</ins><span class="cx"> class SimpleStream(object):
</span><span class="cx">     &quot;&quot;&quot;Superclass of simple streams with a single buffer and a offset and length
</span><span class="cx">     into that buffer.&quot;&quot;&quot;
</span><span class="cx">     implements(IByteStream)
</span><del>-    
</del><ins>+
</ins><span class="cx">     length = None
</span><span class="cx">     start = None
</span><del>-    
</del><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.length = 0
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def split(self, point):
</span><span class="cx">         if self.length is not None:
</span><span class="cx">             if point &gt; self.length:
</span><span class="lines">@@ -165,14 +178,14 @@
</span><span class="cx">         b.start += point
</span><span class="cx">         return (self, b)
</span><span class="cx"> 
</span><del>-##############################
-####      FileStream      ####
-##############################
-    
</del><ins>+#
+# FileStream
+#
+
</ins><span class="cx"> # maximum mmap size
</span><del>-MMAP_LIMIT = 4*1024*1024
</del><ins>+MMAP_LIMIT = 4 * 1024 * 1024
</ins><span class="cx"> # minimum mmap size
</span><del>-MMAP_THRESHOLD = 8*1024
</del><ins>+MMAP_THRESHOLD = 8 * 1024
</ins><span class="cx"> 
</span><span class="cx"> # maximum sendfile length
</span><span class="cx"> SENDFILE_LIMIT = 16777216
</span><span class="lines">@@ -184,7 +197,7 @@
</span><span class="cx">     Python's mmap call sucks and ommitted the &quot;offset&quot; argument for no
</span><span class="cx">     discernable reason. Replace this with a mmap module that has offset.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     offset = kwargs.get('offset', None)
</span><span class="cx">     if offset in [None, 0]:
</span><span class="cx">         if 'offset' in kwargs:
</span><span class="lines">@@ -193,6 +206,8 @@
</span><span class="cx">         raise mmap.error(&quot;mmap: Python sucks and does not support offset.&quot;)
</span><span class="cx">     return mmap.mmap(*args, **kwargs)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class FileStream(SimpleStream):
</span><span class="cx">     implements(ISendfileableStream)
</span><span class="cx">     &quot;&quot;&quot;A stream that reads data from a file. File must be a normal
</span><span class="lines">@@ -213,7 +228,8 @@
</span><span class="cx">         else:
</span><span class="cx">             self.length = length
</span><span class="cx">         self.useMMap = useMMap
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def read(self, sendfile=False):
</span><span class="cx">         if self.f is None:
</span><span class="cx">             return None
</span><span class="lines">@@ -223,7 +239,7 @@
</span><span class="cx">             self.f = None
</span><span class="cx">             return None
</span><span class="cx"> 
</span><del>-        #if sendfile and length &gt; SENDFILE_THRESHOLD:
</del><ins>+        # if sendfile and length &gt; SENDFILE_THRESHOLD:
</ins><span class="cx">         #    # XXX: Yay using non-existent sendfile support!
</span><span class="cx">         #    # FIXME: if we return a SendfileBuffer, and then sendfile
</span><span class="cx">         #    #        fails, then what? Or, what if file is too short?
</span><span class="lines">@@ -238,7 +254,7 @@
</span><span class="cx">             try:
</span><span class="cx">                 res = mmapwrapper(self.f.fileno(), readSize,
</span><span class="cx">                                   access=mmap.ACCESS_READ, offset=self.start)
</span><del>-                #madvise(res, MADV_SEQUENTIAL)
</del><ins>+                # madvise(res, MADV_SEQUENTIAL)
</ins><span class="cx">                 self.length -= readSize
</span><span class="cx">                 self.start += readSize
</span><span class="cx">                 return res
</span><span class="lines">@@ -258,15 +274,16 @@
</span><span class="cx">             self.start += bytesRead
</span><span class="cx">             return b
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.f = None
</span><span class="cx">         SimpleStream.close(self)
</span><span class="cx"> 
</span><span class="cx"> components.registerAdapter(FileStream, file, IByteStream)
</span><span class="cx"> 
</span><del>-##############################
-####     MemoryStream     ####
-##############################
</del><ins>+#
+# MemoryStream
+#
</ins><span class="cx"> 
</span><span class="cx"> class MemoryStream(SimpleStream):
</span><span class="cx">     &quot;&quot;&quot;A stream that reads data from a buffer object.&quot;&quot;&quot;
</span><span class="lines">@@ -284,6 +301,7 @@
</span><span class="cx">                 raise ValueError(&quot;len(mem) &lt; start + length&quot;)
</span><span class="cx">             self.length = length
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         if self.mem is None:
</span><span class="cx">             return None
</span><span class="lines">@@ -295,6 +313,7 @@
</span><span class="cx">         self.length = 0
</span><span class="cx">         return result
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.mem = None
</span><span class="cx">         SimpleStream.close(self)
</span><span class="lines">@@ -302,23 +321,24 @@
</span><span class="cx"> components.registerAdapter(MemoryStream, str, IByteStream)
</span><span class="cx"> components.registerAdapter(MemoryStream, types.BufferType, IByteStream)
</span><span class="cx"> 
</span><del>-##############################
-####    CompoundStream    ####
-##############################
</del><ins>+#
+# CompoundStream
+#
</ins><span class="cx"> 
</span><span class="cx"> class CompoundStream(object):
</span><span class="cx">     &quot;&quot;&quot;A stream which is composed of many other streams.
</span><span class="cx"> 
</span><span class="cx">     Call addStream to add substreams.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     implements(IByteStream, ISendfileableStream)
</span><span class="cx">     deferred = None
</span><span class="cx">     length = 0
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, buckets=()):
</span><span class="cx">         self.buckets = [IByteStream(s) for s in buckets]
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def addStream(self, bucket):
</span><span class="cx">         &quot;&quot;&quot;Add a stream to the output&quot;&quot;&quot;
</span><span class="cx">         bucket = IByteStream(bucket)
</span><span class="lines">@@ -329,13 +349,14 @@
</span><span class="cx">             else:
</span><span class="cx">                 self.length += bucket.length
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self, sendfile=False):
</span><span class="cx">         if self.deferred is not None:
</span><span class="cx">             raise RuntimeError(&quot;Call to read while read is already outstanding&quot;)
</span><span class="cx"> 
</span><span class="cx">         if not self.buckets:
</span><span class="cx">             return None
</span><del>-        
</del><ins>+
</ins><span class="cx">         if sendfile and ISendfileableStream.providedBy(self.buckets[0]):
</span><span class="cx">             try:
</span><span class="cx">                 result = self.buckets[0].read(sendfile)
</span><span class="lines">@@ -346,60 +367,64 @@
</span><span class="cx">                 result = self.buckets[0].read()
</span><span class="cx">             except:
</span><span class="cx">                 return self._gotFailure(Failure())
</span><del>-        
</del><ins>+
</ins><span class="cx">         if isinstance(result, Deferred):
</span><span class="cx">             self.deferred = result
</span><span class="cx">             result.addCallbacks(self._gotRead, self._gotFailure, (sendfile,))
</span><span class="cx">             return result
</span><del>-        
</del><ins>+
</ins><span class="cx">         return self._gotRead(result, sendfile)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _gotFailure(self, f):
</span><span class="cx">         self.deferred = None
</span><span class="cx">         del self.buckets[0]
</span><span class="cx">         self.close()
</span><span class="cx">         return f
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def _gotRead(self, result, sendfile):
</span><span class="cx">         self.deferred = None
</span><span class="cx">         if result is None:
</span><span class="cx">             del self.buckets[0]
</span><span class="cx">             # Next bucket
</span><span class="cx">             return self.read(sendfile)
</span><del>-        
</del><ins>+
</ins><span class="cx">         if self.length is not None:
</span><span class="cx">             self.length -= len(result)
</span><span class="cx">         return result
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def split(self, point):
</span><span class="cx">         num = 0
</span><span class="cx">         origPoint = point
</span><span class="cx">         for bucket in self.buckets:
</span><del>-            num+=1
</del><ins>+            num += 1
</ins><span class="cx"> 
</span><span class="cx">             if point == 0:
</span><span class="cx">                 b = CompoundStream()
</span><span class="cx">                 b.buckets = self.buckets[num:]
</span><span class="cx">                 del self.buckets[num:]
</span><del>-                return self,b
-            
</del><ins>+                return self, b
+
</ins><span class="cx">             if bucket.length is None:
</span><span class="cx">                 # Indeterminate length bucket.
</span><span class="cx">                 # give up and use fallback splitter.
</span><span class="cx">                 return fallbackSplit(self, origPoint)
</span><del>-            
</del><ins>+
</ins><span class="cx">             if point &lt; bucket.length:
</span><del>-                before,after = bucket.split(point)
</del><ins>+                before, after = bucket.split(point)
</ins><span class="cx">                 b = CompoundStream()
</span><span class="cx">                 b.buckets = self.buckets[num:]
</span><span class="cx">                 b.buckets[0] = after
</span><del>-                
-                del self.buckets[num+1:]
</del><ins>+
+                del self.buckets[num + 1:]
</ins><span class="cx">                 self.buckets[num] = before
</span><del>-                return self,b
-            
</del><ins>+                return self, b
+
</ins><span class="cx">             point -= bucket.length
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         for bucket in self.buckets:
</span><span class="cx">             bucket.close()
</span><span class="lines">@@ -407,10 +432,11 @@
</span><span class="cx">         self.length = 0
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##############################
-####      readStream      ####
-##############################
</del><span class="cx"> 
</span><ins>+#
+# readStream
+#
+
</ins><span class="cx"> class _StreamReader(object):
</span><span class="cx">     &quot;&quot;&quot;Process a stream's data using callbacks for data and stream finish.&quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -419,12 +445,14 @@
</span><span class="cx">         self.gotDataCallback = gotDataCallback
</span><span class="cx">         self.result = Deferred()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def run(self):
</span><span class="cx">         # self.result may be del'd in _read()
</span><span class="cx">         result = self.result
</span><span class="cx">         self._read()
</span><span class="cx">         return result
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def _read(self):
</span><span class="cx">         try:
</span><span class="cx">             result = self.stream.read()
</span><span class="lines">@@ -436,11 +464,13 @@
</span><span class="cx">         else:
</span><span class="cx">             self._gotData(result)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _gotError(self, failure):
</span><span class="cx">         result = self.result
</span><span class="cx">         del self.result, self.gotDataCallback, self.stream
</span><span class="cx">         result.errback(failure)
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def _gotData(self, data):
</span><span class="cx">         if data is None:
</span><span class="cx">             result = self.result
</span><span class="lines">@@ -454,6 +484,8 @@
</span><span class="cx">             return
</span><span class="cx">         reactor.callLater(0, self._read)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def readStream(stream, gotDataCallback):
</span><span class="cx">     &quot;&quot;&quot;Pass a stream's data to a callback.
</span><span class="cx"> 
</span><span class="lines">@@ -464,6 +496,7 @@
</span><span class="cx">     return _StreamReader(stream, gotDataCallback).run()
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> def readAndDiscard(stream):
</span><span class="cx">     &quot;&quot;&quot;Read all the data from the given stream, and throw it out.
</span><span class="cx"> 
</span><span class="lines">@@ -471,6 +504,8 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     return readStream(stream, lambda _: None)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def readIntoFile(stream, outFile):
</span><span class="cx">     &quot;&quot;&quot;Read a stream and write it into a file.
</span><span class="cx"> 
</span><span class="lines">@@ -481,6 +516,8 @@
</span><span class="cx">         return _
</span><span class="cx">     return readStream(stream, outFile.write).addBoth(done)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def connectStream(inputStream, factory):
</span><span class="cx">     &quot;&quot;&quot;Connect a protocol constructed from a factory to stream.
</span><span class="cx"> 
</span><span class="lines">@@ -498,21 +535,26 @@
</span><span class="cx">         lambda _: p.connectionLost(ti_error.ConnectionDone()), lambda _: p.connectionLost(_))
</span><span class="cx">     return out
</span><span class="cx"> 
</span><del>-##############################
-####     fallbackSplit    ####
-##############################
</del><span class="cx"> 
</span><ins>+
+#
+# fallbackSplit
+#
+
</ins><span class="cx"> def fallbackSplit(stream, point):
</span><span class="cx">     after = PostTruncaterStream(stream, point)
</span><span class="cx">     before = TruncaterStream(stream, point, after)
</span><span class="cx">     return (before, after)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TruncaterStream(object):
</span><span class="cx">     def __init__(self, stream, point, postTruncater):
</span><span class="cx">         self.stream = stream
</span><span class="cx">         self.length = point
</span><span class="cx">         self.postTruncater = postTruncater
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def read(self):
</span><span class="cx">         if self.length == 0:
</span><span class="cx">             if self.postTruncater is not None:
</span><span class="lines">@@ -521,13 +563,14 @@
</span><span class="cx">                 postTruncater.sendInitialSegment(self.stream.read())
</span><span class="cx">             self.stream = None
</span><span class="cx">             return None
</span><del>-        
</del><ins>+
</ins><span class="cx">         result = self.stream.read()
</span><span class="cx">         if isinstance(result, Deferred):
</span><span class="cx">             return result.addCallback(self._gotRead)
</span><span class="cx">         else:
</span><span class="cx">             return self._gotRead(result)
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def _gotRead(self, data):
</span><span class="cx">         if data is None:
</span><span class="cx">             raise ValueError(&quot;Ran out of data for a split of a indeterminate length source&quot;)
</span><span class="lines">@@ -544,7 +587,8 @@
</span><span class="cx">                 postTruncater.sendInitialSegment(after)
</span><span class="cx">                 self.stream = None
</span><span class="cx">             return before
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def split(self, point):
</span><span class="cx">         if point &gt; self.length:
</span><span class="cx">             raise ValueError(&quot;split point (%d) &gt; length (%d)&quot; % (point, self.length))
</span><span class="lines">@@ -554,7 +598,8 @@
</span><span class="cx">         self.length = point
</span><span class="cx">         self.postTruncater = post
</span><span class="cx">         return self, trunc
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         if self.postTruncater is not None:
</span><span class="cx">             self.postTruncater.notifyClosed(self)
</span><span class="lines">@@ -563,14 +608,15 @@
</span><span class="cx">             self.stream.close()
</span><span class="cx">             self.stream = None
</span><span class="cx">             self.length = 0
</span><del>-            
</del><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class PostTruncaterStream(object):
</span><span class="cx">     deferred = None
</span><span class="cx">     sentInitialSegment = False
</span><span class="cx">     truncaterClosed = None
</span><span class="cx">     closed = False
</span><del>-    
</del><ins>+
</ins><span class="cx">     length = None
</span><span class="cx">     def __init__(self, stream, point):
</span><span class="cx">         self.stream = stream
</span><span class="lines">@@ -578,6 +624,7 @@
</span><span class="cx">         if stream.length is not None:
</span><span class="cx">             self.length = stream.length - point
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         if not self.sentInitialSegment:
</span><span class="cx">             self.sentInitialSegment = True
</span><span class="lines">@@ -585,12 +632,14 @@
</span><span class="cx">                 readAndDiscard(self.truncaterClosed)
</span><span class="cx">                 self.truncaterClosed = None
</span><span class="cx">             return self.deferred
</span><del>-        
</del><ins>+
</ins><span class="cx">         return self.stream.read()
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def split(self, point):
</span><span class="cx">         return fallbackSplit(self, point)
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.closed = True
</span><span class="cx">         if self.truncaterClosed is not None:
</span><span class="lines">@@ -600,9 +649,10 @@
</span><span class="cx">         elif self.sentInitialSegment:
</span><span class="cx">             # first half already finished up
</span><span class="cx">             self.stream.close()
</span><del>-            
</del><ins>+
</ins><span class="cx">         self.deferred = None
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     # Callbacks from TruncaterStream
</span><span class="cx">     def sendInitialSegment(self, data):
</span><span class="cx">         if self.closed:
</span><span class="lines">@@ -614,7 +664,8 @@
</span><span class="cx">                 data.chainDeferred(self.deferred)
</span><span class="cx">             else:
</span><span class="cx">                 self.deferred.callback(data)
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def notifyClosed(self, truncater):
</span><span class="cx">         if self.closed:
</span><span class="cx">             # we are closed, have first half really close
</span><span class="lines">@@ -627,10 +678,12 @@
</span><span class="cx">             # Idle, store closed info.
</span><span class="cx">             self.truncaterClosed = truncater
</span><span class="cx"> 
</span><del>-########################################
-#### ProducerStream/StreamProducer  ####
-########################################
-            
</del><ins>+
+
+#
+# ProducerStream/StreamProducer
+#
+
</ins><span class="cx"> class ProducerStream(object):
</span><span class="cx">     &quot;&quot;&quot;Turns producers into a IByteStream.
</span><span class="cx">     Thus, implements IConsumer and IByteStream.&quot;&quot;&quot;
</span><span class="lines">@@ -642,13 +695,14 @@
</span><span class="cx">     producer = None
</span><span class="cx">     producerPaused = False
</span><span class="cx">     deferred = None
</span><del>-    
</del><ins>+
</ins><span class="cx">     bufferSize = 5
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, length=None):
</span><span class="cx">         self.buffer = []
</span><span class="cx">         self.length = length
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     # IByteStream implementation
</span><span class="cx">     def read(self):
</span><span class="cx">         if self.buffer:
</span><span class="lines">@@ -666,26 +720,29 @@
</span><span class="cx">                                               or self.producerPaused):
</span><span class="cx">                 self.producerPaused = False
</span><span class="cx">                 self.producer.resumeProducing()
</span><del>-                
</del><ins>+
</ins><span class="cx">             return deferred
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def split(self, point):
</span><span class="cx">         return fallbackSplit(self, point)
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def close(self):
</span><span class="cx">         &quot;&quot;&quot;Called by reader of stream when it is done reading.&quot;&quot;&quot;
</span><del>-        self.buffer=[]
</del><ins>+        self.buffer = []
</ins><span class="cx">         self.closed = True
</span><span class="cx">         if self.producer is not None:
</span><span class="cx">             self.producer.stopProducing()
</span><span class="cx">             self.producer = None
</span><span class="cx">         self.deferred = None
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     # IConsumer implementation
</span><span class="cx">     def write(self, data):
</span><span class="cx">         if self.closed:
</span><span class="cx">             return
</span><del>-        
</del><ins>+
</ins><span class="cx">         if self.deferred:
</span><span class="cx">             deferred = self.deferred
</span><span class="cx">             self.deferred = None
</span><span class="lines">@@ -697,6 +754,7 @@
</span><span class="cx">                 self.producer.pauseProducing()
</span><span class="cx">                 self.producerPaused = True
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def finish(self, failure=None):
</span><span class="cx">         &quot;&quot;&quot;Called by producer when it is done.
</span><span class="cx"> 
</span><span class="lines">@@ -716,13 +774,14 @@
</span><span class="cx">                 deferred.callback(None)
</span><span class="cx">         else:
</span><span class="cx">             if failure is not None:
</span><del>-               self.failed = True
-               self.failure = failure
-    
</del><ins>+                self.failed = True
+                self.failure = failure
+
+
</ins><span class="cx">     def registerProducer(self, producer, streaming):
</span><span class="cx">         if self.producer is not None:
</span><span class="cx">             raise RuntimeError(&quot;Cannot register producer %s, because producer %s was never unregistered.&quot; % (producer, self.producer))
</span><del>-        
</del><ins>+
</ins><span class="cx">         if self.closed:
</span><span class="cx">             producer.stopProducing()
</span><span class="cx">         else:
</span><span class="lines">@@ -731,9 +790,12 @@
</span><span class="cx">             if not streaming:
</span><span class="cx">                 producer.resumeProducing()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def unregisterProducer(self):
</span><span class="cx">         self.producer = None
</span><del>-        
</del><ins>+
+
+
</ins><span class="cx"> class StreamProducer(object):
</span><span class="cx">     &quot;&quot;&quot;A push producer which gets its data by reading a stream.&quot;&quot;&quot;
</span><span class="cx">     implements(ti_interfaces.IPushProducer)
</span><span class="lines">@@ -742,21 +804,23 @@
</span><span class="cx">     finishedCallback = None
</span><span class="cx">     paused = False
</span><span class="cx">     consumer = None
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, stream, enforceStr=True):
</span><span class="cx">         self.stream = stream
</span><span class="cx">         self.enforceStr = enforceStr
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def beginProducing(self, consumer):
</span><span class="cx">         if self.stream is None:
</span><span class="cx">             return defer.succeed(None)
</span><del>-        
</del><ins>+
</ins><span class="cx">         self.consumer = consumer
</span><span class="cx">         finishedCallback = self.finishedCallback = Deferred()
</span><span class="cx">         self.consumer.registerProducer(self, True)
</span><span class="cx">         self.resumeProducing()
</span><span class="cx">         return finishedCallback
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def resumeProducing(self):
</span><span class="cx">         self.paused = False
</span><span class="cx">         if self.deferred is not None:
</span><span class="lines">@@ -767,13 +831,14 @@
</span><span class="cx">         except:
</span><span class="cx">             self.stopProducing(Failure())
</span><span class="cx">             return
</span><del>-        
</del><ins>+
</ins><span class="cx">         if isinstance(data, Deferred):
</span><span class="cx">             self.deferred = data
</span><span class="cx">             self.deferred.addCallbacks(self._doWrite, self.stopProducing)
</span><span class="cx">         else:
</span><span class="cx">             self._doWrite(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _doWrite(self, data):
</span><span class="cx">         if self.consumer is None:
</span><span class="cx">             return
</span><span class="lines">@@ -785,19 +850,21 @@
</span><span class="cx">                 self.finishedCallback.callback(None)
</span><span class="cx">             self.finishedCallback = self.deferred = self.consumer = self.stream = None
</span><span class="cx">             return
</span><del>-        
</del><ins>+
</ins><span class="cx">         self.deferred = None
</span><span class="cx">         if self.enforceStr:
</span><span class="cx">             # XXX: sucks that we have to do this. make transport.write(buffer) work!
</span><span class="cx">             data = str(buffer(data))
</span><span class="cx">         self.consumer.write(data)
</span><del>-        
</del><ins>+
</ins><span class="cx">         if not self.paused:
</span><span class="cx">             self.resumeProducing()
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def pauseProducing(self):
</span><span class="cx">         self.paused = True
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def stopProducing(self, failure=ti_error.ConnectionLost()):
</span><span class="cx">         if self.consumer is not None:
</span><span class="cx">             self.consumer.unregisterProducer()
</span><span class="lines">@@ -810,13 +877,15 @@
</span><span class="cx">         self.paused = True
</span><span class="cx">         if self.stream is not None:
</span><span class="cx">             self.stream.close()
</span><del>-            
</del><ins>+
</ins><span class="cx">         self.finishedCallback = self.deferred = self.consumer = self.stream = None
</span><span class="cx"> 
</span><del>-##############################
-####    ProcessStreamer   ####
-##############################
</del><span class="cx"> 
</span><ins>+
+#
+# ProcessStreamer
+#
+
</ins><span class="cx"> class _ProcessStreamerProtocol(protocol.ProcessProtocol):
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, inputStream, outStream, errStream):
</span><span class="lines">@@ -824,39 +893,47 @@
</span><span class="cx">         self.outStream = outStream
</span><span class="cx">         self.errStream = errStream
</span><span class="cx">         self.resultDeferred = defer.Deferred()
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def connectionMade(self):
</span><span class="cx">         p = StreamProducer(self.inputStream)
</span><span class="cx">         # if the process stopped reading from the input stream,
</span><span class="cx">         # this is not an error condition, so it oughtn't result
</span><span class="cx">         # in a ConnectionLost() from the input stream:
</span><del>-        p.stopProducing = lambda err=None: StreamProducer.stopProducing(p, err)
-        
</del><ins>+        p.stopProducing = lambda err = None: StreamProducer.stopProducing(p, err)
+
</ins><span class="cx">         d = p.beginProducing(self.transport)
</span><span class="cx">         d.addCallbacks(lambda _: self.transport.closeStdin(),
</span><span class="cx">                        self._inputError)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _inputError(self, f):
</span><span class="cx">         log.failure(&quot;Error in input stream for transport {transport}&quot;, f, transport=self.transport)
</span><span class="cx">         self.transport.closeStdin()
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def outReceived(self, data):
</span><span class="cx">         self.outStream.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def errReceived(self, data):
</span><span class="cx">         self.errStream.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def outConnectionLost(self):
</span><span class="cx">         self.outStream.finish()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def errConnectionLost(self):
</span><span class="cx">         self.errStream.finish()
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def processEnded(self, reason):
</span><span class="cx">         self.resultDeferred.errback(reason)
</span><span class="cx">         del self.resultDeferred
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ProcessStreamer(object):
</span><span class="cx">     &quot;&quot;&quot;Runs a process hooked up to streams.
</span><span class="cx"> 
</span><span class="lines">@@ -874,7 +951,8 @@
</span><span class="cx">         self._program = program
</span><span class="cx">         self._args = args
</span><span class="cx">         self._env = env
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def run(self):
</span><span class="cx">         &quot;&quot;&quot;Run the process.
</span><span class="cx"> 
</span><span class="lines">@@ -886,29 +964,36 @@
</span><span class="cx">         del self._env
</span><span class="cx">         return self._protocol.resultDeferred.addErrback(lambda _: _.trap(ti_error.ProcessDone))
</span><span class="cx"> 
</span><del>-##############################
-####   generatorToStream  ####
-##############################
</del><span class="cx"> 
</span><ins>+
+#
+# generatorToStream
+#
+
</ins><span class="cx"> class _StreamIterator(object):
</span><del>-    done=False
</del><ins>+    done = False
</ins><span class="cx"> 
</span><span class="cx">     def __iter__(self):
</span><span class="cx">         return self
</span><ins>+
+
</ins><span class="cx">     def next(self):
</span><span class="cx">         if self.done:
</span><span class="cx">             raise StopIteration
</span><span class="cx">         return self.value
</span><del>-    wait=object()
</del><ins>+    wait = object()
</ins><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class _IteratorStream(object):
</span><span class="cx">     length = None
</span><del>-    
</del><ins>+
</ins><span class="cx">     def __init__(self, fun, stream, args, kwargs):
</span><del>-        self._stream=stream
</del><ins>+        self._stream = stream
</ins><span class="cx">         self._streamIterator = _StreamIterator()
</span><span class="cx">         self._gen = fun(self._streamIterator, *args, **kwargs)
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def read(self):
</span><span class="cx">         try:
</span><span class="cx">             val = self._gen.next()
</span><span class="lines">@@ -922,34 +1007,39 @@
</span><span class="cx">                 else:
</span><span class="cx">                     return self._gotRead(newdata)
</span><span class="cx">             return val
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def _gotRead(self, data):
</span><span class="cx">         if data is None:
</span><del>-            self._streamIterator.done=True
</del><ins>+            self._streamIterator.done = True
</ins><span class="cx">         else:
</span><del>-            self._streamIterator.value=data
</del><ins>+            self._streamIterator.value = data
</ins><span class="cx">         return self.read()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self._stream.close()
</span><span class="cx">         del self._gen, self._stream, self._streamIterator
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def split(self):
</span><span class="cx">         return fallbackSplit(self)
</span><del>-    
</del><ins>+
+
+
</ins><span class="cx"> def generatorToStream(fun):
</span><span class="cx">     &quot;&quot;&quot;Converts a generator function into a stream.
</span><del>-    
</del><ins>+
</ins><span class="cx">     The function should take an iterator as its first argument,
</span><span class="cx">     which will be converted *from* a stream by this wrapper, and
</span><span class="cx">     yield items which are turned *into* the results from the
</span><span class="cx">     stream's 'read' call.
</span><del>-    
</del><ins>+
</ins><span class="cx">     One important point: before every call to input.next(), you
</span><span class="cx">     *MUST* do a &quot;yield input.wait&quot; first. Yielding this magic value
</span><span class="cx">     takes care of ensuring that the input is not a deferred before
</span><span class="cx">     you see it.
</span><del>-    
</del><ins>+
</ins><span class="cx">     &gt;&gt;&gt; from txweb2 import stream
</span><span class="cx">     &gt;&gt;&gt; from string import maketrans
</span><span class="cx">     &gt;&gt;&gt; alphabet = 'abcdefghijklmnopqrstuvwxyz'
</span><span class="lines">@@ -974,61 +1064,67 @@
</span><span class="cx">     &gt;&gt;&gt; evenMoreEncryptedStream = encrypt(encryptedStream, 13)
</span><span class="cx">     &gt;&gt;&gt; evenMoreEncryptedStream.read()
</span><span class="cx">     'SampleSampleSample'
</span><del>-    
</del><ins>+
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def generatorToStream_inner(stream, *args, **kwargs):
</span><span class="cx">         return _IteratorStream(fun, stream, args, kwargs)
</span><span class="cx">     return generatorToStream_inner
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-##############################
-####    BufferedStream    ####
-##############################
</del><span class="cx"> 
</span><ins>+#
+# BufferedStream
+#
+
</ins><span class="cx"> class BufferedStream(object):
</span><span class="cx">     &quot;&quot;&quot;A stream which buffers its data to provide operations like
</span><span class="cx">     readline and readExactly.&quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     data = &quot;&quot;
</span><span class="cx">     def __init__(self, stream):
</span><span class="cx">         self.stream = stream
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _readUntil(self, f):
</span><span class="cx">         &quot;&quot;&quot;Internal helper function which repeatedly calls f each time
</span><span class="cx">         after more data has been received, until it returns non-None.&quot;&quot;&quot;
</span><span class="cx">         while True:
</span><span class="cx">             r = f()
</span><span class="cx">             if r is not None:
</span><del>-                yield r; return
-            
</del><ins>+                yield r
+                return
+
</ins><span class="cx">             newdata = self.stream.read()
</span><span class="cx">             if isinstance(newdata, defer.Deferred):
</span><span class="cx">                 newdata = defer.waitForDeferred(newdata)
</span><del>-                yield newdata; newdata = newdata.getResult()
-            
</del><ins>+                yield newdata
+                newdata = newdata.getResult()
+
</ins><span class="cx">             if newdata is None:
</span><span class="cx">                 # End Of File
</span><span class="cx">                 newdata = self.data
</span><span class="cx">                 self.data = ''
</span><del>-                yield newdata; return
</del><ins>+                yield newdata
+                return
</ins><span class="cx">             self.data += str(newdata)
</span><span class="cx">     _readUntil = defer.deferredGenerator(_readUntil)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def readExactly(self, size=None):
</span><span class="cx">         &quot;&quot;&quot;Read exactly size bytes of data, or, if size is None, read
</span><span class="cx">         the entire stream into a string.&quot;&quot;&quot;
</span><span class="cx">         if size is not None and size &lt; 0:
</span><span class="cx">             raise ValueError(&quot;readExactly: size cannot be negative: %s&quot;, size)
</span><del>-        
</del><ins>+
</ins><span class="cx">         def gotdata():
</span><span class="cx">             data = self.data
</span><span class="cx">             if size is not None and len(data) &gt;= size:
</span><del>-                pre,post = data[:size], data[size:]
</del><ins>+                pre, post = data[:size], data[size:]
</ins><span class="cx">                 self.data = post
</span><span class="cx">                 return pre
</span><span class="cx">         return self._readUntil(gotdata)
</span><del>-    
-        
</del><ins>+
+
</ins><span class="cx">     def readline(self, delimiter='\r\n', size=None):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Read a line of data from the string, bounded by
</span><span class="lines">@@ -1040,7 +1136,7 @@
</span><span class="cx">         the next line will be returned together.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         if size is not None and size &lt; 0:
</span><del>-            raise ValueError(&quot;readline: size cannot be negative: %s&quot; % (size, ))
</del><ins>+            raise ValueError(&quot;readline: size cannot be negative: %s&quot; % (size,))
</ins><span class="cx"> 
</span><span class="cx">         def gotdata():
</span><span class="cx">             data = self.data
</span><span class="lines">@@ -1055,18 +1151,20 @@
</span><span class="cx">                 splitpoint = data.find(delimiter)
</span><span class="cx">                 if splitpoint != -1:
</span><span class="cx">                     splitpoint += len(delimiter)
</span><del>-            
</del><ins>+
</ins><span class="cx">             if splitpoint != -1:
</span><span class="cx">                 pre = data[:splitpoint]
</span><span class="cx">                 self.data = data[splitpoint:]
</span><span class="cx">                 return pre
</span><span class="cx">         return self._readUntil(gotdata)
</span><del>-    
</del><ins>+
+
</ins><span class="cx">     def pushback(self, pushed):
</span><span class="cx">         &quot;&quot;&quot;Push data back into the buffer.&quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         self.data = pushed + self.data
</span><del>-        
</del><ins>+
+
</ins><span class="cx">     def read(self):
</span><span class="cx">         data = self.data
</span><span class="cx">         if data:
</span><span class="lines">@@ -1074,17 +1172,18 @@
</span><span class="cx">             return data
</span><span class="cx">         return self.stream.read()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _len(self):
</span><span class="cx">         l = self.stream.length
</span><span class="cx">         if l is None:
</span><span class="cx">             return None
</span><span class="cx">         return l + len(self.data)
</span><del>-    
</del><ins>+
</ins><span class="cx">     length = property(_len)
</span><del>-    
</del><ins>+
</ins><span class="cx">     def split(self, offset):
</span><span class="cx">         off = offset - len(self.data)
</span><del>-        
</del><ins>+
</ins><span class="cx">         pre, post = self.stream.split(max(0, off))
</span><span class="cx">         pre = BufferedStream(pre)
</span><span class="cx">         post = BufferedStream(post)
</span><span class="lines">@@ -1093,14 +1192,15 @@
</span><span class="cx">             post.data = self.data[-off:]
</span><span class="cx">         else:
</span><span class="cx">             pre.data = self.data
</span><del>-        
</del><ins>+
</ins><span class="cx">         return pre, post
</span><span class="cx"> 
</span><del>-        
-#########################
-####    MD5Stream    ####
-#########################
</del><span class="cx"> 
</span><ins>+
+#
+# MD5Stream
+#
+
</ins><span class="cx"> class MD5Stream(SimpleStream):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     An wrapper which computes the MD5 hash of the data read from the
</span></span></pre></div>
<a id="CalendarServertrunktxweb2test__init__py"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/__init__.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/__init__.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/__init__.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -6,4 +6,3 @@
</span><span class="cx"> txweb2.test: unittests for the Twext.Web2, Web Server Framework
</span><span class="cx"> 
</span><span class="cx"> &quot;&quot;&quot;
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2testsimple_clientpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/simple_client.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/simple_client.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/simple_client.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><del>-import socket, sys
</del><ins>+import socket
+import sys
</ins><span class="cx"> 
</span><span class="cx"> test_type = sys.argv[1]
</span><span class="cx"> port = int(sys.argv[2])
</span><span class="lines">@@ -10,12 +11,12 @@
</span><span class="cx"> 
</span><span class="cx"> if socket_type == 'ssl':
</span><span class="cx">     s2 = socket.ssl(s)
</span><del>-    send=s2.write
-    recv=s2.read
</del><ins>+    send = s2.write
+    recv = s2.read
</ins><span class="cx"> else:
</span><del>-    send=s.send
-    recv=s.recv
-    
</del><ins>+    send = s.send
+    recv = s.recv
+
</ins><span class="cx"> print &gt;&gt; sys.stderr, &quot;&gt;&gt; Making %s request to port %d&quot; % (socket_type, port)
</span><span class="cx"> 
</span><span class="cx"> send(&quot;GET /error HTTP/1.0\r\n&quot;)
</span><span class="lines">@@ -24,20 +25,20 @@
</span><span class="cx"> if test_type == &quot;lingeringClose&quot;:
</span><span class="cx">     print &gt;&gt; sys.stderr, &quot;&gt;&gt; Sending lots of data&quot;
</span><span class="cx">     send(&quot;Content-Length: 1000000\r\n\r\n&quot;)
</span><del>-    send(&quot;X&quot;*1000000)
</del><ins>+    send(&quot;X&quot; * 1000000)
</ins><span class="cx"> else:
</span><span class="cx">     send('\r\n')
</span><span class="cx"> 
</span><del>-#import time
-#time.sleep(5)
</del><ins>+# import time
+# time.sleep(5)
</ins><span class="cx"> print &gt;&gt; sys.stderr, &quot;&gt;&gt; Getting data&quot;
</span><del>-data=''
</del><ins>+data = ''
</ins><span class="cx"> while len(data) &lt; 299999:
</span><span class="cx">     try:
</span><del>-        x=recv(10000)
</del><ins>+        x = recv(10000)
</ins><span class="cx">     except:
</span><span class="cx">         break
</span><span class="cx">     if x == '':
</span><span class="cx">         break
</span><del>-    data+=x
</del><ins>+    data += x
</ins><span class="cx"> sys.stdout.write(data)
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_clientpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_client.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_client.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_client.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -22,13 +22,16 @@
</span><span class="cx">     def dataReceived(self, data):
</span><span class="cx">         self.data += data
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def write(self, data):
</span><span class="cx">         self.transport.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self.done = True
</span><span class="cx">         self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def loseConnection(self):
</span><span class="cx">         self.done = True
</span><span class="cx">         self.transport.loseConnection()
</span><span class="lines">@@ -52,15 +55,20 @@
</span><span class="cx"> 
</span><span class="cx">         return cxn
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeToClient(self, cxn, data):
</span><span class="cx">         cxn.server.write(data)
</span><span class="cx">         self.iterate(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeLines(self, cxn, lines):
</span><span class="cx">         self.writeToClient(cxn, '\r\n'.join(lines))
</span><span class="cx"> 
</span><del>-    def assertReceived(self, cxn, expectedStatus, expectedHeaders,
-                       expectedContent=None):
</del><ins>+
+    def assertReceived(
+        self, cxn, expectedStatus, expectedHeaders,
+        expectedContent=None
+    ):
</ins><span class="cx">         self.iterate(cxn)
</span><span class="cx"> 
</span><span class="cx">         headers, content = cxn.server.data.split('\r\n\r\n', 1)
</span><span class="lines">@@ -80,15 +88,18 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEquals(content, expectedContent)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertDone(self, cxn):
</span><span class="cx">         self.iterate(cxn)
</span><span class="cx">         self.assertEquals(cxn.server.done, True, 'Connection not closed.')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertHeaders(self, resp, expectedHeaders):
</span><span class="cx">         headers = list(resp.headers.getAllRawHeaders())
</span><span class="cx">         headers.sort()
</span><span class="cx">         self.assertEquals(headers, expectedHeaders)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkResponse(self, resp, code, headers, length, data):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Assert various things about a response: http code, headers, stream
</span><span class="lines">@@ -130,6 +141,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_delayedContent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure that the client returns the response object as soon as the
</span><span class="lines">@@ -164,6 +176,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_prematurePipelining(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Ensure that submitting a second request before it's allowed results
</span><span class="lines">@@ -189,6 +202,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_userHeaders(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure that headers get through in both directions.
</span><span class="lines">@@ -237,6 +251,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_streamedUpload(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure that sending request content works.
</span><span class="lines">@@ -260,6 +275,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_sentHead(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Ensure that HEAD requests work, and return Content-Length.
</span><span class="lines">@@ -282,6 +298,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_sentHeadKeepAlive(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Ensure that keepalive works right after a HEAD request.
</span><span class="lines">@@ -309,9 +326,9 @@
</span><span class="cx">             didIt[0] = second
</span><span class="cx"> 
</span><span class="cx">             if second:
</span><del>-                keepAlive='close'
</del><ins>+                keepAlive = 'close'
</ins><span class="cx">             else:
</span><del>-                keepAlive='Keep-Alive'
</del><ins>+                keepAlive = 'Keep-Alive'
</ins><span class="cx"> 
</span><span class="cx">             cxn.server.data = ''
</span><span class="cx"> 
</span><span class="lines">@@ -319,10 +336,10 @@
</span><span class="cx">                 self.checkResponse, 200, [('Content-Length', ['5'])], 0, None)
</span><span class="cx"> 
</span><span class="cx">             self.assertReceived(cxn, 'HEAD / HTTP/1.1',
</span><del>-                                ['Connection: '+ keepAlive])
</del><ins>+                                ['Connection: ' + keepAlive])
</ins><span class="cx"> 
</span><span class="cx">             self.writeLines(cxn, ('HTTP/1.1 200 OK',
</span><del>-                                  'Connection: '+ keepAlive,
</del><ins>+                                  'Connection: ' + keepAlive,
</ins><span class="cx">                                   'Content-Length: 5',
</span><span class="cx">                                   '\r\n'))
</span><span class="cx"> 
</span><span class="lines">@@ -332,6 +349,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_chunkedUpload(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Ensure chunked data is correctly decoded on upload.
</span><span class="lines">@@ -385,6 +403,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(lambda _: self.assertDone(cxn))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_serverIsntHttp(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Check that an error is returned if the server doesn't talk HTTP.
</span><span class="lines">@@ -435,6 +454,7 @@
</span><span class="cx">         self.writeLines(cxn, ('HTTP/1.1 200',
</span><span class="cx">                               '\r\n'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_errorReadingRequestStream(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Ensure that stream errors are propagated to the response.
</span><span class="lines">@@ -492,4 +512,3 @@
</span><span class="cx">             return self.assertFailure(response.stream.read(), ValueError)
</span><span class="cx">         d.addCallback(cb)
</span><span class="cx">         return d
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_fileuploadpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_fileupload.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_fileupload.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_fileupload.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx">                 raise ValueError(&quot;len(mem) &lt; start + length&quot;)
</span><span class="cx">             self.length = length
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         if self.mem is None:
</span><span class="cx">             return None
</span><span class="lines">@@ -41,6 +42,7 @@
</span><span class="cx">             self.start += amtToRead
</span><span class="cx">         return result
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.mem = None
</span><span class="cx">         stream.SimpleStream.close(self)
</span><span class="lines">@@ -58,21 +60,24 @@
</span><span class="cx">         d.addCallback(self._assertFailures, expected_error)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _assertFailures(self, failures, *expectedFailures):
</span><span class="cx">         for flag, failure in failures:
</span><span class="cx">             self.failUnlessEqual(flag, defer.FAILURE)
</span><span class="cx">             failure.trap(*expectedFailures)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def doTest(self, boundary, data, expected_args, expected_files):
</span><del>-        #import time, gc, cgi, cStringIO
</del><ins>+        # import time, gc, cgi, cStringIO
</ins><span class="cx">         for bytes in range(1, 20):
</span><del>-            #s = TestStream(data, maxReturn=bytes)
</del><ins>+            # s = TestStream(data, maxReturn=bytes)
</ins><span class="cx">             s = stream.IStream(data)
</span><del>-            #t=time.time()
</del><ins>+            # t=time.time()
</ins><span class="cx">             d = waitForDeferred(fileupload.parseMultipartFormData(s, boundary))
</span><del>-            yield d; args, files = d.getResult()
-            #e=time.time()
-            #print &quot;%.2g&quot;%(e-t)
</del><ins>+            yield d
+            args, files = d.getResult()
+            # e=time.time()
+            # print &quot;%.2g&quot;%(e-t)
</ins><span class="cx">             self.assertEquals(args, expected_args)
</span><span class="cx"> 
</span><span class="cx">             # Read file data back into memory to compare.
</span><span class="lines">@@ -81,17 +86,17 @@
</span><span class="cx">                 out[name] = [(filename, ctype, f.read()) for (filename, ctype, f) in l]
</span><span class="cx">             self.assertEquals(out, expected_files)
</span><span class="cx"> 
</span><del>-        #data=cStringIO.StringIO(data)
-        #t=time.time()
-        #d=cgi.parse_multipart(data, {'boundary':boundary})
-        #e=time.time()
-        #print &quot;CGI: %.2g&quot;%(e-t)
</del><ins>+        # data=cStringIO.StringIO(data)
+        # t=time.time()
+        # d=cgi.parse_multipart(data, {'boundary':boundary})
+        # e=time.time()
+        # print &quot;CGI: %.2g&quot;%(e-t)
</ins><span class="cx">     doTest = deferredGenerator(doTest)
</span><span class="cx"> 
</span><span class="cx">     def testNormalUpload(self):
</span><span class="cx">         return self.doTest(
</span><span class="cx">             '---------------------------155781040421463194511908194298',
</span><del>-&quot;&quot;&quot;-----------------------------155781040421463194511908194298\r
</del><ins>+            &quot;&quot;&quot;-----------------------------155781040421463194511908194298\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;foo&quot;\r
</span><span class="cx"> \r
</span><span class="cx"> Foo Bar\r
</span><span class="lines">@@ -104,14 +109,15 @@
</span><span class="cx"> blah\r
</span><span class="cx"> -----------------------------155781040421463194511908194298--\r
</span><span class="cx"> &quot;&quot;&quot;,
</span><del>-            {'foo':['Foo Bar']},
-            {'file':[('filename', MimeType('text', 'html'),
</del><ins>+            {'foo': ['Foo Bar']},
+            {'file': [('filename', MimeType('text', 'html'),
</ins><span class="cx">                       &quot;Contents of a file\nblah\nblah&quot;)]})
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testMultipleUpload(self):
</span><span class="cx">         return self.doTest(
</span><span class="cx">             'xyz',
</span><del>-&quot;&quot;&quot;--xyz\r
</del><ins>+            &quot;&quot;&quot;--xyz\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;foo&quot;\r
</span><span class="cx"> \r
</span><span class="cx"> Foo Bar\r
</span><span class="lines">@@ -131,15 +137,15 @@
</span><span class="cx"> bleh\r
</span><span class="cx"> --xyz--\r
</span><span class="cx"> &quot;&quot;&quot;,
</span><del>-            {'foo':['Foo Bar', 'Baz']},
-            {'file':[('filename', MimeType('text', 'html'), &quot;blah&quot;),
-                     ('filename', MimeType('text', 'plain'), &quot;bleh&quot;)]})
</del><ins>+            {'foo': ['Foo Bar', 'Baz']},
+            {'file': [('filename', MimeType('text', 'html'), &quot;blah&quot;),
+                      ('filename', MimeType('text', 'plain'), &quot;bleh&quot;)]})
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def testStupidFilename(self):
</span><span class="cx">         return self.doTest(
</span><span class="cx">             '----------0xKhTmLbOuNdArY',
</span><del>-&quot;&quot;&quot;------------0xKhTmLbOuNdArY\r
</del><ins>+            &quot;&quot;&quot;------------0xKhTmLbOuNdArY\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;foo&quot;; name=&quot;foobar.txt&quot;\r
</span><span class="cx"> Content-Type: text/plain\r
</span><span class="cx"> \r
</span><span class="lines">@@ -149,14 +155,14 @@
</span><span class="cx"> ------------0xKhTmLbOuNdArY--\r
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">             {},
</span><del>-            {'file':[('foo&quot;; name=&quot;foobar.txt', MimeType('text', 'plain'),
</del><ins>+            {'file': [('foo&quot;; name=&quot;foobar.txt', MimeType('text', 'plain'),
</ins><span class="cx">                       &quot;Contents of a file\nblah\nblah&quot;)]})
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def testEmptyFilename(self):
</span><span class="cx">         return self.doTest(
</span><span class="cx">             'curlPYafCMnsamUw9kSkJJkSen41sAV',
</span><del>-&quot;&quot;&quot;--curlPYafCMnsamUw9kSkJJkSen41sAV\r
</del><ins>+            &quot;&quot;&quot;--curlPYafCMnsamUw9kSkJJkSen41sAV\r
</ins><span class="cx"> cONTENT-tYPE: application/octet-stream\r
</span><span class="cx"> cONTENT-dISPOSITION: FORM-DATA; NAME=&quot;foo&quot;; FILENAME=&quot;&quot;\r
</span><span class="cx"> \r
</span><span class="lines">@@ -164,7 +170,7 @@
</span><span class="cx"> --curlPYafCMnsamUw9kSkJJkSen41sAV--\r
</span><span class="cx"> &quot;&quot;&quot;,
</span><span class="cx">             {},
</span><del>-            {'foo':[('', MimeType('application', 'octet-stream'),
</del><ins>+            {'foo': [('', MimeType('application', 'octet-stream'),
</ins><span class="cx">                      &quot;qwertyuiop&quot;)]})
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -172,7 +178,7 @@
</span><span class="cx">     def testMissingContentDisposition(self):
</span><span class="cx">         return self.doTestError(
</span><span class="cx">             '----------0xKhTmLbOuNdArY',
</span><del>-&quot;&quot;&quot;------------0xKhTmLbOuNdArY\r
</del><ins>+            &quot;&quot;&quot;------------0xKhTmLbOuNdArY\r
</ins><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="cx"> Blah blah I am a stupid webbrowser\r
</span><span class="lines">@@ -184,7 +190,7 @@
</span><span class="cx">     def testRandomData(self):
</span><span class="cx">         return self.doTestError(
</span><span class="cx">             'boundary',
</span><del>-&quot;&quot;&quot;--sdkjsadjlfjlj skjsfdkljsd
</del><ins>+            &quot;&quot;&quot;--sdkjsadjlfjlj skjsfdkljsd
</ins><span class="cx"> sfdkjsfdlkjhsfadklj sffkj&quot;&quot;&quot;,
</span><span class="cx">             fileupload.MimeFormatError)
</span><span class="cx"> 
</span><span class="lines">@@ -275,16 +281,17 @@
</span><span class="cx">         for bytes in range(1, 20):
</span><span class="cx">             s = TestStream(data, maxReturn=bytes)
</span><span class="cx">             d = waitForDeferred(fileupload.parse_urlencoded(s))
</span><del>-            yield d; args = d.getResult()
</del><ins>+            yield d
+            args = d.getResult()
</ins><span class="cx">             self.assertEquals(args, expected_args)
</span><span class="cx">     doTest = deferredGenerator(doTest)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_parseValid(self):
</span><del>-        self.doTest(&quot;a=b&amp;c=d&amp;c=e&quot;, {'a':['b'], 'c':['d', 'e']})
-        self.doTest(&quot;a=b&amp;c=d&amp;c=e&quot;, {'a':['b'], 'c':['d', 'e']})
-        self.doTest(&quot;a=b+c%20d&quot;, {'a':['b c d']})
</del><ins>+        self.doTest(&quot;a=b&amp;c=d&amp;c=e&quot;, {'a': ['b'], 'c': ['d', 'e']})
+        self.doTest(&quot;a=b&amp;c=d&amp;c=e&quot;, {'a': ['b'], 'c': ['d', 'e']})
+        self.doTest(&quot;a=b+c%20d&quot;, {'a': ['b c d']})
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_parseInvalid(self):
</span><del>-        self.doTest(&quot;a&amp;b=c&quot;, {'b':['c']})
</del><ins>+        self.doTest(&quot;a&amp;b=c&quot;, {'b': ['c']})
</ins></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_httppy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_http.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_http.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_http.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -1,7 +1,9 @@
</span><span class="cx"> 
</span><span class="cx"> from __future__ import nested_scopes
</span><span class="cx"> 
</span><del>-import time, sys, os
</del><ins>+import os
+import sys
+import time
</ins><span class="cx"> 
</span><span class="cx"> from zope.interface import implements
</span><span class="cx"> 
</span><span class="lines">@@ -20,6 +22,7 @@
</span><span class="cx"> 
</span><span class="cx"> class RedirectResponseTestCase(unittest.TestCase):
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTemporary(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Verify the &quot;temporary&quot; parameter sets the appropriate response code
</span><span class="lines">@@ -29,6 +32,8 @@
</span><span class="cx">         req = http.RedirectResponse(&quot;http://example.com/&quot;, temporary=True)
</span><span class="cx">         self.assertEquals(req.code, responsecode.TEMPORARY_REDIRECT)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class PreconditionTestCase(unittest.TestCase):
</span><span class="cx">     def checkPreconditions(self, request, response, expectedResult, expectedCode,
</span><span class="cx">                            **kw):
</span><span class="lines">@@ -41,6 +46,7 @@
</span><span class="cx">             self.assertEquals(e.response.code, expectedCode)
</span><span class="cx">         self.assertEquals(preconditionsPass, expectedResult)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testWithoutHeaders(self):
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><span class="cx">         out_headers = http_headers.Headers()
</span><span class="lines">@@ -58,6 +64,7 @@
</span><span class="cx">         out_headers.setHeader(&quot;ETag&quot;, http_headers.ETag('foo'))
</span><span class="cx">         self.checkPreconditions(request, response, True, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testIfMatch(self):
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><span class="cx">         out_headers = http_headers.Headers()
</span><span class="lines">@@ -72,7 +79,7 @@
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-Match&quot;, ('&quot;frob&quot;',))
</span><span class="cx">         self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
</span><span class="cx"> 
</span><del>-        ## Actually set the ETag header
</del><ins>+        # Actually set the ETag header
</ins><span class="cx">         out_headers.setHeader(&quot;ETag&quot;, http_headers.ETag('foo'))
</span><span class="cx">         out_headers.setHeader(&quot;Last-Modified&quot;, 946771200) # Sun, 02 Jan 2000 00:00:00 GMT
</span><span class="cx"> 
</span><span class="lines">@@ -99,6 +106,7 @@
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-Match&quot;, ('W/&quot;foo&quot;',))
</span><span class="cx">         self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testIfUnmodifiedSince(self):
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><span class="cx">         out_headers = http_headers.Headers()
</span><span class="lines">@@ -149,9 +157,9 @@
</span><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><span class="cx"> 
</span><span class="cx">         # With a non-GET method
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><del>-        request.method=&quot;GET&quot;
</del><ins>+        request.method = &quot;GET&quot;
</ins><span class="cx"> 
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-Modified-Since&quot;, ('Sat, 01 Jan 2000 00:00:00 GMT',))
</span><span class="cx">         self.checkPreconditions(request, response, True, responsecode.OK)
</span><span class="lines">@@ -169,6 +177,7 @@
</span><span class="cx">         request.headers.setHeader(&quot;If-Modified-Since&quot;, time.time() + 500)
</span><span class="cx">         self.checkPreconditions(request, response, True, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testIfNoneMatch(self):
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><span class="cx">         out_headers = http_headers.Headers()
</span><span class="lines">@@ -182,24 +191,24 @@
</span><span class="cx"> 
</span><span class="cx">         # behavior of entityExists
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-None-Match&quot;, ('*',))
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
</span><del>-        request.method=&quot;GET&quot;
</del><ins>+        request.method = &quot;GET&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><span class="cx">         self.checkPreconditions(request, response, True, responsecode.OK, entityExists=False)
</span><span class="cx"> 
</span><span class="cx">         # tag matches
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-None-Match&quot;, ('&quot;frob&quot;, &quot;foo&quot;',))
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
</span><del>-        request.method=&quot;GET&quot;
</del><ins>+        request.method = &quot;GET&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><span class="cx"> 
</span><span class="cx">         # now with IMS, also:
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-Modified-Since&quot;, ('Mon, 03 Jan 2000 00:00:00 GMT',))
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
</span><del>-        request.method=&quot;GET&quot;
</del><ins>+        request.method = &quot;GET&quot;
</ins><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><span class="cx"> 
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-Modified-Since&quot;, ('Sat, 01 Jan 2000 00:00:00 GMT',))
</span><span class="lines">@@ -232,15 +241,16 @@
</span><span class="cx">         self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED)
</span><span class="cx"> 
</span><span class="cx">         # Weak tags not okay for other methods
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         out_headers.setHeader(&quot;ETag&quot;, http_headers.ETag('foo', weak=True))
</span><span class="cx">         request.headers.setRawHeaders(&quot;If-None-Match&quot;, ('W/&quot;foo&quot;',))
</span><span class="cx">         self.checkPreconditions(request, response, True, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testNoResponse(self):
</span><span class="cx">         # Ensure that passing etag/lastModified arguments instead of response works.
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><del>-        request.method=&quot;PUT&quot;
</del><ins>+        request.method = &quot;PUT&quot;
</ins><span class="cx">         request.headers.setRawHeaders(&quot;If-None-Match&quot;, ('&quot;foo&quot;',))
</span><span class="cx"> 
</span><span class="cx">         self.checkPreconditions(request, None, True, responsecode.OK)
</span><span class="lines">@@ -249,10 +259,12 @@
</span><span class="cx">                                 lastModified=946771200)
</span><span class="cx"> 
</span><span class="cx">         # Make sure that, while you shoudn't do this, that it doesn't cause an error
</span><del>-        request.method=&quot;GET&quot;
</del><ins>+        request.method = &quot;GET&quot;
</ins><span class="cx">         self.checkPreconditions(request, None, False, responsecode.NOT_MODIFIED,
</span><span class="cx">                                 etag=http_headers.ETag('foo'))
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class IfRangeTestCase(unittest.TestCase):
</span><span class="cx">     def testIfRange(self):
</span><span class="cx">         request = http.Request(None, &quot;GET&quot;, &quot;/&quot;, &quot;HTTP/1.1&quot;, 0, http_headers.Headers())
</span><span class="lines">@@ -302,6 +314,7 @@
</span><span class="cx"> class LoopbackRelay(loopback.LoopbackRelay):
</span><span class="cx">     implements(interfaces.IProducer)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def pauseProducing(self):
</span><span class="cx">         self.paused = True
</span><span class="cx"> 
</span><span class="lines">@@ -330,6 +343,7 @@
</span><span class="cx">         return address.IPv4Address('TCP', 'localhost', 4321)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TestRequestMixin(object):
</span><span class="cx">     def __init__(self, *args, **kwargs):
</span><span class="cx">         super(TestRequestMixin, self).__init__(*args, **kwargs)
</span><span class="lines">@@ -338,81 +352,105 @@
</span><span class="cx">         headers.sort()
</span><span class="cx">         self.cmds.append(('init', self.method, self.uri, self.clientproto, self.stream.length, tuple(headers)))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def process(self):
</span><span class="cx">         pass
</span><ins>+
+
</ins><span class="cx">     def handleContentChunk(self, data):
</span><span class="cx">         self.cmds.append(('contentChunk', data))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def handleContentComplete(self):
</span><span class="cx">         self.cmds.append(('contentComplete',))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self.cmds.append(('connectionLost', reason))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _finished(self, x):
</span><span class="cx">         self._reallyFinished(x)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TestRequest(TestRequestMixin, http.Request):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Stub request for testing.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TestSSLRedirectRequest(TestRequestMixin, SSLRedirectRequest):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Stub request for HSTS testing.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TestResponse(object):
</span><span class="cx">     implements(iweb.IResponse)
</span><span class="cx"> 
</span><span class="cx">     code = responsecode.OK
</span><span class="cx">     headers = None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def __init__(self):
</span><span class="cx">         self.headers = http_headers.Headers()
</span><span class="cx">         self.stream = stream.ProducerStream()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def write(self, data):
</span><span class="cx">         self.stream.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def finish(self):
</span><span class="cx">         self.stream.finish()
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TestClient(protocol.Protocol):
</span><span class="cx">     data = &quot;&quot;
</span><span class="cx">     done = False
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def dataReceived(self, data):
</span><del>-        self.data+=data
</del><ins>+        self.data += data
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def write(self, data):
</span><span class="cx">         self.transport.write(data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connectionLost(self, reason):
</span><span class="cx">         self.done = True
</span><span class="cx">         self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def loseConnection(self):
</span><span class="cx">         self.done = True
</span><span class="cx">         self.transport.loseConnection()
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TestConnection:
</span><span class="cx">     def __init__(self):
</span><span class="cx">         self.requests = []
</span><span class="cx">         self.client = None
</span><span class="cx">         self.callLaters = []
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def fakeCallLater(self, secs, f):
</span><span class="cx">         assert secs == 0
</span><span class="cx">         self.callLaters.append(f)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class HTTPTests(unittest.TestCase):
</span><span class="cx"> 
</span><span class="cx">     requestClass = TestRequest
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         super(HTTPTests, self).setUp()
</span><span class="cx"> 
</span><span class="lines">@@ -441,6 +479,7 @@
</span><span class="cx"> 
</span><span class="cx">         return cxn
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def iterate(self, cxn):
</span><span class="cx">         callLaters = cxn.callLaters
</span><span class="cx">         cxn.callLaters = []
</span><span class="lines">@@ -453,6 +492,7 @@
</span><span class="cx">         if cxn.clientToServer.shouldLose:
</span><span class="cx">             cxn.clientToServer.clearBuffer()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def compareResult(self, cxn, cmds, data):
</span><span class="cx">         self.iterate(cxn)
</span><span class="cx">         for receivedRequest, expectedCommands in map(None, cxn.requests, cmds):
</span><span class="lines">@@ -467,16 +507,20 @@
</span><span class="cx">             self.assertEquals(receivedRequest.cmds, sortedHeaderCommands)
</span><span class="cx">         self.assertEquals(cxn.client.data, data)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertDone(self, cxn, done=True):
</span><span class="cx">         self.iterate(cxn)
</span><span class="cx">         self.assertEquals(cxn.client.done, done)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class GracefulShutdownTestCase(HTTPTests):
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _callback(self, result):
</span><span class="cx">         self.callbackFired = True
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testAllConnectionsClosedWithoutConnectedChannels(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         allConnectionsClosed( ) should fire right away if no connected channels
</span><span class="lines">@@ -487,6 +531,7 @@
</span><span class="cx">         factory.allConnectionsClosed().addCallback(self._callback)
</span><span class="cx">         self.assertTrue(self.callbackFired)  # now!
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testallConnectionsClosedWithConnectedChannels(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         allConnectionsClosed( ) should only fire after all connected channels
</span><span class="lines">@@ -511,11 +556,13 @@
</span><span class="cx">         self.assertTrue(self.callbackFired)  # now!
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class CoreHTTPTestCase(HTTPTests):
</span><span class="cx">     # Note: these tests compare the client output using string
</span><span class="cx">     #       matching. It is acceptable for this to change and break
</span><span class="cx">     #       the test if you know what you are doing.
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP0_9(self, nouri=False):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -528,7 +575,7 @@
</span><span class="cx">         # Second request which should not be handled
</span><span class="cx">         cxn.client.write(&quot;GET /two\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds[0] += [('init', 'GET', '/', (0,9), 0, ()), ('contentComplete',)]
</del><ins>+        cmds[0] += [('init', 'GET', '/', (0, 9), 0, ()), ('contentComplete',)]
</ins><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         response = TestResponse()
</span><span class="lines">@@ -547,9 +594,11 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP0_9_nouri(self):
</span><span class="cx">         self.testHTTP0_9(True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_0(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -559,7 +608,7 @@
</span><span class="cx">         # Second request which should not be handled
</span><span class="cx">         cxn.client.write(&quot;GET /two HTTP/1.0\r\n\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,0), 5,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 0), 5,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input'),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="lines">@@ -582,6 +631,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_0_keepalive(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -592,14 +642,14 @@
</span><span class="cx">         # Third request shouldn't be handled
</span><span class="cx">         cxn.client.write(&quot;GET /three HTTP/1.0\r\n\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,0), 5,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 0), 5,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input'),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         response0 = TestResponse()
</span><del>-        response0.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;6&quot;, ))
</del><ins>+        response0.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;6&quot;,))
</ins><span class="cx">         response0.headers.setRawHeaders(&quot;Yo&quot;, (&quot;One&quot;, &quot;Two&quot;))
</span><span class="cx">         cxn.requests[0].writeResponse(response0)
</span><span class="cx">         response0.write(&quot;&quot;)
</span><span class="lines">@@ -615,13 +665,13 @@
</span><span class="cx"> 
</span><span class="cx">         # Now for second request:
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[1] += [('init', 'GET', '/two', (1,0), 0, ()), 
</del><ins>+        cmds[1] += [('init', 'GET', '/two', (1, 0), 0, ()),
</ins><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">         response1 = TestResponse()
</span><del>-        response1.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;0&quot;, ))
</del><ins>+        response1.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;0&quot;,))
</ins><span class="cx">         cxn.requests[1].writeResponse(response1)
</span><span class="cx">         response1.write(&quot;&quot;)
</span><span class="cx"> 
</span><span class="lines">@@ -631,6 +681,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_1_pipelining(self):
</span><span class="cx">         cxn = self.connect(maxPipeline=2)
</span><span class="cx">         cmds = []
</span><span class="lines">@@ -645,19 +696,19 @@
</span><span class="cx">         cxn.client.write(&quot;GET /four HTTP/1.1\r\nHost: localhost\r\n\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 5, 
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 5,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input'),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[1] += [('init', 'GET', '/two', (1,1), 0, 
</del><ins>+        cmds[1] += [('init', 'GET', '/two', (1, 1), 0,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx"> 
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         response0 = TestResponse()
</span><del>-        response0.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;6&quot;, ))
</del><ins>+        response0.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;6&quot;,))
</ins><span class="cx">         cxn.requests[0].writeResponse(response0)
</span><span class="cx">         response0.write(&quot;&quot;)
</span><span class="cx"> 
</span><span class="lines">@@ -672,7 +723,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Now the third request gets read:
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[2] += [('init', 'GET', '/three', (1,1), 0,
</del><ins>+        cmds[2] += [('init', 'GET', '/three', (1, 1), 0,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="lines">@@ -680,7 +731,7 @@
</span><span class="cx">         # Let's write out the third request before the second.
</span><span class="cx">         # This should not cause anything to be written to the client.
</span><span class="cx">         response2 = TestResponse()
</span><del>-        response2.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;5&quot;, ))
</del><ins>+        response2.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;5&quot;,))
</ins><span class="cx">         cxn.requests[2].writeResponse(response2)
</span><span class="cx"> 
</span><span class="cx">         response2.write(&quot;Three&quot;)
</span><span class="lines">@@ -689,7 +740,7 @@
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         response1 = TestResponse()
</span><del>-        response1.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;3&quot;, ))
</del><ins>+        response1.headers.setRawHeaders(&quot;Content-Length&quot;, (&quot;3&quot;,))
</ins><span class="cx">         cxn.requests[1].writeResponse(response1)
</span><span class="cx">         response1.write(&quot;Two&quot;)
</span><span class="cx"> 
</span><span class="lines">@@ -700,7 +751,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Fourth request shows up
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[3] += [('init', 'GET', '/four', (1,1), 0,
</del><ins>+        cmds[3] += [('init', 'GET', '/four', (1, 1), 0,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         data += &quot;HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nThree&quot;
</span><span class="lines">@@ -718,20 +769,21 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_1_chunking(self, extraHeaders=&quot;&quot;):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\nHost: localhost\r\n\r\n5\r\nInput\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), None,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), None,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input')]
</span><span class="cx"> 
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;1; blahblahblah\r\na\r\n10\r\nabcdefghijklmnop\r\n&quot;)
</span><del>-        cmds[0] += [('contentChunk', 'a'),('contentChunk', 'abcdefghijklmnop')]
</del><ins>+        cmds[0] += [('contentChunk', 'a'), ('contentChunk', 'abcdefghijklmnop')]
</ins><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;0\r\nRandom-Ignored-Trailer: foo\r\n\r\n&quot;)
</span><span class="lines">@@ -765,12 +817,13 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_1_expect_continue(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nContent-Length: 5\r\nHost: localhost\r\nExpect: 100-continue\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 5,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 5,
</ins><span class="cx">                      (('Expect', ['100-continue']), ('Host', ['localhost'])))]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="lines">@@ -795,12 +848,13 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHTTP1_1_expect_continue_early_reply(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nContent-Length: 5\r\nHost: localhost\r\nExpect: 100-continue\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 5,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 5,
</ins><span class="cx">                      (('Host', ['localhost']), ('Expect', ['100-continue'])))]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="lines">@@ -817,13 +871,14 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testHeaderContinuation(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nHost: localhost\r\nFoo: yada\r\n yada\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 0,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 0,
</ins><span class="cx">                      (('Host', ['localhost']), ('Foo', ['yada yada']),)),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="lines">@@ -831,23 +886,26 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTimeout_immediate(self):
</span><span class="cx">         # timeout 0 =&gt; timeout on first iterate call
</span><del>-        cxn = self.connect(inputTimeOut = 0)
</del><ins>+        cxn = self.connect(inputTimeOut=0)
</ins><span class="cx">         return deferLater(reactor, 0, self.assertDone, cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTimeout_inRequest(self):
</span><del>-        cxn = self.connect(inputTimeOut = 0.3)
</del><ins>+        cxn = self.connect(inputTimeOut=0.3)
</ins><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><span class="cx">         return deferLater(reactor, 0.5, self.assertDone, cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTimeout_betweenRequests(self):
</span><del>-        cxn = self.connect(betweenRequestsTimeOut = 0.3)
</del><ins>+        cxn = self.connect(betweenRequestsTimeOut=0.3)
</ins><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 0, ()),
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 0, ()),
</ins><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="lines">@@ -861,6 +919,7 @@
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx">         return deferLater(reactor, 0.5, self.assertDone, cxn) # Wait for timeout
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTimeout_idleRequest(self):
</span><span class="cx">         cxn = self.connect(idleTimeOut=0.3)
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -873,6 +932,7 @@
</span><span class="cx"> 
</span><span class="cx">         return deferLater(reactor, 0.5, self.assertDone, cxn) # Wait for timeout
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTimeout_abortRequest(self):
</span><span class="cx">         cxn = self.connect(allowPersistentConnections=False, closeTimeOut=0.3)
</span><span class="cx">         cxn.client.transport.loseConnection = lambda : None
</span><span class="lines">@@ -897,19 +957,20 @@
</span><span class="cx">             self.assertTrue(cxn.serverToClient.aborted)
</span><span class="cx">         return deferLater(reactor, 0.5, self.assertDone, cxn) # Wait for timeout
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testConnectionCloseRequested(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 0, ()),
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 0, ()),
</ins><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nConnection: close\r\n\r\n&quot;)
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[1] += [('init', 'GET', '/', (1,1), 0, ()),
</del><ins>+        cmds[1] += [('init', 'GET', '/', (1, 1), 0, ()),
</ins><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="lines">@@ -930,6 +991,7 @@
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testConnectionKeepAliveOff(self):
</span><span class="cx">         cxn = self.connect(allowPersistentConnections=False)
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -950,6 +1012,7 @@
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testExtraCRLFs(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cmds = [[]]
</span><span class="lines">@@ -957,7 +1020,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Some broken clients (old IEs) send an extra CRLF after post
</span><span class="cx">         cxn.client.write(&quot;POST / HTTP/1.1\r\nContent-Length: 5\r\nHost: localhost\r\n\r\nInput\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'POST', '/', (1,1), 5,
</del><ins>+        cmds[0] += [('init', 'POST', '/', (1, 1), 5,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input'),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="lines">@@ -966,20 +1029,21 @@
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET /two HTTP/1.1\r\n\r\n&quot;)
</span><span class="cx">         cmds.append([])
</span><del>-        cmds[1] += [('init', 'GET', '/two', (1,1), 0, ()),
</del><ins>+        cmds[1] += [('init', 'GET', '/two', (1, 1), 0, ()),
</ins><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx"> 
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testDisallowPersistentConnections(self):
</span><span class="cx">         cxn = self.connect(allowPersistentConnections=False)
</span><span class="cx">         cmds = [[]]
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nHost: localhost\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n&quot;)
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), 0,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), 0,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentComplete',)]
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="lines">@@ -991,6 +1055,7 @@
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testIgnoreBogusContentLength(self):
</span><span class="cx">         # Ensure that content-length is ignored when transfer-encoding
</span><span class="cx">         # is also specified.
</span><span class="lines">@@ -999,7 +1064,7 @@
</span><span class="cx">         data = &quot;&quot;
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nContent-Length: 100\r\nTransfer-Encoding: chunked\r\nHost: localhost\r\n\r\n5\r\nInput\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds[0] += [('init', 'GET', '/', (1,1), None,
</del><ins>+        cmds[0] += [('init', 'GET', '/', (1, 1), None,
</ins><span class="cx">                      (('Host', ['localhost']),)),
</span><span class="cx">                     ('contentChunk', 'Input')]
</span><span class="cx"> 
</span><span class="lines">@@ -1018,56 +1083,67 @@
</span><span class="cx">         cxn.client.loseConnection()
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class ErrorTestCase(HTTPTests):
</span><ins>+
</ins><span class="cx">     def assertStartsWith(self, first, second, msg=None):
</span><span class="cx">         self.assert_(first.startswith(second), '%r.startswith(%r)' % (first, second))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkError(self, cxn, code):
</span><span class="cx">         self.iterate(cxn)
</span><del>-        self.assertStartsWith(cxn.client.data, &quot;HTTP/1.1 %d &quot;%code)
</del><ins>+        self.assertStartsWith(cxn.client.data, &quot;HTTP/1.1 %d &quot; % code)
</ins><span class="cx">         self.assertIn(&quot;\r\nConnection: close\r\n&quot;, cxn.client.data)
</span><span class="cx">         # Ensure error messages have a defined content-length.
</span><span class="cx">         self.assertIn(&quot;\r\nContent-Length:&quot;, cxn.client.data)
</span><span class="cx">         self.assertDone(cxn)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testChunkingError1(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\nasdf\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testChunkingError2(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n1\r\nblahblah\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testChunkingError3(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n-1\r\nasdf\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTooManyHeaders(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><del>-        cxn.client.write(&quot;Foo: Bar\r\n&quot;*5000)
</del><ins>+        cxn.client.write(&quot;Foo: Bar\r\n&quot; * 5000)
</ins><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testLineTooLong(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><del>-        cxn.client.write(&quot;Foo: &quot;+(&quot;Bar&quot;*10000))
</del><ins>+        cxn.client.write(&quot;Foo: &quot; + (&quot;Bar&quot; * 10000))
</ins><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testLineTooLong2(self):
</span><span class="cx">         cxn = self.connect()
</span><del>-        cxn.client.write(&quot;GET &quot;+(&quot;/Bar&quot;)*10000 +&quot; HTTP/1.1\r\n&quot;)
</del><ins>+        cxn.client.write(&quot;GET &quot; + (&quot;/Bar&quot;) * 10000 + &quot; HTTP/1.1\r\n&quot;)
</ins><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 414)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testNoColon(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><span class="lines">@@ -1096,57 +1172,67 @@
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testWrongProtocol(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / Foobar/1.0\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testBadProtocolVersion(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testBadProtocolVersion2(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/-1.0\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testWrongProtocolVersion(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/2.0\r\n&quot;)
</span><span class="cx"> 
</span><span class="cx">         self.checkError(cxn, 505)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testUnsupportedTE(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><span class="cx">         cxn.client.write(&quot;Transfer-Encoding: blahblahblah, chunked\r\n\r\n&quot;)
</span><span class="cx">         self.checkError(cxn, 501)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testTEWithoutChunked(self):
</span><span class="cx">         cxn = self.connect()
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\n&quot;)
</span><span class="cx">         cxn.client.write(&quot;Transfer-Encoding: gzip\r\n\r\n&quot;)
</span><span class="cx">         self.checkError(cxn, 400)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class PipelinedErrorTestCase(ErrorTestCase):
</span><span class="cx">     # Make sure that even low level reading errors don't corrupt the data stream,
</span><span class="cx">     # but always wait until their turn to respond.
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def connect(self):
</span><span class="cx">         cxn = ErrorTestCase.connect(self)
</span><span class="cx">         cxn.client.write(&quot;GET / HTTP/1.1\r\nHost: localhost\r\n\r\n&quot;)
</span><span class="cx"> 
</span><del>-        cmds = [[('init', 'GET', '/', (1,1), 0,
</del><ins>+        cmds = [[('init', 'GET', '/', (1, 1), 0,
</ins><span class="cx">                  (('Host', ['localhost']),)),
</span><del>-                ('contentComplete', )]]
</del><ins>+                ('contentComplete',)]]
</ins><span class="cx">         data = &quot;&quot;
</span><span class="cx">         self.compareResult(cxn, cmds, data)
</span><span class="cx">         return cxn
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkError(self, cxn, code):
</span><span class="cx">         self.iterate(cxn)
</span><span class="cx">         self.assertEquals(cxn.client.data, '')
</span><span class="lines">@@ -1167,7 +1253,9 @@
</span><span class="cx">         ErrorTestCase.checkError(self, cxn, code)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class SimpleFactory(channel.HTTPFactory):
</span><ins>+
</ins><span class="cx">     def buildProtocol(self, addr):
</span><span class="cx">         # Do a bunch of crazy crap just so that the test case can know when the
</span><span class="cx">         # connection is done.
</span><span class="lines">@@ -1180,21 +1268,28 @@
</span><span class="cx">         self.conn = p
</span><span class="cx">         return p
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class SimpleRequest(http.Request):
</span><ins>+
</ins><span class="cx">     def process(self):
</span><span class="cx">         response = TestResponse()
</span><span class="cx">         if self.uri == &quot;/error&quot;:
</span><del>-            response.code=402
</del><ins>+            response.code = 402
</ins><span class="cx">         elif self.uri == &quot;/forbidden&quot;:
</span><del>-            response.code=403
</del><ins>+            response.code = 403
</ins><span class="cx">         else:
</span><del>-            response.code=404
</del><ins>+            response.code = 404
</ins><span class="cx">             response.write(&quot;URI %s unrecognized.&quot; % self.uri)
</span><span class="cx">         response.finish()
</span><span class="cx">         self.writeResponse(response)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class AbstractServerTestMixin:
</span><ins>+
</ins><span class="cx">     type = None
</span><ins>+
</ins><span class="cx">     def testBasicWorkingness(self):
</span><span class="cx">         args = ('-u', util.sibpath(__file__, &quot;simple_client.py&quot;), &quot;basic&quot;,
</span><span class="cx">                 str(self.port), self.type)
</span><span class="lines">@@ -1202,12 +1297,14 @@
</span><span class="cx">             utils.getProcessOutputAndValue(sys.executable, args=args,
</span><span class="cx">                                            env=os.environ)
</span><span class="cx">         )
</span><del>-        yield d; out,err,code = d.getResult()
</del><ins>+        yield d
+        out, err, code = d.getResult()
</ins><span class="cx"> 
</span><span class="cx">         self.assertEquals(code, 0, &quot;Error output:\n%s&quot; % (err,))
</span><span class="cx">         self.assertEquals(out, &quot;HTTP/1.1 402 Payment Required\r\nContent-Length: 0\r\nConnection: close\r\n\r\n&quot;)
</span><span class="cx">     testBasicWorkingness = deferredGenerator(testBasicWorkingness)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testLingeringClose(self):
</span><span class="cx">         args = ('-u', util.sibpath(__file__, &quot;simple_client.py&quot;),
</span><span class="cx">                 &quot;lingeringClose&quot;, str(self.port), self.type)
</span><span class="lines">@@ -1215,15 +1312,20 @@
</span><span class="cx">             utils.getProcessOutputAndValue(sys.executable, args=args,
</span><span class="cx">                                            env=os.environ)
</span><span class="cx">         )
</span><del>-        yield d; out,err,code = d.getResult()
</del><ins>+        yield d
+        out, err, code = d.getResult()
</ins><span class="cx">         self.assertEquals(code, 0, &quot;Error output:\n%s&quot; % (err,))
</span><span class="cx">         self.assertEquals(out, &quot;HTTP/1.1 402 Payment Required\r\nContent-Length: 0\r\nConnection: close\r\n\r\n&quot;)
</span><span class="cx">     testLingeringClose = deferredGenerator(testLingeringClose)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TCPServerTest(unittest.TestCase, AbstractServerTestMixin):
</span><ins>+
</ins><span class="cx">     type = 'tcp'
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><del>-        factory=SimpleFactory(requestFactory=SimpleRequest)
</del><ins>+        factory = SimpleFactory(requestFactory=SimpleRequest)
</ins><span class="cx"> 
</span><span class="cx">         factory.testcase = self
</span><span class="cx">         self.factory = factory
</span><span class="lines">@@ -1232,6 +1334,7 @@
</span><span class="cx">         self.socket = reactor.listenTCP(0, factory)
</span><span class="cx">         self.port = self.socket.getHost().port
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def tearDown(self):
</span><span class="cx">         # Make sure the listening port is closed
</span><span class="cx">         d = defer.maybeDeferred(self.socket.stopListening)
</span><span class="lines">@@ -1260,7 +1363,7 @@
</span><span class="cx">     def setUp(self):
</span><span class="cx">         HTTPChannel.allowPersistentConnections = True
</span><span class="cx">         sCTX = ssl.DefaultOpenSSLContextFactory(certPath, certPath)
</span><del>-        factory=SimpleFactory(requestFactory=SimpleRequest)
</del><ins>+        factory = SimpleFactory(requestFactory=SimpleRequest)
</ins><span class="cx"> 
</span><span class="cx">         factory.testcase = self
</span><span class="cx">         self.factory = factory
</span><span class="lines">@@ -1269,6 +1372,7 @@
</span><span class="cx">         self.socket = reactor.listenSSL(0, factory, sCTX)
</span><span class="cx">         self.port = self.socket.getHost().port
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def tearDown(self):
</span><span class="cx">         # Make sure the listening port is closed
</span><span class="cx">         d = defer.maybeDeferred(self.socket.stopListening)
</span><span class="lines">@@ -1279,6 +1383,7 @@
</span><span class="cx">             return self.connlost
</span><span class="cx">         return d.addCallback(finish)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def testLingeringClose(self):
</span><span class="cx">         return super(SSLServerTest, self).testLingeringClose()
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_http_headerspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_http_headers.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_http_headers.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_http_headers.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx">              {'private': ['set-cookie', 'set-cookie2'],
</span><span class="cx">               'no-cache': ['proxy-authenticate']},
</span><span class="cx">              ['private=&quot;Set-Cookie, Set-Cookie2&quot;', 'no-cache=&quot;Proxy-Authenticate&quot;']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Cache-Control&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -252,7 +252,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;close&quot;, ['close', ]),
</span><span class="cx">             (&quot;close, foo-bar&quot;, ['close', 'foo-bar'])
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Connection&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -271,7 +271,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             ('chunked', ['chunked']),
</span><span class="cx">             ('gzip, chunked', ['gzip', 'chunked'])
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Transfer-Encoding&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> #     def testUpgrade(self):
</span><span class="lines">@@ -305,13 +305,13 @@
</span><span class="cx">               http_headers.MimeType('text', 'html', (('level', '1'),)): 1.0,
</span><span class="cx">               http_headers.MimeType('*', '*'): 1.0}),
</span><span class="cx"> 
</span><del>-       (&quot;text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5&quot;,
</del><ins>+            (&quot;text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5&quot;,
</ins><span class="cx">              {http_headers.MimeType('text', '*'): 0.3,
</span><span class="cx">               http_headers.MimeType('text', 'html'): 0.7,
</span><span class="cx">               http_headers.MimeType('text', 'html', (('level', '1'),)): 1.0,
</span><span class="cx">               http_headers.MimeType('text', 'html', (('level', '2'),)): 0.4,
</span><span class="cx">               http_headers.MimeType('*', '*'): 0.5}),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx"> 
</span><span class="cx">         self.runRoundtripTest(&quot;Accept&quot;, table)
</span><span class="cx"> 
</span><span class="lines">@@ -329,7 +329,7 @@
</span><span class="cx">             (&quot;&quot;,
</span><span class="cx">              {'iso-8859-1': 1.0},
</span><span class="cx">              [&quot;iso-8859-1&quot;]), # Yes this is an actual change -- we'll say that's okay. :)
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Accept-Charset&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -347,7 +347,7 @@
</span><span class="cx">             (&quot;gzip;q=1.0, identity;q=0.5, *;q=0&quot;,
</span><span class="cx">              {'gzip': 1.0, 'identity': 0.5, '*': 0},
</span><span class="cx">              [&quot;gzip&quot;, &quot;identity;q=0.5&quot;, &quot;*;q=0&quot;]),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Accept-Encoding&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -357,7 +357,7 @@
</span><span class="cx">              {'da': 1.0, 'en-gb': 0.8, 'en': 0.7}),
</span><span class="cx">             (&quot;*&quot;,
</span><span class="cx">              {'*': 1}),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Accept-Language&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -369,7 +369,7 @@
</span><span class="cx">             ('Digest nonce=&quot;bar&quot;, realm=&quot;foo&quot;, username=&quot;baz&quot;, response=&quot;bax&quot;',
</span><span class="cx">              ('digest', 'nonce=&quot;bar&quot;, realm=&quot;foo&quot;, username=&quot;baz&quot;, response=&quot;bax&quot;'),
</span><span class="cx">              ['digest', 'nonce=&quot;bar&quot;', 'realm=&quot;foo&quot;', 'username=&quot;baz&quot;', 'response=&quot;bax&quot;'])
</span><del>-            )
</del><ins>+        )
</ins><span class="cx"> 
</span><span class="cx">         self.runRoundtripTest(&quot;Authorization&quot;, table)
</span><span class="cx"> 
</span><span class="lines">@@ -381,10 +381,12 @@
</span><span class="cx">             ('name,&quot;blah=value,&quot;', [Cookie('name,&quot;blah', 'value,&quot;')]),
</span><span class="cx">             ('name,&quot;blah  = value,&quot;  ', [Cookie('name,&quot;blah', 'value,&quot;')], ['name,&quot;blah=value,&quot;']),
</span><span class="cx">             (&quot;`~!@#$%^&amp;*()-_+[{]}\\|:'\&quot;,&lt;.&gt;/?=`~!@#$%^&amp;*()-_+[{]}\\|:'\&quot;,&lt;.&gt;/?&quot;, [Cookie(&quot;`~!@#$%^&amp;*()-_+[{]}\\|:'\&quot;,&lt;.&gt;/?&quot;, &quot;`~!@#$%^&amp;*()-_+[{]}\\|:'\&quot;,&lt;.&gt;/?&quot;)]),
</span><del>-            ('name,&quot;blah  = value,&quot;  ; name2=val2',
-               [Cookie('name,&quot;blah', 'value,&quot;'), Cookie('name2', 'val2')],
-               ['name,&quot;blah=value,&quot;', 'name2=val2']),
-            )
</del><ins>+            (
+                'name,&quot;blah  = value,&quot;  ; name2=val2',
+                [Cookie('name,&quot;blah', 'value,&quot;'), Cookie('name2', 'val2')],
+                ['name,&quot;blah=value,&quot;', 'name2=val2']
+            ),
+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Cookie&quot;, table)
</span><span class="cx"> 
</span><span class="cx">         # newstyle RFC2965 Cookie
</span><span class="lines">@@ -399,7 +401,7 @@
</span><span class="cx">             ('$Version = 1, NAME = &quot;qq\\&quot;qq&quot;,Frob=boo',
</span><span class="cx">              [Cookie('name', 'qq&quot;qq', version=1), Cookie('frob', 'boo', version=1)],
</span><span class="cx">              ['$Version=&quot;1&quot;;name=&quot;qq\\&quot;qq&quot;;frob=&quot;boo&quot;']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Cookie&quot;, table2)
</span><span class="cx"> 
</span><span class="cx">         # Generate only!
</span><span class="lines">@@ -413,7 +415,7 @@
</span><span class="cx">              '$Version=&quot;1&quot;;name2=&quot;value2&quot;'),
</span><span class="cx">             ([Cookie('name', 'qq&quot;qq'), Cookie('name2', 'value2', version=1)],
</span><span class="cx">              '$Version=&quot;1&quot;;name=&quot;qq\\&quot;qq&quot;;name2=&quot;value2&quot;'),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         for row in table3:
</span><span class="cx">             self.assertEquals(generateHeader(&quot;Cookie&quot;, row[0]), [row[1], ])
</span><span class="cx"> 
</span><span class="lines">@@ -425,7 +427,7 @@
</span><span class="cx">             ('name,&quot;blah = value, ; expires=&quot;Sun, 09 Sep 2001 01:46:40 GMT&quot;',
</span><span class="cx">              [Cookie('name,&quot;blah', 'value,', expires=1000000000)],
</span><span class="cx">              ['name,&quot;blah=value,', 'expires=Sun, 09 Sep 2001 01:46:40 GMT']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Set-Cookie&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -433,7 +435,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             ('name=&quot;value&quot;; Comment=&quot;YadaYada&quot;; CommentURL=&quot;http://frobnotz/&quot;; Discard; Domain=&quot;blah.blah&quot;; Max-Age=10; Path=&quot;/foo&quot;; Port=&quot;80,8080&quot;; Secure; Version=&quot;1&quot;',
</span><span class="cx">              [Cookie(&quot;name&quot;, &quot;value&quot;, comment=&quot;YadaYada&quot;, commenturl=&quot;http://frobnotz/&quot;, discard=True, domain=&quot;blah.blah&quot;, expires=1000000000, path=&quot;/foo&quot;, ports=(80, 8080), secure=True, version=1)]),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Set-Cookie2&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -445,7 +447,7 @@
</span><span class="cx">              {'foobar': ('twiddle',)}),
</span><span class="cx">             (&quot;foo=bar;a=b;c&quot;,
</span><span class="cx">              {'foo': ('bar', ('a', 'b'), ('c', None))})
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Expect&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -457,7 +459,7 @@
</span><span class="cx">              [(&quot;return&quot;, &quot;representation&quot;, [])]),
</span><span class="cx">             (&quot;return =minimal;arg1;arg2=val2&quot;,
</span><span class="cx">              [(&quot;return&quot;, &quot;minimal&quot;, [(&quot;arg1&quot;, None), (&quot;arg2&quot;, &quot;val2&quot;)])]),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Prefer&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -473,10 +475,10 @@
</span><span class="cx">         table = (
</span><span class="cx">             ('&quot;xyzzy&quot;', [http_headers.ETag('xyzzy')]),
</span><span class="cx">             ('&quot;xyzzy&quot;, &quot;r2d2xxxx&quot;, &quot;c3piozzzz&quot;', [http_headers.ETag('xyzzy'),
</span><del>-                                                    http_headers.ETag('r2d2xxxx'),
-                                                    http_headers.ETag('c3piozzzz')]),
</del><ins>+                                                  http_headers.ETag('r2d2xxxx'),
+                                                  http_headers.ETag('c3piozzzz')]),
</ins><span class="cx">             ('*', ['*']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;If-Match&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -486,7 +488,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;Sun, 09 Sep 2001 01:46:40 GMT&quot;, 1000000000),
</span><span class="cx">             (&quot;Sun, 09 Sep 2001 01:46:40 GMT; length=500&quot;, 1000000000, [&quot;Sun, 09 Sep 2001 01:46:40 GMT&quot;]),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx"> 
</span><span class="cx">         self.runRoundtripTest(&quot;If-Modified-Since&quot;, table)
</span><span class="cx"> 
</span><span class="lines">@@ -501,7 +503,7 @@
</span><span class="cx">                                                         http_headers.ETag('r2d2xxxx', weak=True),
</span><span class="cx">                                                         http_headers.ETag('c3piozzzz', weak=True)]),
</span><span class="cx">             ('*', ['*']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;If-None-Match&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -511,7 +513,7 @@
</span><span class="cx">             ('W/&quot;xyzzy&quot;', http_headers.ETag('xyzzy', weak=True)),
</span><span class="cx">             ('W/&quot;xyzzy&quot;', http_headers.ETag('xyzzy', weak=True)),
</span><span class="cx">             (&quot;Sun, 09 Sep 2001 01:46:40 GMT&quot;, 1000000000),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;If-Range&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -534,7 +536,7 @@
</span><span class="cx">             (&quot;bytes=-500&quot;, ('bytes', [(None, 500), ])),
</span><span class="cx">             (&quot;bytes=9500-&quot;, ('bytes', [(9500, None), ])),
</span><span class="cx">             (&quot;bytes=0-0,-1&quot;, ('bytes', [(0, 0), (None, 1)])),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Range&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -548,7 +550,7 @@
</span><span class="cx">             (&quot;deflate&quot;, {'deflate': 1}),
</span><span class="cx">             (&quot;&quot;, {}),
</span><span class="cx">             (&quot;trailers, deflate;q=0.5&quot;, {'trailers': 1, 'deflate': 0.5}),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;TE&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -571,7 +573,7 @@
</span><span class="cx">             ('&quot;xyzzy&quot;', http_headers.ETag('xyzzy')),
</span><span class="cx">             ('W/&quot;xyzzy&quot;', http_headers.ETag('xyzzy', weak=True)),
</span><span class="cx">             ('&quot;&quot;', http_headers.ETag('')),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;ETag&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -589,7 +591,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;Sun, 09 Sep 2001 01:46:40 GMT&quot;, 1000000000, [&quot;10&quot;]),
</span><span class="cx">             (&quot;120&quot;, 999999990 + 120),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Retry-After&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -601,7 +603,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;*&quot;, [&quot;*&quot;]),
</span><span class="cx">             (&quot;Accept, Accept-Encoding&quot;, [&quot;accept&quot;, &quot;accept-encoding&quot;], [&quot;accept&quot;, &quot;accept-encoding&quot;])
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Vary&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -685,14 +687,14 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;GET&quot;, ['GET', ]),
</span><span class="cx">             (&quot;GET, HEAD, PUT&quot;, ['GET', 'HEAD', 'PUT']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Allow&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def testContentEncoding(self):
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;gzip&quot;, ['gzip', ]),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Content-Encoding&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -700,7 +702,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;da&quot;, ['da', ]),
</span><span class="cx">             (&quot;mi, en&quot;, ['mi', 'en']),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Content-Language&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -729,7 +731,7 @@
</span><span class="cx">             (&quot;bytes 734-1233/*&quot;, (&quot;bytes&quot;, 734, 1233, None)),
</span><span class="cx">             (&quot;bytes */1234&quot;, (&quot;bytes&quot;, None, None, 1234)),
</span><span class="cx">             (&quot;bytes */*&quot;, (&quot;bytes&quot;, None, None, None))
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Content-Range&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -737,7 +739,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;text/html;charset=iso-8859-4&quot;, http_headers.MimeType('text', 'html', (('charset', 'iso-8859-4'),))),
</span><span class="cx">             (&quot;text/html&quot;, http_headers.MimeType('text', 'html')),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Content-Type&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -745,7 +747,7 @@
</span><span class="cx">         table = (
</span><span class="cx">             (&quot;attachment;filename=foo.txt&quot;, http_headers.MimeDisposition('attachment', (('filename', 'foo.txt'),))),
</span><span class="cx">             (&quot;inline&quot;, http_headers.MimeDisposition('inline')),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         self.runRoundtripTest(&quot;Content-Disposition&quot;, table)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -837,12 +839,9 @@
</span><span class="cx">         &quot;&quot;&quot;Test that various uses of the constructer are equal
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        kwargMime = http_headers.MimeDisposition('attachment',
-                                          key='value')
-        dictMime = http_headers.MimeDisposition('attachment',
-                                         {'key': 'value'})
-        tupleMime = http_headers.MimeDisposition('attachment',
-                                          (('key', 'value'),))
</del><ins>+        kwargMime = http_headers.MimeDisposition('attachment', key='value')
+        dictMime = http_headers.MimeDisposition('attachment', {'key': 'value'})
+        tupleMime = http_headers.MimeDisposition('attachment', (('key', 'value'),))
</ins><span class="cx"> 
</span><span class="cx">         stringMime = http_headers.MimeDisposition.fromString('attachment;key=value')
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_httpauthpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_httpauth.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_httpauth.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_httpauth.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return nonce
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _fakeStaticTime():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Return a stable time
</span><span class="lines">@@ -77,8 +78,7 @@
</span><span class="cx">         Test acceptance of username/password in basic auth.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         response = base64.encodestring('%s:%s' % (
</span><del>-                self.username,
-                self.password))
</del><ins>+            self.username, self.password))
</ins><span class="cx"> 
</span><span class="cx">         d = self.credentialFactory.decode(response, _trivial_GET)
</span><span class="cx">         return d.addCallback(
</span><span class="lines">@@ -90,8 +90,7 @@
</span><span class="cx">         Incorrect passwords cause auth to fail.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         response = base64.encodestring('%s:%s' % (
</span><del>-                self.username,
-                'incorrectPassword'))
</del><ins>+            self.username, 'incorrectPassword'))
</ins><span class="cx"> 
</span><span class="cx">         d = self.credentialFactory.decode(response, _trivial_GET)
</span><span class="cx">         return d.addCallback(
</span><span class="lines">@@ -103,8 +102,7 @@
</span><span class="cx">         Responses that have incorrect padding cause auth to fail.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         response = base64.encodestring('%s:%s' % (
</span><del>-                self.username,
-                self.password))
</del><ins>+            self.username, self.password))
</ins><span class="cx"> 
</span><span class="cx">         response = response.strip('=')
</span><span class="cx"> 
</span><span class="lines">@@ -164,6 +162,7 @@
</span><span class="cx">         self.credentialFactory = digest.DigestCredentialFactory('md5',
</span><span class="cx">                                                                 'test realm')
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getDigestResponse(self, challenge, ncount):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Calculate the response for the given challenge
</span><span class="lines">@@ -180,9 +179,10 @@
</span><span class="cx">                            nonce,
</span><span class="cx">                            cnonce),
</span><span class="cx">             algo, nonce, ncount, cnonce, qop, &quot;GET&quot;, &quot;/write/&quot;, None
</span><del>-            )
</del><ins>+        )
</ins><span class="cx">         return expected
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_getChallenge(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that all the required fields exist in the challenge,
</span><span class="lines">@@ -194,8 +194,8 @@
</span><span class="cx">             self.assertEquals(challenge['qop'], 'auth')
</span><span class="cx">             self.assertEquals(challenge['realm'], 'test realm')
</span><span class="cx">             self.assertEquals(challenge['algorithm'], 'md5')
</span><del>-            self.assertTrue(challenge.has_key(&quot;nonce&quot;))
-            self.assertTrue(challenge.has_key(&quot;opaque&quot;))
</del><ins>+            self.assertTrue(&quot;nonce&quot; in challenge)
+            self.assertTrue(&quot;opaque&quot; in challenge)
</ins><span class="cx">         return d.addCallback(_test)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -266,6 +266,7 @@
</span><span class="cx">                               _trivial_GET)
</span><span class="cx">         self.assertEquals(str(e), &quot;Invalid response, no username given.&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_noNonce(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that login fails when our response does not contain a nonce
</span><span class="lines">@@ -277,6 +278,7 @@
</span><span class="cx">                               _trivial_GET)
</span><span class="cx">         self.assertEquals(str(e), &quot;Invalid response, no nonce given.&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_noOpaque(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that login fails when our response does not contain a nonce
</span><span class="lines">@@ -288,6 +290,7 @@
</span><span class="cx">                               _trivial_GET)
</span><span class="cx">         self.assertEquals(str(e), &quot;Invalid response, no opaque given.&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_checkHash(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Check that given a hash of the form 'username:realm:password'
</span><span class="lines">@@ -296,9 +299,9 @@
</span><span class="cx">         d = self._createAndDecodeChallenge()
</span><span class="cx">         def _test(creds):
</span><span class="cx">             self.failUnless(creds.checkHash(
</span><del>-                    md5('username:test realm:password').hexdigest()))
</del><ins>+                md5('username:test realm:password').hexdigest()))
</ins><span class="cx">             self.failIf(creds.checkHash(
</span><del>-                    md5('username:test realm:bogus').hexdigest()))
</del><ins>+                md5('username:test realm:bogus').hexdigest()))
</ins><span class="cx">         return d.addCallback(_test)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -319,7 +322,7 @@
</span><span class="cx">                 clientAddress.host)
</span><span class="cx"> 
</span><span class="cx">             badOpaque = ('foo-%s' % (
</span><del>-                    'nonce,clientip'.encode('base64').strip('\n'),))
</del><ins>+                'nonce,clientip'.encode('base64').strip('\n'),))
</ins><span class="cx"> 
</span><span class="cx">             self.assertRaises(
</span><span class="cx">                 error.LoginFailed,
</span><span class="lines">@@ -454,7 +457,7 @@
</span><span class="cx">             (&quot;user&quot;, &quot;realm&quot;, &quot;password&quot;, &quot;preHA1&quot;),
</span><span class="cx">             (None, &quot;realm&quot;, None, &quot;preHA1&quot;),
</span><span class="cx">             (None, None, &quot;password&quot;, &quot;preHA1&quot;),
</span><del>-            )
</del><ins>+        )
</ins><span class="cx"> 
</span><span class="cx">         for pszUsername, pszRealm, pszPassword, preHA1 in arguments:
</span><span class="cx">             self.assertRaises(
</span><span class="lines">@@ -467,7 +470,7 @@
</span><span class="cx">                 &quot;nonce&quot;,
</span><span class="cx">                 &quot;cnonce&quot;,
</span><span class="cx">                 preHA1=preHA1
</span><del>-                )
</del><ins>+            )
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_noNewlineOpaque(self):
</span><span class="lines">@@ -500,6 +503,7 @@
</span><span class="cx">         self.username = username
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TestAuthRealm(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test realm that supports the IHTTPUser interface
</span><span class="lines">@@ -517,6 +521,7 @@
</span><span class="cx">         raise NotImplementedError(&quot;Only IHTTPUser interface is supported&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ProtectedResource(test_server.BaseTestResource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A test resource for use with HTTPAuthWrapper that holds on to it's
</span><span class="lines">@@ -531,11 +536,13 @@
</span><span class="cx">         self.request = req
</span><span class="cx">         return super(ProtectedResource, self).render(req)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def locateChild(self, req, segments):
</span><span class="cx">         self.segments = segments
</span><span class="cx">         return super(ProtectedResource, self).locateChild(req, segments)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class NonAnonymousResource(test_server.BaseTestResource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A resource that forces authentication by raising an
</span><span class="lines">@@ -558,6 +565,7 @@
</span><span class="cx">             return super(NonAnonymousResource, self).render(req)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class HTTPAuthResourceTest(test_server.BaseCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Tests for the HTTPAuthWrapper Resource
</span><span class="lines">@@ -580,6 +588,7 @@
</span><span class="cx">         self.protectedResource = ProtectedResource()
</span><span class="cx">         self.protectedResource.responseText = &quot;You shouldn't see me.&quot;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def tearDown(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Clean up by getting rid of the portal, credentialFactory, and
</span><span class="lines">@@ -589,6 +598,7 @@
</span><span class="cx">         del self.credFactory
</span><span class="cx">         del self.protectedResource
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_authenticatedRequest(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that after successful authentication the request provides
</span><span class="lines">@@ -627,6 +637,7 @@
</span><span class="cx">         d.addCallback(checkRequest)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_allowedMethods(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that unknown methods result in a 401 instead of a 405 when
</span><span class="lines">@@ -650,6 +661,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_unauthorizedResponse(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that a request with no credentials results in a
</span><span class="lines">@@ -678,6 +690,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d.addCallback(makeDeepRequest)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_badCredentials(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that a request with bad credentials results in a valid
</span><span class="lines">@@ -700,6 +713,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_successfulLogin(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that a request with good credentials results in the
</span><span class="lines">@@ -721,6 +735,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_wrongScheme(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that a request with credentials for a scheme that is not
</span><span class="lines">@@ -743,6 +758,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_multipleWWWAuthenticateSchemes(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that our unauthorized response can contain challenges for
</span><span class="lines">@@ -764,6 +780,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_authorizationAgainstMultipleSchemes(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that we can successfully authenticate when presented
</span><span class="lines">@@ -774,7 +791,7 @@
</span><span class="cx">             self.protectedResource,
</span><span class="cx">             (basic.BasicCredentialFactory('test realm'),
</span><span class="cx">              FakeDigestCredentialFactory('md5', 'test realm')),
</span><del>-                                        self.portal,
</del><ins>+            self.portal,
</ins><span class="cx">             interfaces=(IHTTPUser,))
</span><span class="cx"> 
</span><span class="cx">         def respondBasic(ign):
</span><span class="lines">@@ -782,9 +799,8 @@
</span><span class="cx"> 
</span><span class="cx">             d = self.assertResponse((root, 'http://localhost/',
</span><span class="cx">                                      {'authorization':
</span><del>-                                        ('basic', credentials)}),
-                                    (200,
-                                     {}, None))
</del><ins>+                                      ('basic', credentials)}),
+                                    (200, {}, None))
</ins><span class="cx"> 
</span><span class="cx">             return d
</span><span class="cx"> 
</span><span class="lines">@@ -805,6 +821,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_wrappedResourceGetsFullSegments(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that the wrapped resource gets all the URL segments in it's
</span><span class="lines">@@ -833,6 +850,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_invalidCredentials(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Malformed or otherwise invalid credentials (as determined by
</span><span class="lines">@@ -854,6 +872,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_anonymousAuthentication(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         If our portal has a credentials checker for IAnonymous credentials
</span><span class="lines">@@ -883,10 +902,11 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_forceAuthentication(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that if an HTTPError with an Unauthorized status code is raised
</span><del>-        from within our protected resource, we add the WWW-Authenticate 
</del><ins>+        from within our protected resource, we add the WWW-Authenticate
</ins><span class="cx">         headers if they do not already exist.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.portal.registerChecker(checkers.AllowAnonymousAccess())
</span><span class="lines">@@ -897,7 +917,7 @@
</span><span class="cx">         root = wrapper.HTTPAuthResource(nonAnonResource,
</span><span class="cx">                                         [self.credFactory],
</span><span class="cx">                                         self.portal,
</span><del>-                                        interfaces = (IHTTPUser,))
</del><ins>+                                        interfaces=(IHTTPUser,))
</ins><span class="cx"> 
</span><span class="cx">         def _tryAuthenticate(result):
</span><span class="cx">             credentials = base64.encodestring('username:password')
</span><span class="lines">@@ -923,6 +943,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_responseFilterDoesntClobberHeaders(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that if an UNAUTHORIZED response is returned and
</span><span class="lines">@@ -937,7 +958,7 @@
</span><span class="cx">         root = wrapper.HTTPAuthResource(nonAnonResource,
</span><span class="cx">                                         [self.credFactory],
</span><span class="cx">                                         self.portal,
</span><del>-                                        interfaces = (IHTTPUser,))
</del><ins>+                                        interfaces=(IHTTPUser,))
</ins><span class="cx"> 
</span><span class="cx">         d = self.assertResponse(
</span><span class="cx">             (root, 'http://localhost/',
</span><span class="lines">@@ -949,6 +970,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_renderHTTP(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test that if the renderHTTP method is ever called we authenticate
</span><span class="lines">@@ -960,7 +982,7 @@
</span><span class="cx">         root = wrapper.HTTPAuthResource(self.protectedResource,
</span><span class="cx">                                         [self.credFactory],
</span><span class="cx">                                         self.portal,
</span><del>-                                        interfaces = (IHTTPUser,))
</del><ins>+                                        interfaces=(IHTTPUser,))
</ins><span class="cx"> 
</span><span class="cx">         request = SimpleRequest(None, &quot;GET&quot;, &quot;/&quot;)
</span><span class="cx">         request.prepath = ['']
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_logpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_log.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_log.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_log.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -16,6 +16,8 @@
</span><span class="cx">     def logMessage(self, message):
</span><span class="cx">         self.messages.append(message)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class SetDateWrapperResource(WrapperResource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A resource wrapper which sets the date header.
</span><span class="lines">@@ -28,6 +30,8 @@
</span><span class="cx"> 
</span><span class="cx">         req.addResponseFilter(_filter, atEnd=True)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class NoneStreamResource(Resource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A basic empty resource.
</span><span class="lines">@@ -35,6 +39,8 @@
</span><span class="cx">     def render(self, req):
</span><span class="cx">         return Response(200)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TestLogging(BaseCase):
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.patch(theLogPublisher, &quot;observers&quot;, [])
</span><span class="lines">@@ -47,6 +53,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.root = SetDateWrapperResource(LogWrapperResource(self.resrc))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertLogged(self, **expected):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Check that logged messages matches expected format.
</span><span class="lines">@@ -84,6 +91,7 @@
</span><span class="cx">         else:
</span><span class="cx">             self.assertEquals(len(messages), 0, &quot;len(%r) != 0&quot; % (messages, ))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_logSimpleRequest(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Check the log for a simple request.
</span><span class="lines">@@ -100,6 +108,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_logErrors(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test the error log.
</span><span class="lines">@@ -130,6 +139,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_logNoneResponseStream(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test the log of an empty resource.
</span><span class="lines">@@ -145,4 +155,3 @@
</span><span class="cx">         d.addCallback(_cbCheckLog)
</span><span class="cx"> 
</span><span class="cx">         return d
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_resource.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_resource.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_resource.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -22,6 +22,8 @@
</span><span class="cx"> class PreconditionError (Exception):
</span><span class="cx">     &quot;Precondition Failure&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TestResource (RenderMixin):
</span><span class="cx">     implements(IResource)
</span><span class="cx"> 
</span><span class="lines">@@ -38,12 +40,15 @@
</span><span class="cx">     def preconditions_BLEARGH(self, request):
</span><span class="cx">         raise PreconditionError()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def precondition_HUCKHUCKBLORP(self, request):
</span><span class="cx">         return fail(None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def preconditions_SWEETHOOKUPS(self, request):
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def preconditions_HOOKUPS(self, request):
</span><span class="cx">         return succeed(None)
</span><span class="cx"> 
</span><span class="lines">@@ -54,11 +59,15 @@
</span><span class="cx">         response.stream = MemoryStream(self.renderOutput)
</span><span class="cx">         return response
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> def generateResponse(method):
</span><span class="cx">     resource = TestResource()
</span><span class="cx">     method = getattr(resource, &quot;http_&quot; + method)
</span><span class="cx">     return method(SimpleRequest(Site(resource), method, &quot;/&quot;))
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class RenderMixInTestCase (unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test RenderMixin.
</span><span class="lines">@@ -130,6 +139,7 @@
</span><span class="cx">         d = resource.renderHTTP(request)
</span><span class="cx">         d.addCallback(checkResponse)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_OPTIONS_status(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         RenderMixin.http_OPTIONS()
</span><span class="lines">@@ -138,6 +148,7 @@
</span><span class="cx">         response = generateResponse(&quot;OPTIONS&quot;)
</span><span class="cx">         self.assertEquals(response.code, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_OPTIONS_allow(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         RenderMixin.http_OPTIONS()
</span><span class="lines">@@ -149,6 +160,7 @@
</span><span class="cx">             self._my_allowed_methods
</span><span class="cx">         )
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_TRACE_status(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         RenderMixin.http_TRACE()
</span><span class="lines">@@ -177,6 +189,7 @@
</span><span class="cx">         response = generateResponse(&quot;HEAD&quot;)
</span><span class="cx">         self.assertEquals(response.code, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_HEAD_body(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         RenderMixin.http_HEAD()
</span><span class="lines">@@ -198,6 +211,7 @@
</span><span class="cx">         response = generateResponse(&quot;GET&quot;)
</span><span class="cx">         self.assertEquals(response.code, responsecode.OK)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_GET_body(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         RenderMixin.http_GET()
</span><span class="lines">@@ -209,6 +223,8 @@
</span><span class="cx">             TestResource.renderOutput
</span><span class="cx">         )
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class ResourceTestCase (unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test Resource.
</span><span class="lines">@@ -226,6 +242,8 @@
</span><span class="cx">         raise NotImplementedError()
</span><span class="cx">     test_child_nonsense.todo = &quot;Someone should write this test&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class PostableResourceTestCase (unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test PostableResource.
</span><span class="lines">@@ -234,6 +252,8 @@
</span><span class="cx">         raise NotImplementedError()
</span><span class="cx">     test_POST.todo = &quot;Someone should write this test&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class LeafResourceTestCase (unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test LeafResource.
</span><span class="lines">@@ -249,6 +269,8 @@
</span><span class="cx">         self.assertEquals(child, resource)
</span><span class="cx">         self.assertEquals(segments, StopTraversal)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class WrapperResourceTestCase (unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test WrapperResource.
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_serverpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_server.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_server.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_server.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> @implementer(iweb.IResource)
</span><span class="cx"> class ResourceAdapter(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="lines">@@ -56,6 +57,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> @implementer(iweb.IOldNevowResource)
</span><span class="cx"> class OldResourceAdapter(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="lines">@@ -99,7 +101,8 @@
</span><span class="cx">         IResource returns the same object.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @implementer(iweb.IResource)
</span><del>-        class Resource(object): &quot;&quot;
</del><ins>+        class Resource(object):
+            &quot;&quot;
</ins><span class="cx">         resource = Resource()
</span><span class="cx">         self.assertIdentical(iweb.IResource(resource), resource)
</span><span class="cx"> 
</span><span class="lines">@@ -123,7 +126,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, site, method, prepath, uri, length=None,
</span><del>-                 headers=None, version=(1,1), content=None):
</del><ins>+                 headers=None, version=(1, 1), content=None):
</ins><span class="cx">         self.producer = None
</span><span class="cx">         self.site = site
</span><span class="cx">         self.method = method
</span><span class="lines">@@ -152,39 +155,49 @@
</span><span class="cx">         self.data = ''
</span><span class="cx">         self.deferredFinish = defer.Deferred()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeIntermediateResponse(code, headers=None):
</span><span class="cx">         pass
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def writeHeaders(self, code, headers):
</span><span class="cx">         self.responseHeaders = headers
</span><span class="cx">         self.code = code
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def write(self, data):
</span><span class="cx">         self.data += data
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def finish(self, failed=False):
</span><span class="cx">         result = self.code, self.responseHeaders, self.data, failed
</span><span class="cx">         self.finished = True
</span><span class="cx">         self.deferredFinish.callback(result)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def abortConnection(self):
</span><span class="cx">         self.finish(failed=True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def registerProducer(self, producer, streaming):
</span><span class="cx">         if self.producer is not None:
</span><span class="cx">             raise ValueError(&quot;Producer still set: &quot; + repr(self.producer))
</span><span class="cx">         self.producer = producer
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def unregisterProducer(self):
</span><span class="cx">         self.producer = None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getHostInfo(self):
</span><span class="cx">         return self.hostInfo
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getRemoteHost(self):
</span><span class="cx">         return self.remoteHost
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class BaseTestResource(resource.Resource):
</span><span class="cx">     responseCode = 200
</span><span class="cx">     responseText = 'This is a fake resource.'
</span><span class="lines">@@ -199,18 +212,22 @@
</span><span class="cx">         for i in children:
</span><span class="cx">             self.putChild(i[0], i[1])
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, req):
</span><span class="cx">         return http.Response(self.responseCode, headers=self.responseHeaders,
</span><span class="cx">                              stream=self.responseStream())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def responseStream(self):
</span><span class="cx">         return stream.MemoryStream(self.responseText)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class MyRenderError(Exception):
</span><span class="cx">     &quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ErrorWithProducerResource(BaseTestResource):
</span><span class="cx"> 
</span><span class="cx">     addSlash = True
</span><span class="lines">@@ -225,7 +242,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> _unset = object()
</span><span class="cx"> class BaseCase(unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="lines">@@ -241,6 +257,7 @@
</span><span class="cx">         site = server.Site(root)
</span><span class="cx">         return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def getResponseFor(self, root, uri, headers={},
</span><span class="cx">                        method=None, version=None, prepath='', content=None, length=_unset):
</span><span class="cx">         if not isinstance(headers, http_headers.Headers):
</span><span class="lines">@@ -260,6 +277,7 @@
</span><span class="cx">         cr.request.process()
</span><span class="cx">         return cr.deferredFinish
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertResponse(self, request_data, expected_response, failure=False):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @type request_data: C{tuple}
</span><span class="lines">@@ -276,6 +294,7 @@
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _cbGotResponse(self, (code, headers, data, failed), expected_response, expectedfailure=False):
</span><span class="cx">         expected_code, expected_headers, expected_data = expected_response
</span><span class="cx">         self.assertEquals(code, expected_code)
</span><span class="lines">@@ -286,6 +305,7 @@
</span><span class="cx">         self.assertEquals(failed, expectedfailure)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ErrorHandlingTest(BaseCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Tests for error handling.
</span><span class="lines">@@ -299,10 +319,10 @@
</span><span class="cx">         root = ErrorWithProducerResource()
</span><span class="cx">         site = server.Site(root)
</span><span class="cx">         tcr = TestChanRequest(site, &quot;GET&quot;, &quot;/&quot;, &quot;http://localhost/&quot;)
</span><del>-        request = server.Request(tcr, &quot;GET&quot;, &quot;/&quot;, (1, 1),
-                                 0, http_headers.Headers(
-                                        {&quot;host&quot;: &quot;localhost&quot;}),
-                                        site=site)
</del><ins>+        request = server.Request(
+            tcr, &quot;GET&quot;, &quot;/&quot;, (1, 1),
+            0, http_headers.Headers({&quot;host&quot;: &quot;localhost&quot;}),
+            site=site)
</ins><span class="cx">         proc = request.process()
</span><span class="cx">         done = []
</span><span class="cx">         proc.addBoth(done.append)
</span><span class="lines">@@ -336,40 +356,47 @@
</span><span class="cx">             f.responseText = 'Remote Addr: %r' % req.remoteAddr.host
</span><span class="cx">             return f
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         self.root = self.SampleTestResource()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_root(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host/'),
</span><span class="cx">             (200, {}, 'This is a fake resource.'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_validChild(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host/validChild'),
</span><span class="cx">             (200, {}, 'This is a valid child resource.'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_invalidChild(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host/invalidChild'),
</span><span class="cx">             (404, {}, None))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_remoteAddrExposure(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host/remoteAddr'),
</span><span class="cx">             (200, {}, &quot;Remote Addr: 'remotehost'&quot;))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_leafresource(self):
</span><span class="cx">         class TestResource(resource.LeafResource):
</span><span class="cx">             def render(self, req):
</span><span class="cx">                 return http.Response(stream=&quot;prepath:%s postpath:%s&quot; % (
</span><del>-                        req.prepath,
-                        req.postpath))
</del><ins>+                    req.prepath,
+                    req.postpath))
</ins><span class="cx"> 
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (TestResource(), 'http://host/consumed/path/segments'),
</span><span class="cx">             (200, {}, &quot;prepath:[] postpath:['consumed', 'path', 'segments']&quot;))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_redirectResource(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure a redirect response has the correct status and Location header.
</span><span class="lines">@@ -384,6 +411,7 @@
</span><span class="cx">             (redirectResource, 'http://localhost/'),
</span><span class="cx">             (301, {'location': 'https://localhost/foo?bar=baz'}, None))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_redirectResourceWithSchemeRemapping(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure a redirect response has the correct status and Location header, when
</span><span class="lines">@@ -396,7 +424,7 @@
</span><span class="cx">             site.SSLPort = 8443
</span><span class="cx">             site.BindSSLPorts = []
</span><span class="cx">             return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
</span><del>-    
</del><ins>+
</ins><span class="cx">         self.patch(self, &quot;chanrequest&quot;, chanrequest2)
</span><span class="cx"> 
</span><span class="cx">         redirectResource = resource.RedirectResource(path='/foo')
</span><span class="lines">@@ -405,6 +433,7 @@
</span><span class="cx">             (redirectResource, 'http://localhost:8443/'),
</span><span class="cx">             (301, {'location': 'https://localhost:8443/foo'}, None))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_redirectResourceWithoutSchemeRemapping(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure a redirect response has the correct status and Location header, when
</span><span class="lines">@@ -417,7 +446,7 @@
</span><span class="cx">             site.SSLPort = 8443
</span><span class="cx">             site.BindSSLPorts = []
</span><span class="cx">             return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
</span><del>-    
</del><ins>+
</ins><span class="cx">         self.patch(self, &quot;chanrequest&quot;, chanrequest2)
</span><span class="cx"> 
</span><span class="cx">         redirectResource = resource.RedirectResource(path='/foo')
</span><span class="lines">@@ -426,6 +455,7 @@
</span><span class="cx">             (redirectResource, 'http://localhost:8008/'),
</span><span class="cx">             (301, {'location': 'http://localhost:8008/foo'}, None))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_redirectResourceWithoutSSLSchemeRemapping(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure a redirect response has the correct status and Location header, when
</span><span class="lines">@@ -438,7 +468,7 @@
</span><span class="cx">             site.SSLPort = 8443
</span><span class="cx">             site.BindSSLPorts = []
</span><span class="cx">             return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
</span><del>-    
</del><ins>+
</ins><span class="cx">         self.patch(self, &quot;chanrequest&quot;, chanrequest2)
</span><span class="cx"> 
</span><span class="cx">         redirectResource = resource.RedirectResource(path='/foo')
</span><span class="lines">@@ -448,30 +478,36 @@
</span><span class="cx">             (301, {'location': 'http://localhost:8443/foo'}, None))
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class URLParsingTest(BaseCase):
</span><span class="cx">     class TestResource(resource.LeafResource):
</span><span class="cx">         def render(self, req):
</span><del>-            return http.Response(stream=&quot;Host:%s, Path:%s&quot;%(req.host, req.path))
</del><ins>+            return http.Response(stream=&quot;Host:%s, Path:%s&quot; % (req.host, req.path))
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         self.root = self.TestResource()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_normal(self):
</span><span class="cx">         return self.assertResponse(
</span><del>-            (self.root, '/path', {'Host':'host'}),
</del><ins>+            (self.root, '/path', {'Host': 'host'}),
</ins><span class="cx">             (200, {}, 'Host:host, Path:/path'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_fullurl(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host/path'),
</span><span class="cx">             (200, {}, 'Host:host, Path:/path'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_strangepath(self):
</span><span class="cx">         # Ensure that the double slashes don't confuse it
</span><span class="cx">         return self.assertResponse(
</span><del>-            (self.root, '//path', {'Host':'host'}),
</del><ins>+            (self.root, '//path', {'Host': 'host'}),
</ins><span class="cx">             (200, {}, 'Host:host, Path://path'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_strangepathfull(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.root, 'http://host//path'),
</span><span class="lines">@@ -481,7 +517,7 @@
</span><span class="cx"> 
</span><span class="cx"> class TestDeferredRendering(BaseCase):
</span><span class="cx">     class ResourceWithDeferreds(BaseTestResource):
</span><del>-        addSlash=True
</del><ins>+        addSlash = True
</ins><span class="cx">         responseText = 'I should be wrapped in a Deferred.'
</span><span class="cx">         def render(self, req):
</span><span class="cx">             d = defer.Deferred()
</span><span class="lines">@@ -494,11 +530,13 @@
</span><span class="cx">             reactor.callLater(0, d.callback, BaseTestResource())
</span><span class="cx">             return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_deferredRootResource(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.ResourceWithDeferreds(), 'http://host/'),
</span><span class="cx">             (200, {}, 'I should be wrapped in a Deferred.'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_deferredChild(self):
</span><span class="cx">         return self.assertResponse(
</span><span class="cx">             (self.ResourceWithDeferreds(), 'http://host/deferred'),
</span><span class="lines">@@ -521,6 +559,7 @@
</span><span class="cx">             ))
</span><span class="cx">         return defer.DeferredList(ds, fireOnOneErrback=True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_hostRedirect(self):
</span><span class="cx">         ds = []
</span><span class="cx">         for url1, url2 in (
</span><span class="lines">@@ -533,6 +572,7 @@
</span><span class="cx">             ))
</span><span class="cx">         return defer.DeferredList(ds, fireOnOneErrback=True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_pathRedirect(self):
</span><span class="cx">         root = BaseTestResource()
</span><span class="cx">         redirect = resource.RedirectResource(path=&quot;/other&quot;)
</span><span class="lines">@@ -555,6 +595,7 @@
</span><span class="cx">     def __init__(self, test):
</span><span class="cx">         self.test = test
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def render(self, request):
</span><span class="cx">         self.test.assertEquals(request.urlForResource(self), self.expectedURI)
</span><span class="cx">         return 201
</span><span class="lines">@@ -589,12 +630,13 @@
</span><span class="cx"> 
</span><span class="cx">         for uri in (foo.expectedURI, bar.expectedURI, baz.expectedURI):
</span><span class="cx">             ds.append(self.assertResponse(
</span><del>-                (root, uri, {'Host':'host'}),
</del><ins>+                (root, uri, {'Host': 'host'}),
</ins><span class="cx">                 (201, {}, None),
</span><span class="cx">             ))
</span><span class="cx"> 
</span><span class="cx">         return defer.DeferredList(ds, fireOnOneErrback=True)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_urlEncoding(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test to make sure that URL encoding is working.
</span><span class="lines">@@ -608,10 +650,11 @@
</span><span class="cx">         root.putChild(&quot;foo bar&quot;, child)
</span><span class="cx"> 
</span><span class="cx">         return self.assertResponse(
</span><del>-            (root, child.expectedURI, {'Host':'host'}),
</del><ins>+            (root, child.expectedURI, {'Host': 'host'}),
</ins><span class="cx">             (201, {}, None)
</span><span class="cx">         )
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_locateResource(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test urlForResource() on resource looked up via a locateResource() call.
</span><span class="lines">@@ -629,6 +672,7 @@
</span><span class="cx">         d.addCallback(gotResource)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_unknownResource(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test urlForResource() on unknown resource.
</span><span class="lines">@@ -639,6 +683,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertRaises(server.NoURLForResourceError, request.urlForResource, child)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_locateChildResource(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test urlForResource() on deeply nested resource looked up via
</span><span class="lines">@@ -677,6 +722,7 @@
</span><span class="cx">         d.addCallback(gotResource)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_deferredLocateChild(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test deferred value from locateChild()
</span><span class="lines">@@ -742,11 +788,13 @@
</span><span class="cx">         ctype = http_headers.MimeType('application', 'x-www-form-urlencoded')
</span><span class="cx">         content = &quot;key=value&amp;multiple=two+words&amp;multiple=more%20words&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
</ins><span class="cx">         def cb(ign):
</span><span class="cx">             self.assertEquals(request.files, {})
</span><del>-            self.assertEquals(request.args,
</del><ins>+            self.assertEquals(
+                request.args,
</ins><span class="cx">                 {'multiple': ['two words', 'more words'], 'key': ['value']})
</span><span class="cx">         return server.parsePOSTData(request).addCallback(cb)
</span><span class="cx"> 
</span><span class="lines">@@ -758,7 +806,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data',
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;; filename=&quot;myfilename&quot;\r
</span><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="lines">@@ -766,13 +814,15 @@
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
</ins><span class="cx">         def cb(ign):
</span><span class="cx">             self.assertEquals(request.args, {})
</span><span class="cx">             self.assertEquals(request.files.keys(), ['FileNameOne'])
</span><del>-            self.assertEquals(request.files.values()[0][0][:2],
-                  ('myfilename', http_headers.MimeType('text', 'html', {})))
</del><ins>+            self.assertEquals(
+                request.files.values()[0][0][:2],
+                ('myfilename', http_headers.MimeType('text', 'html', {})))
</ins><span class="cx">             f = request.files.values()[0][0][2]
</span><span class="cx">             self.assertEquals(f.read(), &quot;my great content wooo&quot;)
</span><span class="cx">         return server.parsePOSTData(request).addCallback(cb)
</span><span class="lines">@@ -784,7 +834,7 @@
</span><span class="cx">         C{http.HTTPError}.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data')
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;; filename=&quot;myfilename&quot;\r
</span><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="lines">@@ -792,10 +842,10 @@
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
-        return self.assertFailure(server.parsePOSTData(request),
-            http.HTTPError)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
+        return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_wrongContentType(self):
</span><span class="lines">@@ -805,21 +855,21 @@
</span><span class="cx">         ctype = http_headers.MimeType('application', 'foobar')
</span><span class="cx">         content = &quot;key=value&amp;multiple=two+words&amp;multiple=more%20words&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
-        return self.assertFailure(server.parsePOSTData(request),
-            http.HTTPError)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
+        return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_mimeParsingError(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         A malformed content should result in a C{http.HTTPError}.
</span><del>-        
</del><ins>+
</ins><span class="cx">         The tested content has an invalid closing boundary.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data',
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;; filename=&quot;myfilename&quot;\r
</span><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="lines">@@ -827,10 +877,10 @@
</span><span class="cx"> -----weeoundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
-        return self.assertFailure(server.parsePOSTData(request),
-            http.HTTPError)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
+        return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_multipartMaxMem(self):
</span><span class="lines">@@ -840,7 +890,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data',
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;\r
</span><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="lines">@@ -849,12 +899,15 @@
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
</ins><span class="cx">         def cb(res):
</span><del>-            self.assertEquals(res.response.description,
</del><ins>+            self.assertEquals(
+                res.response.description,
</ins><span class="cx">                 &quot;Maximum length of 10 bytes exceeded.&quot;)
</span><del>-        return self.assertFailure(server.parsePOSTData(request, maxMem=10),
</del><ins>+        return self.assertFailure(
+            server.parsePOSTData(request, maxMem=10),
</ins><span class="cx">             http.HTTPError).addCallback(cb)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -865,7 +918,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data',
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;; filename=&quot;myfilename&quot;\r
</span><span class="cx"> Content-Type: text/html\r
</span><span class="cx"> \r
</span><span class="lines">@@ -874,12 +927,15 @@
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
</ins><span class="cx">         def cb(res):
</span><del>-            self.assertEquals(res.response.description,
</del><ins>+            self.assertEquals(
+                res.response.description,
</ins><span class="cx">                 &quot;Maximum length of 10 bytes exceeded.&quot;)
</span><del>-        return self.assertFailure(server.parsePOSTData(request, maxSize=10),
</del><ins>+        return self.assertFailure(
+            server.parsePOSTData(request, maxSize=10),
</ins><span class="cx">             http.HTTPError).addCallback(cb)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -911,12 +967,15 @@
</span><span class="cx"> -----xyz--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
</ins><span class="cx">         def cb(res):
</span><del>-            self.assertEquals(res.response.description,
</del><ins>+            self.assertEquals(
+                res.response.description,
</ins><span class="cx">                 &quot;Maximum number of fields 3 exceeded&quot;)
</span><del>-        return self.assertFailure(server.parsePOSTData(request, maxFields=3),
</del><ins>+        return self.assertFailure(
+            server.parsePOSTData(request, maxFields=3),
</ins><span class="cx">             http.HTTPError).addCallback(cb)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -929,13 +988,12 @@
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><span class="cx">         # XXX: maybe this is not a good example
</span><span class="cx">         # parseContentDispositionFormData could handle this problem
</span><del>-        content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        content = &quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;FileNameOne&quot;; filename=&quot;myfilename and invalid data \r
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         root = resource.Resource()
</span><del>-        request = SimpleRequest(server.Site(root), &quot;GET&quot;, &quot;/&quot;,
-                http_headers.Headers({'content-type': ctype}), content)
-        return self.assertFailure(server.parsePOSTData(request),
-            ValueError)
-
</del><ins>+        request = SimpleRequest(
+            server.Site(root), &quot;GET&quot;, &quot;/&quot;,
+            http_headers.Headers({'content-type': ctype}), content)
+        return self.assertFailure(server.parsePOSTData(request), ValueError)
</ins></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_staticpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_static.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_static.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_static.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -20,6 +20,7 @@
</span><span class="cx">         self.text = &quot;Hello, World\n&quot;
</span><span class="cx">         self.data = static.Data(self.text, &quot;text/plain&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_dataState(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test the internal state of the Data object
</span><span class="lines">@@ -67,11 +68,13 @@
</span><span class="cx">         self.tempdir = self.mktemp()
</span><span class="cx">         os.mkdir(self.tempdir)
</span><span class="cx"> 
</span><del>-        self.root = static.FileSaver(self.tempdir,
-                              expectedFields=['FileNameOne'],
-                              maxBytes=16)
</del><ins>+        self.root = static.FileSaver(
+            self.tempdir,
+            expectedFields=['FileNameOne'],
+            maxBytes=16)
</ins><span class="cx">         self.root.addSlash = True
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def uploadFile(self, fieldname, filename, mimetype, content, resrc=None,
</span><span class="cx">                    host='foo', path='/'):
</span><span class="cx">         if not resrc:
</span><span class="lines">@@ -80,12 +83,12 @@
</span><span class="cx">         ctype = http_headers.MimeType('multipart', 'form-data',
</span><span class="cx">                                       (('boundary', '---weeboundary'),))
</span><span class="cx"> 
</span><del>-        return self.getResponseFor(resrc, '/',
-                            headers={'host': 'foo',
-                                     'content-type': ctype },
-                            length=len(content),
-                            method='POST',
-                            content=&quot;&quot;&quot;-----weeboundary\r
</del><ins>+        return self.getResponseFor(
+            resrc, '/',
+            headers={'host': 'foo', 'content-type': ctype},
+            length=len(content),
+            method='POST',
+            content=&quot;&quot;&quot;-----weeboundary\r
</ins><span class="cx"> Content-Disposition: form-data; name=&quot;%s&quot;; filename=&quot;%s&quot;\r
</span><span class="cx"> Content-Type: %s\r
</span><span class="cx"> \r
</span><span class="lines">@@ -93,6 +96,7 @@
</span><span class="cx"> -----weeboundary--\r
</span><span class="cx"> &quot;&quot;&quot; % (fieldname, filename, mimetype, content))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _CbAssertInResponse(self, (code, headers, data, failed),
</span><span class="cx">                             expected_response, expectedFailure=False):
</span><span class="cx"> 
</span><span class="lines">@@ -107,36 +111,43 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEquals(failed, expectedFailure)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def fileNameFromResponse(self, response):
</span><del>-        (code, headers, data, failure) = response
-        return data[data.index('Saved file')+11:data.index('&lt;br /&gt;')]
</del><ins>+        (_ignore_code, _ignore_headers, data, _ignore_failure) = response
+        return data[data.index('Saved file') + 11:data.index('&lt;br /&gt;')]
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertInResponse(self, response, expected_response, failure=False):
</span><span class="cx">         d = response
</span><span class="cx">         d.addCallback(self._CbAssertInResponse, expected_response, failure)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_enforcesMaxBytes(self):
</span><span class="cx">         return self.assertInResponse(
</span><del>-            self.uploadFile('FileNameOne', 'myfilename', 'text/html', 'X'*32),
</del><ins>+            self.uploadFile('FileNameOne', 'myfilename', 'text/html', 'X' * 32),
</ins><span class="cx">             (200, {}, 'exceeds maximum length'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_enforcesMimeType(self):
</span><span class="cx">         return self.assertInResponse(
</span><span class="cx">             self.uploadFile('FileNameOne', 'myfilename',
</span><span class="cx">                             'application/x-python', 'X'),
</span><span class="cx">             (200, {}, 'type not allowed'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_invalidField(self):
</span><span class="cx">         return self.assertInResponse(
</span><span class="cx">             self.uploadFile('NotARealField', 'myfilename', 'text/html', 'X'),
</span><span class="cx">             (200, {}, 'not a valid field'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_reportFileSave(self):
</span><span class="cx">         return self.assertInResponse(
</span><span class="cx">             self.uploadFile('FileNameOne', 'myfilename', 'text/plain', 'X'),
</span><span class="cx">             (200, {}, 'Saved file'))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_compareFileContents(self):
</span><span class="cx">         def gotFname(fname):
</span><span class="cx">             contents = file(fname, 'rb').read()
</span></span></pre></div>
<a id="CalendarServertrunktxweb2testtest_streampy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/test/test_stream.py (14119 => 14120)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/test/test_stream.py        2014-10-29 02:35:02 UTC (rev 14119)
+++ CalendarServer/trunk/txweb2/test/test_stream.py        2014-10-29 16:28:01 UTC (rev 14120)
</span><span class="lines">@@ -5,7 +5,9 @@
</span><span class="cx"> Tests for the stream implementations in L{txweb2}.
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-import tempfile, sys, os
</del><ins>+import os
+import sys
+import tempfile
</ins><span class="cx"> 
</span><span class="cx"> from zope.interface import implements
</span><span class="cx"> 
</span><span class="lines">@@ -24,6 +26,7 @@
</span><span class="cx">         raise TypeError(&quot;%s doesn't conform to the buffer interface&quot; % (data,))
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class SimpleStreamTests:
</span><span class="cx">     text = '1234567890'
</span><span class="cx">     def test_split(self):
</span><span class="lines">@@ -48,6 +51,7 @@
</span><span class="cx">                 self.assertEquals(bufstr(b.read()), self.text[point + 2:8])
</span><span class="cx">             self.assertEquals(b.read(), None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_read(self):
</span><span class="cx">         s = self.makeStream()
</span><span class="cx">         self.assertEquals(s.length, len(self.text))
</span><span class="lines">@@ -66,10 +70,13 @@
</span><span class="cx">         self.assertEquals(s.read(), None)
</span><span class="cx">         self.assertEquals(s.length, 0)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class FileStreamTest(SimpleStreamTests, unittest.TestCase):
</span><span class="cx">     def makeStream(self, *args, **kw):
</span><span class="cx">         return stream.FileStream(self.f, *args, **kw)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Create a file containing C{self.text} to be streamed.
</span><span class="lines">@@ -79,6 +86,7 @@
</span><span class="cx">         f.seek(0, 0)
</span><span class="cx">         self.f = f
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_close(self):
</span><span class="cx">         s = self.makeStream()
</span><span class="cx">         s.close()
</span><span class="lines">@@ -88,6 +96,7 @@
</span><span class="cx">         # would raise exception if f is closed
</span><span class="cx">         self.f.seek(0, 0)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_read2(self):
</span><span class="cx">         s = self.makeStream(0)
</span><span class="cx">         s.CHUNK_SIZE = 6
</span><span class="lines">@@ -108,6 +117,8 @@
</span><span class="cx">         self.assertEquals(bufstr(s.read()), self.text)
</span><span class="cx">         self.assertRaises(RuntimeError, s.read) # ran out of data
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class MMapFileStreamTest(SimpleStreamTests, unittest.TestCase):
</span><span class="cx">     text = SimpleStreamTests.text
</span><span class="cx">     text = text * (stream.MMAP_THRESHOLD // len(text) + 1)
</span><span class="lines">@@ -115,6 +126,7 @@
</span><span class="cx">     def makeStream(self, *args, **kw):
</span><span class="cx">         return stream.FileStream(self.f, *args, **kw)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setUp(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Create a file containing C{self.text}, which should be long enough to
</span><span class="lines">@@ -125,6 +137,7 @@
</span><span class="cx">         f.seek(0, 0)
</span><span class="cx">         self.f = f
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_mmapwrapper(self):
</span><span class="cx">         self.assertRaises(TypeError, stream.mmapwrapper)
</span><span class="cx">         self.assertRaises(TypeError, stream.mmapwrapper, offset=0)
</span><span class="lines">@@ -133,15 +146,19 @@
</span><span class="cx">     if not stream.mmap:
</span><span class="cx">         test_mmapwrapper.skip = 'mmap not supported here'
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class MemoryStreamTest(SimpleStreamTests, unittest.TestCase):
</span><span class="cx">     def makeStream(self, *args, **kw):
</span><span class="cx">         return stream.MemoryStream(self.text, *args, **kw)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_close(self):
</span><span class="cx">         s = self.makeStream()
</span><span class="cx">         s.close()
</span><span class="cx">         self.assertEquals(s.length, 0)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_read2(self):
</span><span class="cx">         self.assertRaises(ValueError, self.makeStream, 0, 20)
</span><span class="cx"> 
</span><span class="lines">@@ -174,46 +191,54 @@
</span><span class="cx">         s = stream.MemoryStream(self.data)
</span><span class="cx">         self.s = stream.BufferedStream(s)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _cbGotData(self, data, expected):
</span><span class="cx">         self.assertEqual(data, expected)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readline(self):
</span><span class="cx">         &quot;&quot;&quot;Test that readline reads a line.&quot;&quot;&quot;
</span><span class="cx">         d = self.s.readline()
</span><span class="cx">         d.addCallback(self._cbGotData, 'I was angry with my friend:\r\n')
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineWithSize(self):
</span><span class="cx">         &quot;&quot;&quot;Test the size argument to readline&quot;&quot;&quot;
</span><span class="cx">         d = self.s.readline(size=5)
</span><span class="cx">         d.addCallback(self._cbGotData, 'I was')
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineWithBigSize(self):
</span><span class="cx">         &quot;&quot;&quot;Test the size argument when it's bigger than the length of the line.&quot;&quot;&quot;
</span><span class="cx">         d = self.s.readline(size=40)
</span><span class="cx">         d.addCallback(self._cbGotData, 'I was angry with my friend:\r\n')
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineWithZero(self):
</span><span class="cx">         &quot;&quot;&quot;Test readline with size = 0.&quot;&quot;&quot;
</span><span class="cx">         d = self.s.readline(size=0)
</span><span class="cx">         d.addCallback(self._cbGotData, '')
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineFinished(self):
</span><span class="cx">         &quot;&quot;&quot;Test readline on a finished stream.&quot;&quot;&quot;
</span><span class="cx">         nolines = len(self.data.split('\r\n'))
</span><del>-        for i in range(nolines):
</del><ins>+        for _ in range(nolines):
</ins><span class="cx">             self.s.readline()
</span><span class="cx">         d = self.s.readline()
</span><span class="cx">         d.addCallback(self._cbGotData, '')
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineNegSize(self):
</span><span class="cx">         &quot;&quot;&quot;Ensure that readline with a negative size raises an exception.&quot;&quot;&quot;
</span><span class="cx">         self.assertRaises(ValueError, self.s.readline, size=-1)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readlineSizeInDelimiter(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test behavior of readline when size falls inside the
</span><span class="lines">@@ -224,12 +249,14 @@
</span><span class="cx">         d.addCallback(lambda _: self.s.readline())
</span><span class="cx">         d.addCallback(self._cbGotData, &quot;\nI told my wrath, my wrath did end.\r\n&quot;)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readExactly(self):
</span><span class="cx">         &quot;&quot;&quot;Make sure readExactly with no arg reads all the data.&quot;&quot;&quot;
</span><span class="cx">         d = self.s.readExactly()
</span><span class="cx">         d.addCallback(self._cbGotData, self.data)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readExactlyLimited(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test readExactly with a number.
</span><span class="lines">@@ -238,6 +265,7 @@
</span><span class="cx">         d.addCallback(self._cbGotData, self.data[:10])
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readExactlyBig(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Test readExactly with a number larger than the size of the
</span><span class="lines">@@ -247,6 +275,7 @@
</span><span class="cx">         d.addCallback(self._cbGotData, self.data)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_read(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Make sure read() also functions. (note that this test uses
</span><span class="lines">@@ -255,6 +284,8 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.assertEqual(str(self.s.read()), self.data)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class TestStreamer:
</span><span class="cx">     implements(stream.IStream, stream.IByteStream)
</span><span class="cx"> 
</span><span class="lines">@@ -266,17 +297,22 @@
</span><span class="cx">     def __init__(self, list):
</span><span class="cx">         self.list = list
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         self.readCalled += 1
</span><span class="cx">         if self.list:
</span><span class="cx">             return self.list.pop(0)
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def close(self):
</span><span class="cx">         self.closeCalled += 1
</span><span class="cx">         self.list = []
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class FallbackSplitTest(unittest.TestCase):
</span><ins>+
</ins><span class="cx">     def test_split(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 5)
</span><span class="lines">@@ -287,6 +323,7 @@
</span><span class="cx">         d.addCallback(self._cbSplit, left, right)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _cbSplit(self, result, left, right):
</span><span class="cx">         self.assertEquals(bufstr(result), 'e')
</span><span class="cx">         self.assertEquals(left.read(), None)
</span><span class="lines">@@ -295,6 +332,7 @@
</span><span class="cx">         self.assertEquals(bufstr(right.read()), 'ijkl')
</span><span class="cx">         self.assertEquals(right.read(), None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_split2(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 4)
</span><span class="lines">@@ -309,6 +347,7 @@
</span><span class="cx">         self.assertEquals(bufstr(right.read()), 'ijkl')
</span><span class="cx">         self.assertEquals(right.read(), None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_splitsplit(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 5)
</span><span class="lines">@@ -329,6 +368,7 @@
</span><span class="cx">         self.assertEquals(bufstr(right.read()), 'ijkl')
</span><span class="cx">         self.assertEquals(right.read(), None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_closeboth(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 5)
</span><span class="lines">@@ -340,6 +380,7 @@
</span><span class="cx">         self.assertEquals(s.readCalled, 0)
</span><span class="cx">         self.assertEquals(s.closeCalled, 1)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_closeboth_rev(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 5)
</span><span class="lines">@@ -351,6 +392,7 @@
</span><span class="cx">         self.assertEquals(s.readCalled, 0)
</span><span class="cx">         self.assertEquals(s.closeCalled, 1)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_closeleft(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 5)
</span><span class="lines">@@ -359,11 +401,13 @@
</span><span class="cx">         d.addCallback(self._cbCloseleft, right)
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _cbCloseleft(self, result, right):
</span><span class="cx">         self.assertEquals(bufstr(result), 'fgh')
</span><span class="cx">         self.assertEquals(bufstr(right.read()), 'ijkl')
</span><span class="cx">         self.assertEquals(right.read(), None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_closeright(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         left, right = stream.fallbackSplit(s, 3)
</span><span class="lines">@@ -375,11 +419,13 @@
</span><span class="cx">         self.assertEquals(s.closeCalled, 1)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ProcessStreamerTest(unittest.TestCase):
</span><span class="cx"> 
</span><span class="cx">     if interfaces.IReactorProcess(reactor, None) is None:
</span><span class="cx">         skip = &quot;Platform lacks spawnProcess support, can't test process streaming.&quot;
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def runCode(self, code, inputStream=None):
</span><span class="cx">         if inputStream is None:
</span><span class="cx">             inputStream = stream.MemoryStream(&quot;&quot;)
</span><span class="lines">@@ -387,6 +433,7 @@
</span><span class="cx">                                       [sys.executable, &quot;-u&quot;, &quot;-c&quot;, code],
</span><span class="cx">                                       os.environ)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_output(self):
</span><span class="cx">         p = self.runCode(&quot;import sys\nfor i in range(100): sys.stdout.write('x' * 1000)&quot;)
</span><span class="cx">         l = []
</span><span class="lines">@@ -396,6 +443,7 @@
</span><span class="cx">         d2 = p.run()
</span><span class="cx">         return d.addCallback(verify).addCallback(lambda _: d2)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_errouput(self):
</span><span class="cx">         p = self.runCode(&quot;import sys\nfor i in range(100): sys.stderr.write('x' * 1000)&quot;)
</span><span class="cx">         l = []
</span><span class="lines">@@ -405,6 +453,7 @@
</span><span class="cx">         p.run()
</span><span class="cx">         return d.addCallback(verify)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_input(self):
</span><span class="cx">         p = self.runCode(&quot;import sys\nsys.stdout.write(sys.stdin.read())&quot;,
</span><span class="cx">                          &quot;hello world&quot;)
</span><span class="lines">@@ -416,6 +465,7 @@
</span><span class="cx">             return d2
</span><span class="cx">         return d.addCallback(verify)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_badexit(self):
</span><span class="cx">         p = self.runCode(&quot;raise ValueError&quot;)
</span><span class="cx">         l = []
</span><span class="lines">@@ -426,6 +476,7 @@
</span><span class="cx">             self.assert_(p.errStream.closed)
</span><span class="cx">         return p.run().addErrback(lambda _: _.trap(ProcessTerminated) and l.append(1)).addCallback(verify)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_inputerror(self):
</span><span class="cx">         p = self.runCode(&quot;import sys\nsys.stdout.write(sys.stdin.read())&quot;,
</span><span class="cx">                          TestStreamer([&quot;hello&quot;, defer.fail(ZeroDivisionError())]))
</span><span class="lines">@@ -440,6 +491,7 @@
</span><span class="cx">             self.assertEqual(len(excs), 1)
</span><span class="cx">         return d.addCallback(verify).addCallback(cbVerified)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_processclosedinput(self):
</span><span class="cx">         p = self.runCode(&quot;import sys; sys.stdout.write(sys.stdin.read(3));&quot; +
</span><span class="cx">                          &quot;sys.stdin.close(); sys.stdout.write('def')&quot;,
</span><span class="lines">@@ -452,6 +504,7 @@
</span><span class="cx">         return d.addCallback(verify).addCallback(lambda _: d2)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class AdapterTestCase(unittest.TestCase):
</span><span class="cx"> 
</span><span class="cx">     def test_adapt(self):
</span><span class="lines">@@ -465,14 +518,17 @@
</span><span class="cx">             self.assertEquals(s.read(), None)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ReadStreamTestCase(unittest.TestCase):
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_pull(self):
</span><span class="cx">         l = []
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         return stream.readStream(s, l.append).addCallback(
</span><span class="cx">             lambda _: self.assertEquals(l, [&quot;abcd&quot;, &quot;efgh&quot;, &quot;ijkl&quot;]))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_pullFailure(self):
</span><span class="cx">         l = []
</span><span class="cx">         s = TestStreamer(['abcd', defer.fail(RuntimeError()), 'ijkl'])
</span><span class="lines">@@ -481,12 +537,15 @@
</span><span class="cx">             self.assertEquals(l, [&quot;abcd&quot;])
</span><span class="cx">         return stream.readStream(s, l.append).addErrback(test)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_pullException(self):
</span><span class="cx">         class Failer:
</span><del>-            def read(self): raise RuntimeError
</del><ins>+            def read(self):
+                raise RuntimeError
</ins><span class="cx">         return stream.readStream(Failer(), lambda _: None).addErrback(
</span><span class="cx">             lambda _: _.trap(RuntimeError))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_processingException(self):
</span><span class="cx">         s = TestStreamer(['abcd', defer.succeed('efgh'), 'ijkl'])
</span><span class="cx">         return stream.readStream(s, lambda x: 1 / 0).addErrback(
</span><span class="lines">@@ -508,6 +567,7 @@
</span><span class="cx">         return d
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class CompoundStreamTest:
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     CompoundStream lets you combine many streams into one continuous stream.
</span><span class="lines">@@ -583,6 +643,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class AsynchronousDummyStream(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     An L{IByteStream} implementation which always returns a
</span><span class="lines">@@ -592,14 +653,18 @@
</span><span class="cx">     def __init__(self):
</span><span class="cx">         self._readResults = []
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def read(self):
</span><span class="cx">         result = defer.Deferred()
</span><span class="cx">         self._readResults.append(result)
</span><span class="cx">         return result
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _write(self, bytes):
</span><span class="cx">         self._readResults.pop(0).callback(bytes)
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class MD5StreamTest(unittest.TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Tests for L{stream.MD5Stream}.
</span><span class="lines">@@ -622,6 +687,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.assertEquals(self.digest, md5Stream.getMD5())
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_asynchronous(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{stream.MD5Stream} also supports L{IByteStream} providers which return
</span><span class="lines">@@ -648,6 +714,7 @@
</span><span class="cx"> 
</span><span class="cx">         return result
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_getMD5FailsBeforeClose(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{stream.MD5Stream.getMD5} raises L{RuntimeError} if called before
</span><span class="lines">@@ -657,6 +724,7 @@
</span><span class="cx">         md5Stream = stream.MD5Stream(dataStream)
</span><span class="cx">         self.assertRaises(RuntimeError, md5Stream.getMD5)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_initializationFailsWithoutStream(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{stream.MD5Stream.__init__} raises L{ValueError} if passed C{None} as
</span><span class="lines">@@ -664,6 +732,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.assertRaises(ValueError, stream.MD5Stream, None)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_readAfterClose(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         L{stream.MD5Stream.read} raises L{RuntimeError} if called after
</span></span></pre>
</div>
</div>

</body>
</html>