diff --git a/nfv/nfv-common/nfv_common/selectable.py b/nfv/nfv-common/nfv_common/selectable.py index a60f378b..a4245c16 100755 --- a/nfv/nfv-common/nfv_common/selectable.py +++ b/nfv/nfv-common/nfv_common/selectable.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2016 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ from six.moves import queue as threading_queue class ThreadQueue(object): def __init__(self, queue_id): + if hasattr(queue_id, "encode"): + queue_id = queue_id.encode() self._queue_id = queue_id self._send_socket, self._receive_socket = socket.socketpair() self._receive_socket.setblocking(False) diff --git a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_compute_api.py b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_compute_api.py index cd5c1683..374670a9 100755 --- a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_compute_api.py +++ b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_compute_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -816,7 +816,9 @@ class NFVIComputeAPI(nfvi.api.v1.NFVIComputeAPI): request_dispatch.send_header(key, value) request_dispatch.end_headers() if http_body is not None: - request_dispatch.wfile.write(http_body.encode()) + if hasattr(http_body, "encode"): + http_body = http_body.encode() + request_dispatch.wfile.write(http_body) request_dispatch.done() DLOG.info("Sent response for request %s." % request_uuid) diff --git a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/rest_api.py b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/rest_api.py index a01acb47..a06d2630 100755 --- a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/rest_api.py +++ b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/rest_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2016 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -323,7 +323,10 @@ def _rest_api_request(token_id, request_info.add_header(header_type, header_value) if api_cmd_payload is not None: - request_info.data = api_cmd_payload.encode() + if hasattr(api_cmd_payload, "encode"): + request_info.data = api_cmd_payload.encode() + else: + request_info.data = api_cmd_payload DLOG.verbose("Rest-API method=%s, api_cmd=%s, api_cmd_headers=%s, " "api_cmd_payload=%s" % (method, api_cmd, api_cmd_headers, diff --git a/nfv/nfv-vim/nfv_vim/nfvi/objects/v1/_instance.py b/nfv/nfv-vim/nfv_vim/nfvi/objects/v1/_instance.py index f39233d5..42b68bf0 100755 --- a/nfv/nfv-vim/nfv_vim/nfvi/objects/v1/_instance.py +++ b/nfv/nfv-vim/nfv_vim/nfvi/objects/v1/_instance.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2016 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -379,7 +379,19 @@ class InstanceActionData(ObjectData): if self.context is None: data['context'] = dict() else: - data['context'] = self.context.as_dict() + context = self.context.as_dict().copy() + + # In Python 3, it has been observed that some values present + # in the `context` dictionary are bytes instead of strings. + # This can lead to some exceptions later in the code when + # attempting to serialize this object into JSON. + if six.PY3: + for key, value in context.items(): + if isinstance(value, bytes): + context[key] = value.decode() + + data['context'] = context + return data def __str__(self): diff --git a/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/acceptor.py b/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/acceptor.py index 78f3a8b5..a9f151bd 100644 --- a/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/acceptor.py +++ b/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/acceptor.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -61,7 +61,7 @@ class APIController(Middleware): return self._default_dispatcher def _is_nfvi_request(self, request): - body = get_jason_request_body(request) + body = get_json_request_body(request) data = json.loads(body) for action in self._actions: if action in list(data): @@ -86,7 +86,7 @@ class APIController(Middleware): def _generate_log(self, req): environ = req.environ - body = get_jason_request_body(req) + body = get_json_request_body(req) if CONF.debug and body is not None: data = json.loads(body) self._print_data(data) @@ -203,12 +203,12 @@ class DebugHeaders(Middleware): LOG.info('-' * 70 + '\n') -def get_jason_request_body(request): +def get_json_request_body(request): content_type = request.content_type if not content_type or content_type.startswith('text/plain'): LOG.info("Content type null or plain text") content_type = 'application/json' if content_type in ('JSON', 'application/json') and \ - request.body.startswith('{'): + request.body.startswith(b'{'): LOG.debug("Req body: (%s)" % request.body) return request.body diff --git a/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/proxy.py b/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/proxy.py index ef11964e..30d47103 100644 --- a/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/proxy.py +++ b/nova-api-proxy/nova-api-proxy/nova_api_proxy/apps/proxy.py @@ -7,7 +7,7 @@ # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php # -# Copyright (c) 2015-2018 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -39,6 +39,15 @@ class Proxy(Application): LOG.debug("Proxy the request to the remote host: (%s)", environ[ 'HTTP_HOST']) start_ms = get_monotonic_timestamp_in_ms() + + # In Python 3, the builtin `http` library raises an exception if one + # or more headers are set to `NoneType`. See: + # https://github.com/python/cpython/blob/3.9/Lib/http/client.py#L1253 + for key, value in environ.items(): + if key.startswith("HTTP_"): + if value is None: + environ[key] = "" + result = self.proxy_app(environ, start_response) now_ms = get_monotonic_timestamp_in_ms() elapsed_secs = (now_ms - start_ms) // 1000