rek2_httpserver 0.1.1

HTTP server that accepts POST data to exfiltrate files from remote servers to local computer during hacking and penetration testing
Documentation
<!--
ReK2 2025
Hispagatos
gemini://rek2.hispagatos.org
https://rek2.hispagatos.org
-->

# Testing Guide

This document describes how to test the rek2_httpserver project using Rust's built-in testing framework.

## Test Structure

The project includes comprehensive testing with proper separation of concerns:

### Unit Tests (`src/lib.rs`)
Located in the library module with organized test modules:

- **`filename_extraction`** - Tests filename extraction from various sources
- **`content_disposition_parsing`** - Tests HTTP header parsing logic  
- **`edge_cases`** - Tests edge cases like unicode, special characters, long names

### Integration Tests (`tests/upload_tests.rs`)
Full end-to-end testing of the upload functionality:

- File upload with different methods
- Directory structure preservation
- Binary file integrity
- Content-length verification
- Error handling scenarios

## Running Tests

### Basic Commands

```bash
# Run all tests (unit + integration)
cargo test

# Run only unit tests
cargo test --lib

# Run only integration tests
cargo test --test upload_tests

# Run with verbose output
cargo test -- --nocapture

# Run tests in parallel (default) or single-threaded
cargo test -- --test-threads=1
```

### Specific Test Categories

```bash
# Run filename extraction tests
cargo test filename_extraction

# Run content disposition parsing tests
cargo test content_disposition_parsing

# Run edge case tests
cargo test edge_cases

# Run a specific test
cargo test test_upload_with_url_filename
```

### Test Coverage

```bash
# Generate test coverage report (requires cargo-tarpaulin)
cargo install cargo-tarpaulin
cargo tarpaulin --out Html

# Or with llvm-cov (requires nightly)
cargo +nightly test --coverage
```

## Test Details

### Unit Tests (17 tests)

#### Filename Extraction Tests
- `test_url_path_priority` - URL path takes precedence
- `test_url_decoding` - Percent-encoded URLs are decoded
- `test_x_filename_header` - X-Filename header extraction
- `test_content_disposition` - Content-Disposition header parsing
- `test_priority_order` - Verifies URL > X-Filename > Content-Disposition priority
- `test_fallback_generation` - Auto-generated filename when none provided

#### Content-Disposition Parsing Tests
- `test_simple_filename` - Basic filename extraction
- `test_quoted_filename` - Filenames with quotes
- `test_rfc5987_encoded` - RFC 5987 encoded filenames
- `test_no_filename` - Headers without filename
- `test_malformed` - Malformed headers
- `test_empty_filename` - Empty filename values

#### Edge Case Tests
- `test_unicode_filename` - Unicode characters in filenames
- `test_special_characters` - Special characters (@#$%^&)
- `test_very_long_filename` - Very long filenames (300+ chars)
- `test_windows_path` - Windows-style paths
- `test_path_traversal` - Path traversal attempts

### Integration Tests (10 tests)

#### Upload Functionality Tests
- `test_basic_upload` - Basic file upload without filename
- `test_upload_with_url_filename` - Upload with filename in URL path
- `test_upload_with_x_filename_header` - Upload with X-Filename header
- `test_upload_with_content_disposition` - Upload with Content-Disposition
- `test_upload_preserves_directory_structure` - Directory structure preservation
- `test_content_length_verification` - Content-Length header validation
- `test_empty_file_upload` - Zero-byte file uploads
- `test_binary_file_integrity` - Binary data integrity
- `test_url_encoded_filename` - URL-encoded filenames
- `test_filename_priority` - Priority order verification

## Writing New Tests

### Unit Test Example

```rust
#[test]
fn test_custom_functionality() {
    let result = extract_filename("test.txt", None, None);
    assert_eq!(result, "test.txt");
}
```

### Integration Test Example

```rust
#[test]
fn test_custom_upload() {
    let temp_dir = TempDir::new().unwrap();
    let output_dir = temp_dir.path().to_str().unwrap();
    
    let body = Bytes::from("test data");
    let result = handle_upload_internal(
        "custom.txt",
        None,
        None,
        None,
        None,
        body,
        output_dir,
    );
    
    assert_eq!(result.status, StatusCode::OK);
    assert!(result.message.contains("custom.txt"));
}
```

## Test Guidelines

### Best Practices

1. **Isolation** - Each test uses temporary directories
2. **Deterministic** - Tests don't depend on external state
3. **Descriptive Names** - Test names clearly describe what's being tested
4. **Assertions** - Use specific assertions for better error messages
5. **Edge Cases** - Include tests for boundary conditions

### Test Data

- Use `tempfile::TempDir` for temporary directories
- Use `bytes::Bytes` for binary test data
- Test with various file sizes (0 bytes to large files)
- Include special characters and unicode in test filenames

### Performance Considerations

- Tests run in parallel by default
- Use `-- --test-threads=1` if tests interfere with each other
- Keep test data small for fast execution
- Use `#[ignore]` for slow tests that should be run separately

## Continuous Integration

For CI environments, add this to your workflow:

```yaml
- name: Run tests
  run: cargo test --all-features

- name: Run tests with coverage
  run: cargo tarpaulin --out Xml
```

## Debugging Tests

### Common Issues

1. **File permissions** - Ensure test has write access to temp directories
2. **Path separators** - Use `std::path::Path` for cross-platform compatibility
3. **Timing issues** - Avoid depending on exact timestamps in tests

### Debug Output

```bash
# Show test output
cargo test -- --nocapture

# Show which tests are running
cargo test -- --show-output

# Run specific test with debug info
RUST_LOG=debug cargo test test_name -- --nocapture
```

## Test Maintenance

- Run tests before every commit
- Update tests when changing functionality
- Add tests for new features
- Remove or update obsolete tests
- Keep test documentation current

## Performance Benchmarks

For performance testing, consider adding benchmarks:

```bash
# Install criterion for benchmarks
cargo install cargo-criterion

# Run benchmarks
cargo criterion
```

This ensures the upload server maintains good performance characteristics under various load conditions.