]> git.mxchange.org Git - simgear.git/commitdiff
HTTP SVN fixes, cap max update-report depth.
authorJames Turner <zakalawe@mac.com>
Sun, 28 Jul 2013 20:07:40 +0000 (21:07 +0100)
committerJames Turner <zakalawe@mac.com>
Sun, 28 Jul 2013 20:07:40 +0000 (21:07 +0100)
simgear/io/DAVMultiStatus.cxx
simgear/io/SVNDirectory.cxx
simgear/io/SVNDirectory.hxx
simgear/io/SVNRepository.cxx

index 5270fca6175f9ce0738a66258fcc6d28b1ddaced..6e1425dcc02c493fe3d13aced88e50010ab81bbc 100644 (file)
@@ -58,7 +58,10 @@ DAVResource::DAVResource(const string& href) :
   _url(href),
   _container(NULL)
 {
-    assert(!href.empty()); 
+    assert(!href.empty());
+    if (strutils::ends_with(href, "/")) {
+        _url = href.substr(0, _url.size() - 1);
+    }
 }
 
 void DAVResource::setVersionName(const std::string& aVersion)
index 311fc4f9a7deb34727bff9292f39c321f333b0ed..cc572fc11da25dff410a0125f1b544e9db760923 100644 (file)
@@ -28,7 +28,12 @@ typedef std::map<std::string, DAVResource*> DAVResourceMap;
 
 const char* DAV_CACHE_NAME = ".terrasync_cache";
 const char* CACHE_VERSION_4_TOKEN = "terrasync-cache-4";
-const unsigned int MAX_UPDATE_REPORT_DEPTH = 3;
+
+// important: with the Google servers, setting this higher than '1' causes
+// server internal errors (500, the connection is closed). In other words we
+// can only specify update report items one level deep at most and no more.
+// (the root and its direct children, not NOT grand-children)
+const unsigned int MAX_UPDATE_REPORT_DEPTH = 1;
 
 enum LineState
 {
@@ -90,11 +95,15 @@ void SVNDirectory::parseCache()
   char versionName[128];
   LineState lineState = LINESTATE_HREF;
   std::ifstream file(p.c_str());
+    if (!file.is_open()) {
+        SG_LOG(SG_IO, SG_WARN, "unable to open cache file for reading:" << p);
+        return;
+    }
   bool doneSelf = false;
     
   file.getline(href, 1024);
   if (strcmp(CACHE_VERSION_4_TOKEN, href)) {
-    SG_LOG(SG_IO, SG_WARN, "invalid cache file:" << p.str());
+    SG_LOG(SG_IO, SG_WARN, "invalid cache file [missing header token]:" << p << " '" << href << "'");
     return;
   }
     
@@ -128,8 +137,11 @@ void SVNDirectory::parseCache()
         doneSelf = true;
       } else {
         DAVResource* child = addChildDirectory(hrefPtr)->collection();
-        child->setVersionName(versionName);
-      }
+          string s = strutils::strip(versionName);
+          if (!s.empty()) {
+              child->setVersionName(versionName);
+          }
+      } // of done self test
     } // of line-state switching 
   } // of file get-line loop
 }
@@ -142,7 +154,7 @@ void SVNDirectory::writeCache()
       d.create(0755);
   }
   
-  p.append(DAV_CACHE_NAME);
+  p.append(string(DAV_CACHE_NAME) + ".new");
     
   std::ofstream file(p.c_str(), std::ios::trunc);
 // first, cache file version header
@@ -159,6 +171,16 @@ void SVNDirectory::writeCache()
         file << child->name() << '\n' << child->versionName() << "\n";
     }
   } // of child iteration
+    
+    file.close();
+    
+// approximately atomic delete + rename operation
+    SGPath cacheName(localPath);
+    cacheName.append(DAV_CACHE_NAME);
+    if (cacheName.exists()) {
+        cacheName.remove();
+    }
+    p.rename(cacheName);
 }
 
 void SVNDirectory::setBaseUrl(const string& url)
@@ -210,6 +232,7 @@ SVNDirectory::addChildDirectory(const std::string& dirName)
     
     DAVCollection* childCol = dav->createChildCollection(dirName);
     SVNDirectory* child = new SVNDirectory(this, childCol);
+    childCol->setVersionName(child->cachedRevision());
     _children.push_back(child);
     writeCache();
     return child;
@@ -245,11 +268,6 @@ void SVNDirectory::deleteChildByName(const std::string& nm)
     writeCache();
 }
   
-void SVNDirectory::requestFailed(HTTP::Request *req)
-{
-    SG_LOG(SG_IO, SG_WARN, "Request failed for:" << req->url());
-}
-  
 bool SVNDirectory::isDoingSync() const
 {
   if (_doingUpdateReport) {
@@ -303,7 +321,7 @@ void SVNDirectory::mergeUpdateReportDetails(unsigned int depth,
     
     Dir d(localPath);
     if (depth >= MAX_UPDATE_REPORT_DEPTH) {
-        std::cerr << localPath << "exceeded MAX_UPDATE_REPORT_DEPTH, cleaning" << std::endl;
+        SG_LOG(SG_IO, SG_INFO, localPath << "exceeded MAX_UPDATE_REPORT_DEPTH, cleaning");
         d.removeChildren();
         return;
     }
index 06876dd4ad1b26612093a7d61212a8aa1d280da1..68bca1b008b0e1384b3cff9d2736e1ce1e8be10b 100644 (file)
@@ -51,11 +51,7 @@ public:
   
   // init from a collection
   SVNDirectory(SVNDirectory* pr, DAVCollection* col);
-  
-//  void update();
- // void gotResource(HTTP::Request* get, const std::string& etag);
-  void requestFailed(HTTP::Request* req);
-  
+
   void beginUpdateReport();
   void updateReportComplete();
   
index 339323ef6219f6b716d9d3021fd8ba310413d8d9..80dec23d383a7d238897a9d3bac4f01813d41dc8 100644 (file)
@@ -184,6 +184,13 @@ namespace { // anonmouse
         }
         _davStatus.parseXML(s, n);
       }
+        
+        virtual void failed()
+        {
+            HTTP::Request::failed();
+            _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+        }
+        
     private:
       SVNRepoPrivate* _repo;
       DAVMultiStatus _davStatus;
@@ -291,7 +298,11 @@ protected:
     }
   }
 
-
+    virtual void failed()
+    {
+        HTTP::Request::failed();
+        _repo->updateFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+    }
 private:
   string _request;
   mutable int _requestSent;