private function buildEndpoint()

in src/Api/Serializer/RestSerializer.php [201:269]


    private function buildEndpoint(Operation $operation, array $args, array $opts)
    {
        $serviceName = $this->api->getServiceName();
        // Create an associative array of variable definitions used in expansions
        $varDefinitions = $this->getVarDefinitions($operation, $args);

        $relative = preg_replace_callback(
            '/\{([^\}]+)\}/',
            function (array $matches) use ($varDefinitions) {
                $isGreedy = substr($matches[1], -1, 1) == '+';
                $k = $isGreedy ? substr($matches[1], 0, -1) : $matches[1];
                if (!isset($varDefinitions[$k])) {
                    return '';
                }

                if ($isGreedy) {
                    return str_replace('%2F', '/', rawurlencode($varDefinitions[$k]));
                }

                return rawurlencode($varDefinitions[$k]);
            },
            $operation['http']['requestUri']
        );

        // Add the query string variables or appending to one if needed.
        if (!empty($opts['query'])) {
           $relative = $this->appendQuery($opts['query'], $relative);
        }

        $path = $this->endpoint->getPath();

        if ($this->isUseEndpointV2 && $serviceName === 's3') {
            if (substr($path, -1) === '/' && $relative[0] === '/') {
                $path = rtrim($path, '/');
            }
            $relative = $path . $relative;

            if (strpos($relative, '../') !== false
                || substr($relative, -2) === '..'
            ) {
                if ($relative[0] !== '/') {
                    $relative = '/' . $relative;
                }

                return new Uri($this->endpoint->withPath('') . $relative);
            }
        }

        if ((!empty($relative) && $relative !== '/')
            && !$this->isUseEndpointV2
        ) {
            $this->normalizePath($path);
        }

        // If endpoint has path, remove leading '/' to preserve URI resolution.
        if ($path && $relative[0] === '/') {
            $relative = substr($relative, 1);
        }

        //Append path to endpoint when leading '//...'
        // present as uri cannot be properly resolved
        if ($this->isUseEndpointV2 && strpos($relative, '//') === 0) {
            return new Uri($this->endpoint . $relative);
        }

        // Expand path place holders using Amazon's slightly different URI
        // template syntax.
        return UriResolver::resolve($this->endpoint, new Uri($relative));
    }