HttpClient.hpp

1. Overview

The HttpClient.hpp header defines the HttpClient utility class and the associated HttpResponse structure, providing a lightweight, synchronous HTTP communication layer for BastionGuard.

This module abstracts low-level networking details and offers a unified interface for interacting with external web services, threat intelligence providers, and cloud-based APIs.

Functionally, HttpClient provides:

  • HTTP GET and POST request support
  • Custom header injection (API keys, user-agent, authorization)
  • Configurable request timeouts
  • Centralized error handling and diagnostics
  • URL encoding utilities
  • Encapsulation of libcurl initialization and execution

2. Dependencies and Includes

#include <string>
#include <map>
  • <string> – URLs, payloads, and response bodies
  • <map> – HTTP request header key-value pairs

3. Data Structures

3.1 HttpResponse Structure

struct HttpResponse {
    int status = 0;
    std::string body;
    std::string error;
};

Encapsulates the outcome of an HTTP request.

  • status – HTTP status code (0 indicates transport-level failure)
  • body – response payload returned by the server
  • error – diagnostic message (typically from libcurl)

4. Class Declaration and Scope

class HttpClient

The class is implemented as a static utility container. All methods are static, and no instances are intended to be created.

This design simplifies usage across backend services and background workers.


5. Public Interface

5.1 HTTP GET Request

static HttpResponse get(
    const std::string& url,
    const std::map<std::string, std::string>& headers = {},
    long timeoutSeconds = 20
);

Executes a synchronous HTTP GET request with optional custom headers.

  • url – target endpoint
  • headers – optional request headers
  • timeoutSeconds – maximum execution time

5.2 HTTP POST Request

static HttpResponse post(
    const std::string& url,
    const std::string& body,
    const std::map<std::string, std::string>& headers = {},
    long timeoutSeconds = 20
);

Executes a synchronous HTTP POST request, transmitting a request payload to the server.

  • body – request payload (JSON, form data, etc.)
  • headers – optional request headers
  • timeoutSeconds – maximum execution time

5.3 URL Encoding Utility

static std::string urlEncode(const std::string& value);

Encodes arbitrary strings for safe inclusion in URLs and query parameters.

This function is typically used for encoding email addresses, tokens, and search parameters.


6. Internal State and Initialization

6.1 Global Initialization Helper

static void ensureCurlGlobalInit();

Ensures that libcurl global initialization is performed exactly once before any request.

This prevents race conditions and undefined behavior in multi-threaded environments.


6.2 Unified Request Executor

static HttpResponse perform(
    const std::string& url,
    const char* method,
    const std::string& requestBody,
    const std::map<std::string, std::string>& headers,
    long timeoutSeconds
);

Centralizes low-level request execution for both GET and POST operations.

This method configures libcurl options, attaches headers, handles callbacks, and collects results.


7. Internal Logic

A typical request workflow includes:

  • Ensuring libcurl global initialization
  • Creating and configuring a CURL handle
  • Applying timeout and redirect policies
  • Injecting custom headers
  • Registering response callbacks
  • Executing the request
  • Collecting status codes and payloads
  • Cleaning up resources

8. Integration with Cloud and Provider APIs

HttpClient is a core dependency for:

  • Identity leak providers (HIBP, LeakCheck, etc.)
  • Malware intelligence services
  • Update and repository management subsystems
  • Remote configuration and telemetry modules

9. Auto-Update (Scheduled Refresh)

This component does not implement scheduling. It is used as a building block by higher-level update services.


10. Settings and Configuration

Default timeouts and header conventions are defined at call sites. Advanced tuning may be provided by configuration layers.


11. Performance and Reliability

  • Synchronous execution: blocking behavior requires offloading to worker threads in UI contexts.
  • Connection reuse: libcurl pooling may be leveraged internally for improved throughput.
  • Timeout enforcement: protects against stalled connections.
  • Retry strategies: transient failures should be handled by higher-level logic.

12. Runtime and Security Considerations

  • TLS verification: certificate validation must be enabled to prevent man-in-the-middle attacks.
  • Header sanitization: sensitive headers (API keys, tokens) should never be logged.
  • Input validation: URLs and payloads must be validated before transmission.
  • Thread safety: global initialization and handle usage must be synchronized correctly.
  • Rate limiting: callers must respect provider quotas to avoid service bans.
  • Error propagation: detailed diagnostics should be surfaced to facilitate troubleshooting without exposing secrets.