瀏覽代碼

Merge topic 'ctest_submit_headers'

1a7d00bd ctest_submit: Add HTTPHEADER option

Acked-by: Kitware Robot <[email protected]>
Merge-request: !793
Brad King 8 年之前
父節點
當前提交
e1ae739e1f

+ 8 - 2
Help/command/ctest_submit.rst

@@ -6,6 +6,7 @@ Perform the :ref:`CTest Submit Step` as a :ref:`Dashboard Client`.
 ::
 ::
 
 
   ctest_submit([PARTS <part>...] [FILES <file>...]
   ctest_submit([PARTS <part>...] [FILES <file>...]
+               [HTTPHEADER <header>]
                [RETRY_COUNT <count>]
                [RETRY_COUNT <count>]
                [RETRY_DELAY <delay>]
                [RETRY_DELAY <delay>]
                [RETURN_VALUE <result-var>]
                [RETURN_VALUE <result-var>]
@@ -36,6 +37,10 @@ The options are:
   Specify an explicit list of specific files to be submitted.
   Specify an explicit list of specific files to be submitted.
   Each individual file must exist at the time of the call.
   Each individual file must exist at the time of the call.
 
 
+``HTTPHEADER <HTTP-header>``
+  Specify HTTP header to be included in the request to CDash during submission.
+  This suboption can be repeated several times.
+
 ``RETRY_COUNT <count>``
 ``RETRY_COUNT <count>``
   Specify how many times to retry a timed-out submission.
   Specify how many times to retry a timed-out submission.
 
 
@@ -57,6 +62,7 @@ Submit to CDash Upload API
 ::
 ::
 
 
   ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]
   ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]
+               [HTTPHEADER <header>]
                [RETRY_COUNT <count>]
                [RETRY_COUNT <count>]
                [RETRY_DELAY <delay>]
                [RETRY_DELAY <delay>]
                [QUIET])
                [QUIET])
@@ -67,5 +73,5 @@ with a content hash of the file. If CDash does not already have the file,
 then it is uploaded. Along with the file, a CDash type string is specified
 then it is uploaded. Along with the file, a CDash type string is specified
 to tell CDash which handler to use to process the data.
 to tell CDash which handler to use to process the data.
 
 
-This signature accepts the ``RETRY_COUNT``, ``RETRY_DELAY``, and ``QUIET``
-options as described above.
+This signature accepts the ``HTTPHEADER``, ``RETRY_COUNT``, ``RETRY_DELAY``, and
+``QUIET`` options as described above.

+ 5 - 0
Help/release/dev/ctest_submit_headers.rst

@@ -0,0 +1,5 @@
+ctest_submit_headers
+--------------------
+
+* The :command:`ctest_submit` command gained a ``HTTPHEADER`` option
+  to specify custom headers to send during submission.

+ 24 - 1
Source/CTest/cmCTestCurl.cxx

@@ -143,9 +143,17 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
   ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION,
   ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION,
                      curlWriteMemoryCallback);
                      curlWriteMemoryCallback);
   ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, curlDebugCallback);
   ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, curlDebugCallback);
-  // Be sure to set Content-Type to satisfy fussy modsecurity rules
+  // Set Content-Type to satisfy fussy modsecurity rules.
   struct curl_slist* headers =
   struct curl_slist* headers =
     ::curl_slist_append(CM_NULLPTR, "Content-Type: text/xml");
     ::curl_slist_append(CM_NULLPTR, "Content-Type: text/xml");
+  // Add any additional headers that the user specified.
+  for (std::vector<std::string>::const_iterator h = this->HttpHeaders.begin();
+       h != this->HttpHeaders.end(); ++h) {
+    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+                       "   Add HTTP Header: \"" << *h << "\"" << std::endl,
+                       this->Quiet);
+    headers = ::curl_slist_append(headers, h->c_str());
+  }
   ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, headers);
   ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, headers);
   std::vector<char> responseData;
   std::vector<char> responseData;
   std::vector<char> debugData;
   std::vector<char> debugData;
@@ -203,7 +211,22 @@ bool cmCTestCurl::HttpRequest(std::string const& url,
   ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void*)&debugData);
   ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void*)&debugData);
   ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1);
   ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1);
 
 
+  // Add headers if any were specified.
+  struct curl_slist* headers = CM_NULLPTR;
+  if (!this->HttpHeaders.empty()) {
+    for (std::vector<std::string>::const_iterator h =
+           this->HttpHeaders.begin();
+         h != this->HttpHeaders.end(); ++h) {
+      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+                         "   Add HTTP Header: \"" << *h << "\"" << std::endl,
+                         this->Quiet);
+      headers = ::curl_slist_append(headers, h->c_str());
+    }
+  }
+
+  ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, headers);
   CURLcode res = ::curl_easy_perform(this->Curl);
   CURLcode res = ::curl_easy_perform(this->Curl);
