@Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String method = request.getMethod();
        String pathInfo = request.getPathInfo();
        String referer = request.getHeader("Referer");
        String query = request.getQueryString();
        String serverName = request.getServerName();
        String ua = request.getHeader("User-Agent");
        boolean isOptions = "OPTIONS".equals(method);
        if (referer != null
                && referer.contains("http://validator.w3.org/check?uri=")
                && !referer.startsWith("http://validator.w3.org/check?uri=")) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        if (ua == null) {
            response.sendError(400, "Bad request. Valid requests must include a User-Agent header.");
            return;
        }
        if (!isOptions) {
            Object[] fields = new String[] { method, ua, query, referer };
            log4j.info(String.format("%s\t%s\t%s\t%s", fields));
        }
        if (pathInfo == null) {
            pathInfo = "/"; // Fix for Jigsaw
        }
        if ("/robots.txt".equals(pathInfo)) {
            // if we get here, we've got a POST
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }
        log4j.debug("pathInfo: " + pathInfo);
        log4j.debug("serverName: " + serverName);

        if ("validator.nu".equals(serverName) && "/html5/".equals(pathInfo)) {
                response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
                response.setHeader("Location", "http://html5.validator.nu/" + (query == null ? "" : "?" + query));
        } else if (hostMatch(GENERIC_HOST, serverName) && GENERIC_PATH.equals(pathInfo)) {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "content-type");
            if (isOptions) {
                sendOptions(request, response);
            } else {
                new VerifierServletTransaction(request, response).service();
            }
        } else if (hostMatch(HTML5_HOST, serverName) && HTML5_PATH.equals(pathInfo)) {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "content-type");
            if (isOptions) {
                sendOptions(request, response);
            } else {
                new Html5ConformanceCheckerTransaction(request, response).service();
            }
        } else if (hostMatch(PARSETREE_HOST, serverName) && PARSETREE_PATH.equals(pathInfo)) {
            if (isOptions) {
                sendGetOnlyOptions(request, response);
            } else {
                new ParseTreePrinter(request, response).service();
            }
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
    }
@see jakarta.servlet.http.HttpServlet#doPost(jakarta.servlet.http.HttpServletRequest,
     jakarta.servlet.http.HttpServletResponse)
src/nu/validator/servlet/VerifierServlet.java