Search in sources :

Example 1 with CharChunk

use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.

the class CoyoteAdapter method normalizeChars.

private static boolean normalizeChars(MessageBytes uriMB) {
    CharChunk uriCC = uriMB.getCharChunk();
    char[] c = uriCC.getChars();
    int start = uriCC.getStart();
    int end = uriCC.getEnd();
    // URL * is acceptable
    if ((end - start == 1) && c[start] == (char) '*')
        return true;
    int pos = 0;
    int index = 0;
    // Check for null char
    for (pos = start; pos < end; pos++) {
        if (c[pos] == (char) '\\') {
            if (ALLOW_BACKSLASH) {
                c[pos] = (char) '/';
            } else {
                return false;
            }
        }
        if (c[pos] == (char) 0) {
            return false;
        }
    }
    // The URL must start with '/'
    if (c[start] != (char) '/') {
        return false;
    }
    // Replace "//" with "/"
    if (COLLAPSE_ADJACENT_SLASHES) {
        for (pos = start; pos < (end - 1); pos++) {
            if (c[pos] == (char) '/') {
                while ((pos + 1 < end) && (c[pos + 1] == (char) '/')) {
                    copyChars(c, pos, pos + 1, end - pos - 1);
                    end--;
                }
            }
        }
    }
    // as the next character is a non-significant WS.
    if (((end - start) > 2) && (c[end - 1] == (char) '.')) {
        if ((c[end - 2] == (char) '/') || ((c[end - 2] == (char) '.') && (c[end - 3] == (char) '/'))) {
            c[end] = (char) '/';
            end++;
        }
    }
    uriCC.setEnd(end);
    index = 0;
    // Resolve occurrences of "/./" in the normalized path
    while (true) {
        index = uriCC.indexOf("/./", 0, 3, index);
        if (index < 0)
            break;
        copyChars(c, start + index, start + index + 2, end - start - index - 2);
        end = end - 2;
        uriCC.setEnd(end);
    }
    index = 0;
    // Resolve occurrences of "/../" in the normalized path
    while (true) {
        index = uriCC.indexOf("/../", 0, 4, index);
        if (index < 0)
            break;
        // Prevent from going outside our context
        if (index == 0)
            return false;
        int index2 = -1;
        for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos--) {
            if (c[pos] == (char) '/') {
                index2 = pos;
            }
        }
        copyChars(c, start + index2, start + index + 3, end - start - index - 3);
        end = end + index2 - index - 3;
        uriCC.setEnd(end);
        index = index2;
    }
    uriCC.setChars(c, start, end);
    return true;
}
Also used : CharChunk(org.glassfish.grizzly.http.util.CharChunk)

Example 2 with CharChunk

use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.

the class VirtualServerPipeline method redirectIfNecessary.

/**
 * Checks to see if the given request needs to be redirected.
 *
 * @param request The request to process
 * @param response The response to return
 *
 * @return true if redirect has occurred, false otherwise
 */
private boolean redirectIfNecessary(Request request, Response response) throws IOException {
    if (redirects == null) {
        return false;
    }
    HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
    HttpServletResponse hres = (HttpServletResponse) request.getResponse();
    String requestURI = hreq.getRequestURI();
    RedirectParameters redirectMatch = null;
    // Determine the longest 'from' URI prefix match
    int size = redirects.size();
    for (int i = 0; i < size; i++) {
        RedirectParameters elem = redirects.get(i);
        String elemFromWithTrailingSlash = elem.from;
        if (!elemFromWithTrailingSlash.endsWith("/")) {
            elemFromWithTrailingSlash += "/";
        }
        if (requestURI.equals(elem.from) || requestURI.startsWith(elemFromWithTrailingSlash)) {
            if (redirectMatch != null) {
                if (elem.from.length() > redirectMatch.from.length()) {
                    redirectMatch = elem;
                }
            } else {
                redirectMatch = elem;
            }
        }
    }
    if (redirectMatch != null) {
        // Redirect prefix match found, need to redirect
        String location = null;
        String uriSuffix = requestURI.substring(redirectMatch.from.length());
        if ("/".equals(redirectMatch.from)) {
            uriSuffix = "/" + uriSuffix;
            // START 6810361
            if (redirectMatch.urlPrefixPath != null && uriSuffix.startsWith(redirectMatch.urlPrefixPath)) {
                return false;
            }
        // END 6810361
        }
        // Implements welcome page only redirection
        if ("".equals(redirectMatch.from)) {
            if (!("/".equals(requestURI)))
                return false;
        }
        // END 6810361
        if (redirectMatch.urlPrefix != null) {
            // Replace 'from' URI prefix with URL prefix
            location = redirectMatch.urlPrefix + uriSuffix;
        } else {
            // Replace 'from' URI prefix with complete URL
            location = redirectMatch.url;
        }
        String queryString = hreq.getQueryString();
        if (queryString != null) {
            location += "?" + queryString;
        }
        CharChunk locationCC = null;
        if (redirectMatch.isEscape) {
            try {
                URL url = new URL(location);
                locationCC = locations.poll();
                if (locationCC == null) {
                    locationCC = new CharChunk();
                }
                locationCC.append(url.getProtocol());
                locationCC.append("://");
                locationCC.append(url.getHost());
                if (url.getPort() != -1) {
                    locationCC.append(":");
                    locationCC.append(String.valueOf(url.getPort()));
                }
                locationCC.append(response.encode(url.getPath()));
                if (queryString != null) {
                    locationCC.append("?");
                    locationCC.append(url.getQuery());
                }
                location = locationCC.toString();
            } catch (MalformedURLException mue) {
                if (redirectMatch.validURI) {
                    logger.log(Level.WARNING, LogFacade.INVALID_REDIRECTION_LOCATION, location);
                } else {
                    if (logger.isLoggable(Level.FINE)) {
                        logger.log(Level.FINE, LogFacade.INVALID_REDIRECTION_LOCATION, location);
                    }
                }
            } finally {
                if (locationCC != null) {
                    locationCC.recycle();
                    locations.offer(locationCC);
                }
            }
        }
        hres.sendRedirect(location);
        return true;
    }
    return false;
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) MalformedURLException(java.net.MalformedURLException) HttpServletResponse(javax.servlet.http.HttpServletResponse) String(java.lang.String) CharChunk(org.glassfish.grizzly.http.util.CharChunk) URL(java.net.URL)

Example 3 with CharChunk

use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.

the class Request method convertURI.

// START CR 6309511
/**
 * Character conversion of the URI.
 */
protected void convertURI(MessageBytes uri) throws Exception {
    ByteChunk bc = uri.getByteChunk();
    CharChunk cc = uri.getCharChunk();
    int length = bc.getLength();
    cc.allocate(length, -1);
    String enc = connector.getURIEncoding();
    if (enc != null && !enc.isEmpty() && !Globals.ISO_8859_1_ENCODING.equalsIgnoreCase(enc)) {
        B2CConverter conv = getURIConverter();
        try {
            if (conv == null) {
                conv = new B2CConverter(enc);
                setURIConverter(conv);
            }
        } catch (IOException e) {
            // Ignore
            log.log(Level.SEVERE, LogFacade.INVALID_URI_ENCODING);
            connector.setURIEncoding(null);
        }
        if (conv != null) {
            try {
                conv.convert(bc, cc, cc.getBuffer().length - cc.getEnd());
                uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength());
                return;
            } catch (IOException e) {
                log.log(Level.SEVERE, LogFacade.INVALID_URI_CHAR_ENCODING);
                cc.recycle();
            }
        }
    }
    // Default encoding: fast conversion
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < length; i++) {
        cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    uri.setChars(cbuf, 0, length);
}
Also used : B2CConverter(org.glassfish.grizzly.http.util.B2CConverter) ByteChunk(org.glassfish.grizzly.http.util.ByteChunk) IOException(java.io.IOException) CharChunk(org.glassfish.grizzly.http.util.CharChunk)

Example 4 with CharChunk

use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.

the class StandardContext method getRequestDispatcher.

/**
 * Return a <code>RequestDispatcher</code> instance that acts as a
 * wrapper for the resource at the given path.  The path must begin
 * with a "/" and is interpreted as relative to the current context root.
 */
