Skip to content

Commit 7c5154b

Browse files
huacnleeclaude
andauthored
feat(rust): Add Config::header() for custom HTTP and WebSocket headers (#520)
## Summary - Added `custom_headers: HashMap<String, String>` field to `Config` struct - Added `Config::header(key, value) -> Self` builder method to set custom headers - Custom headers are injected into every HTTP request (via `create_http_client()`) and WebSocket upgrade request (via `create_ws_request()`) - Updated `CHANGELOG.md` ## Use Case Enables callers to pass arbitrary headers (e.g. `x-cli-cmd`, `x-channel-key`) for server-side telemetry and analytics without modifying the SDK internals. ```rust let config = Config::from_oauth(oauth) .header("x-cli-cmd", "cash-flow") .header("x-channel-key", "kol-123"); ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 485cf02 commit 7c5154b

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## Added
1010

11+
- **Rust:** `Config::header(key, value)` builder method to inject custom headers into every HTTP request and WebSocket upgrade request.
1112
- **Rust, Python:** `ContentContext` adds three new methods:
1213
- `topic_detail(topic_id)` — get detail of a single topic.
1314
- `list_topic_replies(opts)` — list replies for a topic, with optional page/size filtering.

rust/src/config.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66
sync::Arc,
77
};
88

9-
pub(crate) use http::{HeaderValue, Request, header};
9+
pub(crate) use http::{HeaderName, HeaderValue, Request, header};
1010
use longbridge_httpcli::{HttpClient, HttpClientConfig, is_cn};
1111
use longbridge_oauth::OAuth;
1212
use num_enum::IntoPrimitive;
@@ -127,6 +127,8 @@ pub struct Config {
127127
pub(crate) enable_print_quote_packages: bool,
128128
pub(crate) language: Language,
129129
pub(crate) log_path: Option<PathBuf>,
130+
/// Extra headers injected into every HTTP and WebSocket upgrade request.
131+
pub(crate) custom_headers: HashMap<String, String>,
130132
}
131133

132134
/// Reads an env var by trying `LONGBRIDGE_<suffix>` first, then falling back
@@ -218,6 +220,7 @@ impl Config {
218220
push_candlestick_mode: extras.push_candlestick_mode,
219221
enable_print_quote_packages: extras.enable_print_quote_packages,
220222
log_path: extras.log_path,
223+
custom_headers: Default::default(),
221224
}
222225
}
223226

@@ -266,6 +269,7 @@ impl Config {
266269
push_candlestick_mode: extras.push_candlestick_mode,
267270
enable_print_quote_packages: extras.enable_print_quote_packages,
268271
log_path: extras.log_path,
272+
custom_headers: Default::default(),
269273
}
270274
}
271275

@@ -320,6 +324,7 @@ impl Config {
320324
push_candlestick_mode: extras.push_candlestick_mode,
321325
enable_print_quote_packages: extras.enable_print_quote_packages,
322326
log_path: extras.log_path,
327+
custom_headers: Default::default(),
323328
})
324329
}
325330

@@ -419,7 +424,12 @@ impl Config {
419424
config = config.http_url(url.clone());
420425
}
421426

422-
HttpClient::new(config).header(header::ACCEPT_LANGUAGE, self.language.as_str())
427+
let mut client =
428+
HttpClient::new(config).header(header::ACCEPT_LANGUAGE, self.language.as_str());
429+
for (key, value) in &self.custom_headers {
430+
client = client.header(key.as_str(), value.as_str());
431+
}
432+
client
423433
}
424434

425435
fn create_ws_request(&self, url: &str) -> tokio_tungstenite::tungstenite::Result<Request<()>> {
@@ -428,6 +438,14 @@ impl Config {
428438
header::ACCEPT_LANGUAGE,
429439
HeaderValue::from_str(self.language.as_str()).unwrap(),
430440
);
441+
for (key, value) in &self.custom_headers {
442+
if let (Ok(name), Ok(val)) = (
443+
HeaderName::from_bytes(key.as_bytes()),
444+
HeaderValue::from_str(value),
445+
) {
446+
request.headers_mut().append(name, val);
447+
}
448+
}
431449
Ok(request)
432450
}
433451

@@ -471,6 +489,13 @@ impl Config {
471489
self
472490
}
473491

492+
/// Add a custom header to every HTTP request and WebSocket upgrade request.
493+
#[must_use]
494+
pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
495+
self.custom_headers.insert(key.into(), value.into());
496+
self
497+
}
498+
474499
/// Set the HTTP endpoint URL in place.
475500
pub fn set_http_url(&mut self, url: impl Into<String>) {
476501
self.http_url = Some(url.into());

0 commit comments

Comments
 (0)