202 lines
4.8 KiB
Markdown
202 lines
4.8 KiB
Markdown
# Hoppscotch Relay
|
|
|
|
[](https://opensource.org/licenses/MIT)
|
|
|
|
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.
|
|
|
|
## Features
|
|
|
|
- 🚀 **Full HTTP Support**: Handle GET, POST, PUT, DELETE, and other HTTP methods
|
|
- 📦 **Multiple Body Types**:
|
|
- Raw text/JSON
|
|
- URL-encoded forms
|
|
- Multipart form data
|
|
- File uploads
|
|
- 🔒 **Security**:
|
|
- Client certificate authentication (PEM & PFX/PKCS#12)
|
|
- Custom root certificate bundles
|
|
- Certificate validation control
|
|
- 🌐 **Proxy Support**:
|
|
- HTTP/HTTPS proxy configuration
|
|
- Authentication support
|
|
- NTLM support
|
|
- ⚡ **Performance**:
|
|
- Async design
|
|
- Request cancellation support
|
|
- Progress logs
|
|
- 📊 **Detailed Metrics**:
|
|
- Response timing
|
|
- Status tracking
|
|
- Header parsing
|
|
|
|
## Installation
|
|
|
|
Add this to your `Cargo.toml`:
|
|
|
|
```toml
|
|
[dependencies]
|
|
hoppscotch-relay = "0.1.1"
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Basic Request
|
|
|
|
```rust
|
|
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);
|
|
```
|
|
|
|
### POST Request with JSON Body
|
|
|
|
```rust
|
|
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())?;
|
|
```
|
|
|
|
### File Upload with Form Data
|
|
|
|
```rust
|
|
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,
|
|
);
|
|
```
|
|
|
|
### Client Certificate Authentication
|
|
|
|
```rust
|
|
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,
|
|
);
|
|
```
|
|
|
|
### Proxy Configuration
|
|
|
|
```rust
|
|
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),
|
|
);
|
|
```
|
|
|
|
## Request Cancellation
|
|
|
|
The library supports request cancellation through Tokio's `CancellationToken`:
|
|
|
|
```rust
|
|
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();
|
|
```
|
|
|
|
## Building from Source
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone https://github.com/hoppscotch/hoppscotch-relay
|
|
cd hoppscotch-relay
|
|
```
|
|
|
|
2. Build the project:
|
|
```bash
|
|
cargo build --release
|
|
```
|