protected void handleConnection(Socket sock) throws IOException {
        OutputStream out = new BufferedOutputStream(
            sock.getOutputStream(), 4096);
        InputStream in = new BufferedInputStream(sock.getInputStream(), 4096);
        String connectionHeader;
        do {
            // create request and response 
            Response resp = new Response(out);
            Request req;
            try {
                req = new Request(in);
            } catch (InterruptedIOException ignore) { // timeout
                break;
            } catch (IOException ioe) {
                resp.sendError(400, "invalid request: " + ioe.getMessage());
                break;
            }
            // handle request
            try {
                handleTransaction(req, resp);
            } catch (InterruptedIOException ignore) { // timeout
                break;
            } catch (IOException ioe) {
                resp.sendError(500,
                    "error processing request: " + ioe.getMessage());
                break;
            }
            out.flush(); // flush response output
            // consume any leftover body data so next request can be processed
            req.consumeBody();
            // persist or close connection as necessary
            connectionHeader = req.getHeaders().get("Connection");
        } while (!"close".equalsIgnoreCase(connectionHeader));
    }