feat: make vercel compatible

Signed-off-by: Tony Tang <tonytang@lilith.com>
This commit is contained in:
Tony Tang
2025-10-15 11:36:13 +08:00
parent 70aaa22b3f
commit 7e3115fad0
6 changed files with 3456 additions and 12 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@
coverage/
node_modules/
.vercel

View File

@@ -152,21 +152,66 @@ export CORSANYWHERE_WHITELIST=https://example.com,http://example.com,http://exam
node server.js
```
This application can immediately be run on Heroku, see https://devcenter.heroku.com/articles/nodejs
for instructions. Note that their [Acceptable Use Policy](https://www.heroku.com/policy/aup) forbids
the use of Heroku for operating an open proxy, so make sure that you either enforce a whitelist as
shown above, or severly rate-limit the number of requests.
For example, to blacklist abuse.example.com and rate-limit everything to 50 requests per 3 minutes,
except for my.example.com and my2.example.com (which may be unlimited), use:
## Vercel Deployment
```
export PORT=8080
export CORSANYWHERE_BLACKLIST=https://abuse.example.com,http://abuse.example.com
export CORSANYWHERE_RATELIMIT='50 3 my.example.com my2.example.com'
node server.js
CORS Anywhere can be deployed on Vercel using serverless functions. The project includes
configuration files for easy deployment.
### Quick Deploy
1. **Install Vercel CLI** (if not already installed):
```bash
npm install -g vercel
```
2. **Login to Vercel**:
```bash
vercel login
```
3. **Deploy**:
```bash
npm run deploy
```
or
```bash
vercel --prod
```
### Configuration
The deployment uses:
- `api/index.js` - Serverless function entry point
- `vercel.json` - Vercel configuration with routing and function settings
### Environment Variables
You can configure CORS Anywhere using environment variables in your Vercel project:
- `CORSANYWHERE_WHITELIST` - Comma-separated list of allowed origins
- `CORSANYWHERE_BLACKLIST` - Comma-separated list of blocked origins
- `CORSANYWHERE_RATELIMIT` - Rate limiting configuration
Example:
```
CORSANYWHERE_WHITELIST=https://myapp.com,https://myapp.vercel.app
CORSANYWHERE_RATELIMIT=100 5 myapp.com
```
### Important Notes
- Vercel serverless functions have execution time limits (30 seconds by default)
- Large file downloads may timeout
- Consider upgrading to Vercel Pro for longer function timeouts if needed
- Rate limiting and origin restrictions are recommended to prevent abuse
### Usage
After deployment, your CORS proxy will be available at your Vercel domain:
```
https://your-project.vercel.app/http://example.com/api/data
```
## License

61
api/index.js Normal file
View File

@@ -0,0 +1,61 @@
const cors_proxy = require('../lib/cors-anywhere');
// Parse environment variables for configuration
function parseEnvList(env) {
if (!env) {
return [];
}
return env.split(',');
}
const originBlacklist = parseEnvList(process.env.CORSANYWHERE_BLACKLIST);
const originWhitelist = parseEnvList(process.env.CORSANYWHERE_WHITELIST);
// Set up rate-limiting to avoid abuse
const checkRateLimit = require('../lib/rate-limit')(process.env.CORSANYWHERE_RATELIMIT);
// Create the CORS Anywhere server options
const options = {
originBlacklist: originBlacklist,
originWhitelist: originWhitelist,
requireHeader: ['origin', 'x-requested-with'],
checkRateLimit: checkRateLimit,
removeHeaders: [
'cookie',
'cookie2',
// Strip Vercel-specific headers that might cause issues
'x-vercel-id',
'x-vercel-forwarded-for',
'x-vercel-deployment-url',
'x-vercel-trace',
// Keep other headers that might be useful
],
redirectSameOrigin: true,
httpProxyOptions: {
// Vercel handles forwarding headers, so we can keep this
xfwd: true,
},
};
// Create the server (this will give us access to the internal handler)
const server = cors_proxy.createServer(options);
// Extract the request handler from the server
// This is a bit of a hack, but necessary for Vercel serverless functions
const requestHandler = server.listeners('request')[0];
module.exports = (req, res) => {
// Vercel serverless functions expect the handler to be called directly
// But we need to ensure the request URL is properly formatted
// For Vercel, the path might include the API route prefix
// We need to adjust the URL to match what CORS Anywhere expects
const originalUrl = req.url;
if (req.url.startsWith('/api/')) {
// Remove the /api/ prefix for CORS Anywhere
req.url = req.url.substring(4);
}
// Call the CORS Anywhere handler
requestHandler(req, res);
};

3317
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -43,9 +43,11 @@
"scripts": {
"lint": "eslint .",
"test": "mocha ./test/test*.js --reporter spec",
"test-coverage": "istanbul cover ./node_modules/.bin/_mocha -- test/test.js test/test-ratelimit.js --reporter spec"
"test-coverage": "istanbul cover ./node_modules/.bin/_mocha -- test/test.js test/test-ratelimit.js --reporter spec",
"dev": "node server.js",
"deploy": "vercel --prod"
},
"engines": {
"node": ">=0.10.0"
"node": ">=14.0.0"
}
}

18
vercel.json Normal file
View File

@@ -0,0 +1,18 @@
{
"version": 2,
"functions": {
"api/index.js": {
"maxDuration": 30
}
},
"routes": [
{
"src": "/(.*)",
"dest": "/api/index.js"
}
],
"outputDirectory": null,
"env": {
"NODE_ENV": "production"
}
}