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

com.enonic.xp.web.servlet.ServletRequestUrlHelper Maven / Gradle / Ivy

The newest version!
package com.enonic.xp.web.servlet;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import com.google.common.base.Splitter;
import com.google.common.net.HostAndPort;

import com.enonic.xp.annotation.PublicApi;
import com.enonic.xp.web.vhost.VirtualHost;
import com.enonic.xp.web.vhost.VirtualHostHelper;

import static com.google.common.base.Strings.isNullOrEmpty;

@PublicApi
public final class ServletRequestUrlHelper
{
    private static final int[] RFC_8187_ATTR_CHAR =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&+-.^_`|~".chars().sorted().toArray();

    @Deprecated
    public static String createUri( final String path )
    {
        return createUri( ServletRequestHolder.getRequest(), path );
    }

    public static String createUri( final HttpServletRequest req, final String path )
    {
        final StringBuilder str = new StringBuilder();

        if ( !isNullOrEmpty( path ) )
        {
            if ( !path.startsWith( "/" ) )
            {
                str.append( "/" );
            }

            str.append( path );
        }
        else
        {
            str.append( "/" );
        }

        return rewriteUri( req, str.toString() ).getRewrittenUri();
    }

    @Deprecated
    public static String getScheme()
    {
        return getScheme( ServletRequestHolder.getRequest() );
    }

    @Deprecated
    public static String getScheme( final HttpServletRequest req )
    {
        return req.getScheme();
    }

    @Deprecated
    public static String getHost()
    {
        return getHost( ServletRequestHolder.getRequest() );
    }

    @Deprecated
    public static String getHost( final HttpServletRequest req )
    {
        return req.getServerName();
    }

    @Deprecated
    public static int getPort()
    {
        return getPort( ServletRequestHolder.getRequest() );
    }

    @Deprecated
    public static int getPort( final HttpServletRequest req )
    {
        return req.getServerPort();
    }

    @Deprecated
    public static HostAndPort getHostAndPort()
    {
        return getHostAndPort( ServletRequestHolder.getRequest() );
    }

    @Deprecated
    public static HostAndPort getHostAndPort( final HttpServletRequest req )
    {
        return HostAndPort.fromParts( req.getServerName(), req.getServerPort() );
    }

    @Deprecated
    public static String getRemoteAddress( final HttpServletRequest req )
    {
        return req.getRemoteAddr();
    }

    @Deprecated
    public static String getPath()
    {
        return getPath( ServletRequestHolder.getRequest() );
    }

    public static String getPath( final HttpServletRequest req )
    {
        return createUri( req, req.getRequestURI() );
    }

    @Deprecated
    private static String getQueryString( final HttpServletRequest req )
    {
        return req.getQueryString();
    }

    @Deprecated
    public static String getServerUrl()
    {
        return getServerUrl( ServletRequestHolder.getRequest() );
    }

    public static String getServerUrl( final HttpServletRequest req )
    {
        final StringBuilder str = new StringBuilder();

        //Appends the scheme part
        String scheme = req.getScheme();
        str.append( scheme );

        //Appends the host
        str.append( "://" ).append( req.getServerName() );

        //Appends the port if necessary
        final int port = req.getServerPort();
        if ( needPortNumber( scheme, port ) )
        {
            str.append( ":" ).append( port );
        }

        return str.toString();
    }

    @Deprecated
    public static String getFullUrl()
    {
        return getFullUrl( ServletRequestHolder.getRequest() );
    }

    public static String getFullUrl( final HttpServletRequest req )
    {
        //Appends the server part
        StringBuilder fullUrl = new StringBuilder( getServerUrl( req ) );

        //Appends the path part
        fullUrl.append( getPath( req ) );

        //Appends the query string part
        final String queryString = req.getQueryString();
        if ( queryString != null )
        {
            fullUrl.append( "?" ).append( queryString );
        }

        return fullUrl.toString();
    }

    private static boolean needPortNumber( final String scheme, final int port )
    {
        final boolean isUndefined = port < 0;
        final boolean isHttpOrWs = ( "http".equals( scheme ) || "ws".equals( scheme ) ) && 80 == port;
        final boolean isHttpsOrWss = ( "https".equals( scheme ) || "wss".equals( scheme ) ) && 443 == port;
        return !( isUndefined || isHttpOrWs || isHttpsOrWss );
    }

    @Deprecated
    public static UriRewritingResult rewriteUri( final String uri )
    {
        return rewriteUri( ServletRequestHolder.getRequest(), uri );
    }

    public static UriRewritingResult rewriteUri( final HttpServletRequest req, final String uri )
    {
        UriRewritingResult.Builder resultBuilder = UriRewritingResult.create().rewrittenUri( uri );
        if ( req == null )
        {
            return resultBuilder.build();
        }

        final VirtualHost vhost = VirtualHostHelper.getVirtualHost( req );
        if ( vhost == null )
        {
            return resultBuilder.build();
        }

        final String targetPath = vhost.getTarget();
        if ( needRewrite( uri, targetPath ) )
        {
            final String result = uri.substring( targetPath.length() );
            final String newUri = normalizePath( vhost.getSource() + ( "/".equals( targetPath ) ? "/" : "" ) + result );
            return resultBuilder.rewrittenUri( newUri )
                .deletedUriPrefix( targetPath )
                .newUriPrefix( normalizePath( vhost.getSource() ) )
                .build();
        }

        return resultBuilder.rewrittenUri( normalizePath( uri ) ).outOfScope( true ).build();
    }

    private static boolean needRewrite( final String uri, final String targetPath )
    {
        if ( targetPath.equals( "/" ) )
        {
            return uri.startsWith( "/" );
        }
        if ( uri.equals( targetPath ) )
        {
            return true;
        }

        final int queryPos = uri.indexOf( '?' );

        if ( queryPos == -1 )
        {
            return uri.startsWith( targetPath + "/" );
        }
        else
        {
            final String uriWithoutQuery = uri.substring( 0, queryPos );
            if ( uriWithoutQuery.equals( targetPath ) )
            {
                return true;
            }
            else
            {
                return uriWithoutQuery.startsWith( targetPath + "/" );
            }
        }
    }

    private static String normalizePath( final String value )
    {
        if ( isNullOrEmpty( value ) )
        {
            return "/";
        }

        final Iterable parts = Splitter.on( '/' ).trimResults().omitEmptyStrings().split( value );
        return "/" + String.join( "/", parts );
    }

    public static String contentDispositionAttachment( final String fileName )
    {
        final StringBuilder builder = new StringBuilder();
        builder.append( "attachment; filename=" );
        appendQuoted( builder, fileName );
        builder.append( "; filename*=" );
        appendRfc8187Encoded( builder, fileName, StandardCharsets.UTF_8 );
        return builder.toString();
    }

    private static void appendQuoted( final StringBuilder builder, final String input )
    {
        builder.append( "\"" );
        input.codePoints().forEachOrdered( value -> {
            if ( value == '"' )
            {
                builder.append( "\\\"" );
            }
            else
            {
                builder.appendCodePoint( value );
            }
        } );
        builder.append( "\"" );
    }

    private static void appendRfc8187Encoded( final StringBuilder builder, final String input, final Charset charset )
    {
        builder.append( charset.name() );
        builder.append( "''" );
        for ( byte b : input.getBytes( charset ) )
        {
            if ( Arrays.binarySearch( RFC_8187_ATTR_CHAR, b ) >= 0 )
            {
                builder.append( (char) b );
            }
            else
            {
                builder.append( '%' );
                builder.append( Character.toUpperCase( Character.forDigit( ( b >>> 4 ) & 0x0f, 16 ) ) );
                builder.append( Character.toUpperCase( Character.forDigit( b & 0x0f, 16 ) ) );
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy