All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.rewrite.handler.InvalidURIRule Maven / Gradle / Ivy

//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;

import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 

Rule that protects against invalid unicode characters in URLs, * returning a configurable status code with body message.

*

The logic is as follows:

*
    *
  • if a decoded URI character is an iso control character, apply the rule
  • *
  • if no {@link Character.UnicodeBlock} is found for a decoded URI character, apply the rule
  • *
  • if a decoded URI character is in UnicodeBlock.SPECIALS, apply the rule
  • *
*/ public class InvalidURIRule extends Rule { private static final Logger LOG = LoggerFactory.getLogger(InvalidURIRule.class); private static final int REPLACEMENT_CHAR_CODEPOINT = 65533; // UTF-8 Replacement Char as codepoint private int _code = HttpStatus.BAD_REQUEST_400; private String _message = "Illegal URI"; @Override public boolean isTerminating() { return true; } public int getCode() { return _code; } /** * Set the response code. * @param code the response code */ public void setCode(int code) { _code = code; } public String getMessage() { return _message; } /** *

Sets the message for the response body (if the response code may have a body).

* * @param message the response message */ public void setMessage(String message) { _message = message; } @Override public Handler matchAndApply(Handler input) throws IOException { String path = input.getHttpURI().getDecodedPath(); int i = 0; while (i < path.length()) { int codepoint = path.codePointAt(i); if (!isValidChar(codepoint)) return apply(input); i += Character.charCount(codepoint); } return null; } private Handler apply(Handler input) { return new Handler(input) { @Override protected boolean handle(Response response, Callback callback) { String message = getMessage(); if (StringUtil.isBlank(message)) { response.setStatus(getCode()); callback.succeeded(); } else { Response.writeError(this, response, callback, getCode(), message); } return true; } }; } protected boolean isValidChar(int codepoint) { Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint); if (LOG.isDebugEnabled()) LOG.debug("{} {} {} {}", Character.charCount(codepoint), codepoint, block, Character.isISOControl(codepoint)); if (codepoint == REPLACEMENT_CHAR_CODEPOINT) return false; return (!Character.isISOControl(codepoint)) && block != null && !Character.UnicodeBlock.SPECIALS.equals(block); } @Override public String toString() { return super.toString() + "[" + _code + ":" + _message + "]"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy