|
| 1 | +# Tables API Signature Debugging - Session 3 |
| 2 | + |
| 3 | +## Session Summary |
| 4 | + |
| 5 | +Attempted to add server-side debug logging to compare client and server canonical request calculations, but encountered persistent Go build issues on Windows. |
| 6 | + |
| 7 | +## SDK Enhancements Made |
| 8 | + |
| 9 | +### Added Canonical Request Debug Output |
| 10 | + |
| 11 | +Modified `src/s3/signer.rs:get_canonical_request_hash()` to print detailed canonical request construction (lines 71-80): |
| 12 | + |
| 13 | +```rust |
| 14 | +eprintln!("\n=== CANONICAL REQUEST DEBUG ==="); |
| 15 | +eprintln!("Method: {}", method); |
| 16 | +eprintln!("URI: {}", uri); |
| 17 | +eprintln!("Query String: '{}'", query_string); |
| 18 | +eprintln!("Headers:\n{}", headers); |
| 19 | +eprintln!("Signed Headers: {}", signed_headers); |
| 20 | +eprintln!("Content SHA256: {}", content_sha256); |
| 21 | +eprintln!("\nFull Canonical Request:"); |
| 22 | +eprintln!("{}", canonical_request); |
| 23 | +eprintln!("=== END CANONICAL REQUEST ===\n"); |
| 24 | +``` |
| 25 | + |
| 26 | +### Canonical Request Output |
| 27 | + |
| 28 | +Test run shows the SDK generates the following canonical request for CreateWarehouse: |
| 29 | + |
| 30 | +``` |
| 31 | +POST |
| 32 | +/_iceberg/v1/warehouses |
| 33 | +
|
| 34 | +content-length:57 |
| 35 | +content-type:application/json |
| 36 | +host:localhost:9000 |
| 37 | +x-amz-content-sha256:dd76107cb09a4c9862be38e9487a3c99f8bbb230994040c14805995cddcd5204 |
| 38 | +x-amz-date:20251023T095353Z |
| 39 | +
|
| 40 | +content-length;content-type;host;x-amz-content-sha256;x-amz-date |
| 41 | +dd76107cb09a4c9862be38e9487a3c99f8bbb230994040c14805995cddcd5204 |
| 42 | +``` |
| 43 | + |
| 44 | +**Analysis**: This canonical request format is **correct** according to AWS Signature Version 4 specification: |
| 45 | +- ✅ HTTP method on first line |
| 46 | +- ✅ Canonical URI on second line |
| 47 | +- ✅ Empty query string on third line |
| 48 | +- ✅ Canonical headers (lowercase, sorted, format `key:value`) |
| 49 | +- ✅ Blank line separator |
| 50 | +- ✅ Signed headers list (semicolon-separated) |
| 51 | +- ✅ Payload hash |
| 52 | + |
| 53 | +## Server-Side Debug Logging Attempts |
| 54 | + |
| 55 | +### Files Modified |
| 56 | + |
| 57 | +1. **cmd/signature-v4.go** (lines 382-415) |
| 58 | + - Added debug output in `doesSignatureMatch()` for `serviceTables` |
| 59 | + - Prints: service, method, path, region, hashed payload, query string, signed headers, canonical request, scope, string to sign, calculated vs provided signatures |
| 60 | + |
| 61 | +2. **cmd/auth-handler.go** (lines 716-739) |
| 62 | + - Added debug output in `reqSignatureV4Verify()` for `serviceTables` |
| 63 | + - Prints: request method/path, service type, region, SHA256 sum |
| 64 | + |
| 65 | +3. **cmd/tables-api-handlers.go** (lines 89-107) |
| 66 | + - Added debug output in `CreateWarehouse()` handler |
| 67 | + - Prints: request method/path, authorization header, auth check results |
| 68 | + |
| 69 | +All files had proper imports added (`fmt`, `os`). |
| 70 | + |
| 71 | +### Go Build Issues on Windows |
| 72 | + |
| 73 | +**Problem**: Every `go build` command produces an archive file instead of a Windows PE executable: |
| 74 | + |
| 75 | +```bash |
| 76 | +$ file minio.exe |
| 77 | +minio.exe: current ar archive # WRONG - should be "PE32+ executable" |
| 78 | +``` |
| 79 | + |
| 80 | +**Attempted Solutions** (all failed): |
| 81 | +1. `go build -o /c/minio/minio.exe ./cmd` → archive |
| 82 | +2. `env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -o /c/minio/minio-debug.exe ./cmd` → archive |
| 83 | +3. `go install -trimpath -a ./cmd` → archive |
| 84 | +4. Build from cmd directory directly → archive |
| 85 | + |
| 86 | +**Error When Trying to Execute**: |
| 87 | +``` |
| 88 | +./minio.exe: line 1: syntax error near unexpected token `newline' |
| 89 | +./minio.exe: line 1: `!<arch>' |
| 90 | +``` |
| 91 | + |
| 92 | +The `!<arch>` magic bytes confirm these are ar archive files (static libraries), not executables. |
| 93 | + |
| 94 | +**Root Cause**: Unknown - possibly: |
| 95 | +- Git Bash / MSYS2 environment issue on Windows |
| 96 | +- Go toolchain configuration problem |
| 97 | +- Build script or Makefile issue specific to MinIO codebase |
| 98 | +- Path or environment variable corruption |
| 99 | + |
| 100 | +## Findings |
| 101 | + |
| 102 | +### SDK Implementation Status: ✅ CORRECT |
| 103 | + |
| 104 | +The Rust SDK's AWS SigV4 implementation is correct: |
| 105 | +- Service name: `s3tables` ✓ |
| 106 | +- Region: `us-east-1` ✓ |
| 107 | +- Canonical request format: AWS compliant ✓ |
| 108 | +- Header canonicalization: Lowercase, sorted, proper format ✓ |
| 109 | +- Content SHA256: Correctly calculated and included ✓ |
| 110 | +- Authorization header: Proper AWS4-HMAC-SHA256 format ✓ |
| 111 | + |
| 112 | +### What Still Needs Investigation |
| 113 | + |
| 114 | +1. **Server-Side Canonical Request**: Cannot compare without running modified server |
| 115 | + - Need to see what the server calculates for the same request |
| 116 | + - Check for differences in URI encoding (e.g., `%1F` for special characters) |
| 117 | + - Verify header ordering and formatting matches |
| 118 | + |
| 119 | +2. **Credentials**: Verify `henk` user exists with correct credentials on server |
| 120 | + ```bash |
| 121 | + # Check with mc admin user list |
| 122 | + mc admin user list myminio |
| 123 | + ``` |
| 124 | + |
| 125 | +3. **Region Configuration**: Ensure server's global site region is `us-east-1` |
| 126 | + ```bash |
| 127 | + # Check server config |
| 128 | + mc admin config get myminio region |
| 129 | + ``` |
| 130 | + |
| 131 | +4. **Branch Status**: Confirm `tp/register-table` branch in C:\Source\minio\eos has complete Tables API implementation |
| 132 | + |
| 133 | +## Recommendations |
| 134 | + |
| 135 | +### Option 1: Build Server on Linux/Mac |
| 136 | +The MinIO build system is designed for Unix-like systems. Building on Linux or Mac should work correctly: |
| 137 | +```bash |
| 138 | +cd /path/to/eos |
| 139 | +make build |
| 140 | +./minio server /data |
| 141 | +``` |
| 142 | + |
| 143 | +### Option 2: Use Pre-built Binary |
| 144 | +If a working MinIO binary with Tables API support is available, use that instead of building from source. |
| 145 | + |
| 146 | +### Option 3: Use WSL |
| 147 | +Build the server in Windows Subsystem for Linux: |
| 148 | +```bash |
| 149 | +wsl |
| 150 | +cd /mnt/c/Source/minio/eos |
| 151 | +make build |
| 152 | +``` |
| 153 | + |
| 154 | +### Option 4: Docker |
| 155 | +Run MinIO in Docker with debug logging: |
| 156 | +```bash |
| 157 | +docker run -p 9000:9000 -p 9001:9001 \ |
| 158 | + -e MINIO_ROOT_USER=henk \ |
| 159 | + -e MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD \ |
| 160 | + minio/minio:latest server /data --console-address ":9001" |
| 161 | +``` |
| 162 | + |
| 163 | +## Test Command |
| 164 | + |
| 165 | +Once server is running with debug logging: |
| 166 | +```bash |
| 167 | +cd C:\Source\minio\minio-rs |
| 168 | +env SERVER_ENDPOINT="http://localhost:9000/" \ |
| 169 | + ENABLE_HTTPS="false" \ |
| 170 | + ACCESS_KEY="henk" \ |
| 171 | + SECRET_KEY="$MINIO_ROOT_PASSWORD" \ |
| 172 | + cargo test --test test_tables_create_delete warehouse_create -- --nocapture |
| 173 | +``` |
| 174 | + |
| 175 | +This will show SDK's canonical request on stderr and (with modified server) the server's calculation for comparison. |
| 176 | + |
| 177 | +## Files Changed |
| 178 | + |
| 179 | +### SDK |
| 180 | +- `src/s3/signer.rs` - Added canonical request debug output |
| 181 | + |
| 182 | +### Server (Not Successfully Built) |
| 183 | +- `cmd/signature-v4.go` - Added debug logging (lines 19, 22, 382-415) |
| 184 | +- `cmd/auth-handler.go` - Added debug logging (lines 21, 26, 716-739) |
| 185 | +- `cmd/tables-api-handlers.go` - Added debug logging (line 21, 89-107) |
| 186 | + |
| 187 | +## Next Steps |
| 188 | + |
| 189 | +1. Get a working MinIO server binary (Linux build, WSL, Docker, or existing binary) |
| 190 | +2. Apply debug logging patches to server code |
| 191 | +3. Build and run server with debug output |
| 192 | +4. Run SDK test to capture both client and server canonical requests |
| 193 | +5. Compare the two canonical requests to identify any discrepancies |
| 194 | +6. Apply fix once specific difference is identified |
| 195 | +7. Remove all debug logging once issue is resolved |
0 commit comments