httpoison to req - #3928
Conversation
Soffi AI SummaryThis PR migrates the Elixir server's HTTP client layer from HTTPoison to Req across the entire codebase. The motivation is to standardize on a more modern, composable HTTP client library and eliminate the repetitive boilerplate that HTTPoison required for response handling. The core change introduces a unified Affected integrations include: Azure DevOps, GitHub, GitLab, Bitbucket (cloud and datacenter), Hydra (OIDC), Prometheus, Loki, Victoria Metrics, Elasticsearch, Ollama, Datadog, Helm repository fetching, Kubernetes version tables, deprecation/compatibility tables, notification delivery, PR automation webhooks, and cloud add-on compatibility fetching. Effectively every external HTTP call in the Elixir server has been migrated. Supporting configuration keys were also updated — A small follow-up of test and cron-related fixes accompanies the migration to ensure the test suite passes cleanly after the library swap. Commits
Updated: 2026-08-06 14:32 UTC |
| defp http_opts, | ||
| do: | ||
| Application.get_env(:console, :httpoison_azure_devops_options, []) ++ [recv_timeout: 60_000] | ||
| Application.get_env(:console, :req_azure_devops_options, []) ++ [receive_timeout: 60_000, decode_body: false, retry: false] |
There was a problem hiding this comment.
Legacy SCM options are dropped
When a deployment supplies proxy, TLS, or timeout settings through the previously supported :httpoison_*_options keys, these clients now read only the renamed :req_*_options keys, causing required connection settings to disappear and the affected SCM integrations to fail.
Greptile SummaryThis PR migrates Console’s direct HTTP calls from HTTPoison to Req.
Confidence Score: 4/5The SCM option-key compatibility break should be fixed before merging because configured proxy and TLS settings can disappear after an upgrade. Four workbench SCM clients stop reading their previously supported application environment keys without a fallback or translation path, causing deployment-specific HTTP settings to be silently omitted. Files Needing Attention: lib/console/ai/tools/workbench/integration/azure_devops/client.ex, lib/console/ai/tools/workbench/integration/bitbucket/client.ex, lib/console/ai/tools/workbench/integration/bitbucket_datacenter/client.ex, lib/console/ai/tools/workbench/integration/gitlab/client.ex
|
| Filename | Overview |
|---|---|
| lib/console/utils/http.ex | Adds centralized translation of legacy proxy, timeout, TLS, and redirect options into Req-compatible options. |
| lib/console/logs/stream/exec.ex | Correctly migrates the Victoria Metrics streaming state machine to Req asynchronous responses and handles all documented message forms. |
| lib/console_web/controllers/ai_controller.ex | Migrates the streaming AI reverse proxy to Req while filtering hop-by-hop response headers and cancelling timed-out streams. |
| lib/console/ai/tools/workbench/integration/azure_devops/client.ex | Migrates requests to Req but drops compatibility with the existing HTTP option configuration key. |
| lib/console/ai/tools/workbench/integration/github/client.ex | Migrates GitHub workbench requests and pagination headers to Req while translating Tentacat’s legacy request options. |
| lib/console/clients/prometheus/client.ex | Migrates instant and range Prometheus queries to Req form encoding with equivalent connection and receive timeouts. |
| lib/console/clients/hydra/client.ex | Migrates Hydra administration and OAuth request handling to Req without changing the decoded response contracts. |
Reviews (1): Last reviewed commit: "httpoison to req" | Re-trigger Greptile
michaeljguarino
left a comment
There was a problem hiding this comment.
this generally makes sense. Have you done any e2e testing, certainly with things like elasticsearch/prometheus queries, and others that route through workbenches
michaeljguarino
left a comment
There was a problem hiding this comment.
I suspect this is close enough to at least start really e2e testing. One thing I want to make sure is covered before merge is done is to ensure the http pool settings currently applied to HTTPoison are translated over (we need decent pool capacity for things like k8s requests especially).
| Req.request( | ||
| method: method, | ||
| url: url, | ||
| body: body, | ||
| headers: headers(config), | ||
| connect_options: [timeout: 10_000], | ||
| receive_timeout: 10_000, | ||
| decode_body: false, | ||
| retry: false | ||
| ) |
There was a problem hiding this comment.
🟨 Outbound HTTP calls now follow redirects by default, enabling redirect-based SSRF on user-supplied URLs
The migration replaces HTTPoison (which does not follow redirects unless follow_redirect: true) with Req, whose :redirect option defaults to true. Several of the converted call sites take fully user/tenant-controlled URLs, e.g. the workbench HTTP tool (Req.request(... url: url ...) at lib/console/ai/tools/workbench/http.ex:51-60), notification sink webhooks (lib/console/deployments/notifications.ex:174-182) and the PR governance webhook (lib/console/deployments/pr/governance/impl/webhook.ex:33). An attacker who can configure such a URL can now point it at a server that responds with a 30x to an internal address (e.g. cloud metadata or in-cluster services), and the console will transparently follow it, whereas previously the redirect was surfaced as a non-2xx response and never followed.
Was this helpful? React with 👍 or 👎 to provide feedback.
use req instead of httpoison
Test Plan
Test environment: https://console.your-env.onplural.sh/
Checklist
Plural Flow: console