@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        final String method = request.getMethod();
        final String url = url(request);

        //note that head and get requests call doGet
        final String cacheKey = makeKey(request.getMethod(), url);
        Object o = getCached(cacheKey);
        if (o != null) {

            if (logger.isLoggable(Level.FINE)) {
                logger.fine("cache hit: " + url);
            }

            try {
                ((WebResponse) o).writeTo(response);
            } finally {
                final Map<String, List<String>> headers = convertRequestHeaders(request);
                if (shouldRefresh((WebResponse) o)) {
                    executor.execute(new RefreshWorker(request.getMethod(), url, cacheKey, headers));
                } else {
                    executor.execute(new InvalidationWorker(request.getMethod(), url, cacheKey, headers, ((WebResponse) o).getTimestamp()));
                }
            }
        } else {
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("cache miss: " + url);
            }
            final WebResponse r = getWebResponse(request, url);
            if (r != null) {
                try {
                    r.writeTo(response);
                } finally {
                    if (r.isOK()) {
                        final Map<String, List<String>> headers = convertRequestHeaders(request);
                        executor.execute(new Runnable() {
                            public void run() {
                                cacheAside(method, headers, url, cacheKey, r);
                            }
                        });
                    }
                }
            } else {
                if (logger.isLoggable(Level.INFO)) {
                    logger.info("no response for " + url);
                }
            }
        }

    }