@requestly/requestly-proxy 1.1.19 → 1.1.21
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/dist/components/proxy-middleware/helpers/harObectCreator.d.ts +3 -3
- package/dist/components/proxy-middleware/helpers/harObectCreator.js +28 -11
- package/dist/components/proxy-middleware/helpers/proxy_ctx_helper.d.ts +7 -0
- package/dist/components/proxy-middleware/helpers/proxy_ctx_helper.js +51 -7
- package/dist/components/proxy-middleware/index.js +3 -10
- package/dist/components/proxy-middleware/middlewares/logger_middleware.js +1 -1
- package/dist/components/proxy-middleware/rule_action_processor/processors/modify_response_processor.js +18 -3
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ export function createRequestHarObject(requestHarObject: any, proxyToServerReque
|
|
|
9
9
|
url: any;
|
|
10
10
|
postData: any;
|
|
11
11
|
};
|
|
12
|
-
export function createHar(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any, responseStatusCode: any, response: any, responseHeaders: any): {
|
|
12
|
+
export function createHar(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any, responseStatusCode: any, response: any, responseHeaders: any, requestParams: any): {
|
|
13
13
|
log: {
|
|
14
14
|
version: string;
|
|
15
15
|
creator: {};
|
|
@@ -60,7 +60,7 @@ export function createHar(requestHeaders: any, method: any, protocol: any, host:
|
|
|
60
60
|
comment: string;
|
|
61
61
|
};
|
|
62
62
|
};
|
|
63
|
-
export function createHarEntry(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any, responseStatusCode: any, response: any, responseHeaders: any): {
|
|
63
|
+
export function createHarEntry(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any, responseStatusCode: any, response: any, responseHeaders: any, requestParams: any): {
|
|
64
64
|
startedDateTime: string;
|
|
65
65
|
request: {
|
|
66
66
|
bodySize: number;
|
|
@@ -102,7 +102,7 @@ export function createHarEntry(requestHeaders: any, method: any, protocol: any,
|
|
|
102
102
|
timings: {};
|
|
103
103
|
comment: string;
|
|
104
104
|
};
|
|
105
|
-
export function createHarRequest(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any): {
|
|
105
|
+
export function createHarRequest(requestHeaders: any, method: any, protocol: any, host: any, path: any, requestBody: any, requestParams: any): {
|
|
106
106
|
bodySize: number;
|
|
107
107
|
headersSize: number;
|
|
108
108
|
httpVersion: string;
|
|
@@ -14,9 +14,26 @@ const createHarHeaders = (request_headers_obj) => {
|
|
|
14
14
|
}
|
|
15
15
|
return headers;
|
|
16
16
|
};
|
|
17
|
-
const createHarQueryStrings = (
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const createHarQueryStrings = (query_params) => {
|
|
18
|
+
let res = [];
|
|
19
|
+
Object.keys(query_params).forEach(query => {
|
|
20
|
+
const query_value = query_params[query];
|
|
21
|
+
if (Array.isArray(query_value)) {
|
|
22
|
+
query_value.forEach(val => {
|
|
23
|
+
res.push({
|
|
24
|
+
"name": query,
|
|
25
|
+
"value": val
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
res.push({
|
|
31
|
+
"name": query,
|
|
32
|
+
"value": query_value
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return res;
|
|
20
37
|
};
|
|
21
38
|
const getContentType = (headers) => {
|
|
22
39
|
let contentType = null;
|
|
@@ -78,7 +95,7 @@ const createHarPostData = (body, headers) => {
|
|
|
78
95
|
// create standard request har object: http://www.softwareishard.com/blog/har-12-spec/#request
|
|
79
96
|
// URL: https://github.com/hoppscotch/hoppscotch/blob/75ab7fdb00c0129ad42d45165bd3ad0af1faca2e/packages/hoppscotch-app/helpers/new-codegen/har.ts#L26
|
|
80
97
|
const createRequestHarObject = (requestHarObject, proxyToServerRequestOptions) => {
|
|
81
|
-
const { method, host, path, body, headers, agent, } = proxyToServerRequestOptions;
|
|
98
|
+
const { method, host, path, body, headers, agent, query_params } = proxyToServerRequestOptions;
|
|
82
99
|
return {
|
|
83
100
|
bodySize: -1,
|
|
84
101
|
headersSize: -1,
|
|
@@ -86,32 +103,32 @@ const createRequestHarObject = (requestHarObject, proxyToServerRequestOptions) =
|
|
|
86
103
|
cookies: [],
|
|
87
104
|
headers: requestHarObject.headers || createHarHeaders(headers),
|
|
88
105
|
method: requestHarObject.method || method,
|
|
89
|
-
queryString: requestHarObject.queryString || createHarQueryStrings(
|
|
106
|
+
queryString: requestHarObject.queryString || createHarQueryStrings(query_params),
|
|
90
107
|
url: requestHarObject.url || ((agent === null || agent === void 0 ? void 0 : agent.protocol) || "http:") + "//" + host + path,
|
|
91
108
|
postData: requestHarObject.postData ||
|
|
92
109
|
createHarPostData(body, requestHarObject.headers),
|
|
93
110
|
};
|
|
94
111
|
};
|
|
95
112
|
exports.createRequestHarObject = createRequestHarObject;
|
|
96
|
-
const createHar = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders) => {
|
|
113
|
+
const createHar = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders, requestParams) => {
|
|
97
114
|
return {
|
|
98
115
|
"log": {
|
|
99
116
|
"version": "1.2",
|
|
100
117
|
"creator": {},
|
|
101
118
|
"browser": {},
|
|
102
119
|
"pages": [],
|
|
103
|
-
"entries": [(0, exports.createHarEntry)(requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders)],
|
|
120
|
+
"entries": [(0, exports.createHarEntry)(requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders, requestParams)],
|
|
104
121
|
"comment": ""
|
|
105
122
|
}
|
|
106
123
|
};
|
|
107
124
|
};
|
|
108
125
|
exports.createHar = createHar;
|
|
109
|
-
const createHarEntry = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders) => {
|
|
126
|
+
const createHarEntry = (requestHeaders, method, protocol, host, path, requestBody, responseStatusCode, response, responseHeaders, requestParams) => {
|
|
110
127
|
return {
|
|
111
128
|
// "pageref": "page_0",
|
|
112
129
|
"startedDateTime": new Date().toISOString(),
|
|
113
130
|
// "time": 50,
|
|
114
|
-
"request": (0, exports.createHarRequest)(requestHeaders, method, protocol, host, path, requestBody),
|
|
131
|
+
"request": (0, exports.createHarRequest)(requestHeaders, method, protocol, host, path, requestBody, requestParams),
|
|
115
132
|
"response": (0, exports.createHarResponse)(responseStatusCode, response, responseHeaders),
|
|
116
133
|
"cache": {},
|
|
117
134
|
"timings": {},
|
|
@@ -121,7 +138,7 @@ const createHarEntry = (requestHeaders, method, protocol, host, path, requestBod
|
|
|
121
138
|
};
|
|
122
139
|
};
|
|
123
140
|
exports.createHarEntry = createHarEntry;
|
|
124
|
-
const createHarRequest = (requestHeaders, method, protocol, host, path, requestBody) => {
|
|
141
|
+
const createHarRequest = (requestHeaders, method, protocol, host, path, requestBody, requestParams) => {
|
|
125
142
|
return {
|
|
126
143
|
bodySize: -1,
|
|
127
144
|
headersSize: -1,
|
|
@@ -129,7 +146,7 @@ const createHarRequest = (requestHeaders, method, protocol, host, path, requestB
|
|
|
129
146
|
cookies: [],
|
|
130
147
|
headers: createHarHeaders(requestHeaders),
|
|
131
148
|
method: method,
|
|
132
|
-
queryString: createHarQueryStrings(
|
|
149
|
+
queryString: createHarQueryStrings(requestParams),
|
|
133
150
|
url: protocol + "://" + host + path,
|
|
134
151
|
postData: createHarPostData(requestBody, createHarHeaders(requestHeaders)),
|
|
135
152
|
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param queryString e.g. ?a=1&b=2 or a=1 or ''
|
|
4
|
+
* @returns object { paramName -> [value1, value2] }
|
|
5
|
+
*/
|
|
6
|
+
export function getQueryParamsMap(queryString: any): {};
|
|
1
7
|
export function get_request_url(ctx: any): string;
|
|
2
8
|
export function get_original_request_headers(ctx: any): any;
|
|
3
9
|
export function get_original_response_headers(ctx: any): any;
|
|
@@ -7,6 +13,7 @@ export function get_response_options(ctx: any): {
|
|
|
7
13
|
headers: any;
|
|
8
14
|
};
|
|
9
15
|
export function get_request_options(ctx: any): any;
|
|
16
|
+
export function get_json_query_params(ctx: any): {};
|
|
10
17
|
export function getRequestHeaders(ctx: any): any;
|
|
11
18
|
export function getRequestContentTypeHeader(ctx: any): any;
|
|
12
19
|
export function getResponseHeaders(ctx: any): any;
|
|
@@ -6,7 +6,50 @@
|
|
|
6
6
|
// } from "../../../../../../../common/components/utils/utils";
|
|
7
7
|
// const CONSTANTS = require("../../../../../../../common/constants");
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.getResponseStatusCode = exports.getResponseContentTypeHeader = exports.getResponseHeaders = exports.getRequestContentTypeHeader = exports.getRequestHeaders = exports.get_request_options = exports.get_response_options = exports.is_request_preflight = exports.get_original_response_headers = exports.get_original_request_headers = exports.get_request_url = void 0;
|
|
9
|
+
exports.getResponseStatusCode = exports.getResponseContentTypeHeader = exports.getResponseHeaders = exports.getRequestContentTypeHeader = exports.getRequestHeaders = exports.get_json_query_params = exports.get_request_options = exports.get_response_options = exports.is_request_preflight = exports.get_original_response_headers = exports.get_original_request_headers = exports.get_request_url = exports.getQueryParamsMap = void 0;
|
|
10
|
+
const requestly_core_1 = require("@requestly/requestly-core");
|
|
11
|
+
function extractUrlComponent(url, name) {
|
|
12
|
+
const myUrl = new URL(url);
|
|
13
|
+
switch (name) {
|
|
14
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.URL:
|
|
15
|
+
return url;
|
|
16
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.PROTOCOL:
|
|
17
|
+
return myUrl.protocol;
|
|
18
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.HOST:
|
|
19
|
+
return myUrl.host;
|
|
20
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.PATH:
|
|
21
|
+
return myUrl.pathname;
|
|
22
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.QUERY:
|
|
23
|
+
return myUrl.search;
|
|
24
|
+
case requestly_core_1.CONSTANTS.URL_COMPONENTS.HASH:
|
|
25
|
+
return myUrl.hash;
|
|
26
|
+
}
|
|
27
|
+
console.error("Invalid source key", url, name);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param queryString e.g. ?a=1&b=2 or a=1 or ''
|
|
32
|
+
* @returns object { paramName -> [value1, value2] }
|
|
33
|
+
*/
|
|
34
|
+
function getQueryParamsMap(queryString) {
|
|
35
|
+
var map = {}, queryParams;
|
|
36
|
+
if (!queryString || queryString === "?") {
|
|
37
|
+
return map;
|
|
38
|
+
}
|
|
39
|
+
if (queryString[0] === "?") {
|
|
40
|
+
queryString = queryString.substr(1);
|
|
41
|
+
}
|
|
42
|
+
queryParams = queryString.split("&");
|
|
43
|
+
queryParams.forEach(function (queryParam) {
|
|
44
|
+
var paramName = queryParam.split("=")[0], paramValue = queryParam.split("=")[1];
|
|
45
|
+
// We are keeping value of param as array so that in future we can support multiple param values of same name
|
|
46
|
+
// And we do not want to lose the params if url already contains multiple params of same name
|
|
47
|
+
map[paramName] = map[paramName] || [];
|
|
48
|
+
map[paramName].push(paramValue);
|
|
49
|
+
});
|
|
50
|
+
return map;
|
|
51
|
+
}
|
|
52
|
+
exports.getQueryParamsMap = getQueryParamsMap;
|
|
10
53
|
const get_request_url = (ctx) => {
|
|
11
54
|
return ((ctx.isSSL ? "https://" : "http://") +
|
|
12
55
|
ctx.clientToProxyRequest.headers.host +
|
|
@@ -49,14 +92,15 @@ const get_response_options = (ctx) => {
|
|
|
49
92
|
};
|
|
50
93
|
exports.get_response_options = get_response_options;
|
|
51
94
|
const get_request_options = (ctx) => {
|
|
52
|
-
return Object.assign({}, ctx.proxyToServerRequestOptions);
|
|
95
|
+
return Object.assign(Object.assign({}, ctx.proxyToServerRequestOptions), { query_params: (0, exports.get_json_query_params)(ctx) });
|
|
53
96
|
};
|
|
54
97
|
exports.get_request_options = get_request_options;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
98
|
+
const get_json_query_params = (ctx) => {
|
|
99
|
+
const url = (0, exports.get_request_url)(ctx);
|
|
100
|
+
let queryString = extractUrlComponent(url, requestly_core_1.CONSTANTS.URL_COMPONENTS.QUERY);
|
|
101
|
+
return getQueryParamsMap(queryString) || null;
|
|
102
|
+
};
|
|
103
|
+
exports.get_json_query_params = get_json_query_params;
|
|
60
104
|
const getRequestHeaders = (ctx) => {
|
|
61
105
|
if (ctx && ctx.proxyToServerRequestOptions) {
|
|
62
106
|
return ctx.proxyToServerRequestOptions.headers || {};
|
|
@@ -160,18 +160,11 @@ class ProxyMiddlewareManager {
|
|
|
160
160
|
const contentTypeHeader = (0, proxy_ctx_helper_1.getResponseContentTypeHeader)(ctx);
|
|
161
161
|
const contentType = (0, http_helpers_1.getContentType)(contentTypeHeader);
|
|
162
162
|
const parsedBody = (0, http_helpers_1.bodyParser)(contentTypeHeader, body);
|
|
163
|
+
ctx.rq.set_original_response({ body: parsedBody });
|
|
163
164
|
ctx.rq_response_body = body;
|
|
165
|
+
ctx.rq_parsed_response_body = parsedBody;
|
|
164
166
|
ctx.rq_response_status_code = (0, proxy_ctx_helper_1.getResponseStatusCode)(ctx);
|
|
165
|
-
|
|
166
|
-
ctx.rq.set_original_response({ body: parsedBody });
|
|
167
|
-
// Body and status code before any modifications
|
|
168
|
-
ctx.rq_response_body = parsedBody;
|
|
169
|
-
const { action_result_objs, continue_request } = yield rules_middleware.on_response_end(ctx);
|
|
170
|
-
// ctx.rq_response_body, ctx.rq_response_status_code after modifications
|
|
171
|
-
// TODO: @sahil to investigate why this is need
|
|
172
|
-
// Remove some conflicting headers like content-length, if any
|
|
173
|
-
delete (0, proxy_ctx_helper_1.getResponseHeaders)(ctx)["content-length"];
|
|
174
|
-
}
|
|
167
|
+
const { action_result_objs, continue_request } = yield rules_middleware.on_response_end(ctx);
|
|
175
168
|
const statusCode = ctx.rq_response_status_code || (0, proxy_ctx_helper_1.getResponseStatusCode)(ctx);
|
|
176
169
|
ctx.proxyToClientResponse.writeHead(statusCode, http_1.default.STATUS_CODES[statusCode], (0, proxy_ctx_helper_1.getResponseHeaders)(ctx));
|
|
177
170
|
ctx.proxyToClientResponse.write(ctx.rq_response_body);
|
|
@@ -75,7 +75,7 @@ class LoggerMiddleware {
|
|
|
75
75
|
const rqLog = {
|
|
76
76
|
id: ctx.uuid,
|
|
77
77
|
timestamp: Math.floor(Date.now() / 1000),
|
|
78
|
-
finalHar: (0, harObectCreator_1.createHar)(ctx.rq.final_request.headers, ctx.rq.final_request.method, protocol, ctx.rq.final_request.host, ctx.rq.final_request.path, ctx.rq.final_request.body, ctx.rq.final_response.status_code, ctx.rq.final_response.body, ctx.rq.final_response.headers || {}),
|
|
78
|
+
finalHar: (0, harObectCreator_1.createHar)(ctx.rq.final_request.headers, ctx.rq.final_request.method, protocol, ctx.rq.final_request.host, ctx.rq.final_request.path, ctx.rq.final_request.body, ctx.rq.final_response.status_code, ctx.rq.final_response.body, ctx.rq.final_response.headers || {}, ctx.rq.final_request.query_params),
|
|
79
79
|
requestShellCurl: this.generate_curl_from_har((_b = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.rq) === null || _a === void 0 ? void 0 : _a.final_request) === null || _b === void 0 ? void 0 : _b.requestHarObject),
|
|
80
80
|
actions: (0, utils_1.get_success_actions_from_action_results)(action_result_objs),
|
|
81
81
|
consoleLogs: (_c = ctx === null || ctx === void 0 ? void 0 : ctx.rq) === null || _c === void 0 ? void 0 : _c.consoleLogs,
|
|
@@ -20,6 +20,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
20
20
|
const http_helpers_1 = require("../../helpers/http_helpers");
|
|
21
21
|
const capture_console_logs_1 = __importDefault(require("capture-console-logs"));
|
|
22
22
|
const utils_2 = require("../../../../utils");
|
|
23
|
+
const constants_1 = require("../../constants");
|
|
23
24
|
const { types } = require("util");
|
|
24
25
|
const process_modify_response_action = (action, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
26
|
const allowed_handlers = [proxy_1.PROXY_HANDLER_TYPE.ON_REQUEST, proxy_1.PROXY_HANDLER_TYPE.ON_RESPONSE_END, proxy_1.PROXY_HANDLER_TYPE.ON_ERROR];
|
|
@@ -47,18 +48,32 @@ const process_modify_response_action = (action, ctx) => __awaiter(void 0, void 0
|
|
|
47
48
|
}
|
|
48
49
|
if (action.responseType &&
|
|
49
50
|
action.responseType === requestly_core_1.CONSTANTS.RESPONSE_BODY_TYPES.CODE) {
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const contentTypeHeader = (0, proxy_ctx_helper_1.getResponseContentTypeHeader)(ctx);
|
|
52
|
+
const contentType = (0, http_helpers_1.getContentType)(contentTypeHeader);
|
|
53
|
+
if (constants_1.RQ_INTERCEPTED_CONTENT_TYPES.includes(contentType) || contentType == null) {
|
|
54
|
+
yield modify_response_using_code(action, ctx);
|
|
55
|
+
delete_breaking_headers(ctx);
|
|
56
|
+
return (0, utils_1.build_action_processor_response)(action, true);
|
|
57
|
+
}
|
|
58
|
+
// Sentry not working
|
|
59
|
+
// Sentry.captureException(new Error(`Content Type ${contentType} not supported for modification in programmatic mode`));
|
|
60
|
+
console.log(`Content Type ${contentType} not supported for modification in programmatic mode`);
|
|
61
|
+
return (0, utils_1.build_action_processor_response)(action, false);
|
|
52
62
|
}
|
|
53
63
|
else if (action.responseType === requestly_core_1.CONSTANTS.RESPONSE_BODY_TYPES.LOCAL_FILE) {
|
|
54
64
|
modify_response_using_local(action, ctx);
|
|
65
|
+
delete_breaking_headers(ctx);
|
|
55
66
|
return (0, utils_1.build_action_processor_response)(action, true);
|
|
56
67
|
}
|
|
57
68
|
else {
|
|
58
69
|
modify_response(ctx, action.response, action.statusCode);
|
|
70
|
+
delete_breaking_headers(ctx);
|
|
59
71
|
return (0, utils_1.build_action_processor_response)(action, true);
|
|
60
72
|
}
|
|
61
73
|
});
|
|
74
|
+
const delete_breaking_headers = (ctx) => {
|
|
75
|
+
delete (0, proxy_ctx_helper_1.getResponseHeaders)(ctx)['content-length'];
|
|
76
|
+
};
|
|
62
77
|
const modify_response = (ctx, new_resp, status_code) => {
|
|
63
78
|
ctx.rq_response_body = new_resp;
|
|
64
79
|
ctx.rq_response_status_code = status_code;
|
|
@@ -97,7 +112,7 @@ const modify_response_using_code = (action, ctx) => __awaiter(void 0, void 0, vo
|
|
|
97
112
|
? ctx.clientToProxyRequest.method
|
|
98
113
|
: null
|
|
99
114
|
: null,
|
|
100
|
-
response: ctx === null || ctx === void 0 ? void 0 : ctx.
|
|
115
|
+
response: ctx === null || ctx === void 0 ? void 0 : ctx.rq_parsed_response_body,
|
|
101
116
|
url: (0, proxy_ctx_helper_1.get_request_url)(ctx),
|
|
102
117
|
responseType: (_c = (_b = ctx === null || ctx === void 0 ? void 0 : ctx.serverToProxyResponse) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c["content-type"],
|
|
103
118
|
requestHeaders: ctx.clientToProxyRequest.headers,
|