kode-bridge 0.3.3

Modern HTTP Over IPC library for Rust with both client and server support (Unix sockets, Windows named pipes).
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
# kode-bridge Server Guide

**Complete guide for building HTTP Over IPC servers**

This guide explains how to use kode-bridge's server functionality to create high-performance IPC servers that handle HTTP-style requests and real-time streaming.

## 🚀 Quick Start

### Enable Server Features

Add to your `Cargo.toml`:

```toml
[dependencies]
kode-bridge = { version = "0.1", features = ["server"] }
# Or for both client and server
kode-bridge = { version = "0.1", features = ["full"] }

# Required dependencies for examples
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tracing-subscriber = "0.3"
```

### Available Features

- `client` (default) - Enables IPC client functionality
- `server` - Enables IPC server functionality  
- `full` - Enables both client and server

## 🌐 HTTP IPC Server

### Basic HTTP Server

```rust
use kode_bridge::{IpcHttpServer, Router, HttpResponse, ServerConfig, Result};
use serde_json::json;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<()> {
    // Configure server
    let config = ServerConfig {
        max_connections: 100,
        read_timeout: Duration::from_secs(30),
        write_timeout: Duration::from_secs(30),
        max_request_size: 1024 * 1024, // 1MB
        enable_logging: true,
        shutdown_timeout: Duration::from_secs(5),
    };

    // Create router with endpoints
    let router = Router::new()
        .get("/health", |_ctx| async move {
            HttpResponse::json(&json!({"status": "healthy"}))
        })
        .post("/api/data", |ctx| async move {
            match ctx.json::<serde_json::Value>() {
                Ok(data) => {
                    println!("Received: {}", data);
                    HttpResponse::json(&json!({"received": data}))
                }
                Err(e) => Ok(HttpResponse::builder()
                    .status(http::StatusCode::BAD_REQUEST)
                    .json(&json!({"error": e.to_string()}))?
                    .build())
            }
        });

    // Start server
    let mut server = IpcHttpServer::with_config("/tmp/my_server.sock", config)?
        .router(router);
    
    server.serve().await
}
```

### HTTP Server Features

#### Request Context
```rust
use kode_bridge::RequestContext;

// Handler function receives RequestContext
let handler = |ctx: RequestContext| async move {
    // Access request details
    println!("Method: {}", ctx.method);
    println!("URI: {}", ctx.uri);
    println!("Headers: {:?}", ctx.headers);
    
    // Parse JSON body
    if let Ok(data) = ctx.json::<MyStruct>() {
        // Process data
    }
    
    // Get query parameters
    let params = ctx.query_params();
    
    // Get body as text
    let text = ctx.text()?;
    
    HttpResponse::ok()
};
```

#### Response Building
```rust
use kode_bridge::{HttpResponse, ResponseBuilder};
use http::StatusCode;

// Simple responses
let response = HttpResponse::ok();
let response = HttpResponse::not_found();
let response = HttpResponse::internal_error();

// JSON responses
let response = HttpResponse::json(&json!({"key": "value"}))?;

// Custom responses
let response = HttpResponse::builder()
    .status(StatusCode::CREATED)
    .header("content-type", "application/json")
    .json(&data)?
    .build();

// Text responses
let response = HttpResponse::text("Hello, World!");

// Error responses
let response = HttpResponse::error(StatusCode::BAD_REQUEST, "Invalid input");
```

#### Routing
```rust
use kode_bridge::Router;

let router = Router::new()
    // HTTP methods
    .get("/users", get_users)
    .post("/users", create_user)
    .put("/users/{id}", update_user)  // Path parameters coming soon
    .delete("/users/{id}", delete_user)
    
    // Async closures
    .get("/status", |_| async { HttpResponse::text("OK") })
    
    // Complex handlers
    .post("/upload", |ctx| async move {
        let body_size = ctx.body.len();
        if body_size > 1024 * 1024 {
            return Ok(HttpResponse::error(
                StatusCode::PAYLOAD_TOO_LARGE, 
                "File too large"
            ));
        }
        
        // Process upload
        HttpResponse::json(&json!({
            "uploaded": true,
            "size": body_size
        }))
    });
```

