Packages

Req-compatible HTTP client that routes requests through a local Tor SOCKS5 proxy

Current section

Files

Jump to
req_tor README.md
Raw

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).