You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by tn...@apache.org on 2015/12/30 20:35:16 UTC

mesos git commit: Added support for parsing url in libprocess.

Repository: mesos
Updated Branches:
  refs/heads/master b94c4c3e6 -> 389e0333c


Added support for parsing url in libprocess.

Review: https://reviews.apache.org/r/41715


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/389e0333
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/389e0333
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/389e0333

Branch: refs/heads/master
Commit: 389e0333cb24727a21ec1ec9e30ddf230a1aa489
Parents: b94c4c3
Author: Timothy Chen <tn...@apache.org>
Authored: Thu Dec 24 01:13:05 2015 -0800
Committer: Timothy Chen <tn...@apache.org>
Committed: Wed Dec 30 11:35:03 2015 -0800

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/http.hpp |  2 +
 3rdparty/libprocess/src/http.cpp             | 77 +++++++++++++++++++++++
 3rdparty/libprocess/src/tests/http_tests.cpp | 35 +++++++++++
 3 files changed, 114 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/389e0333/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index f0666f0..404770f 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -123,6 +123,8 @@ struct URL
       query(_query),
       fragment(_fragment) {}
 
+  static Try<URL> parse(const std::string& urlString);
+
   Option<std::string> scheme;
 
   // TODO(benh): Consider using unrestricted union for 'domain' and 'ip'.

http://git-wip-us.apache.org/repos/asf/mesos/blob/389e0333/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index e937df6..2893d91 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -165,6 +165,83 @@ string Status::string(uint16_t code)
 }
 
 
+// Returns the default port for a given URL scheme.
+static Option<uint16_t> defaultPort(const string& scheme)
+{
+  // TODO(tnachen): Make default port a lookup table.
+  if (scheme == "http") {
+    return 80;
+  } else if (scheme == "https") {
+    return 443;
+  }
+
+  return None();
+}
+
+
+Try<URL> URL::parse(const string& urlString)
+{
+  // TODO(tnachen): Consider using C++11 regex support instead.
+
+  size_t schemePos = urlString.find_first_of("://");
+  if (schemePos == string::npos) {
+    return Error("Missing scheme in url string");
+  }
+
+  const string scheme = strings::lower(urlString.substr(0, schemePos));
+  const string urlPath = urlString.substr(schemePos + 3);
+
+  size_t pathPos = urlPath.find_first_of("/");
+  if (pathPos == 0) {
+    return Error("Host not found in url");
+  }
+
+  // If path is specified in the URL, try to capture the host and path
+  // seperately.
+  string host = urlPath;
+  string path = "/";
+  if (pathPos != string::npos) {
+    host = host.substr(0, pathPos);
+    path = urlPath.substr(pathPos);
+  }
+
+  if (host.empty()) {
+    return Error("Host not found in url");
+  }
+
+  const vector<string> tokens = strings::tokenize(host, ":");
+
+  if (tokens[0].empty()) {
+    return Error("Host not found in url");
+  }
+
+  if (tokens.size() > 2) {
+    return Error("Found multiple ports in url");
+  }
+
+  Option<uint16_t> port;
+  if (tokens.size() == 2) {
+    Try<uint16_t> numifyPort = numify<uint16_t>(tokens[1]);
+    if (numifyPort.isError()) {
+      return Error("Failed to parse port: " + numifyPort.error());
+    }
+
+    port = numifyPort.get();
+  } else {
+    // Attempt to resolve the port based on the URL scheme.
+    port = defaultPort(scheme);
+  }
+
+  if (port.isNone()) {
+    return Error("Unable to determine port from url");
+  }
+
+  // TODO(tnachen): Support parsing query and fragment.
+
+  return URL(scheme, tokens[0], port.get(), path);
+}
+
+
 bool Request::acceptsEncoding(const string& encoding) const
 {
   // From RFC 2616:

http://git-wip-us.apache.org/repos/asf/mesos/blob/389e0333/3rdparty/libprocess/src/tests/http_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/http_tests.cpp b/3rdparty/libprocess/src/tests/http_tests.cpp
index 016e3c1..ec7b4aa 100644
--- a/3rdparty/libprocess/src/tests/http_tests.cpp
+++ b/3rdparty/libprocess/src/tests/http_tests.cpp
@@ -1197,6 +1197,41 @@ TEST(URLTest, Stringification)
 }
 
 
+TEST(URLTest, ParseUrls)
+{
+  Try<http::URL> url = URL::parse("https://auth.docker.com");
+  EXPECT_SOME(url);
+  EXPECT_SOME_EQ("https", url.get().scheme);
+  EXPECT_SOME_EQ(443, url.get().port);
+  EXPECT_SOME_EQ("auth.docker.com", url.get().domain);
+  EXPECT_EQ("/", url.get().path);
+
+  url = URL::parse("http://docker.com/");
+  EXPECT_SOME(url);
+  EXPECT_SOME_EQ("http", url.get().scheme);
+  EXPECT_SOME_EQ(80, url.get().port);
+  EXPECT_SOME_EQ("docker.com", url.get().domain);
+  EXPECT_EQ("/", url.get().path);
+
+  url = URL::parse("http://registry.docker.com:1234/abc/1");
+  EXPECT_SOME(url);
+  EXPECT_SOME_EQ("http", url.get().scheme);
+  EXPECT_SOME_EQ(1234, url.get().port);
+  EXPECT_SOME_EQ("registry.docker.com", url.get().domain);
+  EXPECT_EQ("/abc/1", url.get().path);
+
+  // Missing scheme.
+  EXPECT_ERROR(URL::parse("mesos.com"));
+  // Unknown scheme with no port.
+  EXPECT_ERROR(URL::parse("abc://abc.com"));
+  // Invalid urls.
+  EXPECT_ERROR(URL::parse("://///"));
+  EXPECT_ERROR(URL::parse("://"));
+  EXPECT_ERROR(URL::parse("http://"));
+  EXPECT_ERROR(URL::parse("http:////"));
+}
+
+
 class MockAuthenticator : public Authenticator
 {
 public: