product-os-request 0.0.55

Product OS : Request provides a fully featured HTTP request library combining elements of reqwest and hyper for async requests with a series of helper methods to allow for easier usage depending upon your needs for one-time or repeat usage.
Documentation
# Product OS : Request

[![Crates.io](https://img.shields.io/crates/v/product-os-request)](https://crates.io/crates/product-os-request)
[![Documentation](https://docs.rs/product-os-request/badge.svg)](https://docs.rs/product-os-request)
[![Rust 1.75+](https://img.shields.io/badge/rust-1.75%2B-orange.svg)](https://www.rust-lang.org)
[![License: GPL-3.0](https://img.shields.io/badge/License-GPL%203.0-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

Product OS : Request provides a fully featured HTTP request library combining elements of reqwest and hyper for async requests with a series of helper methods to allow for easier usage depending upon your needs for one-time or repeat usage.

### What is Product OS?

Product OS is a collection of packages that provide different tools and features that can work together to build products more easily for the Rust ecosystem.

## Installation

```toml
[dependencies]
product-os-request = "0.0.1"
```

Pin the version to match the crate `Cargo.toml` when using path or git dependencies.

## Documentation

Full API documentation is available at [docs.rs/product-os-request](https://docs.rs/product-os-request).

## Usage

## Overview

Product OS : Request provides a fully featured HTTP request library with multiple implementation choices, allowing you to select between reqwest (high-level) or hyper (low-level) backends while maintaining a consistent API.


## Features

- **Multiple Implementations** - Choose between reqwest or hyper backends
- **Async HTTP Requests** - Built on tokio for high-performance async I/O
- **Default HTTPS/TLS** - Secure by default using Rustls
- **Requester Pattern** - Reusable configuration for multiple requests
- **Custom Request/Response Types** - Type-safe request building and response handling
- **Proxy Support** - HTTP, HTTPS, and SOCKS5 proxy configuration
- **Redirect Policies** - Configurable redirect handling
- **Certificate Management** - Custom trusted certificates support
- **Streaming Responses** - Optional streaming support for large responses
- **no_std Support** - Works in no_std environments with alloc
- **Comprehensive Documentation** - Well-documented with examples

## Installation

### Using Reqwest (High-Level, More Features)

```toml
[dependencies]
product-os-request = { version = "0.0.55", default-features = false, features = ["std_reqwest"] }
tokio = { version = "1", features = ["full"] }
```

### Using Hyper (Low-Level, More Control)

```toml
[dependencies]
product-os-request = { version = "0.0.55", default-features = false, features = ["std_hyper"] }
tokio = { version = "1", features = ["full"] }
```

### Backward Compatible (defaults to reqwest)

```toml
[dependencies]
product-os-request = "0.0.55"
tokio = { version = "1", features = ["full"] }
```

## Quick Start

### Simple GET Request (Reqwest)

```rust
use product_os_request::{Method, ProductOSRequestClient, ProductOSRequester, ProductOSClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create and configure requester
    let mut requester = ProductOSRequester::new();
    requester.set_timeout(5000);

    // Create client
    let mut client = ProductOSRequestClient::new();
    requester.build(&mut client);

    // Make request
    let request = client.new_request(Method::GET, "https://api.example.com/data");
    let response = client.request(request).await?;
    
    println!("Status: {}", response.status_code());
    let text = client.text(response).await?;
    println!("Response: {}", text);

    Ok(())
}
```

### Simple GET Request (Hyper)

```rust
use product_os_request::{Method, ProductOSHyperClient, ProductOSRequester, ProductOSClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create and configure requester
    let mut requester = ProductOSRequester::new();
    requester.set_timeout(5000);

    // Create hyper-based client
    let mut client = ProductOSHyperClient::new();
    requester.build(&mut client);

    // Make request
    let request = client.new_request(Method::GET, "https://api.example.com/data");
    let response = client.request(request).await?;
    
    println!("Status: {}", response.status_code());
    let text = client.text(response).await?;
    println!("Response: {}", text);

    Ok(())
}
```

### POST with JSON

```rust
use product_os_request::{Method, ProductOSRequestClient, ProductOSRequester, ProductOSClient};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut requester = ProductOSRequester::new();
    let mut client = ProductOSRequestClient::new();
    requester.build(&mut client);

    let mut request = client.new_request(Method::POST, "https://api.example.com/users");
    request.add_header("Content-Type", "application/json", false);

    let json_data = json!({
        "name": "John Doe",
        "email": "john@example.com"
    });

    client.set_body_json(&mut request, json_data).await;
    let response = client.request(request).await?;
    
    let json_response = client.json(response).await?;
    println!("Response: {:#}", json_response);

    Ok(())
}
```

## Features

Product OS Request supports optional features that can be enabled as needed:

```toml
[dependencies]
product-os-request = { version = "0.0.55", features = ["json", "form", "stream"] }
```

### Feature Flags

**No features are enabled by default.** You must explicitly choose an implementation.

#### Core Features (no\_std compatible)

| Feature | Description |
|---------|-------------|
| `uri` | URI type re-exported from `product-os-http` |
| `method` | HTTP method enum with serde support |
| `response` | Response handling with tracing |
| `request` | Request building (includes `method` and `response`) |

#### Standard Library Features

| Feature | Description |
|---------|-------------|
| `method_std` | Method enum with std support |
| `response_std` | Response handling with std support |
| `request_std` | Request building with std support (includes `method_std` and `response_std`) |
| `std_base` | Combines `request_std`, `response_std`, and `method_std` |

#### Backend Implementations

| Feature | Description |
|---------|-------------|
| `std_reqwest` | High-level reqwest-based HTTP client with TLS, cookies, compression |
| `std_hyper` | Low-level hyper-based HTTP client with Rustls TLS |
| `std` | **Deprecated** alias for `std_reqwest` |

#### Hyper Optional Add-ons

| Feature | Description |
|---------|-------------|
| `hyper_timeout` | Request timeouts for the hyper backend (via `tower`) |
| `hyper_compression` | Gzip/Brotli compression for the hyper backend (via `tower-http`) |
| `hyper_cookies` | Cookie jar support for the hyper backend |
| `hyper_proxy` | SOCKS5 proxy support for the hyper backend |
| `std_hyper_full` | Hyper with all optional add-ons enabled |

#### Content and Streaming

| Feature | Description |
|---------|-------------|
| `json` | JSON serialization/deserialization via `serde_json` |
| `form` | Form-encoded body support via `serde_urlencoded` |
| `stream` | Streaming response support |
| `stream_reqwest` | Streaming with reqwest backend |
| `stream_hyper` | Streaming with hyper backend |

### no_std Support

To use in a no_std environment:

```toml
[dependencies]
product-os-request = { version = "0.0.55", default-features = false, features = ["method", "request"] }
```

## Examples

The library includes comprehensive examples in this README demonstrating common use cases.

### Simple GET Request Example

## Configuration Options

### Requester Configuration

```rust
let mut requester = ProductOSRequester::new();

// Timeouts
requester.set_timeout(5000);              // Request timeout in ms
requester.set_connect_timeout(2000);      // Connection timeout in ms

// Security
requester.force_secure(true);             // HTTPS only
requester.trust_all_certificates(false);  // Certificate validation

// Redirects
use product_os_request::RedirectPolicy;
requester.set_redirect_policy(RedirectPolicy::Limit(5));

// Proxy
use product_os_request::Protocol;
requester.set_proxy(Some((Protocol::HTTP, String::from("proxy.example.com:8080"))));

// Custom certificates
let cert_der = include_bytes!("cert.der");
requester.add_trusted_certificate_der(cert_der.to_vec());

// Default headers
requester.add_header("User-Agent", "MyApp/1.0", false);
```

### Request Building

```rust
let mut request = client.new_request(Method::POST, "https://api.example.com/data");

// Headers
request.add_header("Content-Type", "application/json", false);
request.add_header("X-API-Key", "secret", true);  // marked as sensitive

// Authentication
request.bearer_auth(String::from("your-token"));

// Query parameters
request.add_param(String::from("page"), String::from("1"));
request.add_param(String::from("limit"), String::from("10"));

// Body
use bytes::Bytes;
use product_os_http_body::BodyBytes;
let body = BodyBytes::new(Bytes::from("request body"));
request.set_body(body);
```

### Response Handling

```rust
let response = client.request(request).await?;

// Status
let status = response.status_code();
println!("Status: {}", status);

// Headers
let headers = response.get_headers();
for (name, value) in headers {
    println!("{}: {}", name, value);
}

// URL (after redirects)
let url = response.response_url();

// Body as text
let text = client.text(response).await?;

// Body as JSON
let json = client.json(response).await?;

// Body as bytes
let bytes = client.bytes(response).await?;
```

## API Documentation

For detailed API documentation, visit [docs.rs/product-os-request](https://docs.rs/product-os-request).

## Contributing

Contributions are not currently available but will be available on a public repository soon.

## License

This project is licensed under the [GNU GPLv3](https://choosealicense.com/licenses/gpl-3.0/).