Spaces:
Sleeping
Sleeping
Update index.js
Browse files
index.js
CHANGED
|
@@ -3,11 +3,12 @@ import fetch, { Headers as FetchHeaders } from 'node-fetch';
|
|
| 3 |
|
| 4 |
const app = express();
|
| 5 |
app.use(express.raw({
|
| 6 |
-
type: '*/*',
|
| 7 |
limit: '100mb'
|
| 8 |
}));
|
| 9 |
|
| 10 |
app.options('*', (req, res) => {
|
|
|
|
| 11 |
const origin = req.headers.origin;
|
| 12 |
|
| 13 |
if (origin) {
|
|
@@ -21,6 +22,7 @@ app.options('*', (req, res) => {
|
|
| 21 |
|
| 22 |
const requestedHeaders = req.headers['access-control-request-headers'];
|
| 23 |
if (requestedHeaders) {
|
|
|
|
| 24 |
res.setHeader('Access-Control-Allow-Headers', requestedHeaders);
|
| 25 |
} else {
|
| 26 |
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, X-CSRF-Token, Accept, Origin');
|
|
@@ -32,11 +34,13 @@ app.options('*', (req, res) => {
|
|
| 32 |
res.setHeader('Vary', 'Origin');
|
| 33 |
}
|
| 34 |
|
|
|
|
| 35 |
res.status(204).end();
|
| 36 |
});
|
| 37 |
|
| 38 |
|
| 39 |
app.get('/', (req, res) => {
|
|
|
|
| 40 |
const origin = req.headers.origin;
|
| 41 |
if (origin) {
|
| 42 |
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
@@ -54,24 +58,32 @@ app.get('/', (req, res) => {
|
|
| 54 |
});
|
| 55 |
|
| 56 |
app.all('*', async (req, res) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
if (req.url === '/') {
|
|
|
|
| 58 |
return;
|
| 59 |
}
|
| 60 |
|
| 61 |
const clientRequestOrigin = req.headers.origin;
|
|
|
|
| 62 |
|
| 63 |
try {
|
| 64 |
-
// Удаляем первый слеш и декодируем URL
|
| 65 |
let targetUrlString = req.url.substring(1);
|
| 66 |
-
|
|
|
|
| 67 |
try {
|
| 68 |
targetUrlString = decodeURIComponent(targetUrlString);
|
|
|
|
| 69 |
} catch (e) {
|
| 70 |
-
|
| 71 |
-
console.log('URL decoding failed, using original URL');
|
| 72 |
}
|
| 73 |
|
| 74 |
if (!targetUrlString) {
|
|
|
|
| 75 |
addCorsHeaders(res, clientRequestOrigin);
|
| 76 |
res.status(400).send('Target URL is missing in the path.');
|
| 77 |
return;
|
|
@@ -80,7 +92,9 @@ app.all('*', async (req, res) => {
|
|
| 80 |
let targetUrl;
|
| 81 |
try {
|
| 82 |
targetUrl = new URL(targetUrlString);
|
|
|
|
| 83 |
} catch (e) {
|
|
|
|
| 84 |
addCorsHeaders(res, clientRequestOrigin);
|
| 85 |
res.status(400).send(`Invalid target URL provided in path: ${targetUrlString}`);
|
| 86 |
return;
|
|
@@ -89,7 +103,12 @@ app.all('*', async (req, res) => {
|
|
| 89 |
const requestHeaders = {...req.headers};
|
| 90 |
delete requestHeaders['host'];
|
| 91 |
delete requestHeaders['content-length'];
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
|
|
|
| 93 |
const response = await fetch(targetUrl.toString(), {
|
| 94 |
method: req.method,
|
| 95 |
headers: requestHeaders,
|
|
@@ -97,6 +116,9 @@ app.all('*', async (req, res) => {
|
|
| 97 |
redirect: 'manual',
|
| 98 |
compress: false
|
| 99 |
});
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
response.headers.forEach((value, key) => {
|
| 102 |
const lowerKey = key.toLowerCase();
|
|
@@ -113,6 +135,7 @@ app.all('*', async (req, res) => {
|
|
| 113 |
lowerKey !== 'trailers' &&
|
| 114 |
lowerKey !== 'upgrade'
|
| 115 |
) {
|
|
|
|
| 116 |
res.setHeader(key, value);
|
| 117 |
}
|
| 118 |
});
|
|
@@ -122,20 +145,32 @@ app.all('*', async (req, res) => {
|
|
| 122 |
!key.toLowerCase().startsWith('access-control-')
|
| 123 |
).join(', ');
|
| 124 |
if (exposedHeaders) {
|
|
|
|
| 125 |
res.setHeader('Access-Control-Expose-Headers', exposedHeaders || '*');
|
| 126 |
}
|
| 127 |
|
| 128 |
res.status(response.status);
|
|
|
|
| 129 |
|
| 130 |
if (response.body) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
response.body.pipe(res);
|
| 132 |
} else {
|
|
|
|
| 133 |
res.end();
|
| 134 |
}
|
| 135 |
|
| 136 |
} catch (error) {
|
| 137 |
-
console.error(`[${new Date().toISOString()}]
|
|
|
|
| 138 |
if (!res.headersSent) {
|
|
|
|
| 139 |
addCorsHeaders(res, clientRequestOrigin);
|
| 140 |
let statusCode = 500;
|
| 141 |
let message = 'Proxy error occurred.';
|
|
@@ -153,15 +188,17 @@ app.all('*', async (req, res) => {
|
|
| 153 |
statusCode = 400;
|
| 154 |
message = `Invalid target URL format in path: ${req.url.substring(1)}`;
|
| 155 |
}
|
|
|
|
| 156 |
res.status(statusCode).send(message);
|
| 157 |
} else {
|
| 158 |
-
console.error(`
|
| 159 |
res.end();
|
| 160 |
}
|
| 161 |
}
|
| 162 |
});
|
| 163 |
|
| 164 |
function addCorsHeaders(res, clientRequestOrigin) {
|
|
|
|
| 165 |
if (clientRequestOrigin) {
|
| 166 |
res.setHeader('Access-Control-Allow-Origin', clientRequestOrigin);
|
| 167 |
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
|
|
| 3 |
|
| 4 |
const app = express();
|
| 5 |
app.use(express.raw({
|
| 6 |
+
type: '*/*',
|
| 7 |
limit: '100mb'
|
| 8 |
}));
|
| 9 |
|
| 10 |
app.options('*', (req, res) => {
|
| 11 |
+
console.log(`[OPTIONS] Handling preflight request from: ${req.headers.origin}`);
|
| 12 |
const origin = req.headers.origin;
|
| 13 |
|
| 14 |
if (origin) {
|
|
|
|
| 22 |
|
| 23 |
const requestedHeaders = req.headers['access-control-request-headers'];
|
| 24 |
if (requestedHeaders) {
|
| 25 |
+
console.log(`[OPTIONS] Requested headers: ${requestedHeaders}`);
|
| 26 |
res.setHeader('Access-Control-Allow-Headers', requestedHeaders);
|
| 27 |
} else {
|
| 28 |
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, X-CSRF-Token, Accept, Origin');
|
|
|
|
| 34 |
res.setHeader('Vary', 'Origin');
|
| 35 |
}
|
| 36 |
|
| 37 |
+
console.log('[OPTIONS] Sending 204 response');
|
| 38 |
res.status(204).end();
|
| 39 |
});
|
| 40 |
|
| 41 |
|
| 42 |
app.get('/', (req, res) => {
|
| 43 |
+
console.log(`[GET /] Request from: ${req.headers.origin}`);
|
| 44 |
const origin = req.headers.origin;
|
| 45 |
if (origin) {
|
| 46 |
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
|
|
| 58 |
});
|
| 59 |
|
| 60 |
app.all('*', async (req, res) => {
|
| 61 |
+
console.log(`\n[${req.method}] New request received`);
|
| 62 |
+
console.log(`Original URL: ${req.url}`);
|
| 63 |
+
console.log(`Headers:`, req.headers);
|
| 64 |
+
console.log(`Body length: ${req.body ? req.body.length : 0}`);
|
| 65 |
+
|
| 66 |
if (req.url === '/') {
|
| 67 |
+
console.log('[*] Root path detected, skipping');
|
| 68 |
return;
|
| 69 |
}
|
| 70 |
|
| 71 |
const clientRequestOrigin = req.headers.origin;
|
| 72 |
+
console.log(`Client origin: ${clientRequestOrigin}`);
|
| 73 |
|
| 74 |
try {
|
|
|
|
| 75 |
let targetUrlString = req.url.substring(1);
|
| 76 |
+
console.log(`Raw target URL: ${targetUrlString}`);
|
| 77 |
+
|
| 78 |
try {
|
| 79 |
targetUrlString = decodeURIComponent(targetUrlString);
|
| 80 |
+
console.log(`Decoded target URL: ${targetUrlString}`);
|
| 81 |
} catch (e) {
|
| 82 |
+
console.log(`URL decoding failed: ${e.message}`);
|
|
|
|
| 83 |
}
|
| 84 |
|
| 85 |
if (!targetUrlString) {
|
| 86 |
+
console.log('[ERROR] No target URL provided');
|
| 87 |
addCorsHeaders(res, clientRequestOrigin);
|
| 88 |
res.status(400).send('Target URL is missing in the path.');
|
| 89 |
return;
|
|
|
|
| 92 |
let targetUrl;
|
| 93 |
try {
|
| 94 |
targetUrl = new URL(targetUrlString);
|
| 95 |
+
console.log(`Parsed target URL: ${targetUrl.toString()}`);
|
| 96 |
} catch (e) {
|
| 97 |
+
console.log(`[ERROR] URL parsing failed: ${e.message}`);
|
| 98 |
addCorsHeaders(res, clientRequestOrigin);
|
| 99 |
res.status(400).send(`Invalid target URL provided in path: ${targetUrlString}`);
|
| 100 |
return;
|
|
|
|
| 103 |
const requestHeaders = {...req.headers};
|
| 104 |
delete requestHeaders['host'];
|
| 105 |
delete requestHeaders['content-length'];
|
| 106 |
+
|
| 107 |
+
console.log(`Making request to: ${targetUrl.toString()}`);
|
| 108 |
+
console.log(`Method: ${req.method}`);
|
| 109 |
+
console.log(`Headers:`, requestHeaders);
|
| 110 |
|
| 111 |
+
console.log('Starting fetch request...');
|
| 112 |
const response = await fetch(targetUrl.toString(), {
|
| 113 |
method: req.method,
|
| 114 |
headers: requestHeaders,
|
|
|
|
| 116 |
redirect: 'manual',
|
| 117 |
compress: false
|
| 118 |
});
|
| 119 |
+
console.log('Fetch request completed');
|
| 120 |
+
console.log(`Response status: ${response.status}`);
|
| 121 |
+
console.log(`Response headers:`, response.headers.raw());
|
| 122 |
|
| 123 |
response.headers.forEach((value, key) => {
|
| 124 |
const lowerKey = key.toLowerCase();
|
|
|
|
| 135 |
lowerKey !== 'trailers' &&
|
| 136 |
lowerKey !== 'upgrade'
|
| 137 |
) {
|
| 138 |
+
console.log(`Setting response header: ${key} = ${value}`);
|
| 139 |
res.setHeader(key, value);
|
| 140 |
}
|
| 141 |
});
|
|
|
|
| 145 |
!key.toLowerCase().startsWith('access-control-')
|
| 146 |
).join(', ');
|
| 147 |
if (exposedHeaders) {
|
| 148 |
+
console.log(`Setting exposed headers: ${exposedHeaders}`);
|
| 149 |
res.setHeader('Access-Control-Expose-Headers', exposedHeaders || '*');
|
| 150 |
}
|
| 151 |
|
| 152 |
res.status(response.status);
|
| 153 |
+
console.log(`Set response status to: ${response.status}`);
|
| 154 |
|
| 155 |
if (response.body) {
|
| 156 |
+
console.log('Starting to pipe response body...');
|
| 157 |
+
response.body.on('error', (error) => {
|
| 158 |
+
console.error('Error in response body pipe:', error);
|
| 159 |
+
});
|
| 160 |
+
response.body.on('end', () => {
|
| 161 |
+
console.log('Response body pipe completed');
|
| 162 |
+
});
|
| 163 |
response.body.pipe(res);
|
| 164 |
} else {
|
| 165 |
+
console.log('No response body, ending response');
|
| 166 |
res.end();
|
| 167 |
}
|
| 168 |
|
| 169 |
} catch (error) {
|
| 170 |
+
console.error(`[${new Date().toISOString()}] Detailed proxy error:`, error);
|
| 171 |
+
console.error('Error stack:', error.stack);
|
| 172 |
if (!res.headersSent) {
|
| 173 |
+
console.log('Headers not sent yet, sending error response');
|
| 174 |
addCorsHeaders(res, clientRequestOrigin);
|
| 175 |
let statusCode = 500;
|
| 176 |
let message = 'Proxy error occurred.';
|
|
|
|
| 188 |
statusCode = 400;
|
| 189 |
message = `Invalid target URL format in path: ${req.url.substring(1)}`;
|
| 190 |
}
|
| 191 |
+
console.log(`Sending error response: ${statusCode} - ${message}`);
|
| 192 |
res.status(statusCode).send(message);
|
| 193 |
} else {
|
| 194 |
+
console.error(`Headers already sent, cannot send error response`);
|
| 195 |
res.end();
|
| 196 |
}
|
| 197 |
}
|
| 198 |
});
|
| 199 |
|
| 200 |
function addCorsHeaders(res, clientRequestOrigin) {
|
| 201 |
+
console.log(`Adding CORS headers for origin: ${clientRequestOrigin}`);
|
| 202 |
if (clientRequestOrigin) {
|
| 203 |
res.setHeader('Access-Control-Allow-Origin', clientRequestOrigin);
|
| 204 |
res.setHeader('Access-Control-Allow-Credentials', 'true');
|