@Override
public RequestDispatcher getRequestDispatcher(String path) {
    // Validate the path argument
    if (path == null) {
        return null;
    }
    if (!path.startsWith("/") && !path.isEmpty()) {
        String msg = MessageFormat.format(rb.getString(LogFacade.INCORRECT_OR_NOT_EMPTY_PATH), path);
        throw new IllegalArgumentException(msg);
    }
    // Get query string
    String queryString = null;
    int pos = path.indexOf('?');
    if (pos >= 0) {
        queryString = path.substring(pos + 1);
        path = path.substring(0, pos);
    }
    path = RequestUtil.normalize(path);
    if (path == null)
        return (null);
    pos = path.length();
    // Use the thread local URI and mapping data
    DispatchData dd = dispatchData.get();
    if (dd == null) {
        dd = new DispatchData();
        dispatchData.set(dd);
    }
    MessageBytes uriMB = dd.uriMB;
    uriMB.recycle();
    // Retrieve the thread local mapping data
    MappingData mappingData = dd.mappingData;
    // Map the URI
    CharChunk uriCC = uriMB.getCharChunk();
    try {
        uriCC.append(getPath(), 0, getPath().length());
        /*
             * Ignore any trailing path params (separated by ';') for mapping
             * purposes
             */
        int semicolon = path.indexOf(';');
        if (pos >= 0 && semicolon > pos) {
            semicolon = -1;
        }
        uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
        getMapper().map(uriMB, mappingData);
        if (mappingData.wrapper == null) {
            return (null);
        }
        /*
             * Append any trailing path params (separated by ';') that were
             * ignored for mapping purposes, so that they're reflected in the
             * RequestDispatcher's requestURI
             */
        if (semicolon > 0) {
            uriCC.append(path, semicolon, pos - semicolon);
        }
    } catch (Exception e) {
        // Should never happen
        log.log(Level.WARNING, LogFacade.MAPPING_ERROR_EXCEPTION, e);
        return (null);
    }
    Wrapper wrapper = (Wrapper) mappingData.wrapper;
    String wrapperPath = mappingData.wrapperPath.toString();
    String pathInfo = mappingData.pathInfo.toString();
    HttpServletMapping mappingForDispatch = new MappingImpl(mappingData);
    mappingData.recycle();
    // Construct a RequestDispatcher to process this request
    return new ApplicationDispatcher(wrapper, mappingForDispatch, uriCC.toString(), wrapperPath, pathInfo, queryString, null);
}
Also used : Wrapper(org.apache.catalina.Wrapper) MessageBytes(org.glassfish.grizzly.http.util.MessageBytes) MappingData(org.glassfish.grizzly.http.server.util.MappingData) MappingImpl(org.apache.catalina.connector.MappingImpl) SecurityConstraint(org.apache.catalina.deploy.SecurityConstraint) CharChunk(org.glassfish.grizzly.http.util.CharChunk) LifecycleException(org.apache.catalina.LifecycleException) MalformedObjectNameException(javax.management.MalformedObjectNameException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) NamingException(javax.naming.NamingException) MBeanRegistrationException(javax.management.MBeanRegistrationException) MalformedURLException(java.net.MalformedURLException) HttpServletMapping(javax.servlet.http.HttpServletMapping)

Example 5 with CharChunk

use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.

the class ContainerMapper method mapUriWithSemicolon.

/**
 * Maps the decodedURI to the corresponding Adapter, considering that URI
 * may have a semicolon with extra data followed, which shouldn't be a part
 * of mapping process.
 *
 * @param req HTTP request
 * @param decodedURI URI
 * @param semicolonPos semicolon position. Might be <tt>0</tt> if position wasn't resolved yet (so it will be resolved in the method), or <tt>-1</tt> if there is no semicolon in the URI.
 * @param mappingData
 * @return
 * @throws Exception
 */
final HttpHandler mapUriWithSemicolon(final Request req, final DataChunk decodedURI, int semicolonPos, final MappingData mappingData) throws Exception {
    mapperLock.readLock().lock();
    try {
        final CharChunk charChunk = decodedURI.getCharChunk();
        final int oldStart = charChunk.getStart();
        final int oldEnd = charChunk.getEnd();
        if (semicolonPos == 0) {
            semicolonPos = decodedURI.indexOf(';', 0);
        }
        DataChunk localDecodedURI = decodedURI;
        if (semicolonPos >= 0) {
            charChunk.setEnd(semicolonPos);
            // duplicate the URI path, because Mapper may corrupt the attributes,
            // which follow the path
            localDecodedURI = req.getNote(DATA_CHUNK);
            if (localDecodedURI == null) {
                localDecodedURI = DataChunk.newInstance();
                req.setNote(DATA_CHUNK, localDecodedURI);
            }
            localDecodedURI.duplicate(decodedURI);
        }
        try {
            return map(req, localDecodedURI, mappingData);
        } finally {
            charChunk.setStart(oldStart);
            charChunk.setEnd(oldEnd);
        }
    } finally {
        mapperLock.readLock().unlock();
    }
}
Also used : DataChunk(org.glassfish.grizzly.http.util.DataChunk) CharChunk(org.glassfish.grizzly.http.util.CharChunk)

Aggregations

CharChunk (org.glassfish.grizzly.http.util.CharChunk)8 HttpServletRequest (javax.servlet.http.HttpServletRequest)3 MappingData (org.glassfish.grizzly.http.server.util.MappingData)3 DataChunk (org.glassfish.grizzly.http.util.DataChunk)3 IOException (java.io.IOException)2 MalformedURLException (java.net.MalformedURLException)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 Wrapper (org.apache.catalina.Wrapper)2 MessageBytes (org.glassfish.grizzly.http.util.MessageBytes)2 ProxyHandler (com.sun.appserv.ProxyHandler)1 CharConversionException (java.io.CharConversionException)1 String (java.lang.String)1 URL (java.net.URL)1 Principal (java.security.Principal)1 MBeanRegistrationException (javax.management.MBeanRegistrationException)1 MalformedObjectNameException (javax.management.MalformedObjectNameException)1 NamingException (javax.naming.NamingException)1 ServletException (javax.servlet.ServletException)1 HttpServletMapping (javax.servlet.http.HttpServletMapping)1 Context (org.apache.catalina.Context)1