<commit_before>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.web;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.container.servlet.HttpServletUtils;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.resource.internal.entity.EntityResourceActionLister;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.DeletedAttachment;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;

public class XWikiServletURLFactory extends XWikiDefaultURLFactory
{
    private static final Logger LOGGER = LoggerFactory.getLogger(XWikiServletURLFactory.class);

    private EntityReferenceResolver<String> relativeEntityReferenceResolver;

    private EntityReferenceResolver<String> currentEntityReferenceResolver;

    private EntityResourceActionLister actionLister;

    protected URL originalURL;

    /**
     * @deprecated since 10.3, use #defaultURLs instead
     * @see #defaultURLs
     */
    @Deprecated
    protected String defaultURL;

    /**
     * This is the URL which was requested by the user possibly with the host modified if x-forwarded-host header is set
     * or if xwiki.home parameter is set and we are viewing the main page.
     */
    protected Map<String, URL> defaultURLs;

    protected String contextPath;

    public XWikiServletURLFactory()
    {
    }

    // Used by tests
    public XWikiServletURLFactory(URL defaultURL, String contextPath, String actionPath)
    {
        this.contextPath = contextPath;
        this.originalURL = defaultURL;
    }

    /**
     * Creates a new URL factory that uses the server URL and context path specified by the given XWiki context. This
     * constructor should be used only in tests. Make sure {@link XWikiContext#setURL(URL)} is called before this
     * constructor.
     *
     * @param context
     */
    public XWikiServletURLFactory(XWikiContext context)
    {
        init(context);
    }

    @Override
    public void init(XWikiContext context)
    {
        this.defaultURLs = null;

        this.contextPath = context.getWiki().getWebAppPath(context);

        URL homepageConfigration = getXWikiHomeParameter(context);

        // Set the configured home URL for the main wiki
        setDefaultURL(null, homepageConfigration);

        // Check if the request is a deamon thread request
        XWikiRequest request = context.getRequest();
        boolean daemon = request.getHttpServletRequest() instanceof XWikiServletRequestStub
            && ((XWikiServletRequestStub) request.getHttpServletRequest()).isDaemon();

        // Remember initial request base URL for path for last resort
        if (homepageConfigration != null && context.isMainWiki()) {
            // If the main wiki base URL is forced in the configuration use it
            this.originalURL = homepageConfigration;
        } else if (daemon) {
            // In case of daemon thread use the standard URL of the current wiki as reference
            try {
                this.originalURL = context.getWiki().getServerURL(context.getOriginalWikiId(), context);
            } catch (MalformedURLException e) {
                LOGGER.warn("Can't get the standard URL for wiki [{}]: {}", context.getWikiId(),
                    ExceptionUtils.getRootCauseMessage(e));

                // Fallback on request base URL
                this.originalURL = HttpServletUtils.getSourceBaseURL(context.getRequest());
            }
        } else {
            this.originalURL = HttpServletUtils.getSourceBaseURL(context.getRequest());
        }

        // Only take into account initial request if it's meant to be
        if (!daemon) {
            URL defaultWikiURL = this.originalURL;

            // If protocol is forced in the configuration switch to it
            String protocolConfiguration = context.getWiki().Param("xwiki.url.protocol");
            if (StringUtils.isNotEmpty(protocolConfiguration)) {
                try {
                    defaultWikiURL =
                        new URL(protocolConfiguration, this.originalURL.getHost(), this.originalURL.getPort(), "");
                } catch (MalformedURLException e) {<commit_msg>XWIKI-17187: spinner.gif coming from a webjar resource has an absolute URL when the descriptor is different from the initial request * bulletproofing<commit_after>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.web;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.container.servlet.HttpServletUtils;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.resource.internal.entity.EntityResourceActionLister;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.DeletedAttachment;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;

public class XWikiServletURLFactory extends XWikiDefaultURLFactory
{
    private static final Logger LOGGER = LoggerFactory.getLogger(XWikiServletURLFactory.class);

    private EntityReferenceResolver<String> relativeEntityReferenceResolver;

    private EntityReferenceResolver<String> currentEntityReferenceResolver;

    private EntityResourceActionLister actionLister;

    protected URL originalURL;

    /**
     * @deprecated since 10.3, use #defaultURLs instead
     * @see #defaultURLs
     */
    @Deprecated
    protected String defaultURL;

    /**
     * This is the URL which was requested by the user possibly with the host modified if x-forwarded-host header is set
     * or if xwiki.home parameter is set and we are viewing the main page.
     */
    protected Map<String, URL> defaultURLs;

    protected String contextPath;

    public XWikiServletURLFactory()
    {
    }

    // Used by tests
    public XWikiServletURLFactory(URL defaultURL, String contextPath, String actionPath)
    {
        this.contextPath = contextPath;
        this.originalURL = defaultURL;
    }

    /**
     * Creates a new URL factory that uses the server URL and context path specified by the given XWiki context. This
     * constructor should be used only in tests. Make sure {@link XWikiContext#setURL(URL)} is called before this
     * constructor.
     *
     * @param context
     */
    public XWikiServletURLFactory(XWikiContext context)
    {
        init(context);
    }

    @Override
    public void init(XWikiContext context)
    {
        this.defaultURLs = null;
        this.originalURL = null;

        this.contextPath = context.getWiki().getWebAppPath(context);

        URL homepageConfigration = getXWikiHomeParameter(context);

        // Set the configured home URL for the main wiki
        setDefaultURL(null, homepageConfigration);

        // Check if the request is a deamon thread request
        XWikiRequest request = context.getRequest();
        boolean daemon = request.getHttpServletRequest() instanceof XWikiServletRequestStub
            && ((XWikiServletRequestStub) request.getHttpServletRequest()).isDaemon();

        // Remember initial request base URL for path for last resort
        if (homepageConfigration != null && context.isMainWiki()) {
            // If the main wiki base URL is forced in the configuration use it
            this.originalURL = homepageConfigration;
        } else if (daemon) {
            // In case of daemon thread use the standard URL of the current wiki as reference
            try {
                this.originalURL = context.getWiki().getServerURL(context.getOriginalWikiId(), context);
            } catch (MalformedURLException e) {
                LOGGER.warn("Can't get the standard URL for wiki [{}]: {}", context.getWikiId(),
                    ExceptionUtils.getRootCauseMessage(e));
            }
        }

        // Fallback on request base URL
        if (this.originalURL == null) {
            this.originalURL = HttpServletUtils.getSourceBaseURL(context.getRequest());
        }

        // Only take into account initial request if it's meant to be
        if (!daemon) {
            URL defaultWikiURL = this.originalURL;

            // If protocol is forced in the configuration switch to it
            String protocolConfiguration = context.getWiki().Param("xwiki.url.protocol");
            if (StringUtils.isNotEmpty(protocolConfiguration)) {
                try {
                    defaultWikiURL =
                        new URL(protocolConfiguration, this.originalURL.getHost(), this.originalURL.getPort(), "");
                } catch (MalformedURLException e) {
{'fraction_non_alphanumeric': 0.07871303763440861, 'fraction_numerical': 0.003780241935483871, 'mean_word_length': 3.200776287932251, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '265186', 'n_tokens_mistral': 3196, 'n_tokens_neox': 3114, 'n_words': 1002}