@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.
@@ -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 = (path) => {
18
- // TODO -> http://www.softwareishard.com/blog/har-12-spec/#queryString
19
- return [];
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(path),
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(path),
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
- // export const get_json_query_params = (ctx) => {
56
- // const url = get_request_url(ctx);
57
- // let queryString = extractUrlComponent(url, CONSTANTS.URL_COMPONENTS.QUERY);
58
- // return getQueryParamsMap(queryString) || null;
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
- if (constants_1.RQ_INTERCEPTED_CONTENT_TYPES.includes(contentType) && parsedBody) {
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
- yield modify_response_using_code(action, ctx);
51
- return (0, utils_1.build_action_processor_response)(action, true);
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.rq_response_body,
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@requestly/requestly-proxy",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "description": "Proxy that gives superpowers to all the Requestly clients",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {