Example usage for java.net HttpURLConnection HTTP_FORBIDDEN

List of usage examples for java.net HttpURLConnection HTTP_FORBIDDEN

Introduction

In this page you can find the example usage for java.net HttpURLConnection HTTP_FORBIDDEN.

Prototype

int HTTP_FORBIDDEN

To view the source code for java.net HttpURLConnection HTTP_FORBIDDEN.

Click Source Link

Document

HTTP Status-Code 403: Forbidden.

Usage

From source file:com.streamsets.pipeline.stage.origin.httpserver.TestHttpServerPushSource.java

@Test
public void testSource() throws Exception {
    RawHttpConfigs httpConfigs = new RawHttpConfigs();
    httpConfigs.appId = () -> "id";
    httpConfigs.port = NetworkUtils.getRandomPort();
    httpConfigs.maxConcurrentRequests = 1;
    httpConfigs.tlsConfigBean.tlsEnabled = false;
    HttpServerPushSource source = new HttpServerPushSource(httpConfigs, 1, DataFormat.TEXT,
            new DataParserFormatConfig());
    final PushSourceRunner runner = new PushSourceRunner.Builder(HttpServerDPushSource.class, source)
            .addOutputLane("a").build();
    runner.runInit();// w ww.  j a  v  a 2 s.  c  om
    try {
        final List<Record> records = new ArrayList<>();
        runner.runProduce(Collections.<String, String>emptyMap(), 1, new PushSourceRunner.Callback() {
            @Override
            public void processBatch(StageRunner.Output output) {
                records.clear();
                records.addAll(output.getRecords().get("a"));
            }
        });

        // wait for the HTTP server up and running
        HttpReceiverServer httpServer = (HttpReceiverServer) Whitebox.getInternalState(source, "server");
        await().atMost(Duration.TEN_SECONDS).until(isServerRunning(httpServer));

        HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:" + httpConfigs.getPort())
                .openConnection();
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setRequestProperty(Constants.X_SDC_APPLICATION_ID_HEADER, "id");
        connection.setRequestProperty("customHeader", "customHeaderValue");
        connection.getOutputStream().write("Hello".getBytes());
        Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
        Assert.assertEquals(1, records.size());
        Assert.assertEquals("Hello", records.get(0).get("/text").getValue());
        Assert.assertEquals("id",
                records.get(0).getHeader().getAttribute(Constants.X_SDC_APPLICATION_ID_HEADER));
        Assert.assertEquals("customHeaderValue", records.get(0).getHeader().getAttribute("customHeader"));

        // passing App Id via query param should fail when appIdViaQueryParamAllowed is false
        String url = "http://localhost:" + httpConfigs.getPort() + "?"
                + HttpConstants.SDC_APPLICATION_ID_QUERY_PARAM + "=id";
        Response response = ClientBuilder.newClient().target(url).request().post(Entity.json("Hello"));
        Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, response.getStatus());

        runner.setStop();
    } catch (Exception e) {
        Assert.fail(e.getMessage());
    } finally {
        runner.runDestroy();
    }
}

From source file:hudson.bugs.JnlpAccessWithSecuredHudsonTest.java

@PresetData(DataSet.ANONYMOUS_READONLY)
@Test/*from ww w .  j  a va  2s. co m*/
public void anonymousCannotGetSecrets() throws Exception {
    r.jenkins.setNodes(Collections.singletonList(createNewJnlpSlave("test")));
    r.createWebClient().assertFails("computer/test/slave-agent.jnlp", HttpURLConnection.HTTP_FORBIDDEN);
}

From source file:org.apache.maven.wagon.providers.http.LightweightHttpWagon.java

public void fillInputData(InputData inputData)
        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {
    Resource resource = inputData.getResource();

    String visitingUrl = buildUrl(resource.getName());
    try {/*from   w  w  w .  j  a v  a 2s.  c om*/
        List<String> visitedUrls = new ArrayList<String>();

        for (int redirectCount = 0; redirectCount < MAX_REDIRECTS; redirectCount++) {
            if (visitedUrls.contains(visitingUrl)) {
                throw new TransferFailedException("Cyclic http redirect detected. Aborting! " + visitingUrl);
            }
            visitedUrls.add(visitingUrl);

            URL url = new URL(visitingUrl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(this.proxy);

            urlConnection.setRequestProperty("Accept-Encoding", "gzip");
            if (!useCache) {
                urlConnection.setRequestProperty("Pragma", "no-cache");
            }

            addHeaders(urlConnection);

            // TODO: handle all response codes
            int responseCode = urlConnection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_FORBIDDEN
                    || responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
                throw new AuthorizationException("Access denied to: " + buildUrl(resource.getName()));
            }
            if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
                    || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
                visitingUrl = urlConnection.getHeaderField("Location");
                continue;
            }

            InputStream is = urlConnection.getInputStream();
            String contentEncoding = urlConnection.getHeaderField("Content-Encoding");
            boolean isGZipped = contentEncoding != null && "gzip".equalsIgnoreCase(contentEncoding);
            if (isGZipped) {
                is = new GZIPInputStream(is);
            }
            inputData.setInputStream(is);
            resource.setLastModified(urlConnection.getLastModified());
            resource.setContentLength(urlConnection.getContentLength());
            break;
        }
    } catch (MalformedURLException e) {
        throw new ResourceDoesNotExistException("Invalid repository URL: " + e.getMessage(), e);
    } catch (FileNotFoundException e) {
        throw new ResourceDoesNotExistException("Unable to locate resource in repository", e);
    } catch (IOException e) {
        StringBuilder message = new StringBuilder("Error transferring file: ");
        message.append(e.getMessage());
        message.append(" from " + visitingUrl);
        if (getProxyInfo() != null && getProxyInfo().getHost() != null) {
            message.append(" with proxyInfo ").append(getProxyInfo().toString());
        }
        throw new TransferFailedException(message.toString(), e);
    }
}

From source file:org.eclipse.hono.service.tenant.TenantAmqpEndpoint.java

/**
 * Verifies that a response only contains tenant information that the
 * client is authorized to retrieve./*from   w w w.  ja v a 2 s  .  co  m*/
 * <p>
 * If the response does not contain a tenant ID nor a payload, then the
 * returned future will succeed with the response <em>as-is</em>.
 * Otherwise the tenant ID is used together with the endpoint and operation
 * name to check the client's authority to retrieve the data. If the client
 * is authorized, the returned future will succeed with the response as-is,
 * otherwise the future will fail with a {@link ClientErrorException} containing a
 * <em>403 Forbidden</em> status.
 */
@Override
protected Future<EventBusMessage> filterResponse(final HonoUser clientPrincipal,
        final EventBusMessage response) {

    Objects.requireNonNull(clientPrincipal);
    Objects.requireNonNull(response);

    if (response.getTenant() == null || response.getJsonPayload() == null) {
        return Future.succeededFuture(response);
    } else {
        // verify that payload contains tenant that the client is authorized for
        final ResourceIdentifier resourceId = ResourceIdentifier.from(TenantConstants.TENANT_ENDPOINT,
                response.getTenant(), null);
        return getAuthorizationService().isAuthorized(clientPrincipal, resourceId, response.getOperation())
                .map(isAuthorized -> {
                    if (isAuthorized) {
                        return response;
                    } else {
                        throw new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN);
                    }
                });
    }
}

From source file:com.utest.webservice.interceptors.UtestRestFaultOutInterceptor.java

public String buildResponse(final Message message) {
    final StringBuffer sb = new StringBuffer();
    final Fault fault = (Fault) message.getContent(Exception.class);
    final String accept = (String) message.getExchange().getInMessage().get(Message.ACCEPT_CONTENT_TYPE);
    int type = TYPE_TEXT;
    int responseCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
    if (accept.contains(MediaType.APPLICATION_XML)) {
        type = TYPE_XML;/*w w  w .  j  a  v a2s  . c  o  m*/
        message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_XML);
    } else if (accept.contains(MediaType.APPLICATION_JSON)) {
        type = TYPE_JSON;
        message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_JSON);
    } else {
        message.put(Message.CONTENT_TYPE, MediaType.TEXT_PLAIN);
    }
    sb.append(getStart(type));
    if (fault.getCause() instanceof ValidationException) {
        final ValidationException ve = (ValidationException) fault.getCause();
        for (final String errmsg : ve.getMessageKeys()) {
            sb.append(createError(type, fault.getCause(), errmsg));
        }
    } else {
        sb.append(createError(type, fault.getCause(), fault.getCause().getMessage()));
    }

    if ((fault.getCause() instanceof org.apache.cxf.interceptor.security.AccessDeniedException)
            || (fault.getCause() instanceof org.springframework.security.access.AccessDeniedException)) {
        responseCode = HttpURLConnection.HTTP_FORBIDDEN;// Access deny
    } else if (fault.getCause() instanceof NotFoundException) {
        responseCode = HttpURLConnection.HTTP_NOT_FOUND;// Not found
    } else if ((fault.getCause() instanceof StaleObjectStateException)
            || (fault.getCause() instanceof StaleStateException)) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof EmailInUseException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof ScreenNameInUseException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof InvalidParentChildEnvironmentException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof DuplicateTestCaseStepException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof DuplicateNameException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof DeletingActivatedEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof DeletingUsedEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof ActivatingIncompleteEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof UnsupportedEnvironmentSelectionException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof ApprovingIncompleteEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof ActivatingNotApprovedEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof ChangingActivatedEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof IncludingMultileVersionsOfSameEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// not allowed
    } else if (fault.getCause() instanceof AssigningMultileVersionsOfSameEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof IncludingNotActivatedEntityException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// Not allowed
    } else if (fault.getCause() instanceof TestCaseExecutionBlockedException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// Not allowed
    } else if (fault.getCause() instanceof TestCaseExecutionWithoutRestartException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// Not allowed
    } else if (fault.getCause() instanceof InvalidParentChildEnvironmentException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof UnsupportedTeamSelectionException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof NoTeamDefinitionException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof InvalidTeamMemberException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    } else if (fault.getCause() instanceof TestCycleClosedException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    }
    // this is here to catch all business exceptions if this interceptor
    // wasn't updated properly
    else if (fault.getCause() instanceof DomainException) {
        responseCode = HttpURLConnection.HTTP_CONFLICT;// conflict
    }

    message.put(Message.RESPONSE_CODE, responseCode);
    sb.append(getEnd(type));
    return sb.toString();
}

From source file:httpget.HttpGet.java

private void obtainConnection() throws HttpGetException {
    try {//from   w w w . j a v  a2 s  . co  m
        this.connection = (HttpURLConnection) url.openConnection();
        this.connection.setInstanceFollowRedirects(true);
        this.connection.setReadTimeout(this.maxTimeout * 1000);
        if (this.requestHeaders != null) {
            Iterator i = this.requestHeaders.entrySet().iterator();
            while (i.hasNext()) {
                Map.Entry pair = (Map.Entry) i.next();
                this.connection.setRequestProperty((String) pair.getKey(), (String) pair.getValue());
            }
        }
        this.connection.connect();
        this.responseCode = this.connection.getResponseCode();
        if (this.responseCode == HttpURLConnection.HTTP_SEE_OTHER
                || this.responseCode == HttpURLConnection.HTTP_MOVED_TEMP
                || this.responseCode == HttpURLConnection.HTTP_MOVED_PERM) {
            this.redirected_from[this.nRedirects++] = this.url.toString();
            if (this.connection.getHeaderField("location") != null)
                this.setUrl(this.connection.getHeaderField("location"));
            else
                this.setUrl(this.redirectFromResponse());
            this.obtainConnection();
        }

        if (this.responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
            throw new HttpGetException("Toegang verboden (403)", this.url.toString(),
                    new Exception("Toegang verboden (403)"), redirected_from);
        }
        String mimeParts[] = this.connection.getContentType().split(";");
        this.mimeType = mimeParts[0];
    } catch (SocketTimeoutException e) {
        throw (new HttpGetException("Timeout bij ophalen gegevens", this.url.toString(), e, redirected_from));
    } catch (IOException e) {
        throw (new HttpGetException("Probleem met verbinden", this.url.toString(), e, redirected_from));
    }
}

