soajs.controller 4.2.36 → 4.2.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/header.js +51 -0
- package/lib/request.js +44 -13
- package/mw/gotoService/proxyRequest.js +4 -4
- package/mw/gotoService/redirectToService.js +4 -4
- package/mw/gotoService/simpleRTS.js +4 -4
- package/mw/mt/index.js +9 -4
- package/package.json +1 -1
- package/test/data/provision/marketplace/httpmethods.js +1 -1
- package/test/data/provision/oauth/token/access_token.js +1 -1
- package/test/data/provision/oauth/token/refresh_token.js +1 -1
- package/test/data/provision/urac/users/owner.js +1 -1
- package/test/integration/UC1-gateway-routes/oauth-service-mock.js +10 -8
- package/test/integration/UC2-http-methods/service-mock/soa.json +1 -1
package/lib/header.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright SOAJS All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* Use of this source code is governed by an Apache license that can be
|
|
8
|
+
* found in the LICENSE file at the root of this repository
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Encodes a string to be safely used as an HTTP header value.
|
|
14
|
+
* This preserves all data and is the standard, recommended method.
|
|
15
|
+
*
|
|
16
|
+
* @param {string | number | boolean} value The value to encode.
|
|
17
|
+
* @returns {string} The URL-encoded string.
|
|
18
|
+
*/
|
|
19
|
+
function encodeHeaderValue(value) {
|
|
20
|
+
if (value === null || typeof value === 'undefined') {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
return encodeURIComponent(String(value));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Decodes a URL-encoded string from an HTTP header.
|
|
28
|
+
* It safely handles potential errors if the input is malformed.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} encodedValue The percent-encoded header value to decode.
|
|
31
|
+
* @returns {string} The decoded (original) string, or the original
|
|
32
|
+
* string if decoding fails.
|
|
33
|
+
*/
|
|
34
|
+
function decodeHeaderValue(encodedValue) {
|
|
35
|
+
// Return empty string or null as is, to avoid errors.
|
|
36
|
+
if (!encodedValue) {
|
|
37
|
+
return encodedValue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
// The standard way to decode a value encoded by encodeURIComponent.
|
|
42
|
+
return decodeURIComponent(encodedValue);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// This catches errors from malformed URI sequences (e.g., a lone '%').
|
|
45
|
+
console.error(`Failed to decode header value: "${encodedValue}"`, e);
|
|
46
|
+
// Return the original, undecoded value so the app doesn't crash.
|
|
47
|
+
return encodedValue;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { encodeHeaderValue, decodeHeaderValue };
|
package/lib/request.js
CHANGED
|
@@ -18,6 +18,7 @@ function checkStatus(uri) {
|
|
|
18
18
|
const req = http.get(uri, (res) => {
|
|
19
19
|
if (res.statusCode === 200) {
|
|
20
20
|
onResponse = true;
|
|
21
|
+
res.resume();
|
|
21
22
|
resolve(res.statusCode === 200); // Resolve with true if 200, false otherwise
|
|
22
23
|
}
|
|
23
24
|
// res.on('data', () => { }); // Consume data to avoid issues (important!)
|
|
@@ -28,12 +29,12 @@ function checkStatus(uri) {
|
|
|
28
29
|
return reject(err);
|
|
29
30
|
}
|
|
30
31
|
});
|
|
31
|
-
res.on('close', () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
32
|
+
// res.on('close', () => {
|
|
33
|
+
// if (!onResponse) {
|
|
34
|
+
// onResponse = true;
|
|
35
|
+
// return reject(new Error("Closed"));
|
|
36
|
+
// }
|
|
37
|
+
// });
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
req.on('error', (err) => {
|
|
@@ -42,19 +43,26 @@ function checkStatus(uri) {
|
|
|
42
43
|
return reject(err);
|
|
43
44
|
}
|
|
44
45
|
});
|
|
45
|
-
req.on('close', () => {
|
|
46
|
+
// req.on('close', () => {
|
|
47
|
+
// if (!onResponse) {
|
|
48
|
+
// onResponse = true;
|
|
49
|
+
// return reject(new Error("Closed"));
|
|
50
|
+
// }
|
|
51
|
+
// });
|
|
52
|
+
|
|
53
|
+
req.setTimeout(5000, () => {
|
|
54
|
+
req.destroy();
|
|
46
55
|
if (!onResponse) {
|
|
47
56
|
onResponse = true;
|
|
48
|
-
return reject(new Error(
|
|
57
|
+
return reject(new Error('Request timed out'));
|
|
49
58
|
}
|
|
50
59
|
});
|
|
51
60
|
|
|
52
|
-
|
|
53
61
|
req.end();
|
|
54
62
|
});
|
|
55
63
|
}
|
|
56
64
|
|
|
57
|
-
function httpRequestLight({ uri, data = null, method = 'GET', headers = null, json = true }) {
|
|
65
|
+
function httpRequestLight({ uri, data = null, method = 'GET', headers = null, json = true, timeout = 8000 }) {
|
|
58
66
|
return new Promise((resolve, reject) => {
|
|
59
67
|
let onResponse = false;
|
|
60
68
|
let options = {};
|
|
@@ -96,6 +104,8 @@ function httpRequestLight({ uri, data = null, method = 'GET', headers = null, js
|
|
|
96
104
|
|
|
97
105
|
req.on('response', (res) => { // Listen for the 'response' event
|
|
98
106
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
107
|
+
onResponse = true;
|
|
108
|
+
res.resume();
|
|
99
109
|
return reject(new Error(`Status Code: ${res.statusCode}`));
|
|
100
110
|
}
|
|
101
111
|
|
|
@@ -106,7 +116,6 @@ function httpRequestLight({ uri, data = null, method = 'GET', headers = null, js
|
|
|
106
116
|
});
|
|
107
117
|
|
|
108
118
|
res.on('end', () => {
|
|
109
|
-
|
|
110
119
|
if (!onResponse) {
|
|
111
120
|
onResponse = true;
|
|
112
121
|
try {
|
|
@@ -145,6 +154,17 @@ function httpRequestLight({ uri, data = null, method = 'GET', headers = null, js
|
|
|
145
154
|
}
|
|
146
155
|
});
|
|
147
156
|
|
|
157
|
+
// Handle request timeout
|
|
158
|
+
req.on('timeout', () => {
|
|
159
|
+
req.destroy(); // IMPORTANT: Forcefully end the request
|
|
160
|
+
if (!onResponse) {
|
|
161
|
+
onResponse = true;
|
|
162
|
+
return reject(new Error('Request timed out'));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Set the timeout on the request
|
|
166
|
+
req.setTimeout(timeout);
|
|
167
|
+
|
|
148
168
|
if (data) {
|
|
149
169
|
req.write(requestDataString);
|
|
150
170
|
}
|
|
@@ -153,7 +173,7 @@ function httpRequestLight({ uri, data = null, method = 'GET', headers = null, js
|
|
|
153
173
|
});
|
|
154
174
|
}
|
|
155
175
|
|
|
156
|
-
function httpRequest({ uri, data = null, body = null, qs = null, method = 'GET', headers = null, json = true }) {
|
|
176
|
+
function httpRequest({ uri, data = null, body = null, qs = null, method = 'GET', headers = null, json = true, timeout = 8000 }) {
|
|
157
177
|
return new Promise((resolve, reject) => {
|
|
158
178
|
data = data || body; // to be compatible with request package
|
|
159
179
|
|
|
@@ -270,6 +290,17 @@ function httpRequest({ uri, data = null, body = null, qs = null, method = 'GET',
|
|
|
270
290
|
}
|
|
271
291
|
});
|
|
272
292
|
|
|
293
|
+
// Handle request timeout
|
|
294
|
+
req.on('timeout', () => {
|
|
295
|
+
req.destroy(); // IMPORTANT: Forcefully end the request
|
|
296
|
+
if (!onResponse) {
|
|
297
|
+
onResponse = true;
|
|
298
|
+
return reject(new Error('Request timed out'));
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
// Set the timeout on the request
|
|
302
|
+
req.setTimeout(timeout);
|
|
303
|
+
|
|
273
304
|
if (data) {
|
|
274
305
|
req.write(requestDataString);
|
|
275
306
|
}
|
|
@@ -288,7 +319,7 @@ function proxyRequest(req, res, options, extraOptions = {}) {
|
|
|
288
319
|
} else {
|
|
289
320
|
proxyReq = http.request(options);
|
|
290
321
|
}
|
|
291
|
-
|
|
322
|
+
|
|
292
323
|
if (extraOptions && extraOptions.fetchProxReq) {
|
|
293
324
|
extraOptions.fetchProxReq(proxyReq);
|
|
294
325
|
}
|
|
@@ -79,10 +79,10 @@ module.exports = (configuration) => {
|
|
|
79
79
|
.then(() => { })
|
|
80
80
|
.catch((error) => {
|
|
81
81
|
req.soajs.log.error(error.message);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
if (req.soajs.controller.redirectedRequest) {
|
|
83
|
+
req.soajs.controller.redirectedRequest.destroy();
|
|
84
|
+
req.soajs.controller.redirectedRequest = null;
|
|
85
|
+
}
|
|
86
86
|
return req.soajs.controllerResponse(core.error.getError(135));
|
|
87
87
|
});
|
|
88
88
|
};
|
|
@@ -220,10 +220,10 @@ module.exports = (configuration) => {
|
|
|
220
220
|
})
|
|
221
221
|
.catch((err) => {
|
|
222
222
|
req.soajs.log.error(err.message + ' with [' + restServiceParams.name + (restServiceParams.version ? ('@' + restServiceParams.version) : '') + ']');
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
if (req.soajs.controller.redirectedRequest) {
|
|
224
|
+
req.soajs.controller.redirectedRequest.destroy();
|
|
225
|
+
req.soajs.controller.redirectedRequest = null;
|
|
226
|
+
}
|
|
227
227
|
if (!req.soajs.controller.monitorEndingReq) {
|
|
228
228
|
req.soajs.controllerResponse(core.error.getError(135));
|
|
229
229
|
}
|
|
@@ -60,10 +60,10 @@ module.exports = (configuration) => {
|
|
|
60
60
|
})
|
|
61
61
|
.catch((err) => {
|
|
62
62
|
req.soajs.log.error(err.code, err.message);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if (req.soajs.controller.redirectedRequest) {
|
|
64
|
+
req.soajs.controller.redirectedRequest.destroy();
|
|
65
|
+
req.soajs.controller.redirectedRequest = null;
|
|
66
|
+
}
|
|
67
67
|
if (!req.soajs.controller.monitorEndingReq) {
|
|
68
68
|
return req.soajs.controllerResponse(core.error.getError(135));
|
|
69
69
|
}
|
package/mw/mt/index.js
CHANGED
|
@@ -12,6 +12,9 @@ const async = require("async");
|
|
|
12
12
|
|
|
13
13
|
const utils = require("./utils");
|
|
14
14
|
|
|
15
|
+
|
|
16
|
+
const { encodeHeaderValue } = require("../../lib/header.js");
|
|
17
|
+
|
|
15
18
|
/**
|
|
16
19
|
*
|
|
17
20
|
* @param configuration
|
|
@@ -247,8 +250,8 @@ module.exports = (configuration) => {
|
|
|
247
250
|
injectObj.urac = {
|
|
248
251
|
"_id": uracObj._id,
|
|
249
252
|
"username": uracObj.username,
|
|
250
|
-
"firstName": uracObj.firstName,
|
|
251
|
-
"lastName": uracObj.lastName,
|
|
253
|
+
"firstName": encodeHeaderValue(uracObj.firstName),
|
|
254
|
+
"lastName": encodeHeaderValue(uracObj.lastName),
|
|
252
255
|
"email": uracObj.email,
|
|
253
256
|
"groups": uracObj.groups,
|
|
254
257
|
"socialLogin": uracObj.socialLogin,
|
|
@@ -336,12 +339,14 @@ module.exports = (configuration) => {
|
|
|
336
339
|
req.soajs.log.error(err.message);
|
|
337
340
|
}
|
|
338
341
|
let _h = JSON.stringify(injectObj);
|
|
339
|
-
req.headers.soajsinjectobj = Buffer.from(_h, 'ascii').toString('utf-8');
|
|
342
|
+
// req.headers.soajsinjectobj = Buffer.from(_h, 'ascii').toString('utf-8');
|
|
343
|
+
req.headers.soajsinjectobj = _h; //encodeHeaderValue(_h);
|
|
340
344
|
return next();
|
|
341
345
|
});
|
|
342
346
|
} else {
|
|
343
347
|
let _h = JSON.stringify(injectObj);
|
|
344
|
-
req.headers.soajsinjectobj = Buffer.from(_h, 'ascii').toString('utf-8');
|
|
348
|
+
// req.headers.soajsinjectobj = Buffer.from(_h, 'ascii').toString('utf-8');
|
|
349
|
+
req.headers.soajsinjectobj = _h; //encodeHeaderValue(_h);
|
|
345
350
|
return next();
|
|
346
351
|
}
|
|
347
352
|
}
|
package/package.json
CHANGED
|
@@ -20,15 +20,17 @@ function startServer(serverConfig, callback) {
|
|
|
20
20
|
'lastname': "hage"
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
sApp.get('/passport/login', (req, res) =>
|
|
26
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
sApp.get('/passport/login', (req, res) => {
|
|
26
|
+
res.json(sReply);
|
|
27
|
+
});
|
|
28
|
+
|
|
27
29
|
mApp.get('/heartbeat', (req, res) => res.json(mReply));
|
|
28
|
-
|
|
30
|
+
|
|
29
31
|
let sAppServer = sApp.listen(serverConfig.s.port, () => console.log(`${serverConfig.name} service mock listening on port ${serverConfig.s.port}!`));
|
|
30
32
|
let mAppServer = mApp.listen(serverConfig.m.port, () => console.log(`${serverConfig.name} service mock listening on port ${serverConfig.m.port}!`));
|
|
31
|
-
|
|
33
|
+
|
|
32
34
|
return callback(
|
|
33
35
|
{
|
|
34
36
|
"sAppServer": sAppServer,
|
|
@@ -40,11 +42,11 @@ function startServer(serverConfig, callback) {
|
|
|
40
42
|
|
|
41
43
|
function killServer(config) {
|
|
42
44
|
console.log("killing server ....");
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
config.mAppServer.close((err) => {
|
|
45
47
|
console.log("...sAppServer: " + config.name);
|
|
46
48
|
});
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
config.sAppServer.close((err) => {
|
|
49
51
|
console.log("...mAppServer: " + config.name);
|
|
50
52
|
});
|