importing my current diff
[platform/upstream/libzypp.git] / zypp / Url.cc
index 7558095..a56c76e 100644 (file)
  * \file zypp/Url.cc
  */
 #include <zypp/Url.h>
+#include <zypp/base/Gettext.h>
 #include <zypp/base/String.h>
+#include <zypp/base/Regex.h>
 #include <stdexcept>
+#include <iostream>
 
 
 //////////////////////////////////////////////////////////////////////
@@ -26,11 +29,11 @@ namespace zypp
   /*
    * url       = [scheme:] [//authority] /path [?query] [#fragment]
    */
-  #define RX_SPLIT_URL                       "^(([^:/?#]+):)?" \
-                                             "(//([^/?#]*))?"  \
+  #define RX_SPLIT_URL                       "^([^:/?#]+:|)" \
+                                             "(//[^/?#]*|)"  \
                                              "([^?#]*)"        \
-                                             "([?]([^#]*))?"   \
-                                             "(#(.*))?"
+                                             "([?][^#]*|)"   \
+                                             "(#.*|)"
 
 
   ////////////////////////////////////////////////////////////////////
@@ -73,6 +76,11 @@ namespace zypp
         config("psep_querystr",   "?");
         config("vsep_querystr",   "");
 
+        // host is required (isValid=>false)
+        // but not mandatory (see RFC 2255),
+        // that is, accept empty host.
+        config("require_host",    "y");
+
         // not allowed here
         config("rx_username",     "");
         config("rx_password",     "");
@@ -101,7 +109,7 @@ namespace zypp
         else
         {
           ZYPP_THROW(url::UrlNotSupportedException(
-            "Invalid LDAP URL query string"
+            _("Invalid LDAP URL query string")
           ));
         }
         return pmap;
@@ -140,7 +148,8 @@ namespace zypp
           if( !found)
           {
             ZYPP_THROW(url::UrlNotSupportedException(
-              "Invalid LDAP URL query parameter '" + p->first + "'"
+              str::form(_("Invalid LDAP URL query parameter '%s'"),
+                          p->first.c_str())
             ));
           }
         }
@@ -162,21 +171,46 @@ namespace zypp
       {
         UrlRef ref;
 
+        // =====================================
         ref.reset( new LDAPUrl());
         addUrlByScheme("ldap", ref);
         addUrlByScheme("ldaps", ref);
 
+
+        // =====================================
         ref.reset( new UrlBase());
+        ref->config("with_authority",   "n");   // disallow host,...
+        ref->config("require_pathname", "m");   // path is mandatory
+        addUrlByScheme("hd",     ref);
+        addUrlByScheme("cd",     ref);
+        addUrlByScheme("dvd",    ref);
+        addUrlByScheme("dir",    ref);
+        addUrlByScheme("iso",    ref);
+
         // don't show empty authority
         ref->setViewOptions( zypp::url::ViewOption::DEFAULTS -
                              zypp::url::ViewOption::EMPTY_AUTHORITY);
-        ref->config("rx_username",      "");  // disallow username
-        ref->config("rx_password",      "");  // disallow password
-        // FIXME: hmm... also host+port?
-        addUrlByScheme("nfs",    ref);
-
-        ref->config("with_authority"    "n");   // disallow host & port
         addUrlByScheme("mailto", ref);
+        addUrlByScheme("urn",    ref);
+
+        // RFC1738, 3.10: may contain a host
+        ref->config("with_authority",   "y");   // allow host,
+        ref->config("with_port",        "n");   // but no port,
+        ref->config("rx_username",      "");    // username or
+        ref->config("rx_password",      "");    // password ...
+        addUrlByScheme("file",   ref);
+
+        // =====================================
+        ref.reset( new UrlBase());
+        ref->config("require_host",     "m");   // host is mandatory
+        addUrlByScheme("nfs",    ref);
+        addUrlByScheme("smb",    ref);
+        addUrlByScheme("cifs",   ref);
+        addUrlByScheme("http",   ref);
+        addUrlByScheme("https",  ref);
+        ref->config("path_encode_slash2", "y"); // always encode 2. slash
+        addUrlByScheme("ftp",    ref);
+        addUrlByScheme("sftp",   ref);
       }
 
       bool
@@ -217,7 +251,7 @@ namespace zypp
         UrlSchemes                     schemes;
 
         schemes.reserve(urlByScheme.size());
-        for( ; i != urlByScheme.begin(); ++i)
+        for( ; i != urlByScheme.end(); ++i)
         {
           schemes.push_back(i->first);
         }
@@ -227,8 +261,11 @@ namespace zypp
 
 
     // ---------------------------------------------------------------
-    UrlByScheme g_urlSchemeRepository;
-
+    UrlByScheme & g_urlSchemeRepository()
+    {
+      static UrlByScheme _v;
+      return _v;
+    }
 
     //////////////////////////////////////////////////////////////////
   } // anonymous namespace
@@ -255,7 +292,7 @@ namespace zypp
     if( !m_impl)
     {
       ZYPP_THROW(url::UrlException(
-        "Unable to clone Url object"
+        _("Unable to clone Url object")
       ));
     }
   }
@@ -268,7 +305,7 @@ namespace zypp
     if( !m_impl)
     {
       ZYPP_THROW(url::UrlException(
-        "Invalid empty Url reference"
+        _("Invalid empty Url object reference")
       ));
     }
   }
