Skip to content

Commit d5af0b3

Browse files
authored
style: show custom page when proxy fails to resolve dns (#62)
1 parent 0925f01 commit d5af0b3

File tree

2 files changed

+114
-4
lines changed

2 files changed

+114
-4
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import dns from 'dns';
2+
3+
export function isAddressUnreachableError(host) {
4+
return new Promise((resolve, reject) => {
5+
dns.lookup(host, (err, address) => {
6+
if (err) {
7+
if (err.code === 'ENOTFOUND') {
8+
resolve(true);
9+
} else {
10+
reject(err);
11+
}
12+
} else {
13+
resolve(false);
14+
}
15+
});
16+
});
17+
}
18+
19+
export function dataToServeUnreachablePage(host) {
20+
return {
21+
status: 502,
22+
contentType: 'text/html',
23+
body: `
24+
<!DOCTYPE html>
25+
<html lang="en">
26+
<head>
27+
<meta charset="UTF-8">
28+
<title>ERR_NAME_NOT_RESOLVED</title>
29+
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
30+
<style>
31+
body {
32+
background-color: #f2f2f2;
33+
color: #333;
34+
font-family: 'Roboto', sans-serif;
35+
margin: 0;
36+
padding: 0;
37+
}
38+
.container {
39+
max-width: 600px;
40+
margin: 100px auto;
41+
padding: 20px;
42+
text-align: center;
43+
}
44+
.sad-face {
45+
font-size: 80px;
46+
margin-bottom: 20px;
47+
}
48+
h1 {
49+
font-size: 24px;
50+
font-weight: normal;
51+
margin-bottom: 10px;
52+
}
53+
p {
54+
font-size: 16px;
55+
color: #666;
56+
}
57+
@media (max-width: 600px) {
58+
.container {
59+
margin-top: 50px;
60+
padding: 10px;
61+
}
62+
.sad-face {
63+
font-size: 60px;
64+
}
65+
}
66+
</style>
67+
</head>
68+
<body>
69+
<div class="container">
70+
<div class="sad-face">:(</div>
71+
<h1>This site can’t be reached</h1>
72+
<p>The webpage at <strong>${host}/</strong> might be temporarily down or it may have moved permanently to a new web address.</p>
73+
<p><strong>ERR_NAME_NOT_RESOLVED</strong></p>
74+
</div>
75+
</body>
76+
</html>
77+
`.trim()
78+
};
79+
}

src/components/proxy-middleware/index.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import CtxRQNamespace from "./helpers/ctx_rq_namespace";
2121
import { bodyParser, getContentType } from "./helpers/http_helpers";
2222
import { RQ_INTERCEPTED_CONTENT_TYPES } from "./constants";
2323
import { CONSTANTS as GLOBAL_CONSTANTS } from "@requestly/requestly-core";
24+
import { dataToServeUnreachablePage, isAddressUnreachableError } from "./helpers/handleUnreachableAddress";
2425
// import SSLProxyingConfigFetcher from "renderer/lib/fetcher/ssl-proxying-config-fetcher";
2526
// import SSLProxyingManager from "../ssl-proxying/ssl-proxying-manager";
2627

@@ -142,7 +143,7 @@ class ProxyMiddlewareManager {
142143
// Only modify response if any modify_response action is applied
143144
const modifyResponseActionExist = action_result_objs.some((action_result_obj) => action_result_obj?.action?.action === "modify_response")
144145

145-
if(modifyResponseActionExist) {
146+
if (modifyResponseActionExist) {
146147
const statusCode = ctx.rq_response_status_code || 404;
147148
const responseHeaders = getResponseHeaders(ctx) || {}
148149
ctx.proxyToClientResponse.writeHead(
@@ -163,9 +164,39 @@ class ProxyMiddlewareManager {
163164
rules_middleware.action_result_objs,
164165
GLOBAL_CONSTANTS.REQUEST_STATE.COMPLETE
165166
)
166-
} else {
167-
console.log("Expected Error after early termination of request: ", err);
168-
}
167+
}
168+
} else if (kind === "PROXY_TO_SERVER_REQUEST_ERROR") {
169+
try {
170+
const host = get_request_url(ctx);
171+
const isAddressUnreachable = await isAddressUnreachableError(host);
172+
if (isAddressUnreachable) {
173+
const { status, contentType, body } = dataToServeUnreachablePage(host);
174+
ctx.proxyToClientResponse.writeHead(
175+
status,
176+
http.STATUS_CODES[status],
177+
{
178+
"Content-Type": contentType ,
179+
"x-rq-error": "ERR_NAME_NOT_RESOLVED"
180+
}
181+
);
182+
ctx.proxyToClientResponse.end(body);
183+
ctx.rq.set_final_response({
184+
status_code: status,
185+
headers: { "Content-Type": contentType },
186+
body: body,
187+
});
188+
logger_middleware.send_network_log(
189+
ctx,
190+
rules_middleware.action_result_objs,
191+
GLOBAL_CONSTANTS.REQUEST_STATE.COMPLETE
192+
);
193+
return;
194+
}
195+
} catch (error) {
196+
console.error("Error checking address:", error);
197+
}
198+
} else {
199+
console.log("Expected Error after early termination of request: ", err);
169200
}
170201

171202
return callback();

0 commit comments

Comments
 (0)