update_engine: Attach session ID to HTTP header of binary download

In order for Omaha to correlate Omaha Client requests with the actual
binary download, the session ID must be attached to the HTTP header of
the binary download in the X-Goog-Update-SessionId.

Also, remove the HTTP header of X-Goog-Update-SessionId added into the
Omaha requests.

BUG=chromium:940515
TEST=unittests # new unittests

Change-Id: I0759562f2d1c8c003064ad976ca1ae6ce039b960
diff --git a/libcurl_http_fetcher_unittest.cc b/libcurl_http_fetcher_unittest.cc
new file mode 100644
index 0000000..88e48fa
--- /dev/null
+++ b/libcurl_http_fetcher_unittest.cc
@@ -0,0 +1,81 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/libcurl_http_fetcher.h"
+
+#include <string>
+
+#include <brillo/message_loops/fake_message_loop.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/mock_proxy_resolver.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace {
+constexpr char kHeaderName[] = "X-Goog-Test-Header";
+}
+
+class LibcurlHttpFetcherTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    loop_.SetAsCurrent();
+    fake_hardware_.SetIsOfficialBuild(true);
+    fake_hardware_.SetIsOOBEEnabled(false);
+  }
+
+  brillo::FakeMessageLoop loop_{nullptr};
+  FakeHardware fake_hardware_;
+  LibcurlHttpFetcher libcurl_fetcher_{nullptr, &fake_hardware_};
+};
+
+TEST_F(LibcurlHttpFetcherTest, GetEmptyHeaderValueTest) {
+  const string header_value = "";
+  string actual_header_value;
+  libcurl_fetcher_.SetHeader(kHeaderName, header_value);
+  EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
+  EXPECT_EQ("", actual_header_value);
+}
+
+TEST_F(LibcurlHttpFetcherTest, GetHeaderTest) {
+  const string header_value = "This-is-value 123";
+  string actual_header_value;
+  libcurl_fetcher_.SetHeader(kHeaderName, header_value);
+  EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
+  EXPECT_EQ(header_value, actual_header_value);
+}
+
+TEST_F(LibcurlHttpFetcherTest, GetNonExistentHeaderValueTest) {
+  string actual_header_value;
+  // Skip |SetHeaader()| call.
+  EXPECT_FALSE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
+  // Even after a failed |GetHeaderValue()|, enforce that the passed pointer to
+  // modifiable string was cleared to be empty.
+  EXPECT_EQ("", actual_header_value);
+}
+
+TEST_F(LibcurlHttpFetcherTest, GetHeaderEdgeCaseTest) {
+  const string header_value = "\a\b\t\v\f\r\\ edge:-case: \a\b\t\v\f\r\\";
+  string actual_header_value;
+  libcurl_fetcher_.SetHeader(kHeaderName, header_value);
+  EXPECT_TRUE(libcurl_fetcher_.GetHeader(kHeaderName, &actual_header_value));
+  EXPECT_EQ(header_value, actual_header_value);
+}
+
+}  // namespace chromeos_update_engine