@@ -281,7 +318,7 @@ namespace zypp
     if( !m_impl)
     {
       ZYPP_THROW(url::UrlParsingException(
-        "Unable to parse Url components"
+        _("Unable to parse Url components")
       ));
     }
   }
@@ -291,11 +328,11 @@ namespace zypp
   Url&
   Url::operator = (const std::string &encodedUrl)
   {
-    UrlRef  url( parseUrl(encodedUrl));
+    UrlRef url( parseUrl(encodedUrl));
     if( !url)
     {
       ZYPP_THROW(url::UrlParsingException(
-        "Unable to parse Url components"
+        _("Unable to parse Url components")
       ));
     }
     m_impl = url;
@@ -318,7 +355,7 @@ namespace zypp
   Url::registerScheme(const std::string &scheme,
                       UrlRef            urlImpl)
   {
-    return g_urlSchemeRepository.addUrlByScheme(scheme, urlImpl);
+    return g_urlSchemeRepository().addUrlByScheme(scheme, urlImpl);
   }
 
 
@@ -339,18 +376,33 @@ namespace zypp
     catch( ... )
     {}
 
-    if(ret && out.size() == 10)
+    if(ret && out.size() == 5)
     {
-      url = g_urlSchemeRepository.getUrlByScheme(out[2].str());
+      std::string scheme = out[1];
+      if (scheme.size() > 1)
+        scheme = scheme.substr(0, scheme.size()-1);
+      std::string authority = out[2];
+      if (authority.size() >= 2)
+        authority = authority.substr(2);
+      std::string query = out[4];
+      if (query.size() > 1)
+        query = query.substr(1);
+      std::string fragment = out[5];
+      if (fragment.size() > 1)
+        fragment = fragment.substr(1);
+
+      std::cout << "scheme: " << scheme << " authority: " << authority
+        << " query " << query << " fragment " << fragment << std::endl;
+
+      std::cout << "out[3] " << out[3] << std::endl;
+
+      url = g_urlSchemeRepository().getUrlByScheme(scheme);
       if( !url)
       {
         url.reset( new UrlBase());
       }
-      url->init(out[2].str(),
-                out[4].str(),
-                out[5].str(),
-                out[7].str(),
-                out[9].str());
+      url->init(scheme, authority, out[3],
+                query, fragment);
     }
     return url;
   }
@@ -361,7 +413,7 @@ namespace zypp
   zypp::url::UrlSchemes
   Url::getRegisteredSchemes()
   {
-    return g_urlSchemeRepository.getRegisteredSchemes();
+    return g_urlSchemeRepository().getRegisteredSchemes();
   }
 
 
@@ -370,7 +422,7 @@ namespace zypp
   bool
   Url::isRegisteredScheme(const std::string &scheme)
   {
-    return g_urlSchemeRepository.isRegisteredScheme(scheme);
+    return g_urlSchemeRepository().isRegisteredScheme(scheme);
   }
 
 
@@ -408,6 +460,26 @@ namespace zypp
 
   // -----------------------------------------------------------------
   std::string
+  Url::asCompleteString() const
+  {
+    // make sure, all url components are included;
+    // regardless of the current configuration...
+    ViewOptions opts(getViewOptions() +
+                     ViewOption::WITH_SCHEME +
+                     ViewOption::WITH_USERNAME +
+                     ViewOption::WITH_PASSWORD +
+                     ViewOption::WITH_HOST +
+                     ViewOption::WITH_PORT +
+                     ViewOption::WITH_PATH_NAME +
+                     ViewOption::WITH_PATH_PARAMS +
+                     ViewOption::WITH_QUERY_STR +
+                     ViewOption::WITH_FRAGMENT);
+    return m_impl->asString(opts);
+  }
+
+
+  // -----------------------------------------------------------------
+  std::string
   Url::asString(const ViewOptions &opts) const
   {
     return m_impl->asString(opts);
@@ -563,7 +635,7 @@ namespace zypp
       return;
     }
 
-    UrlRef url = g_urlSchemeRepository.getUrlByScheme(scheme);
+    UrlRef url = g_urlSchemeRepository().getUrlByScheme(scheme);
     if( !url)
     {
       url.reset( new UrlBase());
@@ -708,6 +780,19 @@ namespace zypp
     m_impl->setQueryParam(param, value);
   }
 
+  // -----------------------------------------------------------------
+  ViewOptions
+  Url::getViewOptions() const
+  {
+    return m_impl->getViewOptions();
+  }
+
+  // -----------------------------------------------------------------
+  void
+  Url::setViewOptions(const ViewOptions &vopts)
+  {
+    m_impl->setViewOptions(vopts);
+  }
 
   // -----------------------------------------------------------------
   std::ostream & operator<<( std::ostream & str, const Url & url )
@@ -715,7 +800,21 @@ namespace zypp
     return str << url.asString();
   }
 
+  bool operator<( const Url &lhs, const Url &rhs )
+  {
+    return (lhs.asCompleteString() < rhs.asCompleteString());
+  }
 
+  bool operator==( const Url &lhs, const Url &rhs )
+  {
+    return (lhs.asCompleteString() == rhs.asCompleteString());
+  }
+  
+  bool operator!=( const Url &lhs, const Url &rhs )
+  {
+    return (lhs.asCompleteString() != rhs.asCompleteString());
+  }
+  
   ////////////////////////////////////////////////////////////////////
 } // namespace zypp
 //////////////////////////////////////////////////////////////////////