Do not reuse persistent connections for PUTs to avoid ERR_ZERO_SIZE_OBJECT.

A compliant proxy may retry PUTs, but Squid lacks the [rather complicated]
code required to protect the PUT request body from being nibbled during the
first try. Thus, Squid cannot safely retry some PUTs today, and
FwdState::checkRetriable() must return false for all PUTs, to avoid
bogus ERR_ZERO_SIZE_OBJECT errors (especially for clients that did not
reuse a pconn and, hence, may not be ready to handle/retry an error response).

In theory, requests with safe or idempotent methods other than PUT might have
bodies so we apply the same logic to them as well.

=== modified file 'src/forward.cc'
--- src/forward.cc	2012-08-23 00:01:00 +0000
+++ src/forward.cc	2012-08-29 18:10:42 +0000
@@ -459,60 +459,66 @@
  * Return TRUE if this is the kind of request that can be retried
  * after a failure.  If the request is not retriable then we don't
  * want to risk sending it on a persistent connection.  Instead we'll
  * force it to go on a new HTTP connection.
  */
 bool
 FwdState::checkRetriable()
 {
     /* RFC2616 9.1 Safe and Idempotent Methods */
     switch (request->method.id()) {
         /* 9.1.1 Safe Methods */
 
     case METHOD_GET:
 
     case METHOD_HEAD:
         /* 9.1.2 Idempotent Methods */
 
     case METHOD_PUT:
 
     case METHOD_DELETE:
 
     case METHOD_OPTIONS:
 
     case METHOD_TRACE:
         break;
 
     default:
         return false;
     }
 
+    // Optimize: A compliant proxy may retry PUTs, but Squid lacks the [rather
+    // complicated] code required to protect the PUT request body from being
+    // nibbled during the first try. Thus, Squid cannot retry some PUTs today.
+    if (request->body_pipe != NULL)
+        return false;
+
     return true;
 }
 
 void
 FwdState::serverClosed(int fd)
 {
     debugs(17, 2, "fwdServerClosed: FD " << fd << " " << entry->url());
     assert(server_fd == fd);
     server_fd = -1;
 
     retryOrBail();
 }
 
 void
 FwdState::retryOrBail()
 {
     if (checkRetry()) {
         int originserver = (servers->_peer == NULL);
         debugs(17, 3, "fwdServerClosed: re-forwarding (" << n_tries << " tries, " << (squid_curtime - start_t) << " secs)");
 
         if (servers->next) {
             /* use next, or cycle if origin server isn't last */
             FwdServer *fs = servers;
             FwdServer **T, *T2 = NULL;
             servers = fs->next;
 
             for (T = &servers; *T; T2 = *T, T = &(*T)->next);
             if (T2 && T2->_peer) {
                 /* cycle */
                 *T = fs;


