@requestly/requestly-proxy 1.3.9 → 1.3.11
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/handleUnreachableAddress.d.ts +6 -0
- package/dist/components/proxy-middleware/helpers/handleUnreachableAddress.js +86 -0
- package/dist/components/proxy-middleware/index.js +36 -4
- package/dist/components/proxy-middleware/rule_action_processor/handle_mixed_response.d.ts +2 -2
- package/dist/components/proxy-middleware/rule_action_processor/handle_mixed_response.js +5 -1
- package/package.json +2 -2
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isAddressUnreachableError = isAddressUnreachableError;
|
|
7
|
+
exports.dataToServeUnreachablePage = dataToServeUnreachablePage;
|
|
8
|
+
const dns_1 = __importDefault(require("dns"));
|
|
9
|
+
function isAddressUnreachableError(host) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
dns_1.default.lookup(host, (err, address) => {
|
|
12
|
+
if (err) {
|
|
13
|
+
if (err.code === 'ENOTFOUND') {
|
|
14
|
+
resolve(true);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
reject(err);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
resolve(false);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function dataToServeUnreachablePage(host) {
|
|
27
|
+
return {
|
|
28
|
+
status: 502,
|
|
29
|
+
contentType: 'text/html',
|
|
30
|
+
body: `
|
|
31
|
+
<!DOCTYPE html>
|
|
32
|
+
<html lang="en">
|
|
33
|
+
<head>
|
|
34
|
+
<meta charset="UTF-8">
|
|
35
|
+
<title>ERR_NAME_NOT_RESOLVED</title>
|
|
36
|
+
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
|
|
37
|
+
<style>
|
|
38
|
+
body {
|
|
39
|
+
background-color: #f2f2f2;
|
|
40
|
+
color: #333;
|
|
41
|
+
font-family: 'Roboto', sans-serif;
|
|
42
|
+
margin: 0;
|
|
43
|
+
padding: 0;
|
|
44
|
+
}
|
|
45
|
+
.container {
|
|
46
|
+
max-width: 600px;
|
|
47
|
+
margin: 100px auto;
|
|
48
|
+
padding: 20px;
|
|
49
|
+
text-align: center;
|
|
50
|
+
}
|
|
51
|
+
.sad-face {
|
|
52
|
+
font-size: 80px;
|
|
53
|
+
margin-bottom: 20px;
|
|
54
|
+
}
|
|
55
|
+
h1 {
|
|
56
|
+
font-size: 24px;
|
|
57
|
+
font-weight: normal;
|
|
58
|
+
margin-bottom: 10px;
|
|
59
|
+
}
|
|
60
|
+
p {
|
|
61
|
+
font-size: 16px;
|
|
62
|
+
color: #666;
|
|
63
|
+
}
|
|
64
|
+
@media (max-width: 600px) {
|
|
65
|
+
.container {
|
|
66
|
+
margin-top: 50px;
|
|
67
|
+
padding: 10px;
|
|
68
|
+
}
|
|
69
|
+
.sad-face {
|
|
70
|
+
font-size: 60px;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<div class="container">
|
|
77
|
+
<div class="sad-face">:(</div>
|
|
78
|
+
<h1>This site can’t be reached</h1>
|
|
79
|
+
<p>The webpage at <strong>${host}/</strong> might be temporarily down or it may have moved permanently to a new web address.</p>
|
|
80
|
+
<p><strong>ERR_NAME_NOT_RESOLVED</strong></p>
|
|
81
|
+
</div>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
`.trim()
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -17,6 +17,7 @@ const ctx_rq_namespace_1 = __importDefault(require("./helpers/ctx_rq_namespace")
|
|
|
17
17
|
const http_helpers_1 = require("./helpers/http_helpers");
|
|
18
18
|
const constants_1 = require("./constants");
|
|
19
19
|
const requestly_core_1 = require("@requestly/requestly-core");
|
|
20
|
+
const handleUnreachableAddress_1 = require("./helpers/handleUnreachableAddress");
|
|
20
21
|
// import SSLProxyingConfigFetcher from "renderer/lib/fetcher/ssl-proxying-config-fetcher";
|
|
21
22
|
// import SSLProxyingManager from "../ssl-proxying/ssl-proxying-manager";
|
|
22
23
|
exports.MIDDLEWARE_TYPE = {
|
|
@@ -99,10 +100,34 @@ class ProxyMiddlewareManager {
|
|
|
99
100
|
if (!ctx.rq.request_finished) {
|
|
100
101
|
logger_middleware.send_network_log(ctx, rules_middleware.action_result_objs, requestly_core_1.CONSTANTS.REQUEST_STATE.COMPLETE);
|
|
101
102
|
}
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
}
|
|
104
|
+
else if (kind === "PROXY_TO_SERVER_REQUEST_ERROR") {
|
|
105
|
+
try {
|
|
106
|
+
const host = (0, proxy_ctx_helper_1.get_request_url)(ctx);
|
|
107
|
+
const isAddressUnreachable = await (0, handleUnreachableAddress_1.isAddressUnreachableError)(host);
|
|
108
|
+
if (isAddressUnreachable) {
|
|
109
|
+
const { status, contentType, body } = (0, handleUnreachableAddress_1.dataToServeUnreachablePage)(host);
|
|
110
|
+
ctx.proxyToClientResponse.writeHead(status, http_1.default.STATUS_CODES[status], {
|
|
111
|
+
"Content-Type": contentType,
|
|
112
|
+
"x-rq-error": "ERR_NAME_NOT_RESOLVED"
|
|
113
|
+
});
|
|
114
|
+
ctx.proxyToClientResponse.end(body);
|
|
115
|
+
ctx.rq.set_final_response({
|
|
116
|
+
status_code: status,
|
|
117
|
+
headers: { "Content-Type": contentType },
|
|
118
|
+
body: body,
|
|
119
|
+
});
|
|
120
|
+
logger_middleware.send_network_log(ctx, rules_middleware.action_result_objs, requestly_core_1.CONSTANTS.REQUEST_STATE.COMPLETE);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error("Error checking address:", error);
|
|
104
126
|
}
|
|
105
127
|
}
|
|
128
|
+
else {
|
|
129
|
+
console.log("Expected Error after early termination of request: ", err);
|
|
130
|
+
}
|
|
106
131
|
return callback();
|
|
107
132
|
});
|
|
108
133
|
let request_body_chunks = [];
|
|
@@ -121,6 +146,7 @@ class ProxyMiddlewareManager {
|
|
|
121
146
|
let pre_final_body = parsedBody || body.toString("utf8");
|
|
122
147
|
ctx.rq.set_original_request({ body: pre_final_body });
|
|
123
148
|
ctx.rq_request_body = pre_final_body;
|
|
149
|
+
let request_rule_applied = false;
|
|
124
150
|
if (parsedBody && constants_1.RQ_INTERCEPTED_CONTENT_TYPES.includes(contentType)) {
|
|
125
151
|
// Do modifications, if any
|
|
126
152
|
const { action_result_objs, continue_request } = await rules_middleware.on_request_end(ctx);
|
|
@@ -128,9 +154,15 @@ class ProxyMiddlewareManager {
|
|
|
128
154
|
logger_middleware.send_network_log(ctx, rules_middleware.action_result_objs, requestly_core_1.CONSTANTS.REQUEST_STATE.COMPLETE);
|
|
129
155
|
return;
|
|
130
156
|
}
|
|
157
|
+
request_rule_applied = action_result_objs === null || action_result_objs === void 0 ? void 0 : action_result_objs.some((obj) => { var _a; return ((_a = obj === null || obj === void 0 ? void 0 : obj.action) === null || _a === void 0 ? void 0 : _a.action) === constants_1.RULE_ACTION.MODIFY_REQUEST; });
|
|
158
|
+
}
|
|
159
|
+
if (request_rule_applied) {
|
|
160
|
+
ctx.proxyToServerRequest.write(ctx.rq_request_body);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// If no modifications, write the original request body buffer so that we don't mess up during decoding
|
|
164
|
+
ctx.proxyToServerRequest.write(body);
|
|
131
165
|
}
|
|
132
|
-
// Use the updated request
|
|
133
|
-
ctx.proxyToServerRequest.write(ctx.rq_request_body);
|
|
134
166
|
ctx.rq.set_final_request({ body: ctx.rq_request_body });
|
|
135
167
|
return callback();
|
|
136
168
|
});
|
|
@@ -12,12 +12,12 @@ declare function handleMixedResponse(ctx: any, destinationUrl: any): Promise<{
|
|
|
12
12
|
status: boolean;
|
|
13
13
|
response_data: {
|
|
14
14
|
headers: {
|
|
15
|
-
"
|
|
15
|
+
"content-type": any;
|
|
16
16
|
"Content-Length": number;
|
|
17
17
|
"Cache-Control": string;
|
|
18
18
|
} | {
|
|
19
19
|
"Cache-Control": string;
|
|
20
|
-
"
|
|
20
|
+
"content-type"?: undefined;
|
|
21
21
|
"Content-Length"?: undefined;
|
|
22
22
|
};
|
|
23
23
|
status_code: number;
|
|
@@ -76,12 +76,16 @@ const handleMixedResponse = async (ctx, destinationUrl) => {
|
|
|
76
76
|
const mimeType = mime.lookup(path);
|
|
77
77
|
const bodyContent = buffers.toString("utf-8"); // assuming utf-8 encoding
|
|
78
78
|
const headers = mimeType ? {
|
|
79
|
-
"
|
|
79
|
+
"content-type": mimeType,
|
|
80
80
|
"Content-Length": Buffer.byteLength(bodyContent),
|
|
81
81
|
"Cache-Control": "no-cache"
|
|
82
82
|
} : {
|
|
83
83
|
"Cache-Control": "no-cache"
|
|
84
84
|
};
|
|
85
|
+
headers["access-control-allow-origin"] = "*";
|
|
86
|
+
headers["access-control-allow-credentials"] = "true";
|
|
87
|
+
headers["access-control-allow-methods"] = "*";
|
|
88
|
+
headers["access-control-allow-headers"] = "*";
|
|
85
89
|
return {
|
|
86
90
|
status: true,
|
|
87
91
|
response_data: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@requestly/requestly-proxy",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.11",
|
|
4
4
|
"description": "Proxy that gives superpowers to all the Requestly clients",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"author": "",
|
|
27
27
|
"license": "ISC",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@requestly/requestly-core": "
|
|
29
|
+
"@requestly/requestly-core": "1.1.1",
|
|
30
30
|
"@sentry/browser": "^8.33.1",
|
|
31
31
|
"async": "^3.2.5",
|
|
32
32
|
"axios": "^1.7.2",
|