From 7dc5ce32959b189a4d37448a8ae4de74748ed76b Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 19 May 2021 11:32:59 -0700 Subject: [PATCH 1/2] feat: Determine URL protocol based on hostname This will make connections to `localhost` use HTTP. This is insecure but useful for testing. In a future change, we will allow setting transport options at client instantiation time. --- .../services/%service/transports/rest.py.j2 | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 b/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 index afb296aeaf..673d1bf4f2 100644 --- a/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 +++ b/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 @@ -178,7 +178,8 @@ class {{ service.name }}RestTransport({{ service.name }}Transport): {# TODO(yon-mg): Write helper method for handling grpc transcoding url #} # TODO(yon-mg): need to handle grpc transcoding and parse url correctly # current impl assumes basic case of grpc transcoding - url = 'https://{host}{{ method.http_opt['url'] }}'.format( + url = '{protocol}://{host}{{ method.http_opt['url'] }}'.format( + protocol=protocol_for(self._host), host=self._host, {% for field in method.path_params %} {{ field }}=request.{{ method.input.get_field(field).name }}, @@ -230,6 +231,33 @@ class {{ service.name }}RestTransport({{ service.name }}Transport): {% endif %} {% endfor %} +{# TODO: Allow client creation to explictly specify connection + parameters, such as secure/insecure connections, and have tests use + that. Then remove this function. + Tracking issue: + https://github.com/googleapis/gapic-generator-python/issues/901 +#} +def protocol_for(host: str) -> str: + """Determine the URL protocol to use for connecting to the given host. + + This function returns 'http' for hosts that match + `^localhost(:.*)?$` and `https` for all others. This is intended + to allow integration testing over an insecure connection to a + locally running server. + + Args: + host (str): The hostname for REST connection. + + Returns: + str: The protocol (`http` or `https`) to use for connecting to `host`. + """ + + LOCALHOST='localhost' + LOCALHOST_LEN=len(LOCALHOST) + + if host.startswith(LOCALHOST) and (len(host)==LOCALHOST_LEN or host[LOCALHOST_LEN]==":"): + return 'http' + return 'https' __all__ = ( '{{ service.name }}RestTransport', From f6e383fc3d9a2c4e523e1af437126672d8913809 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Thu, 20 May 2021 17:49:26 -0700 Subject: [PATCH 2/2] chore: Implement code-review changes to protocol_for_host() - mark it private with leading underscore - use regex for host matching --- .../%sub/services/%service/transports/rest.py.j2 | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 b/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 index 673d1bf4f2..b718289ef8 100644 --- a/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 +++ b/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2 @@ -2,6 +2,7 @@ {% block content %} +import re import warnings from typing import Callable, Dict, Optional, Sequence, Tuple @@ -179,7 +180,7 @@ class {{ service.name }}RestTransport({{ service.name }}Transport): # TODO(yon-mg): need to handle grpc transcoding and parse url correctly # current impl assumes basic case of grpc transcoding url = '{protocol}://{host}{{ method.http_opt['url'] }}'.format( - protocol=protocol_for(self._host), + protocol=_protocol_for(self._host), host=self._host, {% for field in method.path_params %} {{ field }}=request.{{ method.input.get_field(field).name }}, @@ -237,7 +238,7 @@ class {{ service.name }}RestTransport({{ service.name }}Transport): Tracking issue: https://github.com/googleapis/gapic-generator-python/issues/901 #} -def protocol_for(host: str) -> str: +def _protocol_for(host: str) -> str: """Determine the URL protocol to use for connecting to the given host. This function returns 'http' for hosts that match @@ -251,13 +252,9 @@ def protocol_for(host: str) -> str: Returns: str: The protocol (`http` or `https`) to use for connecting to `host`. """ - - LOCALHOST='localhost' - LOCALHOST_LEN=len(LOCALHOST) - - if host.startswith(LOCALHOST) and (len(host)==LOCALHOST_LEN or host[LOCALHOST_LEN]==":"): - return 'http' - return 'https' + if not hasattr(_protocol_for, 'regex'): + _protocol_for.regex = re.compile("^localhost(:.*)?$") + return 'http' if _protocol_for.regex.match(host) else 'https' __all__ = ( '{{ service.name }}RestTransport',