| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 |
1×
1×
1×
1×
1×
1×
4×
4×
2×
2×
2×
1×
1×
1×
3×
2×
1×
1×
1×
6×
6×
6×
6×
3×
3×
1×
1×
2×
1×
1×
1×
1×
8×
8×
8×
8×
2×
2×
1×
1×
3×
3×
8×
1×
8×
1×
1×
8×
1×
| 'use strict';
const util = require('./util');
const parseString = require('xml2js').parseString;
const parseNumbers = require('xml2js').processors.parseNumbers;
const parseBooleans = require('xml2js').processors.parseBooleans;
const httpStatus = require('http-status');
const jsonResponseHandler = (res, rawBody, context, output) => {
let convertedResponse;
if(res.statusCode === 204) {
convertedResponse = output.convertResponse({
headers: res.headers,
body: {},
status: res.statusMessage,
statusCode: res.statusCode
});
} else {
try {
const parsed = JSON.parse(rawBody.trim());
convertedResponse = output.convertResponse({
headers: res.headers,
body: parsed,
status: res.statusMessage,
statusCode: res.statusCode
});
} catch (err) {
console.warn("couldn't parse JSON:", rawBody.trim(), err);
context.fail(util.failure(500, err, 'Internal Service Error'));
}
}
if(convertedResponse.statusCode >= 200 && convertedResponse.statusCode <= 207) {
context.succeed(convertedResponse);
} else {
// Sometimes vendors tell us everything is okay, but it's really not
const errors = convertedResponse.body.errors || convertedResponse.body;
context.done(util.failure(convertedResponse.statusCode, JSON.stringify(errors), httpStatus[convertedResponse.statusCode]), convertedResponse);
}
};
const xmlResponseHandler = (res, rawBody, context, output) => {
const options = {
trim: true,
ignoreAttrs: false,
explicitArray: false,
explicitRoot: true,
mergeAttrs:true,
valueProcessors: [ parseNumbers, parseBooleans]
};
parseString(rawBody, options, (err, result) => {
let convertedResponse;
if (util.notNull(err)) { context.fail(util.failure(400, err)); }
else {
try {
convertedResponse = output.convertResponse({
headers: res.headers,
body: result,
status: res.statusMessage,
statusCode: res.statusCode
});
} catch (err) {
console.warn("couldn't parse JSON:", rawBody.trim(), err);
context.fail(util.failure(500, err, 'Internal Service Error'));
}
if(convertedResponse.statusCode >= 200 && convertedResponse.statusCode <= 207) {
context.succeed(convertedResponse);
} else {
const errors = convertedResponse.body.errors || convertedResponse.body;
context.done(util.failure(convertedResponse.statusCode, JSON.stringify(errors), httpStatus[convertedResponse.statusCode]), convertedResponse);
}
}
});
};
const getResponseHandler = (headers, handlerType) => {
const contentTypeHeader = headers['content-type'] ? headers['content-type'].split(';')[0].toLowerCase() : '';
const contentType = handlerType ? handlerType : contentTypeHeader;
let handler;
switch(contentType) {
case 'application/json':
case 'application/jsonp':
handler = jsonResponseHandler;
break;
case 'application/atom+xml':
case 'application/xml':
handler = xmlResponseHandler;
break;
case 'soap':
handler = xmlResponseHandler;
break;
}
// If the handler is null and the contentType contains xml anywhere in the string
// use xmlResponseHandler
if(!util.notNull(handler) && contentType.includes('xml')) {
handler = xmlResponseHandler;
}
if(!util.notNull(handler)) {
console.warn('No response type was returned from the vendor. Assuming JSON');
handler = jsonResponseHandler;
}
return handler;
};
module.exports = {getResponseHandler, xmlResponseHandler, jsonResponseHandler};
|