Skip to content

httpoison to req - #3928

Merged
kinjalh merged 12 commits into
masterfrom
http-migration
Aug 21, 2026
Merged

httpoison to req#3928
kinjalh merged 12 commits into
masterfrom
http-migration

Conversation

@kinjalh

@kinjalh kinjalh commented Jul 29, 2026

Copy link
Copy Markdown
Member

use req instead of httpoison

Test Plan

Test environment: https://console.your-env.onplural.sh/

Checklist

  • I have added a meaningful title and summary to convey the impact of this PR to a user.
  • If required, I have updated the Plural documentation accordingly.
  • I have added tests to cover my changes.
  • I have deployed the agent to a test environment and verified that it works as expected (required only when changing agent code).

Plural Flow: console


Open in Devin Review

@kinjalh kinjalh added the backend Changes related to the backend label Jul 29, 2026
@soffi-ai

soffi-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Soffi AI Summary

This PR migrates the Elixir server's HTTP client library from HTTPoison to Req across the entire codebase. The motivation is to standardize on a more modern, composable HTTP client that reduces boilerplate — Req provides a higher-level API with built-in response handling, eliminating the repetitive pattern-matching on HTTPoison.Response status codes and manual JSON decoding that was copy-pasted across dozens of modules.

The key architectural change is the introduction of a shared Http.handle/2 helper and Console.Utils.HTTP.client_options/2 utility that centralizes response handling and option resolution, replacing per-call case expressions that individually matched on {:ok, %HTTPoison.Response{status_code: code, body: body}} for success/error cases and {:error, reason} for transport errors. This pattern was replicated across all external integrations: GitLab, GitHub, Azure DevOps, Bitbucket (cloud and datacenter), Hydra, Prometheus, Elasticsearch (vector and graph), Ollama, Loki, VictoriaMetrics, Datadog, notification webhooks, and others.

Additionally, inline decode_json/1 helper functions that were duplicated in multiple client modules have been removed — JSON decoding is now handled uniformly by the shared response handler. Configuration keys are migrated from :httpoison_*_options to :req_*_options application env keys, with backward-compatible dual-key lookup via client_options/2.

Commits

Commit Summary
74fb44c Initial migration of HTTP calls from HTTPoison to Req across integration clients (GitLab, Azure DevOps, Bitbucket, GitHub, Prometheus, Elasticsearch, Ollama, Loki, etc.), replacing verbose case-match response handling with calls to a new shared Http.handle/2 helper.
d9f6367 Bug fixes from initial migration pass — correcting Req option formats and header structures that differed from HTTPoison's conventions.
ad2c4ad Refactors the Req migration: introduces Console.Utils.HTTP.client_options/2 for dual-key config lookup (:httpoison_*_options:req_*_options), removes duplicated decode_json/1 helpers from individual client modules, and standardizes option passing across all migrated clients.
b55c691 Small bugfix to make existing tests pass with the new Req-based response shapes.
5836363 Test suite fixes — updates test mocks and assertions to match Req's response format instead of HTTPoison's %HTTPoison.Response{} structs.
2330115 Fixes a cron-related test failure exposed by the HTTP client migration.
b0024b3 Fixes redirect handling behavior that differed between HTTPoison and Req.
65cb09d Additional fixes for edge cases discovered during integration testing of the Req migration.
9aab3ea Keeps certain tests commented out to match their pre-existing state on master, avoiding false test regressions from the migration.
43faf69 Final test fix to ensure the full test suite passes with the completed HTTPoison → Req migration.

Updated: 2026-08-21 10:38 UTC

Deploy in Soffi

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]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR migrates Console’s direct HTTP calls from HTTPoison to Req.

  • Updates response matching, request options, form encoding, redirects, and error handling across AI, deployment, SCM, metrics, log, and utility clients.
  • Adds an HTTPoison-to-Req option translation helper.
  • Reworks Victoria Metrics and AI proxy response streaming around Req’s asynchronous response API.
  • Updates affected mocks and tests to use Req response and transport-error structures.

Confidence Score: 4/5

The 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

Important Files Changed

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

@kinjalh kinjalh added the enhancement New feature or request label Jul 29, 2026

@michaeljguarino michaeljguarino left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this generally makes sense. Have you done any e2e testing, certainly with things like elasticsearch/prometheus queries, and others that route through workbenches

@michaeljguarino michaeljguarino left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment on lines +51 to +60
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
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@kinjalh
kinjalh merged commit 8e868ab into master Aug 21, 2026
13 checks passed
@kinjalh
kinjalh deleted the http-migration branch August 21, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Changes related to the backend enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants