{"id":26232558,"url":"https://github.com/bulletmark/corsproxy","last_synced_at":"2025-04-22T10:41:10.013Z","repository":{"id":60785872,"uuid":"212258322","full_name":"bulletmark/corsproxy","owner":"bulletmark","description":"A simple CORS proxy server.","archived":false,"fork":false,"pushed_at":"2025-01-27T23:15:17.000Z","size":44,"stargazers_count":46,"open_issues_count":0,"forks_count":15,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-28T00:25:21.115Z","etag":null,"topics":["api","cors","json"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bulletmark.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-02T04:56:07.000Z","updated_at":"2025-01-27T23:15:21.000Z","dependencies_parsed_at":"2024-01-10T06:24:51.065Z","dependency_job_id":"7fbd40b8-acca-4123-9ee7-55999ae644ce","html_url":"https://github.com/bulletmark/corsproxy","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bulletmark%2Fcorsproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bulletmark%2Fcorsproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bulletmark%2Fcorsproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bulletmark%2Fcorsproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bulletmark","download_url":"https://codeload.github.com/bulletmark/corsproxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243318778,"owners_count":20272136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cors","json"],"created_at":"2025-03-13T00:37:29.869Z","updated_at":"2025-03-13T00:37:30.419Z","avatar_url":"https://github.com/bulletmark.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Simple CORS Proxy\n[![docker-amd64](https://img.shields.io/docker/v/bulletmark/corsproxy?arch=amd64\u0026label=docker-amd64)](https://hub.docker.com/repository/docker/bulletmark/corsproxy)\n[![docker-arm64](https://img.shields.io/docker/v/bulletmark/corsproxy?arch=arm64\u0026label=docker-arm64)](https://hub.docker.com/repository/docker/bulletmark/corsproxy)\n[![docker-arm/v7](https://img.shields.io/docker/v/bulletmark/corsproxy?arch=arm\u0026label=docker-arm/v7)](https://hub.docker.com/repository/docker/bulletmark/corsproxy)\n\n[Corsproxy](https://github.com/bulletmark/corsproxy/) is a small,\nsimple, and efficient Linux HTTP proxy service which receives a HTTP\nrequest on a port and forwards that request to a pre-configured target\nHTTP or HTTPS server. The proxy service then receives the reply from\nthat server, and returns it to the original client unaltered except that\nthe HTTP header has the _Access-Control-Allow-Origin_ field set to get\naround [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)\nrestrictions. It works for both IPv4 and IPv6 source and target\naddresses. HTTP request methods GET, POST, PUT, PATCH, DELETE, or HEAD\nare supported.\n\nWhy another CORS proxy program? [Existing CORS\nproxies](https://github.com/search?q=cors+proxy) I found require the\noriginating client to specify the target server as an option/parameter\nwithin the incoming URL to the proxy. The proxy dynamically extracts the\ntarget server from the URL and then sends the \"real\" URL to the target.\n[My application use case](http://fronius-powermon.duckdns.org) only\nallowed me to change the server name so I could not \"embed\" the real\nserver in the target URL. This simple CORS proxy must instead be\nstatically pre-configured with the target server so it knows where to\nforward incoming requests. E.g.\n\n```sh\n$ ./corsproxy 8000=http://192.168.1.1:9000\n```\n\nThe above will run `corsproxy` to receive requests on port `8000` and\nforward them to HTTP server `192.168.1.1:9000`.\n\n```sh\n$ ./corsproxy 8000=http://192.168.1.1:9000 8001=https://192.168.1.2:9000\n```\n\nThis runs 2 independent proxies. It will do the same as the previous\nexample but will also independently and asynchronously receive requests\non port `8001` and forward them to HTTPS server `192.168.1.2:9000`. You\ncan specify as many proxy mappings as you want.\n\nInstead of specifying the target mappings on the command line as above,\nyou can instead choose to configure them in `~/.config/corsproxy.toml`\na/s per the instructions in the example\n[`corsproxy.toml`](corsproxy.toml) here. The file is convenient if you\nare starting the program via [systemd](https://systemd.io/) etc. Proxy\nmappings are only read from the file if none are specified on the\ncommand line.\n\nThe receiving (i.e. listening) port and server/IP address must at least be\nspecified in each proxy mapping. The target port is optional.\nThe format, as seen in the above examples,\nis `[host:]port=http://server[:targetport]` or `[host:]port=https://server[:targetport]`.\n\nThe latest version and documentation is available at\nhttp://github.com/bulletmark/corsproxy.\n\n## IPv4 and IPv6 Addresses and Examples\n\nOriginally this program was written for IPv4 address proxying only but\nnow handles IPv6 address proxying as well. IPv6 listening and target\nhosts are specified by enclosing them in square brackets, e.g.\n`[2409:d001:4c04:3a10:4d5a:3061:db17:835]` or `[::]`.\n\nThe default host address to listen for a port is `0.0.0.0` to allow all\nIPv4 connections. However, you can limit to local only (i.e. loopback)\nconnections by specifying the host as `127.0.0.1`. Likewise, you can\nspecify IPv6 hosts, e.g. `[::]` for all, or `[::1]` for loopback. Some\nexamples follow:\n\n```sh\n# Local/loopback IPv4 address proxy:\n$ ./corsproxy 127.0.0.1:8000=http://192.168.1.1\n\n# Local/loopback IPv6 address proxy:\n$ ./corsproxy [::1]:8000=http://192.168.1.1\n\n# All IPv4 address proxy:\n$ ./corsproxy 8000=http://192.168.1.1\n# which same as:\n$ ./corsproxy 0.0.0.0:8000=http://192.168.1.1\n\n# All IPv6 address proxy:\n$ ./corsproxy [::]:8000=http://192.168.1.1\n\n# Use 2 mappings for both IPv4 and IPv6 hosts:\n# [Note that Python asyncio does not allow dual stack IPv4/IPv6 so\n# must run 2 separate mappings]\n$ ./corsproxy 8000=http://192.168.1.1 [::]:8000=http://192.168.1.1\n\n# Forward IPv4 HTTP to IPv6 HTTPS server (on it's port 9000):\n$ ./corsproxy 8000=https://[2409:d001:4c04:3a10:4d5a:3061:db17:835]:9000\n```\n\n## Installation\n\nRequires `python` 3.7 or later and any modern\n[systemd](https://systemd.io/)  based Linux environment. E.g. I run it\non a [Raspberry Pi](https://www.raspberrypi.com/) using [Arch Linux\nARM](https://archlinuxarm.org/).\n\nThese instructions assume you are using [systemd](https://systemd.io/)\nto start the application. A [systemd\nservice](https://www.freedesktop.org/software/systemd/man/systemd.service.html)\nservice file is provided.\n\n1. Clone repository and create configuration:\n\n    ```sh\n    $ git clone https://github.com/bulletmark/corsproxy\n    $ cd corsproxy\n    $ mkdir -p ~/.config\n    $ cp corsproxy.toml ~/.config\n    $ vim ~/.config/corsproxy.toml # Add your target servers\n    ```\n\n2. Create virtual environment (venv) and install service:\n\n    ```sh\n    $ python3 -m venv .venv\n    $ .venv/bin/pip install -r requirements.txt\n    $ sudo cp corsproxy.service /etc/systemd/system\n    $ sudoedit /etc/systemd/system/corsproxy.service # Edit #TEMPLATE# values.\n    ```\n\nNote: Alternatively, to create the venv, install the requirement\npackages, insert the template values, and enable + start the service you\ncan use my [pinstall](https://github.com/bulletmark/pinstall) tool. Just\ninstall it and do the following in the `corsproxy` directory.\n\n```sh\n$ pinstall venv\n$ pinstall service\n```\n\n## Starting, Stopping, And Status\n\nTo enable starting at boot and also start immediately:\n\n```sh\n$ sudo systemctl enable corsproxy\n$ sudo systemctl start corsproxy\n```\n\nTo stop immediately and also disable starting at boot:\n\n```sh\n$ sudo systemctl stop corsproxy\n$ sudo systemctl disable corsproxy\n```\n\nShow status:\n\n```sh\n$ systemctl status corsproxy\n```\n\nShow log:\n\n```sh\n$ journalctl -u corsproxy\n```\n\n## Upgrade\n\n`cd` to source directory, as above. Then update the source:\n\n```sh\n$ git pull\n```\n\nUpdate `~/.config/corsproxy.toml` and\n`/etc/systemd/system/corsproxy.service` if necessary. Then restart the\nservice.\n\n```sh\n$ sudo systemctl restart corsproxy\n```\n\n## Docker\n\nAlternatively, for many users it may be easier to install and run this\napplication using [Docker](https://www.docker.com/get-started). Follow\nyour Linux distribution's instructions to ensure Docker is\n[installed](https://docs.docker.com/engine/install/) and enabled to\nautomatically start at boot. Also ensure you [add your\nuser](https://docs.docker.com/engine/install/linux-postinstall/) to the\n`docker` group.\n\nThe Docker image is available on [Docker\nHub](https://hub.docker.com/repository/docker/bulletmark/corsproxy). Run\nthe following command:\n\n```sh\n$ docker run --restart always -d -p 8000:8000 bulletmark/corsproxy 8000=http://192.168.1.98\n```\n\nBe sure to change the target server mapping to what you require. The image\nis available for amd64, arm64, and arm/v7 architectures. E.g. on a\nstandard PC, or on a Raspberry Pi, just run the above single command and\ndocker will download, install, and run the appropriate image. Docker\nwill also restart the corsproxy container when your system starts.\n\n## Usage\n\nType `corsproxy -h` to view the usage summary:\n\n```\nusage: corsproxy [-h] [-d] [-c CONFFILE] [targets ...]\n\nA simple CORS proxy. Reads list of target server mappings from the command\nline, or from your config file. Target server mappings are of the form\n\"[host:]port=http://server[:targetport]\" or\n\"[host:]port=https://server[:targetport]\" where \"port\" is the local listening\nport and \"server[:targetport]\" is the server (and optional target port) to\nproxy to. The default host address to listen on for a port is '0.0.0.0' to\nallow all IPv4 connections but you can specify an alternate host address for\neach server mapping, e.g. '127.0.0.1' to limit to local IPv4 connections, or\n'[::]' for all IPv6 connections, or '[::1]' to limit to local IPv6\nconnections, or any specific IPv4 or IPv6 address to limit to that interface.\nE.g. to listen all IPv4 and IPv6 addresses and forward to same IPv4 server\ndefine 2 mappings: \"0.0.0.0:8000=http://192.168.1.1\"\n\"[::]:8000=http://192.168.1.1\".\n\npositional arguments:\n  targets               1 or more proxy target server mappings\n\noptions:\n  -h, --help            show this help message and exit\n  -d, --debug           enable debug output\n  -c CONFFILE, --conffile CONFFILE\n                        alternative configuration file,\n                        default=\"~/.config/corsproxy.toml\"\n```\n\n## Major Version 2.0 Changes\n\n1. **Incompatible Change:** HTTPS targets are now supported in addition\n   to standard HTTP. This necessitates an incompatible change to how the\n   target server mappings are defined. E.g. a previous mapping\n   `8000:192.168.1.98` now must be defined as `8000=http://192.168.1.98`\n   because you are required to define whether the target server is\n   `http` or `https`. Note the listening port is now separated from the\n   target server with a `=`, not a `:`.\n\n2. **Incompatible Change:** The configuration file `~/.config/corsproxy`\n   is renamed to `~/.config/corsproxy.toml` and is now\n   [TOML](https://toml.io) format.\n\n3. **Enhancement:** IPv6 addresses can now also be specified for both\n   source and target addresses, in addition to IPv4 addresses.\n   Also, source addresses for IPv4 and IPv6 can be specified to limit to\n   loopback interface only, or to a specific interface, etc.\n\n4. **Enhancement:** HTTP methods PUT, PATCH, DELETE, and HEAD are now\n   supported in addition to the normal GET and POST.\n\n5. **Enhancement:** Previously I was using a home-grown implementation\n   to intercept and insert\n   [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)\n   headers. This worked for my use but it may not work generally for all\n   users so now I use the [Starlette](https://www.starlette.io/)\n   middleware [CORS\n   package](https://www.starlette.io/middleware/#corsmiddleware) which\n   is likely to be much more standards based and robust for general use.\n\n6. **Enhancement:** For concurrency, the code now uses native Python\n   [asyncio](https://docs.python.org/3/library/asyncio.html) rather than\n   3rd party\n   [gevent/greenlet](https://greenlet.readthedocs.io/en/latest/) so it\n   is slightly more performant and efficient.\n\n7. Python 3.7+ is required at a minimum. Python 3.6 no longer supported.\n\n## License\n\nCopyright (C) 2019 Mark Blakeney. This program is distributed under the\nterms of the GNU General Public License.\nThis program is free software: you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation, either version 3 of the License, or any later\nversion.\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License at \u003chttp://www.gnu.org/licenses/\u003e for more details.\n\n\u003c!-- vim: se ai syn=markdown: --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbulletmark%2Fcorsproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbulletmark%2Fcorsproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbulletmark%2Fcorsproxy/lists"}