diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index bd80c26d..d247bf8d 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -352,48 +352,48 @@ class Compute: data = json.dumps(data) response = yield from self._session.request(method, url, headers=headers, data=data, auth=self._auth, chunked=chunked) - body = yield from response.read() + body = yield from response.read() + if body: + body = body.decode() + + if response.status >= 300: + # Try to decode the GNS3 error if body: - body = body.decode() - - if response.status >= 300: - # Try to decode the GNS3 error - if body: - try: - msg = json.loads(body)["message"] - except (KeyError, ValueError): - msg = body - else: - msg = "" - - if response.status == 400: - raise aiohttp.web.HTTPBadRequest(text="Bad request {} {}".format(url, body)) - elif response.status == 401: - raise aiohttp.web.HTTPUnauthorized(text="Invalid authentication for compute {}".format(self.id)) - elif response.status == 403: - raise aiohttp.web.HTTPForbidden(text=msg) - elif response.status == 404: - raise aiohttp.web.HTTPNotFound(text=msg) - elif response.status == 409: - try: - raise ComputeConflict(json.loads(body)) - # If the 409 doesn't come from a GNS3 server - except ValueError: - raise aiohttp.web.HTTPConflict(text=msg) - elif response.status == 500: - raise aiohttp.web.HTTPInternalServerError(text="Internal server error {}".format(url)) - elif response.status == 503: - raise aiohttp.web.HTTPServiceUnavailable(text="Service unavailable {} {}".format(url, body)) - else: - raise NotImplementedError("{} status code is not supported".format(response.status)) - if body and len(body): try: - response.json = json.loads(body) - except ValueError: - raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server".format(self._id)) + msg = json.loads(body)["message"] + except (KeyError, ValueError): + msg = body else: - response.json = {} - return response + msg = "" + + if response.status == 400: + raise aiohttp.web.HTTPBadRequest(text="Bad request {} {}".format(url, body)) + elif response.status == 401: + raise aiohttp.web.HTTPUnauthorized(text="Invalid authentication for compute {}".format(self.id)) + elif response.status == 403: + raise aiohttp.web.HTTPForbidden(text=msg) + elif response.status == 404: + raise aiohttp.web.HTTPNotFound(text=msg) + elif response.status == 409: + try: + raise ComputeConflict(json.loads(body)) + # If the 409 doesn't come from a GNS3 server + except ValueError: + raise aiohttp.web.HTTPConflict(text=msg) + elif response.status == 500: + raise aiohttp.web.HTTPInternalServerError(text="Internal server error {}".format(url)) + elif response.status == 503: + raise aiohttp.web.HTTPServiceUnavailable(text="Service unavailable {} {}".format(url, body)) + else: + raise NotImplementedError("{} status code is not supported".format(response.status)) + if body and len(body): + try: + response.json = json.loads(body) + except ValueError: + raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server".format(self._id)) + else: + response.json = {} + return response @asyncio.coroutine def get(self, path, **kwargs): diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 3034bddd..e229ae69 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -289,6 +289,14 @@ def test_forward_get(compute, async_run): mock.assert_called_with("GET", "https://example.com:84/v2/compute/qemu/images", auth=None, data=None, headers={'content-type': 'application/json'}, chunked=False) +def test_forward_404(compute, async_run): + response = MagicMock() + response.status = 404 + with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: + with pytest.raises(aiohttp.web_exceptions.HTTPNotFound): + async_run(compute.forward("GET", "qemu", "images")) + + def test_forward_post(compute, async_run): response = MagicMock() response.status = 200