2
0
David Rose 23 жил өмнө
parent
commit
7251774a7e

+ 2 - 2
panda/src/downloader/urlSpec.I

@@ -23,8 +23,8 @@
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE URLSpec::
-URLSpec(const string &url) {
-  (*this) = url;
+URLSpec(const string &url, bool server_name_expected) {
+  set_url(url, server_name_expected);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 38 - 8
panda/src/downloader/urlSpec.cxx

@@ -67,15 +67,15 @@ operator = (const URLSpec &copy) {
 ////////////////////////////////////////////////////////////////////
 //     Function: URLSpec::get_scheme
 //       Access: Published
-//  Description: Returns the scheme specified by the URL, or "http"
-//               if no scheme is specified.
+//  Description: Returns the scheme specified by the URL, or empty
+//               string if no scheme is specified.
 ////////////////////////////////////////////////////////////////////
 string URLSpec::
 get_scheme() const {
   if (has_scheme()) {
     return _url.substr(0, _scheme_end);
   }
-  return "http";
+  return string();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -365,10 +365,12 @@ set_query(const string &query) {
 //     Function: URLSpec::set_url
 //       Access: Published
 //  Description: Completely replaces the URL with the indicated
-//               string.
+//               string.  If server_name_expected is true, it is a
+//               hint that an undecorated URL is probably a server
+//               name, not a local filename.
 ////////////////////////////////////////////////////////////////////
 void URLSpec::
-set_url(const string &url) {
+set_url(const string &url, bool server_name_expected) {
   _url = url;
   _flags = 0;
 
@@ -390,7 +392,7 @@ set_url(const string &url) {
 
   _scheme_end = start;
   size_t next = _url.find_first_of(":/", start);
-  if (next != string::npos && _url[next] == ':') {
+  if (next < _url.length() - 1 && _url.substr(next, 2) == ":/") {
     // We have a scheme.
     _flags |= F_has_scheme;
     _scheme_end = next;
@@ -411,8 +413,36 @@ set_url(const string &url) {
   _server_end = start;
   _port_start = start;
   _port_end = start;
-  if (start + 1 < _url.length() && _url.substr(start, 2) == "//") {
-    // We have an authority specification.
+
+  // Try to determine if an authority is present.  It is will
+  // generally be present if a scheme was present; also, we have a
+  // hint passed in from the context as to whether we expect an
+  // authority (e.g. a server name) to be present.
+  bool has_authority = (has_scheme() || server_name_expected);
+
+  // We also know we have an authority if the url contains two slashes
+  // at this point.
+  bool leading_slashes = 
+    (start < _url.length() - 1 && _url.substr(start, 2) == "//");
+  if (leading_slashes) {
+    has_authority = true;
+  }
+
+  if (has_authority) {
+    // Now that we know we have an authority, we should ensure there
+    // are two slashes here, since there should be before the
+    // authority.
+    if (!leading_slashes) {
+      if (start < _url.length() && _url[start] == '/') {
+        // Well, at least we had one slash.  Double it.
+        _url = _url.substr(0, start + 1) + _url.substr(start);
+      } else {
+        // No slashes at all.  Insert them.
+        _url = _url.substr(0, start) + "//" + _url.substr(start);
+      }
+    }
+
+    // Begin the actual authority specification.
     start += 2;
     _flags |= F_has_authority;
     _username_start = start;

+ 2 - 2
panda/src/downloader/urlSpec.h

@@ -33,7 +33,7 @@
 class EXPCL_PANDAEXPRESS URLSpec {
 PUBLISHED:
   URLSpec();
-  INLINE URLSpec(const string &url);
+  INLINE URLSpec(const string &url, bool server_name_expected = false);
   INLINE URLSpec(const URLSpec &copy);
   INLINE void operator = (const string &url);
   void operator = (const URLSpec &copy);
@@ -66,7 +66,7 @@ PUBLISHED:
   void set_path(const string &path);
   void set_query(const string &query);
 
-  void set_url(const string &url);
+  void set_url(const string &url, bool server_name_expected = false);
 
   INLINE operator const string & () const;
   INLINE const char *c_str() const;