Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 91debf8

Browse files
Merge pull request googleapis#55 from craigcitro/toplevel_custom
2 parents 94fdc89 + 7ee535d commit 91debf8

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

googleapiclient/discovery.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,23 @@ def _fix_up_method_description(method_desc, root_desc):
491491
return path_url, http_method, method_id, accept, max_size, media_path_url
492492

493493

494+
def _urljoin(base, url):
495+
"""Custom urljoin replacement supporting : before / in url."""
496+
# In general, it's unsafe to simply join base and url. However, for
497+
# the case of discovery documents, we know:
498+
# * base will never contain params, query, or fragment
499+
# * url will never contain a scheme or net_loc.
500+
# In general, this means we can safely join on /; we just need to
501+
# ensure we end up with precisely one / joining base and url. The
502+
# exception here is the case of media uploads, where url will be an
503+
# absolute url.
504+
if url.startswith('http://') or url.startswith('https://'):
505+
return urlparse.urljoin(base, url)
506+
new_base = base if base.endswith('/') else base + '/'
507+
new_url = url[1:] if url.startswith('/') else url
508+
return new_base + new_url
509+
510+
494511
# TODO(dhermes): Convert this class to ResourceMethod and make it callable
495512
class ResourceMethodParameters(object):
496513
"""Represents the parameters associated with a method.
@@ -671,7 +688,7 @@ def method(self, **kwargs):
671688
actual_path_params, actual_query_params, body_value)
672689

673690
expanded_url = uritemplate.expand(pathUrl, params)
674-
url = urlparse.urljoin(self._baseUrl, expanded_url + query)
691+
url = _urljoin(self._baseUrl, expanded_url + query)
675692

676693
resumable = None
677694
multipart_boundary = ''
@@ -697,7 +714,7 @@ def method(self, **kwargs):
697714

698715
# Use the media path uri for media uploads
699716
expanded_url = uritemplate.expand(mediaPathUrl, params)
700-
url = urlparse.urljoin(self._baseUrl, expanded_url + query)
717+
url = _urljoin(self._baseUrl, expanded_url + query)
701718
if media_upload.resumable():
702719
url = _add_query_parameter(url, 'uploadType', 'resumable')
703720

tests/test_discovery.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import copy
2727
import datetime
2828
import httplib2
29+
import itertools
2930
import json
3031
import os
3132
import pickle
@@ -44,6 +45,7 @@
4445
from googleapiclient.discovery import _fix_up_media_upload
4546
from googleapiclient.discovery import _fix_up_method_description
4647
from googleapiclient.discovery import _fix_up_parameters
48+
from googleapiclient.discovery import _urljoin
4749
from googleapiclient.discovery import build
4850
from googleapiclient.discovery import build_from_document
4951
from googleapiclient.discovery import DISCOVERY_URI
@@ -268,6 +270,24 @@ def test_fix_up_method_description_insert(self):
268270
self.assertEqual(result, (path_url, http_method, method_id, accept,
269271
max_size, media_path_url))
270272

273+
def test_urljoin(self):
274+
# We want to exhaustively test various URL combinations.
275+
simple_bases = ['https://www.googleapis.com', 'https://www.googleapis.com/']
276+
long_urls = ['foo/v1/bar:custom?alt=json', '/foo/v1/bar:custom?alt=json']
277+
278+
long_bases = [
279+
'https://www.googleapis.com/foo/v1',
280+
'https://www.googleapis.com/foo/v1/',
281+
]
282+
simple_urls = ['bar:custom?alt=json', '/bar:custom?alt=json']
283+
284+
final_url = 'https://www.googleapis.com/foo/v1/bar:custom?alt=json'
285+
for base, url in itertools.product(simple_bases, long_urls):
286+
self.assertEqual(final_url, _urljoin(base, url))
287+
for base, url in itertools.product(long_bases, simple_urls):
288+
self.assertEqual(final_url, _urljoin(base, url))
289+
290+
271291
def test_ResourceMethodParameters_zoo_get(self):
272292
parameters = ResourceMethodParameters(self.zoo_get_method_desc)
273293

0 commit comments

Comments
 (0)