+  ::curl_slist_free_all(headers);
 
 
   if (!responseData.empty()) {
   if (!responseData.empty()) {
     response = std::string(responseData.begin(), responseData.end());
     response = std::string(responseData.begin(), responseData.end());

+ 5 - 0
Source/CTest/cmCTestCurl.h

@@ -23,6 +23,10 @@ public:
   // currently only supports CURLOPT_SSL_VERIFYPEER_OFF
   // currently only supports CURLOPT_SSL_VERIFYPEER_OFF
   // and CURLOPT_SSL_VERIFYHOST_OFF
   // and CURLOPT_SSL_VERIFYHOST_OFF
   void SetCurlOptions(std::vector<std::string> const& args);
   void SetCurlOptions(std::vector<std::string> const& args);
+  void SetHttpHeaders(std::vector<std::string> const& v)
+  {
+    this->HttpHeaders = v;
+  }
   void SetUseHttp10On() { this->UseHttp10 = true; }
   void SetUseHttp10On() { this->UseHttp10 = true; }
   void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s; }
   void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s; }
   void SetQuiet(bool b) { this->Quiet = b; }
   void SetQuiet(bool b) { this->Quiet = b; }
@@ -35,6 +39,7 @@ protected:
 private:
 private:
   cmCTest* CTest;
   cmCTest* CTest;
   CURL* Curl;
   CURL* Curl;
+  std::vector<std::string> HttpHeaders;
   std::string HTTPProxyAuth;
   std::string HTTPProxyAuth;
   std::string HTTPProxy;
   std::string HTTPProxy;
   curl_proxytype HTTPProxyType;
   curl_proxytype HTTPProxyType;

+ 16 - 0
Source/CTest/cmCTestSubmitCommand.cxx

@@ -129,6 +129,12 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
     static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
     static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
   }
   }
 
 
+  // Pass along any HTTPHEADER to the handler if this option was given.
+  if (!this->HttpHeaders.empty()) {
+    static_cast<cmCTestSubmitHandler*>(handler)->SetHttpHeaders(
+      this->HttpHeaders);
+  }
+
   static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
   static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
     "RetryDelay", this->RetryDelay.c_str());
     "RetryDelay", this->RetryDelay.c_str());
   static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
   static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
@@ -182,6 +188,11 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
     }
     }
   }
   }
   // Arguments used by both modes.
   // Arguments used by both modes.
+  if (arg == "HTTPHEADER") {
+    this->ArgumentDoing = ArgumentDoingHttpHeader;
+    return true;
+  }
+
   if (arg == "RETRY_COUNT") {
   if (arg == "RETRY_COUNT") {
     this->ArgumentDoing = ArgumentDoingRetryCount;
     this->ArgumentDoing = ArgumentDoingRetryCount;
     return true;
     return true;
@@ -230,6 +241,11 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
     return true;
     return true;
   }
   }
 
 
+  if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
+    this->HttpHeaders.push_back(arg);
+    return true;
+  }
+
   if (this->ArgumentDoing == ArgumentDoingRetryCount) {
   if (this->ArgumentDoing == ArgumentDoingRetryCount) {
     this->RetryCount = arg;
     this->RetryCount = arg;
     return true;
     return true;

+ 2 - 0
Source/CTest/cmCTestSubmitCommand.h

@@ -70,6 +70,7 @@ protected:
     ArgumentDoingRetryCount,
     ArgumentDoingRetryCount,
     ArgumentDoingCDashUpload,
     ArgumentDoingCDashUpload,
     ArgumentDoingCDashUploadType,
     ArgumentDoingCDashUploadType,
+    ArgumentDoingHttpHeader,
     ArgumentDoingLast2
     ArgumentDoingLast2
   };
   };
 
 
@@ -83,6 +84,7 @@ protected:
   bool CDashUpload;
   bool CDashUpload;
   std::string CDashUploadFile;
   std::string CDashUploadFile;
   std::string CDashUploadType;
   std::string CDashUploadType;
+  std::vector<std::string> HttpHeaders;
 };
 };
 
 
 #endif
 #endif

+ 11 - 1
Source/CTest/cmCTestSubmitHandler.cxx

@@ -301,9 +301,19 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
   CURLcode res;
   CURLcode res;
   FILE* ftpfile;
   FILE* ftpfile;
   char error_buffer[1024];
   char error_buffer[1024];
+  // Set Content-Type to satisfy fussy modsecurity rules.
   struct curl_slist* headers =
   struct curl_slist* headers =
     ::curl_slist_append(CM_NULLPTR, "Content-Type: text/xml");
     ::curl_slist_append(CM_NULLPTR, "Content-Type: text/xml");
 
 
+  // Add any additional headers that the user specified.
+  for (std::vector<std::string>::const_iterator h = this->HttpHeaders.begin();
+       h != this->HttpHeaders.end(); ++h) {
+    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+                       "   Add HTTP Header: \"" << *h << "\"" << std::endl,
+                       this->Quiet);
+    headers = ::curl_slist_append(headers, h->c_str());
+  }
+
   /* In windows, this will init the winsock stuff */
   /* In windows, this will init the winsock stuff */
   ::curl_global_init(CURL_GLOBAL_ALL);
   ::curl_global_init(CURL_GLOBAL_ALL);
   std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
   std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
@@ -376,7 +386,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
       ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
       ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
       ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
       ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
 
 
-      // Be sure to set Content-Type to satisfy fussy modsecurity rules
       ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
       ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
 
       std::string local_file = *file;
       std::string local_file = *file;
@@ -1014,6 +1023,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
   cmSystemTools::ExpandListArgument(curlopt, args);
   cmSystemTools::ExpandListArgument(curlopt, args);
   curl.SetCurlOptions(args);
   curl.SetCurlOptions(args);
   curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
   curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
+  curl.SetHttpHeaders(this->HttpHeaders);
   std::string dropMethod;
   std::string dropMethod;
   std::string url;
   std::string url;
   this->ConstructCDashURL(dropMethod, url);
   this->ConstructCDashURL(dropMethod, url);

+ 6 - 0
Source/CTest/cmCTestSubmitHandler.h

@@ -43,6 +43,11 @@ public:
   // handle the cdash file upload protocol
   // handle the cdash file upload protocol
   int HandleCDashUploadFile(std::string const& file, std::string const& type);
   int HandleCDashUploadFile(std::string const& file, std::string const& type);
 
 
+  void SetHttpHeaders(std::vector<std::string> const& v)
+  {
+    this->HttpHeaders = v;
+  }
+
   void ConstructCDashURL(std::string& dropMethod, std::string& url);
   void ConstructCDashURL(std::string& dropMethod, std::string& url);
 
 
 private:
 private:
@@ -95,6 +100,7 @@ private:
   bool HasWarnings;
   bool HasWarnings;
   bool HasErrors;
   bool HasErrors;
   cmCTest::SetOfStrings Files;
   cmCTest::SetOfStrings Files;
+  std::vector<std::string> HttpHeaders;
 };
 };
 
 
 #endif
 #endif

+ 1 - 0
Tests/RunCMake/ctest_submit/CDashSubmitHeaders-result.txt

@@ -0,0 +1 @@
+(-1|255)

+ 3 - 0
Tests/RunCMake/ctest_submit/CDashSubmitHeaders-stderr.txt

@@ -0,0 +1,3 @@
+ *Error when uploading file: .*/Configure.xml
+ *Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*)
+ *Problems when submitting via HTTP

+ 1 - 0
Tests/RunCMake/ctest_submit/CDashSubmitHeaders-stdout.txt

@@ -0,0 +1 @@
+Add HTTP Header: "Authorization: Bearer asdf"

+ 1 - 0
Tests/RunCMake/ctest_submit/CDashUploadHeaders-result.txt

@@ -0,0 +1 @@
+(-1|255)

+ 1 - 0
Tests/RunCMake/ctest_submit/CDashUploadHeaders-stderr.txt

@@ -0,0 +1 @@
+Error in HttpRequest

+ 1 - 0
Tests/RunCMake/ctest_submit/CDashUploadHeaders-stdout.txt

@@ -0,0 +1 @@
+Add HTTP Header: "Authorization: Bearer asdf"

+ 2 - 0
Tests/RunCMake/ctest_submit/RunCMakeTest.cmake

@@ -25,6 +25,8 @@ run_ctest_submit(CDashUploadNone CDASH_UPLOAD)
 run_ctest_submit(CDashUploadMissingFile CDASH_UPLOAD bad-upload)
 run_ctest_submit(CDashUploadMissingFile CDASH_UPLOAD bad-upload)
 run_ctest_submit(CDashUploadRetry CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo RETRY_COUNT 2 RETRY_DELAY 1 INTERNAL_TEST_CHECKSUM)
 run_ctest_submit(CDashUploadRetry CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo RETRY_COUNT 2 RETRY_DELAY 1 INTERNAL_TEST_CHECKSUM)
 run_ctest_submit(CDashSubmitQuiet QUIET)
 run_ctest_submit(CDashSubmitQuiet QUIET)
+run_ctest_submit(CDashSubmitHeaders HTTPHEADER "Authorization: Bearer asdf")
+run_ctest_submit(CDashUploadHeaders CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo HTTPHEADER "Authorization: Bearer asdf")
 
 
 function(run_ctest_CDashUploadFTP)
 function(run_ctest_CDashUploadFTP)
   set(CASE_DROP_METHOD ftp)
   set(CASE_DROP_METHOD ftp)