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

org.opendaylight.aaa.web.ServletSpec Maven / Gradle / Ivy

There is a newer version: 0.20.3
Show newest version
/*
 * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.aaa.web;

import static com.google.common.base.Preconditions.checkArgument;

import org.eclipse.jdt.annotation.NonNull;

/**
 * Utility methods for dealing with aspects of Java Servlet Specification. We currently support
 * 
 * version 3.1.
 */
final class ServletSpec {
    private ServletSpec() {
        // utility class
    }

    /**
     * Verify that the specified string is a valid Context Path as defined in Section 3.5.
     *
     * @param str String to check
     * @return The string
     * @throws IllegalArgumentException if {@code str} is not a valid context path
     * @throws NullPointerException if {@code str} is {@code null}
     */
    static @NonNull String requireContextPath(final String str) {
        // We do not allow this:
        //   If this context is the “default” context rooted at the base of the
        //   Web server’s URL name space, this path will be an empty string.
        checkArgument(!str.isEmpty(), "Context path is empty");

        // Otherwise, if the
        // context is not rooted at the root of the server’s name space, the path starts with a
        // character but does not end with a / character.
        checkArgument(str.charAt(0) == '/', "Context path '%s' does not start with '/'", str);
        checkArgument(str.charAt(str.length() - 1) != '/', "Context path '%s' ends with '/'", str);

        // TODO: validate according to https://www.rfc-editor.org/rfc/rfc3986#section-3.3

        return str;
    }

    /**
     * Verify that the specified string is a valid Specification of Mapping as defined in Section 12.2.
     *
     * @param str String to check
     * @return The string
     * @throws IllegalArgumentException if {@code str} is not a valid mapping specification
     * @throws NullPointerException if {@code str} is {@code null}
     */
    static @NonNull String requireMappingSpec(final String str) {
        // Bullet 3:
        //      The empty string ("") is a special URL pattern that exactly maps to the
        //      application's context root, i.e., requests of the form http://host:port//. In this case the path info is ’ / ’ and the servlet path and context path is
        //      empty string (““).
        if (str.isEmpty()) {
            return "";
        }

        final char firstChar = str.charAt(0);
        final int len = str.length();
        if (firstChar == '/') {
            // Bullet 4:
            //      A string containing only the ’ / ’ character indicates the "default" servlet of the
            //      application. In this case the servlet path is the request URI minus the context path
            //      and the path info is null.
            // otherwise ...
            if (len != 1) {
                // ... more checks starting at the second character
                final int star = str.indexOf('*', 1);
                checkArgument(
                    // Bullet 5:
                    //      All other strings are used for exact matches only.
                    star == -1
                    // or Bullet 1:
                    //      A string beginning with a ‘ / ’ character and ending with a ‘ /*’ suffix is used for
                    //      path mapping.
                    || star == len - 1 && str.charAt(star - 1) == '/',
                    // ... otherwise it is a '*' in an exact path
                    "Prefix-based spec '%s' with a '*' at offset %s", str, star);
            }
        } else {
            // Bullet 2:
            //      A string beginning with a ‘ *. ’ prefix is used as an extension mapping
            checkArgument(firstChar == '.' && len > 1 && str.charAt(1) == '*',
                "Spec '%s' is neither prefix-based nor suffix-based", str);

            final int slash = str.indexOf('/', 2);
            checkArgument(slash == -1, "Suffix-based spec '%s' with a '/' at offset %s", str, slash);
            final int star = str.indexOf('*', 2);
            checkArgument(star == -1, "Suffix-based spec '%s' with a '*' at offset %s", str, star);
        }

        return str;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy