<?
    use Bitrix\Main\Application;

    class CStartShopExchange1CResponse
    {
        const SESSION_KEY = 'STARTSHOP_1C_EXCHANGE_AUTH';

        protected static function ParseBasicAuthHeader($sAuthorization)
        {
            if ($sAuthorization === '' || !preg_match('/Basic\s+(.+)/i', $sAuthorization, $arMatches)) {
                return array('', '');
            }

            $sDecoded = base64_decode($arMatches[1], true);

            if ($sDecoded === false || strpos($sDecoded, ':') === false) {
                return array('', '');
            }

            $arCredentials = explode(':', $sDecoded, 2);

            return array((string)$arCredentials[0], (string)$arCredentials[1]);
        }

        protected static function GetBasicAuthCredentials()
        {
            $sLogin = (string)($_SERVER['PHP_AUTH_USER'] ?? '');
            $sPassword = (string)($_SERVER['PHP_AUTH_PW'] ?? '');

            if ($sLogin === '') {
                $sAuthorization = (string)($_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? '');

                if ($sAuthorization === '' && !empty($_SERVER['REMOTE_USER'])) {
                    $sAuthorization = 'Basic '.$_SERVER['REMOTE_USER'];
                }

                list($sLogin, $sPassword) = static::ParseBasicAuthHeader($sAuthorization);
            }

            return array($sLogin, $sPassword);
        }

        protected static function IsCredentialsValid()
        {
            list($sLogin, $sPassword) = static::GetBasicAuthCredentials();

            $sExpectedLogin = (string)CStartShopVariables::Get('1C_EXCHANGE_LOGIN');
            $sExpectedPassword = (string)CStartShopVariables::Get('1C_EXCHANGE_PASSWORD');

            return $sExpectedLogin !== '' && $sExpectedPassword !== ''
                && hash_equals($sExpectedLogin, $sLogin)
                && hash_equals($sExpectedPassword, $sPassword);
        }

        protected static function GetSession()
        {
            return Application::getInstance()->getSession();
        }

        public static function Success($bDie = true) {
            echo "success\n";

            if ($bDie)
                die();
        }

        public static function Progress($bDie = true) {
            echo "progress\n";

            if ($bDie)
                die();
        }

        public static function Failure($sReason = "", $bDie = true) {
            echo "failure\n";
            echo $sReason."\n";

            if ($bDie)
                die();
        }

        public static function Authorize($bDie = true) {
            if (!static::IsCredentialsValid()) {
                static::Failure('Authorize: access denied!', $bDie);
                return false;
            }

            $oSession = static::GetSession();
            $oSession->set(static::SESSION_KEY, true);

            static::Success(false);
            echo $oSession->getName()."\n";
            echo $oSession->getId()."\n";

            if ($bDie)
                die();

            return true;
        }

        public static function CheckAuthorized($bDie = true) {
            if (static::IsCredentialsValid())
                return true;

            $oSession = static::GetSession();
            $sSessionName = $oSession->getName();

            if (!$oSession->has(static::SESSION_KEY)
                || $oSession->get(static::SESSION_KEY) !== true
                || empty($_COOKIE[$sSessionName])
                || !hash_equals((string)$_COOKIE[$sSessionName], (string)$oSession->getId())) {
                static::Failure('Authorize: session required!', $bDie);
                return false;
            }

            return true;
        }

        public static function Initialize($iFileSize = 1048576, $bUseZip = false, $bDie = true) {
            if (!empty($iFileSize) && is_numeric($iFileSize)) {
                echo "zip=".($bUseZip ? "yes" : "no")."\n";
                echo "file_limit=".$iFileSize."\n";
            } else {
                static::Failure("Initialize: invalid parameters!", $bDie);
                return false;
            }

            if ($bDie)
                die();

            return true;
        }
    }
?>
