Shreyas f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
..
src f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
.envrc f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
.gitignore f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
Cargo.lock f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
Cargo.toml f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
LICENSE.md f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
README.md f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
devenv.lock f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
devenv.nix f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago
devenv.yaml f52219bb95 feat: `openssl` based `hoppscotch-relay` for request forwarding (#4442) 3 weeks ago

README.md

Hoppscotch Relay

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:

[dependencies]
hoppscotch-relay = "0.1.1"

Usage

Basic Request

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

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

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

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

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:

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:

    git clone https://github.com/hoppscotch/hoppscotch-relay
    cd hoppscotch-relay
    
  2. Build the project:

    cargo build --release