Current section
Files
Jump to
Current section
Files
README.md
# ReqTor
A [Req](https://github.com/wojtekmach/req) plugin for routing HTTP requests through a Tor SOCKS5 proxy.
Supports both clearnet sites and `.onion` hidden services.
## Installation
Add `req_tor` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:req_tor, "~> 0.1.0"}
]
end
```
## Prerequisites
Ensure Tor is running locally:
```bash
# macOS
brew install tor
brew services start tor
# Linux
sudo apt install tor
sudo systemctl start tor
```
The default SOCKS5 proxy runs on port 9050. Tor Browser uses port 9150.
## Usage
`Req` sends the request directly. `ReqTor` sends it through Tor.
```elixir
Req.get!("https://example.com")
ReqTor.get!("https://check.torproject.org")
# .onion hidden services
ReqTor.get!("http://example.onion/")
# Reuse a client. `head!`, `post!`, `put!`, `patch!`, `delete!`, and `request!` match.
req = ReqTor.new(tor_port: 9150)
ReqTor.get!(req, url: "http://example.onion/")
# Tor Browser user-agent (helps avoid blocks)
req = ReqTor.new(tor_browser: true)
# Skip the proxy for one call
ReqTor.get!(req, url: "https://example.com", tor_enabled: false)
```
`attached?/1` tells a Tor request from a plain Req request:
```elixir
ReqTor.attached?(ReqTor.new())
#=> true
ReqTor.attached?(Req.new())
#=> false
```
To add Tor to a request that already has Req plugins, attach it and still call `ReqTor`:
```elixir
req = Req.new(base_url: "http://example.onion") |> ReqTor.attach()
ReqTor.get!(req, url: "/")
```
## Helper Functions
```elixir
req = ReqTor.new()
# Check if connected through Tor
ReqTor.check_tor?(req)
#=> true
# Get your Tor exit node IP
ReqTor.exit_ip(req)
#=> {:ok, "185.220.101.42"}
# Or pass options straight through
ReqTor.exit_ip(tor_port: 9150)
#=> {:ok, "185.220.101.42"}
```
## Options
| Option | Default | Description |
|--------|---------|-------------|
| `:tor_host` | `"127.0.0.1"` | Tor SOCKS5 proxy host |
| `:tor_port` | `9050` | Tor SOCKS5 proxy port (use `9150` for Tor Browser) |
| `:tor_enabled` | `true` | Route this request through Tor. `false` skips the proxy for that call |
| `:tor_insecure` | `:auto` | `:auto` verifies clearnet TLS and skips it for `.onion`. `true` skips every host. `false` verifies every host |
| `:tor_browser` | `false` | Use Tor Browser's user-agent string. This replaces `:user_agent` |
| `:receive_timeout` | `60000` | Milliseconds to wait on the Tor socket. Req's option, with a longer Tor default |
| `:user_agent` | `ReqTor/<version>` | Sent unless you set this, a `user-agent` header, or `:tor_browser` |
## License
BSD 3-Clause. See [LICENSE](LICENSE).