| 
					
				 | 
			
			
				@@ -15,6 +15,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmVersion.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmGeneratedFileStream.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmCTest.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmXMLParser.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cmsys/Process.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cmsys/Base64.h> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -31,6 +32,80 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class cmCTestSubmitHandler::ResponseParser: public cmXMLParser 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ResponseParser() { this->Status = STATUS_OK; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ~ResponseParser() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  enum StatusType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    STATUS_OK, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    STATUS_WARNING, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    STATUS_ERROR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  StatusType Status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string CDashVersion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string Filename; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string MD5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string Message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string CurrentValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::string CurrentTag; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  virtual void StartElement(const char* name, const char** atts) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->CurrentValue = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(strcmp(name, "cdash") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->CDashVersion = this->FindAttribute(atts, "version"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  virtual void CharacterDataHandler(const char* data, int length) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->CurrentValue.insert(this->CurrentValue.end(), data, data+length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  virtual void EndElement(const char* name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(strcmp(name, "status") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->CurrentValue = cmSystemTools::UpperCase(this->CurrentValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(this->CurrentValue == "OK" || this->CurrentValue == "SUCCESS") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this->Status = STATUS_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else if(this->CurrentValue == "WARNING") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this->Status = STATUS_WARNING; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this->Status = STATUS_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if(strcmp(name, "filename") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->Filename = this->CurrentValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if(strcmp(name, "md5") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->MD5 = this->CurrentValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if(strcmp(name, "message") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->Message = this->CurrentValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static size_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 cmCTestSubmitHandlerWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void *data) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -367,6 +442,13 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         + "FileName=" + ofile; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      char md5[33]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cmSystemTools::ComputeFileMD5(local_file.c_str(), md5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      md5[32] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      std::stringstream md5string; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      md5string << "&MD5=" << md5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      upload_as += md5string.str(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       struct stat st; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if ( ::stat(local_file.c_str(), &st) ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -382,7 +464,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         << local_file.c_str() << " to " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         << upload_as.c_str() << " Size: " << st.st_size << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // specify target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -411,6 +492,47 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // Now run off and do what you've been told! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       res = ::curl_easy_perform(curl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // If we time out or operation is too slow, wait and retry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(res == CURLE_OPERATION_TIMEOUTED) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::string retryTime = this->GetOption("RetryTime") == NULL ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          "" : this->GetOption("RetryTime"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::string retryCount = this->GetOption("RetryCount") == NULL ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          "" : this->GetOption("RetryCount"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int time = retryTime == "" ? atoi(this->CTest->GetCTestConfiguration( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          "CTestRetryTime").c_str()) : atoi(retryTime.c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int count = retryCount == "" ? atoi(this->CTest->GetCTestConfiguration( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          "CTestRetryCount").c_str()) : atoi(retryCount.c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(int i = 0; i < count; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cmCTestLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "   Connection timed out, waiting " << time << " seconds...\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          double stop = cmSystemTools::GetTime() + time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          while(cmSystemTools::GetTime() < stop) {} //wait <time> seconds 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cmCTestLog(this->CTest, HANDLER_OUTPUT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "   Retry submission: Attempt " << (i + 1) << " of " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            << count << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ::fclose(ftpfile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ftpfile = ::fopen(local_file.c_str(), "rb"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chunk.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chunkDebug.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          res = ::curl_easy_perform(curl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(res != CURLE_OPERATION_TIMEDOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if ( chunk.size() > 0 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cmCTestLog(this->CTest, DEBUG, "CURL output: [" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -467,29 +589,39 @@ void cmCTestSubmitHandler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ::ParseResponse(cmCTestSubmitHandlerVectorOfChar chunk) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   std::string output = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  output.append(chunk.begin(), chunk.end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for(cmCTestSubmitHandlerVectorOfChar::iterator i = chunk.begin(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      i != chunk.end(); ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    output += *i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  output = cmSystemTools::UpperCase(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if(output.find("WARNING") != std::string::npos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->HasWarnings = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if(output.find("ERROR") != std::string::npos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if(output.find("<cdash") != output.npos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->HasErrors = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ResponseParser parser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parser.Parse(output.c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(parser.Status != ResponseParser::STATUS_OK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->HasErrors = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Submission failed: " << 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parser.Message << std::endl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if(this->HasWarnings || this->HasErrors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Server Response:\n" << 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    output = cmSystemTools::UpperCase(output); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(output.find("WARNING") != std::string::npos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->HasWarnings = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(output.find("ERROR") != std::string::npos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->HasErrors = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(this->HasWarnings || this->HasErrors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Server Response:\n" << 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //---------------------------------------------------------------------------- 
			 |