Skip to content

Add per-block proxy bypass and proxy variables to Http Request block - #1244

Open
Duc-python wants to merge 2 commits into
openbullet:masterfrom
Duc-python:feature/http-block-proxy-bypass-and-proxy-vars
Open

Duc-python wants to merge 2 commits into
openbullet:masterfrom
Duc-python:feature/http-block-proxy-bypass-and-proxy-vars

Conversation

@Duc-python

@Duc-python Duc-python commented Oct 11, 2026 •

Copy link
Copy Markdown

Description

Two related additions to the Http Request block, both aimed at giving configs finer control over proxies.

1. Per-block proxy bypass (useProxy, default true)

The Http Request block now has a useProxy checkbox. When unchecked, that single request is sent directly even if the job has proxies enabled.

A config could already opt out of the proxy through the SET USEPROXY FALSE statement in a LoliCode block, and JobProxyMode controls it at job level. This adds the missing middle ground: a per-block toggle for the blocks that actually make requests.

The difference is scoping and durability. SET USEPROXY is imperative and mutates data.UseProxy for the bot, so it stays in effect for every subsequent block until you set it back, and it is re-applied at the START: label on each retry. useProxy is declarative and scoped to exactly one block, is rebuilt from the block on every retry, and needs no raw script to express "this one request only".

Common reasons to want it: fetching a token or captcha from a direct request while the actual target traffic goes through the proxy pool, or issuing a single direct request in a config that is otherwise fully proxied.

The decision is made in a new HttpRequestHandler.ResolveProxy helper, so all three HTTP libraries (RuriLibHttp, SystemNet, CurlImpersonate) honour the flag through a single choke point rather than eight scattered checks. When a block bypasses its proxy while the bot has one assigned, a [NO PROXY] line is written to the bot log so it is obvious why the request left from a different IP.

2. input.proxy.* variables

ScriptGlobals now exposes the proxy assigned to the bot as input.proxy.*:

Variable Value
input.proxy.ip / input.proxy.host Proxy.Host
input.proxy.port Proxy.Port
input.proxy.username / input.proxy.password empty string when the proxy needs no authentication
input.proxy.type http, https, socks4, socks4a, socks5
input.proxy.country / input.proxy.ping proxy metadata
input.proxy.inUse whether requests actually go through the proxy

Previously configs had to reach for data.Proxy (and cast ?? on username/password) to use proxy fields. Every field is always present and defaults to an empty value, so configs never need a null check before interpolating them. inUse is what distinguishes "the bot has a proxy" from "this block is using it", which pairs with the useProxy flag above.

The variables are also added to the input-variable autocomplete in both clients (Angular and WPF).

Backwards compatibility

Both additions are additive and preserve existing behaviour:

  • useProxy defaults to true, and LoliCodeWriter omits settings equal to their parameter default, so existing configs neither change behaviour nor grow when re-serialized.
  • A wordlist slice literally named proxy keeps precedence over the new object, so configs that slice into proxy are untouched.

Incidental fix

decodeHtmlSetting is declared in HttpRequestBlockSettingsViewer.xaml but was never assigned in the code-behind, leaving that setting inert in the native client. It is now bound.

No new dependencies.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • dotnet build OpenBullet2.slnx -c Release — succeeds, no new warnings
  • dotnet test RuriLib.Tests — 743 passed, 97 skipped (the skips are the pre-existing Testcontainers-based integration tests, which are skipped without Docker)
  • dotnet test OpenBullet2.Web.Tests — 326 passed
  • dotnet test OpenBullet2.Core.Tests — 31 passed
  • npm run build in openbullet2-web-client — succeeds

New unit tests:

  • HttpClientRequestHandlerTests.ResolveProxy_BypassesOnlyWhenRequested — the full decision table for ResolveProxy across botUsesProxy x blockUseProxy, asserting both which proxy comes back and exactly when the [NO PROXY] notice is emitted. A config with no proxy at all must resolve to null and stay silent regardless of the block setting.
  • HttpTests.HttpRequestStandard_Get_WithoutAnyProxy_Succeeds — end-to-end request against the test HTTP server with no proxy assigned, for all three HTTP libraries and both values of the block setting. These use Testcontainers, so they run in CI but are skipped locally without Docker.
  • HttpRequestBlockInstanceTests — useProxy defaults to true and is emitted as UseProxy in the generated C#; toggling it to false is emitted too; ToLC omits it when it equals the default and writes it when changed; FromLC round-trips it.
  • ScriptGlobalsTests — input.proxy.* is populated from the assigned proxy; every field defaults to empty when no proxy is assigned; fields remain readable but inUse is false when the job has proxies disabled; a wordlist slice named proxy takes precedence.

Manual reproduction: in the config stacker, add an Http Request block and toggle useProxy off. Start a job with proxies enabled and confirm the request log contains [NO PROXY] and the response comes from the local IP, while other blocks still go through the proxy. In a job with no proxies at all, confirm no block logs [NO PROXY] and all requests succeed.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Notes for the reviewer

Two things I deliberately left out, happy to add either if wanted:

  1. End-to-end assertion of the bypass. The unit tests cover the generated UseProxy flag and ResolveProxy inputs, but there is no integration test asserting the request actually leaves from a different IP when the box is unchecked. That would need a live proxy server; the existing HttpRequestProxyIntegrationTests are Testcontainers-based and currently skipped in CI, so I did not add a test that would also never run.
  2. MCP documentation. ConfigMakingMcpTools exposes a Mcp/Docs topic set for config authors, and neither useProxy nor input.proxy.* is documented there yet. The useProxy parameter description is picked up automatically by get_block_details, but input.proxy.* has no home yet.

If you would prefer input.proxy.host only (the Proxy model names the field Host, so ip is an alias), or want the whole thing scoped to a tri-state instead of a bool, say so and I will rework it.

Http Request blocks now expose a `useProxy` parameter (default `true`). When
disabled, that single request is sent directly even if the job has proxies
enabled, which was previously only possible by toggling the proxy at job level
and restarting it.

The check lives in a new `HttpRequestHandler.ResolveProxy` helper so all three
HTTP libraries (RuriLibHttp, SystemNet, CurlImpersonate) honour it through a
single choke point. When a block bypasses its proxy, a `[NO PROXY]` line is
logged so the reason is visible in the bot log.

ScriptGlobals now also exposes the bot proxy as `input.proxy.*` (ip, host, port,
username, password, type, country, ping, inUse) so configs can read proxy fields
without falling back to `data.Proxy`. Every field is always present, defaulting
to empty, so configs do not need null checks. `inUse` reflects whether requests
actually go through the proxy, which distinguishes "the bot has a proxy" from
"this block is using it".

Both additions are backwards compatible: `useProxy` defaults to the previous
behaviour and is omitted from LoliCode when unchanged, and a wordlist slice
literally named `proxy` keeps precedence over the new object.

Also assigns `decodeHtmlSetting` in the native HttpRequestBlockSettingsViewer,
which was declared in XAML but never bound, leaving the setting inert there.
The notice condition checked whether a proxy was assigned to the bot rather
than whether the job was actually using it, so a job with proxies disabled
that still had a proxy object attached would log a misleading bypass notice
on every block with `useProxy` off. The debugger and the `SET PROXY` LoliCode
statement can both produce that state.

ResolveProxy now returns early unless the job is both proxied and has a proxy
assigned, and only logs on the branch that actually drops a proxy in use.

ResolveProxy is also internal rather than protected so the full decision table
is directly testable; RuriLib already grants InternalsVisibleTo to the test
assembly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant