浏览代码

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>...]
+               [HTTPHEADER <header>]
                [RETRY_COUNT <count>]
                [RETRY_DELAY <delay>]
                [RETURN_VALUE <result-var>]
@@ -36,6 +37,10 @@ The options are:
   Specify an explicit list of specific files to be submitted.
   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>``
   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>]
+               [HTTPHEADER <header>]
                [RETRY_COUNT <count>]
                [RETRY_DELAY <delay>]
                [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
 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,
                      curlWriteMemoryCallback);
   ::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 =
     ::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);
   std::vector<char> responseData;
   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_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);
+  ::curl_slist_free_all(headers);
 
   if (!responseData.empty()) {
     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
   // and CURLOPT_SSL_VERIFYHOST_OFF
   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 SetTimeOutSeconds(int s) { this->TimeOutSeconds = s; }
   void SetQuiet(bool b) { this->Quiet = b; }
@@ -35,6 +39,7 @@ protected:
 private:
   cmCTest* CTest;
   CURL* Curl;
+  std::vector<std::string> HttpHeaders;
   std::string HTTPProxyAuth;
   std::string HTTPProxy;
   curl_proxytype HTTPProxyType;

+ 16 - 0
Source/CTest/cmCTestSubmitCommand.cxx

@@ -129,6 +129,12 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
     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(
     "RetryDelay", this->RetryDelay.c_str());
   static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
@@ -182,6 +188,11 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
     }
   }
   // Arguments used by both modes.
+  if (arg == "HTTPHEADER") {
+    this->ArgumentDoing = ArgumentDoingHttpHeader;
+    return true;
+  }
+
   if (arg == "RETRY_COUNT") {
     this->ArgumentDoing = ArgumentDoingRetryCount;
     return true;
@@ -230,6 +241,11 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
     return true;
   }
 
+  if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
+    this->HttpHeaders.push_back(arg);
+    return true;
+  }
+
   if (this->ArgumentDoing == ArgumentDoingRetryCount) {
     this->RetryCount = arg;
     return true;

+ 2 - 0
Source/CTest/cmCTestSubmitCommand.h

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

+ 11 - 1
Source/CTest/cmCTestSubmitHandler.cxx

@@ -301,9 +301,19 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
   CURLcode res;
   FILE* ftpfile;
   char error_buffer[1024];
+  // Set Content-Type to satisfy fussy modsecurity rules.
   struct curl_slist* headers =
     ::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 */
   ::curl_global_init(CURL_GLOBAL_ALL);
   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_VERBOSE, 1);
 
-      // Be sure to set Content-Type to satisfy fussy modsecurity rules
       ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
       std::string local_file = *file;
@@ -1014,6 +1023,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
   cmSystemTools::ExpandListArgument(curlopt, args);
   curl.SetCurlOptions(args);
   curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
+  curl.SetHttpHeaders(this->HttpHeaders);
   std::string dropMethod;
   std::string url;
   this->ConstructCDashURL(dropMethod, url);

+ 6 - 0
Source/CTest/cmCTestSubmitHandler.h

@@ -43,6 +43,11 @@ public:
   // handle the cdash file upload protocol
   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);
 
 private:
@@ -95,6 +100,7 @@ private:
   bool HasWarnings;
   bool HasErrors;
   cmCTest::SetOfStrings Files;
+  std::vector<std::string> HttpHeaders;
 };
 
 #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(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(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)
   set(CASE_DROP_METHOD ftp)