Support methodPath entries containing colon.

Currently, if we have a top-level methodPath of the form `path:methodName`,
we'll pass this to `urlparse.urljoin`, where this is interpreted as
`scheme:netloc`. In cases other than media upload, this is **not** what we
want.

This fixes the issue by adding our own custom `urljoin`, which detects and
handles this case. We also add a test.
diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py
index 45ae80a..afba86f 100644
--- a/googleapiclient/discovery.py
+++ b/googleapiclient/discovery.py
@@ -491,6 +491,23 @@
   return path_url, http_method, method_id, accept, max_size, media_path_url
 
 
+def _urljoin(base, url):
+  """Custom urljoin replacement supporting : before / in url."""
+  # In general, it's unsafe to simply join base and url. However, for
+  # the case of discovery documents, we know:
+  #  * base will never contain params, query, or fragment
+  #  * url will never contain a scheme or net_loc.
+  # In general, this means we can safely join on /; we just need to
+  # ensure we end up with precisely one / joining base and url. The
+  # exception here is the case of media uploads, where url will be an
+  # absolute url.
+  if url.startswith('http://') or url.startswith('https://'):
+    return urlparse.urljoin(base, url)
+  new_base = base if base.endswith('/') else base + '/'
+  new_url = url[1:] if url.startswith('/') else url
+  return new_base + new_url
+
+
 # TODO(dhermes): Convert this class to ResourceMethod and make it callable
 class ResourceMethodParameters(object):
   """Represents the parameters associated with a method.
@@ -671,7 +688,7 @@
         actual_path_params, actual_query_params, body_value)
 
     expanded_url = uritemplate.expand(pathUrl, params)
-    url = urlparse.urljoin(self._baseUrl, expanded_url + query)
+    url = _urljoin(self._baseUrl, expanded_url + query)
 
     resumable = None
     multipart_boundary = ''
@@ -697,7 +714,7 @@
 
       # Use the media path uri for media uploads
       expanded_url = uritemplate.expand(mediaPathUrl, params)
-      url = urlparse.urljoin(self._baseUrl, expanded_url + query)
+      url = _urljoin(self._baseUrl, expanded_url + query)
       if media_upload.resumable():
         url = _add_query_parameter(url, 'uploadType', 'resumable')
 
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index a2593e2..a5f2541 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -26,6 +26,7 @@
 import copy
 import datetime
 import httplib2
+import itertools
 import json
 import os
 import pickle
@@ -44,6 +45,7 @@
 from googleapiclient.discovery import _fix_up_media_upload
 from googleapiclient.discovery import _fix_up_method_description
 from googleapiclient.discovery import _fix_up_parameters
+from googleapiclient.discovery import _urljoin
 from googleapiclient.discovery import build
 from googleapiclient.discovery import build_from_document
 from googleapiclient.discovery import DISCOVERY_URI
@@ -268,6 +270,24 @@
     self.assertEqual(result, (path_url, http_method, method_id, accept,
                               max_size, media_path_url))
 
+  def test_urljoin(self):
+    # We want to exhaustively test various URL combinations.
+    simple_bases = ['https://www.googleapis.com', 'https://www.googleapis.com/']
+    long_urls = ['foo/v1/bar:custom?alt=json', '/foo/v1/bar:custom?alt=json']
+
+    long_bases = [
+      'https://www.googleapis.com/foo/v1',
+      'https://www.googleapis.com/foo/v1/',
+    ]
+    simple_urls = ['bar:custom?alt=json', '/bar:custom?alt=json']
+
+    final_url = 'https://www.googleapis.com/foo/v1/bar:custom?alt=json'
+    for base, url in itertools.product(simple_bases, long_urls):
+      self.assertEqual(final_url, _urljoin(base, url))
+    for base, url in itertools.product(long_bases, simple_urls):
+      self.assertEqual(final_url, _urljoin(base, url))
+
+
   def test_ResourceMethodParameters_zoo_get(self):
     parameters = ResourceMethodParameters(self.zoo_get_method_desc)