#### Server Configuration
```rust
use kode_bridge::ServerConfig;
use std::time::Duration;

let config = ServerConfig {
    // Connection limits
    max_connections: 200,
    
    // Timeouts
    read_timeout: Duration::from_secs(30),
    write_timeout: Duration::from_secs(30),
    shutdown_timeout: Duration::from_secs(10),
    
    // Limits
    max_request_size: 5 * 1024 * 1024, // 5MB
    
    // Logging
    enable_logging: true,
};
```

#### Server Statistics
```rust
// Get server statistics
let stats = server.stats();
println!("Connections: {}", stats.total_connections);
println!("Active: {}", stats.active_connections);  
println!("Requests: {}", stats.total_requests);
println!("Uptime: {:?}", stats.started_at.elapsed());
```

## 🌊 Streaming IPC Server

### Basic Streaming Server

```rust
use kode_bridge::{
    IpcStreamServer, StreamMessage, StreamServerConfig, 
    JsonDataSource, Result
};
use serde_json::json;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<()> {
    // Configure streaming server
    let config = StreamServerConfig {
        max_connections: 500,
        buffer_size: 65536,
        write_timeout: Duration::from_secs(10),
        broadcast_capacity: 1000,
        keepalive_interval: Duration::from_secs(30),
        ..Default::default()
    };

    // Create data source that generates data every 2 seconds
    let data_source = JsonDataSource::new(
        || {
            Ok(json!({
                "timestamp": chrono::Utc::now().timestamp(),
                "data": rand::random::<f64>(),
                "status": "active"
            }))
        },
        Duration::from_secs(2)
    );

    // Create and start server
    let mut server = IpcStreamServer::with_config("/tmp/stream_server.sock", config)?;
    server.serve_with_source(data_source).await
}
```

### Streaming Features

#### Message Types
```rust
use kode_bridge::StreamMessage;

// JSON messages
let msg = StreamMessage::json(&json!({"type": "data", "value": 42}))?;

// Text messages  
let msg = StreamMessage::text("Hello, streaming clients!");

// Binary messages
let msg = StreamMessage::binary(vec![0x01, 0x02, 0x03]);

// Keep-alive ping
let msg = StreamMessage::Ping;

// Server shutdown notification
let msg = StreamMessage::Close;
```

#### Manual Broadcasting
```rust
// Start server without automatic data source
let mut server = IpcStreamServer::new("/tmp/stream.sock")?;

// Start server in background
tokio::spawn(async move {
    server.serve().await
});

// Broadcast messages manually
server.broadcast(StreamMessage::text("Manual message"))?;
server.broadcast(StreamMessage::json(&json!({"event": "update"}))?)?;
```

#### Custom Data Sources
```rust
use kode_bridge::{StreamSource, StreamMessage, Result};
use std::pin::Pin;
use std::future::Future;

struct CustomDataSource {
    counter: u64,
}

impl StreamSource for CustomDataSource {
    fn next_messages(&mut self) -> Pin<Box<dyn Future<Output = Result<Vec<StreamMessage>>> + Send + '_>> {
        Box::pin(async move {
            self.counter += 1;
            let message = StreamMessage::json(&json!({
                "counter": self.counter,
                "timestamp": chrono::Utc::now().timestamp()
            }))?;
            Ok(vec![message])
        })
    }

    fn has_more(&self) -> bool {
        true // Always generate more data
    }

    fn initialize(&mut self) -> Pin<Box<dyn Future<Output = Result<()>> + Send + '_>> {
        Box::pin(async move {
            println!("Data source initialized");
            Ok(())
        })
    }

    fn cleanup(&mut self) -> Pin<Box<dyn Future<Output = Result<()>> + Send + '_>> {
        Box::pin(async move {
            println!("Data source cleaned up");
            Ok(())
        })
    }
}
```

#### Client Management
```rust
// Get connected clients
let clients = server.clients();
for client in clients {
    println!("Client {}: {} messages sent", 
             client.client_id, client.messages_sent);
}

// Get server statistics
let stats = server.stats();
println!("Streaming stats: {}", stats);
println!("Messages/sec: {:.1}", stats.messages_per_second);
```

## 🔧 Cross-Platform Usage

### Unix/Linux/macOS
```bash
# Start HTTP server
cargo run --features=server --example http_server

# Test with client
CUSTOM_SOCK=/tmp/my_server.sock cargo run --features=client --example request
```

### Windows
```cmd
REM Start HTTP server  
cargo run --features=server --example http_server

REM Test with client
set CUSTOM_PIPE=\\.\pipe\my_server
cargo run --features=client --example request
```

## 🎯 Production Deployment

### Error Handling
```rust
use kode_bridge::{HttpResponse, KodeBridgeError};
use http::StatusCode;

let handler = |ctx| async move {
    match process_request(ctx).await {
        Ok(result) => HttpResponse::json(&result),
        Err(e) => {
            tracing::error!("Request failed: {}", e);
            
            let status = if e.to_string().contains("validation") {
                StatusCode::BAD_REQUEST
            } else {
                StatusCode::INTERNAL_SERVER_ERROR
            };
            
            Ok(HttpResponse::error(status, "Request failed"))
        }
    }
};
```

### Graceful Shutdown
```rust
use tokio::signal;

// Start server in background
let mut server = IpcHttpServer::new("/tmp/server.sock")?;
let server_task = tokio::spawn(async move {
    server.serve().await
});

// Wait for shutdown signal
signal::ctrl_c().await?;
println!("Shutting down server...");

// Stop server
server_task.abort();

// Wait for cleanup
tokio::time::sleep(Duration::from_millis(500)).await;
println!("Server stopped");
```

### Monitoring and Metrics
```rust
// Periodic stats reporting
tokio::spawn(async move {
    let mut interval = tokio::time::interval(Duration::from_secs(60));
    loop {
        interval.tick().await;
        let stats = server.stats();
        tracing::info!("Server stats: {}", stats);
        
        // Send to monitoring system
        send_metrics(&stats).await;
    }
});
```

## 📊 Performance Tips

### HTTP Server Optimization
- Use connection pooling on the client side
- Configure appropriate timeouts
- Limit request sizes to prevent memory issues
- Enable request logging only in development

### Streaming Server Optimization  
- Adjust buffer sizes based on message frequency
- Use appropriate broadcast channel capacity
- Implement backpressure for slow clients
- Monitor client lag and disconnect slow clients

### General Tips
- Use `tracing` for structured logging
- Monitor connection counts and memory usage
- Implement health check endpoints
- Use appropriate IPC paths (`/var/run` for production on Unix)

## 🔍 Debugging

### Enable Detailed Logging
```rust
// Add to Cargo.toml dev-dependencies
tracing-subscriber = "0.3"

// In your main function
tracing_subscriber::fmt()
    .with_max_level(tracing::Level::DEBUG)
    .init();
```

### Common Issues
- **Permission denied**: Check socket file permissions
- **Address already in use**: Ensure socket file is cleaned up
- **Connection refused**: Verify server is running and path is correct
- **Message too large**: Check `max_request_size` and `max_message_size`

## 📚 Examples

See the `examples/` directory for complete working examples:

- `examples/http_server.rs` - Full HTTP server with routing
- `examples/stream_server.rs` - Real-time streaming server
- Run with: `cargo run --features=server --example http_server`

---

**kode-bridge** - Modern HTTP Over IPC for Rust 🚀