From source file:hudson.model.AbstractProjectTest.java

/**
 * Makes sure that the workspace deletion is protected.
 *///w  ww .j a  v  a  2  s. c om
@Test
@PresetData(DataSet.NO_ANONYMOUS_READACCESS)
public void wipeWorkspaceProtected() throws Exception {
    FreeStyleProject project = j.createFreeStyleProject();
    project.getBuildersList()
            .add(Functions.isWindows() ? new BatchFile("echo hello") : new Shell("echo hello"));

    FreeStyleBuild b = project.scheduleBuild2(0).get();

    assert b.getWorkspace().exists() : "Workspace should exist by now";

    // make sure that the action link is protected
    JenkinsRule.WebClient wc = j.createWebClient();
    try {
        wc.getPage(new WebRequest(new URL(wc.getContextPath() + project.getUrl() + "doWipeOutWorkspace"),
                HttpMethod.POST));
        fail("Expected HTTP status code 403");
    } catch (FailingHttpStatusCodeException e) {
        assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getStatusCode());
    }
}

From source file:hudson.model.DirectoryBrowserSupportSEC904Test.java

@Test
@Issue("SECURITY-904")
public void symlink_outsideWorkspace_areNotAllowed() throws Exception {
    FreeStyleProject p = j.createFreeStyleProject();

    File secretsFolder = new File(j.jenkins.getRootDir(), "secrets");
    File secretTarget = new File(secretsFolder, "goal.txt");
    String secretContent = "secret";
    FileUtils.write(secretTarget, secretContent);

    /*// w ww  .  j  a v  a 2  s .  c o m
     *  secrets/
     *      goal.txt
     *  workspace/
     *      intermediateFolder/
     *          public2.key
     *          otherFolder/
     *              to_secret3 -> ../../../../secrets/
     *          to_secret2 -> ../../../secrets/
     *          to_secret_goal2 -> ../../../secrets/goal.txt
     *      public1.key
     *      to_secret1 -> ../../secrets/
     *      to_secret_goal1 -> ../../secrets/goal.txt
     *
     */
    if (Functions.isWindows()) {
        // no need to test mklink /H since we cannot create an hard link to a non-existing file
        // and so you need to have access to the master file system directly which is already a problem

        String script = loadContentFromResource("outsideWorkspaceStructure.bat");
        p.getBuildersList().add(new BatchFile(script));
    } else {
        String script = loadContentFromResource("outsideWorkspaceStructure.sh");
        p.getBuildersList().add(new Shell(script));
    }

    assertEquals(Result.SUCCESS, p.scheduleBuild2(0).get().getResult());

    JenkinsRule.WebClient wc = j.createWebClient();
    wc.getOptions().setThrowExceptionOnFailingStatusCode(false);
    { // workspace root must be reachable (regular case)
        Page page = wc.goTo(p.getUrl() + "ws/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_OK));
        String workspaceContent = page.getWebResponse().getContentAsString();
        assertThat(workspaceContent,
                allOf(containsString("public1.key"), containsString("intermediateFolder"),
                        containsString("to_secrets1"), containsString("to_secrets_goal1"),
                        not(containsString("to_secrets2")), not(containsString("to_secrets_goal2"))));
    }
    { // to_secrets1 not reachable
        Page page = wc.goTo(p.getUrl() + "ws/to_secrets1/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_FORBIDDEN));
    }
    { // to_secrets_goal1 not reachable
        Page page = wc.goTo(p.getUrl() + "ws/to_secrets_goal1/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_FORBIDDEN));
    }
    { // intermediateFolder must be reachable (regular case)
        Page page = wc.goTo(p.getUrl() + "ws/intermediateFolder/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_OK));
        String workspaceContent = page.getWebResponse().getContentAsString();
        assertThat(workspaceContent,
                allOf(not(containsString("to_secrets1")), not(containsString("to_secrets_goal1")),
                        containsString("to_secrets2"), containsString("to_secrets_goal2")));
    }
    { // to_secrets2 not reachable
        Page page = wc.goTo(p.getUrl() + "ws/intermediateFolder/to_secrets2/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_FORBIDDEN));
    }
    { // using symbolic in the intermediate path
        Page page = wc.goTo(p.getUrl() + "ws/intermediateFolder/to_secrets2/master.key", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_FORBIDDEN));
    }
    { // to_secrets_goal2 not reachable
        Page page = wc.goTo(p.getUrl() + "ws/intermediateFolder/to_secrets_goal2/", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_FORBIDDEN));
    }

    // pattern search feature
    { // the pattern allow us to search inside the files / folders, 
      // without the patch the master.key from inside the outside symlinks would have been linked
        Page page = wc.goTo(p.getUrl() + "ws/**/*.key", null);
        assertThat(page.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_OK));
        String workspaceContent = page.getWebResponse().getContentAsString();
        assertThat(workspaceContent, allOf(not(containsString("master.key")), containsString("public1.key"),
                containsString("public2.key")));
    }

    // zip feature
    { // all the outside folders / files are not included in the zip
        Page zipPage = wc.goTo(p.getUrl() + "ws/*zip*/ws.zip", null);
        assertThat(zipPage.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_OK));

        List<String> entryNames = getListOfEntriesInDownloadedZip((UnexpectedPage) zipPage);
        assertThat(entryNames, containsInAnyOrder(p.getName() + "/intermediateFolder/public2.key",
                p.getName() + "/public1.key"));
    }
    { // all the outside folders / files are not included in the zip
        Page zipPage = wc.goTo(p.getUrl() + "ws/intermediateFolder/*zip*/intermediateFolder.zip", null);
        assertThat(zipPage.getWebResponse().getStatusCode(), equalTo(HttpURLConnection.HTTP_OK));

        List<String> entryNames = getListOfEntriesInDownloadedZip((UnexpectedPage) zipPage);
        assertThat(entryNames, contains("intermediateFolder/public2.key"));
    }
}

From source file:org.debux.webmotion.shiro.Shiro.java

/**
 * Check if the current user has role.//from  w w  w  . j a  va  2 s.  c  o  m
 * 
 * @param role
 * @return 
 */
public Render hasRole(HttpContext context, Call call) {
    FilterRule rule = (FilterRule) call.getCurrentRule();
    Map<String, String[]> defaultParameters = rule.getDefaultParameters();

    String[] values = defaultParameters.get("role");
    List<String> roles = Arrays.asList(values);

    Subject currentUser = getSubject(context);
    if (currentUser.isAuthenticated()) {

        boolean[] hasRoles = currentUser.hasRoles(roles);
        if (BooleanUtils.and(hasRoles)) {
            doProcess();
            return null;
        } else {
            return renderError(HttpURLConnection.HTTP_FORBIDDEN);
        }

    } else {
        return renderError(HttpURLConnection.HTTP_UNAUTHORIZED);
    }
}

From source file:org.languagetool.server.LanguageToolHttpHandler.java

@Override
public void handle(HttpExchange httpExchange) throws IOException {
    long startTime = System.currentTimeMillis();
    String remoteAddress = null;//from  www. ja v a  2  s. c o  m
    Map<String, String> parameters = new HashMap<>();
    int reqId = reqCounter.incrementRequestCount();
    ServerMetricsCollector.getInstance().logRequest();
    boolean incrementHandleCount = false;
    try {
        URI requestedUri = httpExchange.getRequestURI();
        if (requestedUri.getRawPath().startsWith("/v2/")) {
            // healthcheck should come before other limit checks (requests per time etc.), to be sure it works: 
            String pathWithoutVersion = requestedUri.getRawPath().substring("/v2/".length());
            if (pathWithoutVersion.equals("healthcheck")) {
                if (workQueueFull(httpExchange, parameters,
                        "Healthcheck failed: There are currently too many parallel requests.")) {
                    ServerMetricsCollector.getInstance().logFailedHealthcheck();
                    return;
                } else {
                    String ok = "OK";
                    httpExchange.getResponseHeaders().set("Content-Type", "text/plain");
                    httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, ok.getBytes(ENCODING).length);
                    httpExchange.getResponseBody().write(ok.getBytes(ENCODING));
                    ServerMetricsCollector.getInstance().logResponse(HttpURLConnection.HTTP_OK);
                    return;
                }
            }
        }
        String referrer = httpExchange.getRequestHeaders().getFirst("Referer");
        String origin = httpExchange.getRequestHeaders().getFirst("Origin"); // Referer can be turned off with meta tags, so also check this
        for (String ref : config.getBlockedReferrers()) {
            String errorMessage = null;
            if (ref != null && !ref.isEmpty()) {
                if (referrer != null && siteMatches(referrer, ref)) {
                    errorMessage = "Error: Access with referrer " + referrer + " denied.";
                } else if (origin != null && siteMatches(origin, ref)) {
                    errorMessage = "Error: Access with origin " + origin + " denied.";
                }
            }
            if (errorMessage != null) {
                sendError(httpExchange, HttpURLConnection.HTTP_FORBIDDEN, errorMessage);
                logError(errorMessage, HttpURLConnection.HTTP_FORBIDDEN, parameters, httpExchange);
                ServerMetricsCollector.getInstance().logResponse(HttpURLConnection.HTTP_FORBIDDEN);
                return;
            }
        }
        String origAddress = httpExchange.getRemoteAddress().getAddress().getHostAddress();
        String realAddressOrNull = getRealRemoteAddressOrNull(httpExchange);
        remoteAddress = realAddressOrNull != null ? realAddressOrNull : origAddress;
        reqCounter.incrementHandleCount(remoteAddress, reqId);
        incrementHandleCount = true;
        // According to the Javadoc, "Closing an exchange without consuming all of the request body is
        // not an error but may make the underlying TCP connection unusable for following exchanges.",
        // so we consume the request now, even before checking for request limits:
        parameters = getRequestQuery(httpExchange, requestedUri);
        if (requestLimiter != null) {
            try {
                requestLimiter.checkAccess(remoteAddress, parameters, httpExchange.getRequestHeaders());
            } catch (TooManyRequestsException e) {
                String errorMessage = "Error: Access from " + remoteAddress + " denied: " + e.getMessage();
                int code = HttpURLConnection.HTTP_FORBIDDEN;
                sendError(httpExchange, code, errorMessage);
                // already logged vai DatabaseAccessLimitLogEntry
                logError(errorMessage, code, parameters, httpExchange, false);
                return;
            }
        }
        if (errorRequestLimiter != null && !errorRequestLimiter.wouldAccessBeOkay(remoteAddress, parameters,
                httpExchange.getRequestHeaders())) {
            String textSizeMessage = getTextOrDataSizeMessage(parameters);
            String errorMessage = "Error: Access from " + remoteAddress + " denied - too many recent timeouts. "
                    + textSizeMessage + " Allowed maximum timeouts: " + errorRequestLimiter.getRequestLimit()
                    + " per " + errorRequestLimiter.getRequestLimitPeriodInSeconds() + " seconds";
            int code = HttpURLConnection.HTTP_FORBIDDEN;
            sendError(httpExchange, code, errorMessage);
            logError(errorMessage, code, parameters, httpExchange);
            return;
        }
        if (workQueueFull(httpExchange, parameters,
                "Error: There are currently too many parallel requests. Please try again later.")) {
            ServerMetricsCollector.getInstance()
                    .logRequestError(ServerMetricsCollector.RequestErrorType.QUEUE_FULL);
            return;
        }
        if (allowedIps == null || allowedIps.contains(origAddress)) {
            if (requestedUri.getRawPath().startsWith("/v2/")) {
                ApiV2 apiV2 = new ApiV2(textCheckerV2, config.getAllowOriginUrl());
                String pathWithoutVersion = requestedUri.getRawPath().substring("/v2/".length());
                apiV2.handleRequest(pathWithoutVersion, httpExchange, parameters, errorRequestLimiter,
                        remoteAddress, config);
            } else if (requestedUri.getRawPath().endsWith("/Languages")) {
                throw new IllegalArgumentException(
                        "You're using an old version of our API that's not supported anymore. Please see https://languagetool.org/http-api/migration.php");
            } else if (requestedUri.getRawPath().equals("/")) {
                throw new IllegalArgumentException(
                        "Missing arguments for LanguageTool API. Please see " + API_DOC_URL);
            } else if (requestedUri.getRawPath().contains("/v2/")) {
                throw new IllegalArgumentException(
                        "You have '/v2/' in your path, but not at the root. Try an URL like 'http://server/v2/...' ");
            } else if (requestedUri.getRawPath().equals("/favicon.ico")) {
                sendError(httpExchange, HttpURLConnection.HTTP_NOT_FOUND, "Not found");
            } else {
                throw new IllegalArgumentException(
                        "This is the LanguageTool API. You have not specified any parameters. Please see "
                                + API_DOC_URL);
            }
        } else {
            String errorMessage = "Error: Access from " + StringTools.escapeXML(origAddress) + " denied";
            sendError(httpExchange, HttpURLConnection.HTTP_FORBIDDEN, errorMessage);
            throw new RuntimeException(errorMessage);
        }
    } catch (Exception e) {
        String response;
        int errorCode;
        boolean textLoggingAllowed = false;
        boolean logStacktrace = true;
        Throwable rootCause = ExceptionUtils.getRootCause(e);
        if (e instanceof TextTooLongException || rootCause instanceof TextTooLongException) {
            errorCode = HttpURLConnection.HTTP_ENTITY_TOO_LARGE;
            response = e.getMessage();
            logStacktrace = false;
        } else if (e instanceof ErrorRateTooHighException || rootCause instanceof ErrorRateTooHighException) {
            errorCode = HttpURLConnection.HTTP_BAD_REQUEST;
            response = ExceptionUtils.getRootCause(e).getMessage();
            logStacktrace = false;
        } else if (hasCause(e, AuthException.class)) {
            errorCode = HttpURLConnection.HTTP_FORBIDDEN;
            response = e.getMessage();
            logStacktrace = false;
        } else if (e instanceof IllegalArgumentException || rootCause instanceof IllegalArgumentException) {
            errorCode = HttpURLConnection.HTTP_BAD_REQUEST;
            response = e.getMessage();
        } else if (e instanceof PathNotFoundException || rootCause instanceof PathNotFoundException) {
            errorCode = HttpURLConnection.HTTP_NOT_FOUND;
            response = e.getMessage();
        } else if (e instanceof TimeoutException || rootCause instanceof TimeoutException) {
            errorCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
            response = "Checking took longer than " + config.getMaxCheckTimeMillis() / 1000.0f
                    + " seconds, which is this server's limit. "
                    + "Please make sure you have selected the proper language or consider submitting a shorter text.";
        } else {
            response = "Internal Error: " + e.getMessage();
            errorCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
            textLoggingAllowed = true;
        }
        long endTime = System.currentTimeMillis();
        logError(remoteAddress, e, errorCode, httpExchange, parameters, textLoggingAllowed, logStacktrace,
                endTime - startTime);
        sendError(httpExchange, errorCode, "Error: " + response);

    } finally {
        httpExchange.close();
        if (incrementHandleCount) {
            reqCounter.decrementHandleCount(reqId);
        }
    }
}