Shreyas f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) | 3 weeks ago | |
---|---|---|
.. | ||
src | 3 weeks ago | |
.envrc | 3 weeks ago | |
.gitignore | 3 weeks ago | |
Cargo.lock | 3 weeks ago | |
Cargo.toml | 3 weeks ago | |
LICENSE.md | 3 weeks ago | |
README.md | 3 weeks ago | |
devenv.lock | 3 weeks ago | |
devenv.nix | 3 weeks ago | |
devenv.yaml | 3 weeks ago |
A high-performance HTTP request-response relay used by Hoppscotch Desktop and Hoppscotch Agent for advanced request handling including CORS override, custom headers, certificates, proxies, and local system integration. It uses a custom fork of curl-rust with static OpenSSL builds for consistent SSL/TLS behavior across different platforms.
Add this to your Cargo.toml
:
[dependencies]
hoppscotch-relay = "0.1.1"
use hoppscotch_relay::{RequestWithMetadata, KeyValuePair};
use tokio_util::sync::CancellationToken;
// Create a basic GET request
let request = RequestWithMetadata::new(
1, // Request ID
"GET".to_string(), // Method
"https://api.example.com/data".to_string(), // Endpoint
vec![ // Headers
KeyValuePair {
key: "Accept".to_string(),
value: "application/json".to_string(),
}
],
None, // Body
true, // Validate certificates
vec![], // Root certificate bundles
None, // Client certificate
None, // Proxy configuration
);
// Execute the request with cancellation support
let cancel_token = CancellationToken::new();
let response = hoppscotch_relay::run_request_task(&request, cancel_token)?;
println!("Status: {} {}", response.status, response.status_text);
println!("Response time: {}ms", response.time_end_ms - response.time_start_ms);
let mut request = RequestWithMetadata::new(
2,
"POST".to_string(),
"https://api.example.com/users".to_string(),
vec![
KeyValuePair {
key: "Content-Type".to_string(),
value: "application/json".to_string(),
}
],
Some(BodyDef::Text(r#"{"name": "John Doe"}"#.to_string())),
true,
vec![],
None,
None,
);
let response = hoppscotch_relay::run_request_task(&request, CancellationToken::new())?;
let form_data = vec![
FormDataEntry {
key: "file".to_string(),
value: FormDataValue::File {
filename: "document.pdf".to_string(),
data: std::fs::read("document.pdf")?,
mime: "application/pdf".to_string(),
},
},
FormDataEntry {
key: "description".to_string(),
value: FormDataValue::Text("Important document".to_string()),
},
];
let mut request = RequestWithMetadata::new(
3,
"POST".to_string(),
"https://api.example.com/upload".to_string(),
vec![],
Some(BodyDef::FormData(form_data)),
true,
vec![],
None,
None,
);
let client_cert = ClientCertDef::PEMCert {
certificate_pem: std::fs::read("client.crt")?,
key_pem: std::fs::read("client.key")?,
};
let mut request = RequestWithMetadata::new(
4,
"GET".to_string(),
"https://secure-api.example.com".to_string(),
vec![],
None,
true,
vec![],
Some(client_cert),
None,
);
let proxy_config = ProxyConfig {
url: "http://proxy.example.com:8080".to_string(),
};
let mut request = RequestWithMetadata::new(
5,
"GET".to_string(),
"https://api.example.com".to_string(),
vec![],
None,
true,
vec![],
None,
Some(proxy_config),
);
The library supports request cancellation through Tokio's CancellationToken
:
use tokio_util::sync::CancellationToken;
let cancel_token = CancellationToken::new();
let cancel_token_clone = cancel_token.clone();
// Spawn the request in a separate task
let request_handle = tokio::spawn(async move {
hoppscotch_relay::run_request_task(&request, cancel_token_clone)
});
// Cancel the request after 5 seconds
tokio::time::sleep(Duration::from_secs(5)).await;
cancel_token.cancel();
Clone the repository:
git clone https://github.com/hoppscotch/hoppscotch-relay
cd hoppscotch-relay
Build the project:
cargo build --release