[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    =?utf-8?q?=5Bkdelibs=5D_kioslave/http=3A_Fixed_HTTP_PUT_operatio?=
From:       Dawit Alemayehu <adawit () kde ! org>
Date:       2011-02-23 17:59:43
Message-ID: 20110223175943.92179A609B () git ! kde ! org
[Download RAW message or body]

Git commit 22ff0c74fecccb981be99ec7ade69b7563cc4a2d by Dawit Alemayehu.
Committed on 23/02/2011 at 18:56.
Pushed by adawit into branch 'master'.

Fixed HTTP PUT operation that got broken as result of the recent changes done to improve POST operations

M  +50   -14   kioslave/http/http.cpp     
M  +5    -0    kioslave/http/http.h     

http://commits.kde.org/kdelibs/22ff0c74fecccb981be99ec7ade69b7563cc4a2d

diff --git a/kioslave/http/http.cpp b/kioslave/http/http.cpp
index 83431c1..c597050 100644
--- a/kioslave/http/http.cpp
+++ b/kioslave/http/http.cpp
@@ -3809,15 +3809,13 @@ void HTTPProtocol::setCacheabilityMetadata(bool cachingAllowed)
 
 bool HTTPProtocol::sendCachedBody()
 {
-  kDebug(7113) << "POST'ing cached data...";
-
   infoMessage(i18n("Sending data to %1" ,  m_request.url.host()));
 
   QByteArray cLength ("Content-Length: ");
   cLength += QByteArray::number(m_POSTbuf->size());
   cLength += "\r\n\r\n";
 
-  kDebug( 7113 ) << cLength.trimmed();
+  kDebug(7113) << "sending cached data (size=" << m_POSTbuf->size() << ")";
 
   // Send the content length...
   bool sendOk = (write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
@@ -3851,14 +3849,19 @@ bool HTTPProtocol::sendBody()
   // If we have cached data, the it is either a repost or a DAV request so send
   // the cached data...
   if (m_POSTbuf)
-     return sendCachedBody();
+    return sendCachedBody();
 
   if (m_iPostDataSize == NO_SIZE) {
-      error(ERR_POST_NO_SIZE, m_request.url.host());
-      return false;
+    // Try the old approach of retireving content data from the job
+    // before giving up.
+    if (retrieveAllData())
+      return sendCachedBody();
+
+    error(ERR_POST_NO_SIZE, m_request.url.host());
+    return false;
   }
 
-  kDebug(7113) << "POST'ing live data...";
+  kDebug(7113) << "sending data (size=" << m_iPostDataSize << ")";
 
   infoMessage(i18n("Sending data to %1",  m_request.url.host()));
 
@@ -3870,7 +3873,7 @@ bool HTTPProtocol::sendBody()
 
   // Send the content length...
   bool sendOk = (write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
-  if (!sendOk)  {
+  if (!sendOk) {
     kDebug(7113) << "Connection broken while sending POST content size to" << m_request.url.host();
     error( ERR_CONNECTION_BROKEN, m_request.url.host() );
     return false;
@@ -3882,22 +3885,30 @@ bool HTTPProtocol::sendBody()
   sendOk = true;
   KIO::filesize_t bytesSent = 0;
 
-  while (bytesSent < m_iPostDataSize) {
+  while (true) {
     dataReq();
 
     QByteArray buffer;
     const int bytesRead = readData(buffer);
 
+    // On done...
+    if (bytesRead == 0) {
+      sendOk = (bytesSent == m_iPostDataSize);
+      break;
+    }
+
     // On error return false...
     if (bytesRead < 0) {
       error(ERR_ABORTED, m_request.url.host());
-      return false;
+      sendOk = false;
+      break;
     }
 
     // Cache the POST data in case of a repost request.
     cachePostData(buffer);
 
-    // This will only happen if transmitting the data failed before...
+    // This will only happen if transmitting the data fails, so we will simply
+    // cache the content locally for the potential re-transmit...
     if (!sendOk)
       continue;
 
@@ -3907,9 +3918,6 @@ bool HTTPProtocol::sendBody()
       continue;
     }
 
-    // NOTE: We do not break out of the while loop at this point because we need to
-    // buffer all the content in case we need to re-post due to connection problems
-    // ot proxy authorization requests...
     kDebug(7113) << "Connection broken while sending POST content to" << m_request.url.host();
     error(ERR_CONNECTION_BROKEN, m_request.url.host());
     sendOk = false;
@@ -5056,7 +5064,35 @@ void HTTPProtocol::clearPostDataBuffer()
     m_POSTbuf = 0;
 }
 
+bool HTTPProtocol::retrieveAllData()
+{
+    if (!m_POSTbuf) {
+        m_POSTbuf = createPostBufferDeviceFor(s_MaxInMemPostBufSize + 1);
+    }
 
+    if (!m_POSTbuf) {
+        error (ERR_OUT_OF_MEMORY, m_request.url.host());
+        return false;
+    }
+
+    while (true) {
+        dataReq();
+        QByteArray buffer;
+        const int bytesRead = readData(buffer);
+
+        if (bytesRead < 0) {
+          error(ERR_ABORTED, m_request.url.host());
+          return false;
+        }
+
+        if (bytesRead == 0)
+          break;
+
+        m_POSTbuf->write(buffer.constData(), buffer.size());
+    }
+
+    return true;
+}
 
 // The above code should be kept in sync
 // with the code in http_cache_cleaner.cpp
diff --git a/kioslave/http/http.h b/kioslave/http/http.h
index 31dcc44..67230aa 100644
--- a/kioslave/http/http.h
+++ b/kioslave/http/http.h
@@ -449,6 +449,11 @@ protected:
    */
   void clearPostDataBuffer();
 
+  /**
+   * Returns true on successful retrieval of all content data.
+   */
+  bool retrieveAllData();
+
 protected:
   HTTPServerState m_server;
   HTTPRequest m_request;

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic