aex 0.1.6

A web server for rust.
Documentation
<!DOCTYPE html>
<html>
<head>
    <title>AEX Unified Server Test</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
        .card { border: 1px solid #ddd; border-radius: 8px; padding: 20px; margin: 10px 0; }
        .card h3 { margin-top: 0; color: #333; }
        .btn { background: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; }
        .btn:hover { background: #0056b3; }
        input, textarea { width: 100%; padding: 8px; margin: 5px 0; box-sizing: border-box; }
        #messages { height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; background: #f9f9f9; }
        .log { font-family: monospace; font-size: 12px; }
        .log-info { color: blue; }
        .log-err { color: red; }
        .log-ws { color: green; }
    </style>
</head>
<body>
    <h1>AEX Unified Server Test</h1>
    
    <div class="card">
        <h3>HTTP/1.1 Test</h3>
        <button class="btn" onclick="testHttp()">GET /</button>
        <button class="btn" onclick="testInfo()">GET /info</button>
        <pre id="http-result" class="log"></pre>
    </div>

    <div class="card">
        <h3>WebSocket Test</h3>
        <input type="text" id="ws-msg" placeholder="Message...">
        <button class="btn" onclick="connectWs()">Connect</button>
        <button class="btn" onclick="sendWs()">Send</button>
        <button class="btn" onclick="closeWs()">Disconnect</button>
        <div id="ws-status">Disconnected</div>
        <div id="messages"></div>
    </div>

    <div class="card">
        <h3>HTTP/2 Test</h3>
        <p>Note: HTTP/2 requires TLS or h2c upgrade. Use curl --http2 for testing:</p>
        <code>curl --http2 http://localhost:8080/h2</code>
    </div>

    <script>
        let ws = null;

        async function testHttp() {
            const res = await fetch('/');
            const text = await res.text();
            document.getElementById('http-result').textContent = 'Status: ' + res.status + '\n' + text;
        }

        async function testInfo() {
            const res = await fetch('/info');
            const text = await res.text();
            document.getElementById('http-result').textContent = 'Status: ' + res.status + '\n' + text;
        }

        function connectWs() {
            const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
            ws = new WebSocket(protocol + '//' + location.host + '/ws');
            
            ws.onopen = () => {
                document.getElementById('ws-status').textContent = 'Connected';
                log('WS', 'Connected!', 'log-ws');
            };
            
            ws.onmessage = (e) => {
                log('WS', 'Received: ' + e.data, 'log-ws');
            };
            
            ws.onclose = () => {
                document.getElementById('ws-status').textContent = 'Disconnected';
                log('WS', 'Disconnected', 'log-err');
            };
            
            ws.onerror = (e) => {
                log('WS', 'Error: ' + e, 'log-err');
            };
        }

        function sendWs() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                const msg = document.getElementById('ws-msg').value;
                ws.send(msg);
                log('WS', 'Sent: ' + msg, 'log-ws');
            }
        }

        function closeWs() {
            if (ws) {
                ws.close();
            }
        }

        function log(type, msg, cls) {
            const div = document.createElement('div');
            div.className = 'log ' + cls;
            div.textContent = '[' + new Date().toLocaleTimeString() + '] ' + type + ': ' + msg;
            document.getElementById('messages').appendChild(div);
        }
    </script>
</body>
</html>