diff --git a/src/main/node/infrastructure/service/instance.js b/src/main/node/infrastructure/service/instance.js index a55a324a94f41989aaf566ca3644e13253d4e47e..57df8ce0fc61b648acaf06d41dc652b5ecba3f93 100644 --- a/src/main/node/infrastructure/service/instance.js +++ b/src/main/node/infrastructure/service/instance.js @@ -56,6 +56,7 @@ class Instance { buildRequestOptions(req) { let pathname = `${this.basePath}${req.path}`.replace('//', '/'); + let responseType = this.determineResponseType(req); let answer = { url: url.format({ protocol: this.protocol, hostname: this.host, port: this.port, pathname: pathname, query: req.query }), method: req.method.toLowerCase(), @@ -65,7 +66,12 @@ class Instance { acc[header[0]] = header[1]; } return acc; - }, {}) + }, {}), + // https://gitlab.com/codesketch/ipa/issues/5 + // as a defuault set responseType as arraybuffer so the we get the result as is, + // see https://github.com/axios/axios/blob/ccc78899bb6f595e3c44ec7ad6af610455859d78/lib/adapters/http.js#L197 + // that means the response can be trated as utf8 string only if needed meaning that the response is json, xml, etc. + responseType: responseType }; if (['post', 'put', 'patch'].includes(req.method.toLowerCase())) { answer.data = req.body; @@ -73,6 +79,17 @@ class Instance { logger.debug('request options', JSON.stringify(answer)); return answer; } + + determineResponseType(req) { + let answer = 'arraybuffer'; + if (req.headers.accept) { + const match = /.+\/(.+)/gi.exec(req.headers.accept); + if (['javascript', 'json', 'plain', 'csv', 'xml', 'css', 'html',].some(st => match[1] == st)) { + answer = match[1]; + } + } + return answer; + } } /** diff --git a/src/main/node/infrastructure/service/service.js b/src/main/node/infrastructure/service/service.js index 581941d89d12b9b60363b88172a0861638865565..d198871537e30fa9f494ae16c6553542358f1a47 100644 --- a/src/main/node/infrastructure/service/service.js +++ b/src/main/node/infrastructure/service/service.js @@ -111,9 +111,28 @@ class Service { * @private */ propagateResponse(clientResponse, serverResponse) { - clientResponse.status(serverResponse.status); - Object.entries(serverResponse.headers || {}).forEach(entry => clientResponse.set(entry[0], entry[1])); - clientResponse.send(serverResponse.data); + try { + // https://gitlab.com/codesketch/ipa/issues/5 + // identity the response type based on the response content-type and decide what to do with the response. + let responseData = this.extractResponseData(serverResponse); + clientResponse.status(serverResponse.status); + Object.entries(serverResponse.headers || {}).forEach(entry => clientResponse.set(entry[0], entry[1])); + clientResponse.send(responseData); + } catch (e) { + logger.error('unable to handle response', e); + clientResponse.status(500).json({ message: 'Internal Server Error' }); + } + } + + extractResponseData(res) { + let answer = res.data; + if (res.headers['content-type']) { + const match = /.+\/(.+)/gi.exec(res.headers['content-type']); + if (['javascript', 'json', 'plain', 'csv', 'xml', 'css', 'html',].some(st => match[1] == st)) { + answer = answer.toString('utf-8'); + } + } + return answer; } } diff --git a/src/main/resources/routes.yml b/src/main/resources/routes.yml index d4a62cac5612446f3a09ffc8a22efc4050b66697..7948d229c7e927b081db6d232a00d9b04828c997 100644 --- a/src/main/resources/routes.yml +++ b/src/main/resources/routes.yml @@ -9,6 +9,42 @@ info: servers: - url: http://localhost:3030 paths: + /images/places/{placeId}: + get: + summary: Retrieve the image for a place + operationId: getPlaceImage + backend: + $ref: "#/backends/images" + authentication: + $ref: "#/authentications/api-key" + policies: + - $ref: "#/policies/spike-arrest" + - $ref: "#/policies/quota" + tags: + - images + security: + - ApiKeyAuth: [] + parameters: + - name: placeId + in: path + required: true + description: The identifier for the place to retrieve + schema: + type: string + responses: + '200': + description: Place image + content: + image/png: + schema: + $ref: "#/components/schemas/Image" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /uuid: get: summary: Get a UUID from httpbin @@ -51,7 +87,7 @@ paths: cache: - $ref: "#/cache" tags: - - pets + - anything security: - ApiKeyAuth: [] parameters: @@ -88,6 +124,10 @@ components: name: Authorization schemas: + Image: + type: string + format: binary + UUID: required: - uuid @@ -116,6 +156,9 @@ backends: protocol: http service: places port: 3030 + images: + type: webDiscoveryService + target: https://api.prod.daphne-trails.com/api/ authentications: api-key: