A Ruby client sends a request, the API answers, and your macOS proxy debugger stays empty. There is no row to inspect, so you fall back to puts statements and a mess of logging around every call.
The reason is almost never a broken proxy. Ruby's HTTP stack does not pick up a proxy by accident. Net::HTTP only routes through a proxy when you pass the proxy host and port explicitly, and Faraday only does so when you set its proxy: option. For HTTPS, the client also has to trust Rockxy's certificate path, or the handshake fails before any body is decrypted. The outcome of this guide is a captured Ruby flow: after two small changes, your request shows up in Rockxy with full method, URL, headers, body, response, and timing.
Why Ruby traffic can disappear
Two independent things have to be true before Rockxy can show you a Ruby request, and Ruby makes both explicit rather than automatic:
Net::HTTPneeds the proxy passed in code. Unlike some libraries, baseNet::HTTPdoes not readHTTP_PROXYon its own. If you never give it a proxy host and port, it connects straight to the target and the proxy never sees the connection.- Environment variables are inconsistent and skip loopback. Some entry points (for example
URI#find_proxy, and Faraday when told to inherit the environment) readhttp_proxy/https_proxy, but they also honorno_proxy, and loopback hosts such aslocalhostand127.0.0.1are excluded by default. Relying on the ambient environment gives you different behavior per shell and per client.
The reliable answer is to configure one client explicitly for one request. That removes the ambiguity: you name the proxy in code, and for HTTPS you name the CA file in code, so the same script behaves the same way in every terminal.
What you will need
- Rockxy on macOS 14 (Sonoma) or later. It is a native app; download it from the Rockxy download page.
- Ruby 3.x with the
faradaygem installed if you want the Faraday examples (gem install faraday).Net::HTTPships with the standard library. - A terminal, so you can run one request with an explicit proxy set in code.
- Two ports clear in your head from the start: the proxy port (Rockxy's listener, shown in its toolbar) and the app port if you are hitting a local service. Swapping these two is the single most common mistake.
Step 1 — Confirm Rockxy is capturing and read its proxy port
Start Rockxy and make sure capture is enabled. Read the active proxy port from the toolbar; the examples below assume 8888, but yours may differ. Use whatever value Rockxy shows.
Prove the listener is alive before touching Ruby. Send one request you know Rockxy should see — a plain external HTTP URL routed through the proxy port — with curl:
curl -x http://127.0.0.1:8888 http://neverssl.com/
What you should see in Rockxy: a new row for neverssl.com. If even this does not appear, the proxy port is wrong or capture is off — fix that before writing any Ruby, because no client trick will help until the listener itself receives traffic.
Step 2 — Route Net::HTTP through Rockxy explicitly
Start with plain HTTP so certificate trust is out of the picture. Net::HTTP takes the proxy as extra positional arguments — Net::HTTP.new(host, port, proxy_host, proxy_port). Point a request at a known HTTP endpoint through Rockxy:
require "net/http"
require "uri"
proxy_host = "127.0.0.1"
proxy_port = 8888
uri = URI("http://neverssl.com/")
http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port)
response = http.get(uri.request_uri)
puts "status=#{response.code}"
puts response.body[0, 200]
The block form of Net::HTTP.start takes the same routing through keyword options, which reads more clearly when you have several settings to pass:
require "net/http"
require "uri"
uri = URI("http://neverssl.com/")
Net::HTTP.start(
uri.host, uri.port,
proxy_address: "127.0.0.1",
proxy_port: 8888,
) do |http|
response = http.get(uri.request_uri)
puts "status=#{response.code}"
end
What you should see in Rockxy: a row for neverssl.com/. Selecting it shows GET 200 OK, the request headers the Ruby client sent — including the default User-Agent: Ruby — the response body, and timing. Once one Ruby request is visible, proxy routing is proved and the rest is your application code.
Step 3 — Do the same with Faraday
Faraday wraps an adapter (Net::HTTP by default) and takes the proxy as a connection option. Pass proxy: when you build the connection:
require "faraday"
conn = Faraday.new(
url: "http://neverssl.com",
proxy: "http://127.0.0.1:8888",
)
response = conn.get("/")
puts "status=#{response.status}"
Faraday can also read proxy settings from the environment, but that path honors no_proxy and behaves differently across shells. While you are proving the route, set proxy: explicitly rather than depending on ambient variables. If you do rely on the environment for a real run, remember loopback targets are excluded by default — the same rule covered in the localhost capture guide.
What success looks like in Rockxy
After Step 2 or Step 3, the traffic list shows a row for your request. Selecting it reveals the method, full URL, the request headers your Ruby client sent, the response body, and timing. The screenshot below shows Rockxy capturing app network traffic on macOS — the same shape a Ruby client's request takes once it is routed through the proxy.
Net::HTTP or Faraday appears here the moment it is routed through Rockxy.This is the baseline. Once one boring Ruby request is visible, every harder question — wrong base URL, a missing token, a bad JSON shape, a slow route — has far fewer places to hide.
Capturing HTTPS from Ruby
Everything above is plain HTTP, which is the right way to prove routing first. For HTTPS, two more things have to be true: the host must be inside Rockxy's SSL Proxying scope, and the Ruby client must trust Rockxy's certificate path. Export Rockxy's root certificate to a PEM file first — the steps are in the certificates and trust docs.
With Net::HTTP, keep the proxy arguments, enable use_ssl, and set the CA file rather than turning verification off:
require "net/http"
require "uri"
uri = URI("https://api.github.com/zen")
http = Net::HTTP.new(uri.host, uri.port, "127.0.0.1", 8888)
http.use_ssl = true
http.ca_file = "/path/to/RockxyRootCA.pem"
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.get(uri.request_uri)
puts "status=#{response.code}"
puts response.body
Faraday passes the CA file through its SSL options:
require "faraday"
conn = Faraday.new(
url: "https://api.github.com",
proxy: "http://127.0.0.1:8888",
ssl: { ca_file: "/path/to/RockxyRootCA.pem" },
)
response = conn.get("/zen")
puts "status=#{response.status}"
If you prefer not to edit code, most Ruby OpenSSL builds honor the SSL_CERT_FILE environment variable, so export SSL_CERT_FILE=/path/to/RockxyRootCA.pem can point the client at Rockxy's certificate for the run. Keep the proxy set in code regardless — the CA file only settles trust, not routing.
What you should see in Rockxy: for a decrypted HTTPS request, the selected flow shows a readable request and response body. If instead you see a CONNECT or tunnel-only row, the proxy path exists but decryption did not happen — enable HTTPS decryption for that host and confirm the CA file is the one the client loads. The mechanics are covered in How to Debug HTTPS Traffic on macOS and, for how the interception works, How Rockxy Intercepts HTTPS Without Compromising Security.
If it does not work
The request succeeds but no row appears in Rockxy. The client reached the target directly. For Net::HTTP, confirm you actually passed proxy_host and proxy_port — it does not read shell variables on its own. For Faraday, confirm the proxy: option is set on the connection you are calling.
You see Connection refused to the proxy port. The port in your code does not match Rockxy's listener. Re-read the toolbar value and rerun. This usually means the proxy port drifted after a restart.
The request now fails when it used to succeed. You may have swapped the two ports — sending traffic to the app port as if it were the proxy, or vice versa. In the examples, 8888 is Rockxy's proxy and the target host and port stay as the request destination.
A tunnel row appears but the HTTPS body is unreadable. That is TLS, not routing. Add the host to SSL Proxying scope and point the client at Rockxy's CA file with ca_file or SSL_CERT_FILE. If the target pins its certificate, Rockxy will not silently defeat that — a pinned or failed handshake is surfaced as a failed transaction in the request list so you can see it happened, rather than being decrypted.
You reach for verify_mode = VERIFY_NONE to make it work. Disabling verification hides the exact trust problem you need to fix and is a bad habit to carry into real code. Prefer the exported CA file. If a request is to a localhost service and nothing routes, the loopback exclusion is doing its job — see the localhost capture guide.
Where env-var behavior comes from
The inconsistent parts of this — which entry point reads http_proxy, why no_proxy silently drops loopback — are Ruby and operating-system behavior, not Rockxy behavior. That is exactly why the examples above set the proxy in code. If you would rather understand the environment side, the proxy environment variables guide covers how HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are read on macOS, and the localhost capture guide covers the loopback fast path in detail.
Rockxy is macOS-only. These snippets are self-contained — copy them into a script, swap in the proxy port from your toolbar, and each one runs on its own. There is no sample repository to clone; the code above is the whole example.
Inspect the captured flow with your AI assistant (optional)
Once the Ruby request is captured, you can let an MCP-capable AI tool read it directly instead of pasting terminal output into a chat. Rockxy ships a built-in local MCP server that exposes read and replay tools — list_flows, get_flow_detail, replay_request, and diff_flows — so an assistant like Claude or Cursor can ask "what did that Faraday call actually send?" against the real capture.
Local MCP is 100% free and unlimited in the Free tier. No license upgrade required. The workflow is local-first and user-controlled: Rockxy's MCP server binds to localhost, and captured data stays in a local store on your Mac. Rockxy itself never uploads your traffic to an AI provider. If you enable the workflow, the assistant you connect may include the data it retrieves in its own prompts — that is your choice to make per tool. Setup is in the Connect Claude Desktop to Rockxy guide.
Next steps
The Ruby rule is short: Net::HTTP and Faraday route through a proxy only when you tell them to, and HTTPS decryption needs the CA file named in code or in SSL_CERT_FILE. Set the proxy explicitly for one request, trust the certificate, and your Ruby traffic becomes a normal captured flow.
From here, compare notes with the Python setup guide, move to HTTPS on macOS when you need decrypted bodies, or read the traffic capture docs. If capture behaves oddly in general, the FAQ covers the most frequent setup questions.