# CORSProxy A lightweight CORS (Cross-Origin Resource Sharing) proxy for the [Unsloth Studio](https://unsloth.ai) API. It runs as a local HTTP server that adds the required `Access-Control-*` headers, allowing browser-based frontends to call the Unsloth backend without being blocked by the browser's Same-Origin Policy. ## Features - **Zero dependencies** — uses only Python 3 standard library modules. - **POST proxy** — forwards POST requests with `Content-Type` and `Authorization` headers intact. - **CORS preflight** — responds to `OPTIONS` requests with `204 No Content`. - **Health check** — `GET /health` returns `200 OK` with the current upstream target. - **Systemd unit** — drop-in service file for easy deployment on Linux. - **Hardened** — includes Linux security best practices in the unit file (no-new-privileges, strict system protection, minimal capabilities). ## Installation ### Requirements - Python 3.10+ - `sudo` access (for systemd deployment) ### Manual run ```bash # Clone the repo git clone https://github.com/NikkeDoy/CORSProxy.git cd CORSProxy # Run interactively python main.py ``` ### systemd deployment ```bash # Copy the service file sudo cp services/corsproxy.service /etc/systemd/system/ # Reload systemd and enable the service sudo systemctl daemon-reload sudo systemctl enable corsproxy.service # Start the service sudo systemctl start corsproxy.service # Verify it's running sudo systemctl status corsproxy.service ``` ## Configuration ### Command-line arguments | Argument | Default | Description | |---|---|---| | `--target HOST:PORT` | `127.0.0.1:8888` | Upstream Unsloth Studio address | | `--listen PORT` | `8080` | Port the proxy listens on | ### Examples ```bash # Default: listen :8080, forward to :8888 on localhost python main.py # Custom upstream port python main.py --target 127.0.0.1:8000 # Custom listen port python main.py --listen 9090 # Remote upstream python main.py --target 10.0.0.5:8000 --listen 9090 ``` ### Environment variables (systemd) The service file exposes three tunable environment variables that you can override by editing the `[Service]` section: | Variable | Default | Description | |---|---|---| | `TARGET_HOST` | `127.0.0.1` | Upstream host | | `TARGET_PORT` | `8888` | Upstream port | | `LISTEN_PORT` | `8080` | Local listen port | To override without editing the unit file: ```bash sudo systemctl set-environment TARGET_HOST=10.0.0.5 LISTEN_PORT=9090 sudo systemctl restart corsproxy.service ``` ## Endpoints | Method | Path | Description | |---|---|---| | `POST` | `/*` | Forwarded to the upstream server | | `OPTIONS` | `/*` | Returns `204 No Content` with CORS headers | | `GET` | `/health` | Returns `{"status":"ok","proxy_to":"host:port"}` | | `GET` | `/*` | Any other path returns `405 Method Not Allowed` | ## Health check Verify the proxy is running: ```bash curl http://127.0.0.1:8080/health # {"status": "ok", "proxy_to": "127.0.0.1:8888"} ``` ## Architecture ``` ┌──────────┐ ┌────────────────┐ ┌──────────────┐ │ Browser │ ───────► │ CORS Proxy │ ───────► │ Unsloth API │ │ (origin) │ │ (port 8080) │ (port 8888)│ (upstream) │ └──────────┘ └────────────────┘ └──────────────┘ ``` The proxy sits between the browser and the Unsloth Studio API, injecting the necessary CORS headers so the browser's Same-Origin Policy does not block cross-origin requests. ## Project structure ``` CORSProxy/ ├── main.py # Proxy application (entry point) ├── services/ │ └── corsproxy.service # systemd unit file ├── tests/ # Test suite (TDD) ├── docs/ # Additional documentation ├── .gitignore # Files to exclude from version control └── LICENSE # MIT License ``` ## License MIT License — see [LICENSE](LICENSE) for details. Copyright (c) 2026 NikkeDoy