libchromeos: Move url_utils from Buffet to libchromeos

BUG=chromium:405714
TEST=USE=buffet ./build_packages

Change-Id: Ia46f88ca2e684e37688fb2ab43c258cda95e44c3
Reviewed-on: https://chromium-review.googlesource.com/213363
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Bertrand Simonnet <bsimonnet@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp
index c9ac80d..bbbe8dc 100644
--- a/buffet/buffet.gyp
+++ b/buffet/buffet.gyp
@@ -36,7 +36,6 @@
         'manager.cc',
         'mime_utils.cc',
         'storage_impls.cc',
-        'url_utils.cc'
       ],
     },
     {
@@ -88,7 +87,6 @@
             'http_transport_fake.cc',
             'http_utils_unittest.cc',
             'mime_utils_unittest.cc',
-            'url_utils_unittest.cc'
           ],
         },
       ],
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 5624d0d..9e59d78 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -12,6 +12,7 @@
 #include <base/values.h>
 #include <chromeos/data_encoding.h>
 #include <chromeos/string_utils.h>
+#include <chromeos/url_utils.h>
 
 #include "buffet/commands/command_definition.h"
 #include "buffet/commands/command_manager.h"
@@ -20,7 +21,6 @@
 #include "buffet/http_utils.h"
 #include "buffet/mime_utils.h"
 #include "buffet/storage_impls.h"
-#include "buffet/url_utils.h"
 
 const char buffet::kErrorDomainOAuth2[] = "oauth2";
 const char buffet::kErrorDomainGCD[] = "gcd";
@@ -132,8 +132,8 @@
 std::string BuildURL(const std::string& url,
                      const std::vector<std::string>& subpaths,
                      const chromeos::data_encoding::WebParamList& params) {
-  std::string result = buffet::url::CombineMultiple(url, subpaths);
-  return buffet::url::AppendQueryParams(result, params);
+  std::string result = chromeos::url::CombineMultiple(url, subpaths);
+  return chromeos::url::AppendQueryParams(result, params);
 }
 
 }  // anonymous namespace
diff --git a/buffet/http_transport_fake.cc b/buffet/http_transport_fake.cc
index 40d8eff..abf822b 100644
--- a/buffet/http_transport_fake.cc
+++ b/buffet/http_transport_fake.cc
@@ -11,11 +11,11 @@
 #include <base/logging.h>
 #include <chromeos/bind_lambda.h>
 #include <chromeos/string_utils.h>
+#include <chromeos/url_utils.h>
 
 #include "buffet/http_connection_fake.h"
 #include "buffet/http_request.h"
 #include "buffet/mime_utils.h"
-#include "buffet/url_utils.h"
 
 namespace buffet {
 
@@ -145,8 +145,8 @@
 
 ServerRequest::ServerRequest(const std::string& url,
                              const std::string& method) : method_(method) {
-  auto params = url::GetQueryStringParameters(url);
-  url_ = url::RemoveQueryString(url, true);
+  auto params = chromeos::url::GetQueryStringParameters(url);
+  url_ = chromeos::url::RemoveQueryString(url, true);
   form_fields_.insert(params.begin(), params.end());
 }
 
diff --git a/buffet/http_utils_unittest.cc b/buffet/http_utils_unittest.cc
index 24c5dcd..4bb8383 100644
--- a/buffet/http_utils_unittest.cc
+++ b/buffet/http_utils_unittest.cc
@@ -8,12 +8,12 @@
 #include <base/values.h>
 #include <chromeos/bind_lambda.h>
 #include <chromeos/string_utils.h>
+#include <chromeos/url_utils.h>
 #include <gtest/gtest.h>
 
 #include "buffet/http_transport_fake.h"
 #include "buffet/http_utils.h"
 #include "buffet/mime_utils.h"
-#include "buffet/url_utils.h"
 
 using namespace buffet;        // NOLINT(build/namespaces)
 using namespace buffet::http;  // NOLINT(build/namespaces)
@@ -172,7 +172,7 @@
             http::GetAsString(kMethodEchoUrl, transport, nullptr));
 
   for (std::string data : {"blah", "some data", ""}) {
-    std::string url = url::AppendQueryParam(kFakeUrl, "test", data);
+    std::string url = chromeos::url::AppendQueryParam(kFakeUrl, "test", data);
     EXPECT_EQ(data, http::GetAsString(url, transport, nullptr));
   }
 }
diff --git a/buffet/url_utils.cc b/buffet/url_utils.cc
deleted file mode 100644
index 599fa5b..0000000
--- a/buffet/url_utils.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2014 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "buffet/url_utils.h"
-
-#include <algorithm>
-
-namespace {
-// Given a URL string, determine where the query string starts and ends.
-// URLs have schema, domain and path (along with possible user name, password
-// and port number which are of no interest for us here) which could optionally
-// have a query string that is separated from the path by '?'. Finally, the URL
-// could also have a '#'-separated URL fragment which is usually used by the
-// browser as a bookmark element. So, for example:
-//    http://server.com/path/to/object?k=v&foo=bar#fragment
-// Here:
-//    http://server.com/path/to/object - is the URL of the object,
-//    ?k=v&foo=bar                     - URL query string
-//    #fragment                        - URL fragment string
-// If |exclude_fragment| is true, the function returns the start character and
-// the length of the query string alone. If it is false, the query string length
-// will include both the query string and the fragment.
-bool GetQueryStringPos(const std::string& url, bool exclude_fragment,
-                       size_t* query_pos, size_t* query_len) {
-  size_t query_start = url.find_first_of("?#");
-  if (query_start == std::string::npos) {
-    *query_pos = url.size();
-    if (query_len)
-      *query_len = 0;
-    return false;
-  }
-
-  *query_pos = query_start;
-  if (query_len) {
-    size_t query_end = url.size();
-
-    if (exclude_fragment) {
-      if (url[query_start] == '?') {
-        size_t pos_fragment = url.find('#', query_start);
-        if (pos_fragment != std::string::npos)
-          query_end = pos_fragment;
-      } else {
-        query_end = query_start;
-      }
-    }
-    *query_len = query_end - query_start;
-  }
-  return true;
-}
-}  // anonymous namespace
-
-namespace buffet {
-
-std::string url::TrimOffQueryString(std::string* url) {
-  size_t query_pos;
-  if (!GetQueryStringPos(*url, false, &query_pos, nullptr))
-    return std::string();
-  std::string query_string = url->substr(query_pos);
-  url->resize(query_pos);
-  return query_string;
-}
-
-std::string url::Combine(
-    const std::string& url, const std::string& subpath) {
-  return CombineMultiple(url, {subpath});
-}
-
-std::string url::CombineMultiple(
-    const std::string& url, const std::vector<std::string>& parts) {
-  std::string result = url;
-  if (!parts.empty()) {
-    std::string query_string = TrimOffQueryString(&result);
-    for (const auto& part : parts) {
-      if (!part.empty()) {
-        if (!result.empty() && result.back() != '/')
-          result += '/';
-        size_t non_slash_pos = part.find_first_not_of('/');
-        if (non_slash_pos != std::string::npos)
-          result += part.substr(non_slash_pos);
-      }
-    }
-    result += query_string;
-  }
-  return result;
-}
-
-std::string url::GetQueryString(
-    const std::string& url, bool remove_fragment) {
-  std::string query_string;
-  size_t query_pos, query_len;
-  if (GetQueryStringPos(url, remove_fragment, &query_pos, &query_len)) {
-    query_string = url.substr(query_pos, query_len);
-  }
-  return query_string;
-}
-
-chromeos::data_encoding::WebParamList url::GetQueryStringParameters(
-    const std::string& url) {
-  // Extract the query string and remove the leading '?'.
-  std::string query_string = GetQueryString(url, true);
-  if (!query_string.empty() && query_string.front() == '?')
-    query_string.erase(query_string.begin());
-  return chromeos::data_encoding::WebParamsDecode(query_string);
-}
-
-std::string url::GetQueryStringValue(
-    const std::string& url, const std::string& name) {
-  return GetQueryStringValue(GetQueryStringParameters(url), name);
-}
-
-std::string url::GetQueryStringValue(
-    const chromeos::data_encoding::WebParamList& params,
-    const std::string& name) {
-  for (const auto& pair : params) {
-    if (name.compare(pair.first) == 0)
-      return pair.second;
-  }
-  return std::string();
-}
-
-std::string url::RemoveQueryString(
-    const std::string& url, bool remove_fragment_too) {
-  size_t query_pos, query_len;
-  if (!GetQueryStringPos(url, !remove_fragment_too, &query_pos, &query_len))
-    return url;
-  std::string result = url.substr(0, query_pos);
-  size_t fragment_pos = query_pos + query_len;
-  if (fragment_pos < url.size()) {
-    result += url.substr(fragment_pos);
-  }
-  return result;
-}
-
-std::string url::AppendQueryParam(
-    const std::string& url, const std::string& name, const std::string& value) {
-  return AppendQueryParams(url, {{name, value}});
-}
-
-std::string url::AppendQueryParams(
-    const std::string& url,
-    const chromeos::data_encoding::WebParamList& params) {
-  if (params.empty())
-    return url;
-  size_t query_pos, query_len;
-  GetQueryStringPos(url, true, &query_pos, &query_len);
-  size_t fragment_pos = query_pos + query_len;
-  std::string result = url.substr(0, fragment_pos);
-  if (query_len == 0) {
-    result += '?';
-  } else if (query_len > 1) {
-    result += '&';
-  }
-  result += chromeos::data_encoding::WebParamsEncode(params);
-  if (fragment_pos < url.size()) {
-    result += url.substr(fragment_pos);
-  }
-  return result;
-}
-
-bool url::HasQueryString(const std::string& url) {
-  size_t query_pos, query_len;
-  GetQueryStringPos(url, true, &query_pos, &query_len);
-  return (query_len > 0);
-}
-
-}  // namespace buffet
diff --git a/buffet/url_utils.h b/buffet/url_utils.h
deleted file mode 100644
index f0e9080..0000000
--- a/buffet/url_utils.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BUFFET_URL_UTILS_H_
-#define BUFFET_URL_UTILS_H_
-
-#include <string>
-#include <vector>
-
-#include <base/basictypes.h>
-#include <chromeos/data_encoding.h>
-
-namespace buffet {
-
-namespace url {
-
-// Appends a subpath to url and delimiting then with '/' if the path doesn't
-// end with it already. Also handles URLs with query parameters/fragment.
-std::string Combine(const std::string& url,
-                    const std::string& subpath) WARN_UNUSED_RESULT;
-std::string CombineMultiple(
-    const std::string& url,
-    const std::vector<std::string>& parts) WARN_UNUSED_RESULT;
-
-// Removes the query string/fragment from |url| and returns the query string.
-// This method actually modifies |url|. So, if you call it on this:
-//    http://www.test.org/?foo=bar
-// it will modify |url| to "http://www.test.org/" and return "?foo=bar"
-std::string TrimOffQueryString(std::string* url);
-
-// Returns the query string, if available.
-// For example, for the following URL:
-//    http://server.com/path/to/object?k=v&foo=bar#fragment
-// Here:
-//    http://server.com/path/to/object - is the URL of the object,
-//    ?k=v&foo=bar                     - URL query string
-//    #fragment                        - URL fragment string
-// If |remove_fragment| is true, the function returns the query string without
-// the fragment. Otherwise the fragment is included as part of the result.
-std::string GetQueryString(const std::string& url, bool remove_fragment);
-
-// Parses the query string into a set of key-value pairs.
-chromeos::data_encoding::WebParamList GetQueryStringParameters(
-    const std::string& url);
-
-// Returns a value of the specified query parameter, or empty string if missing.
-std::string GetQueryStringValue(const std::string& url,
-                                const std::string& name);
-std::string GetQueryStringValue(
-    const chromeos::data_encoding::WebParamList& params,
-    const std::string& name);
-
-// Removes the query string and/or a fragment part from URL.
-// If |remove_fragment| is specified, the fragment is also removed.
-// For example:
-//    http://server.com/path/to/object?k=v&foo=bar#fragment
-// true  -> http://server.com/path/to/object
-// false -> http://server.com/path/to/object#fragment
-std::string RemoveQueryString(const std::string& url,
-                              bool remove_fragment) WARN_UNUSED_RESULT;
-
-// Appends a single query parameter to the URL.
-std::string AppendQueryParam(const std::string& url,
-                             const std::string& name,
-                             const std::string& value) WARN_UNUSED_RESULT;
-// Appends a list of query parameters to the URL.
-std::string AppendQueryParams(
-    const std::string& url,
-    const chromeos::data_encoding::WebParamList& params) WARN_UNUSED_RESULT;
-
-// Checks if the URL has query parameters.
-bool HasQueryString(const std::string& url);
-
-}  // namespace url
-}  // namespace buffet
-
-#endif  // BUFFET_URL_UTILS_H_
diff --git a/buffet/url_utils_unittest.cc b/buffet/url_utils_unittest.cc
deleted file mode 100644
index 7f4826d..0000000
--- a/buffet/url_utils_unittest.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "buffet/url_utils.h"
-
-#include <gtest/gtest.h>
-
-using namespace buffet;  // NOLINT(build/namespaces)
-
-TEST(UrlUtils, Combine) {
-  EXPECT_EQ("http://sample.org/path",
-            url::Combine("http://sample.org", "path"));
-  EXPECT_EQ("http://sample.org/path",
-            url::Combine("http://sample.org/", "path"));
-  EXPECT_EQ("path1/path2", url::Combine("", "path1/path2"));
-  EXPECT_EQ("path1/path2", url::Combine("path1", "path2"));
-  EXPECT_EQ("http://sample.org",
-            url::Combine("http://sample.org", ""));
-  EXPECT_EQ("http://sample.org/path",
-            url::Combine("http://sample.org/", "/path"));
-  EXPECT_EQ("http://sample.org/path",
-            url::Combine("http://sample.org", "//////path"));
-  EXPECT_EQ("http://sample.org/",
-            url::Combine("http://sample.org", "///"));
-  EXPECT_EQ("http://sample.org/obj/path1/path2",
-            url::Combine("http://sample.org/obj", "path1/path2"));
-  EXPECT_EQ("http://sample.org/obj/path1/path2#tag",
-            url::Combine("http://sample.org/obj#tag", "path1/path2"));
-  EXPECT_EQ("http://sample.org/obj/path1/path2?k1=v1&k2=v2",
-            url::Combine("http://sample.org/obj?k1=v1&k2=v2", "path1/path2"));
-  EXPECT_EQ("http://sample.org/obj/path1/path2?k1=v1#k2=v2",
-            url::Combine("http://sample.org/obj/?k1=v1#k2=v2", "path1/path2"));
-  EXPECT_EQ("http://sample.org/obj/path1/path2#tag?",
-            url::Combine("http://sample.org/obj#tag?", "path1/path2"));
-  EXPECT_EQ("path1/path2", url::CombineMultiple("", {"path1", "path2"}));
-  EXPECT_EQ("http://sample.org/obj/part1/part2",
-            url::CombineMultiple("http://sample.org",
-                                 {"obj", "", "/part1/", "part2"}));
-}
-
-TEST(UrlUtils, GetQueryString) {
-  EXPECT_EQ("", url::GetQueryString("http://sample.org", false));
-  EXPECT_EQ("", url::GetQueryString("http://sample.org", true));
-  EXPECT_EQ("", url::GetQueryString("", false));
-  EXPECT_EQ("", url::GetQueryString("", true));
-
-  EXPECT_EQ("?q=v&b=2#tag?2",
-            url::GetQueryString("http://s.com/?q=v&b=2#tag?2", false));
-  EXPECT_EQ("?q=v&b=2",
-            url::GetQueryString("http://s.com/?q=v&b=2#tag?2", true));
-
-  EXPECT_EQ("#tag?a=2",
-            url::GetQueryString("http://s.com/#tag?a=2", false));
-  EXPECT_EQ("",
-            url::GetQueryString("http://s.com/#tag?a=2", true));
-
-  EXPECT_EQ("?a=2&b=2",
-            url::GetQueryString("?a=2&b=2", false));
-  EXPECT_EQ("?a=2&b=2",
-            url::GetQueryString("?a=2&b=2", true));
-
-  EXPECT_EQ("#s#?d#?f?#s?#d",
-            url::GetQueryString("#s#?d#?f?#s?#d", false));
-  EXPECT_EQ("",
-            url::GetQueryString("#s#?d#?f?#s?#d", true));
-}
-
-TEST(UrlUtils, GetQueryStringParameters) {
-  auto params = url::GetQueryStringParameters(
-    "http://sample.org/path?k=v&&%3Dkey%3D=val%26&r#blah");
-
-  EXPECT_EQ(3, params.size());
-  EXPECT_EQ("k", params[0].first);
-  EXPECT_EQ("v", params[0].second);
-  EXPECT_EQ("=key=", params[1].first);
-  EXPECT_EQ("val&", params[1].second);
-  EXPECT_EQ("r", params[2].first);
-  EXPECT_EQ("", params[2].second);
-}
-
-TEST(UrlUtils, GetQueryStringValue) {
-  std::string url = "http://url?key1=val1&&key2=val2";
-  EXPECT_EQ("val1", url::GetQueryStringValue(url, "key1"));
-  EXPECT_EQ("val2", url::GetQueryStringValue(url, "key2"));
-  EXPECT_EQ("", url::GetQueryStringValue(url, "key3"));
-
-  auto params = url::GetQueryStringParameters(url);
-  EXPECT_EQ("val1", url::GetQueryStringValue(params, "key1"));
-  EXPECT_EQ("val2", url::GetQueryStringValue(params, "key2"));
-  EXPECT_EQ("", url::GetQueryStringValue(params, "key3"));
-}
-
-TEST(UrlUtils, TrimOffQueryString) {
-  std::string url = "http://url?key1=val1&key2=val2#fragment";
-  std::string query = url::TrimOffQueryString(&url);
-  EXPECT_EQ("http://url", url);
-  EXPECT_EQ("?key1=val1&key2=val2#fragment", query);
-
-  url = "http://url#fragment";
-  query = url::TrimOffQueryString(&url);
-  EXPECT_EQ("http://url", url);
-  EXPECT_EQ("#fragment", query);
-
-  url = "http://url";
-  query = url::TrimOffQueryString(&url);
-  EXPECT_EQ("http://url", url);
-  EXPECT_EQ("", query);
-}
-
-TEST(UrlUtils, RemoveQueryString) {
-  std::string url = "http://url?key1=val1&key2=val2#fragment";
-  EXPECT_EQ("http://url", url::RemoveQueryString(url, true));
-  EXPECT_EQ("http://url#fragment", url::RemoveQueryString(url, false));
-}
-
-TEST(UrlUtils, AppendQueryParam) {
-  std::string url = "http://server.com/path";
-  url = url::AppendQueryParam(url, "param", "value");
-  EXPECT_EQ("http://server.com/path?param=value", url);
-  url = url::AppendQueryParam(url, "param2", "v");
-  EXPECT_EQ("http://server.com/path?param=value&param2=v", url);
-
-  url = "http://server.com/path#fragment";
-  url = url::AppendQueryParam(url, "param", "value");
-  EXPECT_EQ("http://server.com/path?param=value#fragment", url);
-  url = url::AppendQueryParam(url, "param2", "v");
-  EXPECT_EQ("http://server.com/path?param=value&param2=v#fragment", url);
-
-  url = url::AppendQueryParam("http://server.com/path?", "param", "value");
-  EXPECT_EQ("http://server.com/path?param=value", url);
-}
-
-TEST(UrlUtils, AppendQueryParams) {
-  std::string url = "http://server.com/path";
-  url = url::AppendQueryParams(url, {});
-  EXPECT_EQ("http://server.com/path", url);
-  url = url::AppendQueryParams(url, {{"param", "value"}, {"q", "="}});
-  EXPECT_EQ("http://server.com/path?param=value&q=%3D", url);
-  url += "#fr?";
-  url = url::AppendQueryParams(url, {{"p", "1"}, {"s&", "\n"}});
-  EXPECT_EQ("http://server.com/path?param=value&q=%3D&p=1&s%26=%0A#fr?", url);
-}
-
-TEST(UrlUtils, HasQueryString) {
-  EXPECT_FALSE(url::HasQueryString("http://server.com/path"));
-  EXPECT_FALSE(url::HasQueryString("http://server.com/path#blah?v=1"));
-  EXPECT_TRUE(url::HasQueryString("http://server.com/path?v=1#blah"));
-  EXPECT_TRUE(url::HasQueryString("http://server.com/path?v=1"));
-  EXPECT_FALSE(url::HasQueryString(""));
-  EXPECT_TRUE(url::HasQueryString("?ss"));
-}