Current File : //usr/lib/onecom-webapps/webshop/proxy.php
<?php
ob_start();

function getHost() {
    // Load config
    if (isset($_SERVER['ONECOM_WEBSHOP_HOST'])) {
        return $_SERVER['ONECOM_WEBSHOP_HOST'];
    } else {
        return 'http://localhost:3000';
    }
}

function requestWebShop($opts) {
    $host = getHost();

    if (isset($_SERVER['PATH_INFO'])) {
        $pathInfo = $_SERVER['PATH_INFO'];
    } else {
        $pathInfo = '/';
    }

    if (isset($opts['font']) && isset($opts['fontColor']) && isset($opts['focusColor'])) {

        if (empty($opts['bgColor'])) {
            $opts['bgColor'] = '';
        }
        if (empty($opts['borderColor'])) {
            $opts['borderColor'] = '';
        }
        if (empty($opts['buttonTextColor'])) {
            $opts['buttonTextColor'] = '';
        }
        if (empty($opts['buttonClassname'])) {
            $opts['buttonClassname'] = '';
        }

        $style = '&font=' . rawurlencode($opts['font']) .
                '&fontColor=' . rawurlencode($opts['fontColor']) .
                '&focusColor=' . rawurlencode($opts['focusColor']) .
                '&bgColor=' . rawurlencode($opts['bgColor']) .
                '&borderColor=' . rawurlencode($opts['borderColor']) .
                '&buttonTextColor=' . rawurlencode($opts['buttonTextColor']) .
                '&buttonClassname=' . rawurlencode($opts['buttonClassname']);

    } elseif (isset($opts['buttonClassname'])) {

        if (empty($opts['showCategory'])) {
            $opts['showCategory'] = 'true';
        }

        $style = '&buttonClassname=' . rawurlencode($opts['buttonClassname']) .
                 '&showCategory=' . rawurlencode($opts['showCategory']);
    } else {
        $style = '';
    }

    $handle = curl_init();
    $url = $host . '/shop/v1/' .
            rawurlencode((isset($_SERVER['ALLOW_DOMAIN_OVERRIDE']) && $_SERVER['ALLOW_DOMAIN_OVERRIDE'] && isset($opts['domain'])) ? $opts['domain'] : $_SERVER['ONECOM_DOMAIN_NAME']) . '/' .
            rawurlencode($opts['endpoint']) .
            $pathInfo .
            '?base=' . rawurlencode($_SERVER['SCRIPT_NAME']) .
            '&locale=' . rawurlencode($opts['locale']);
    if (count($_GET)) {
        $url .= '&' . http_build_query($_GET);
    }
    $url .= $style;

    curl_setopt($handle, CURLOPT_URL, $url);

    $requestHeadersArray = array();

    $requestHeadersArray['x-proxied-by'] = 'webshop-php-proxy';

    if (isset($_SERVER['HTTP_X_ONECOM_FORWARDED_IP']) && isset($_SERVER['HTTP_X_ONECOM_FORWARDED_PROTO'])) {
        $requestHeadersArray['x-forwarded-for'] = $_SERVER['HTTP_X_ONECOM_FORWARDED_IP'];
        $requestHeadersArray['x-forwarded-proto'] = $_SERVER['HTTP_X_ONECOM_FORWARDED_PROTO'];
    }

    $curlRequestHeaders = [];
    foreach($requestHeadersArray as $key => $val) {
        $curlRequestHeaders[] = "{$key}: {$val}";
    }
    curl_setopt($handle, CURLOPT_HTTPHEADER, $curlRequestHeaders);

    if ($opts['endpoint'] === 'body') {
        // Response header handling. Passes on ALL headers too
        curl_setopt($handle, CURLOPT_HEADERFUNCTION, 'bodyResponseHeaderProxy');
    }

    curl_exec($handle);

    if ($opts['endpoint'] == 'body') {
        ob_end_flush();
    }
}

function requestContentType() {
    $requestHeaders = getallheaders();

    foreach($requestHeaders as $key => $value) {
        if (strtolower($key) === 'content-type') {
            return $value;
        }
    }

    return null;
}

function apiResponseHeaderProxy($curl, $headerLine) {
    preg_match('/([^\r]+)/i', $headerLine, $matches);

    $proxyHeaders = array(
        'last-modified' => true,
        'etag' => true,
        'date' => true,
        'content-type' => true,
        'content-disposition' => true,
        'location' => true,
        'x-one-version' => true,
        'content-encoding' => true,
        'content-length' => true
    );

    // Gets all headers, also HTTP/1.1 statusCode statusMessage
    if (count($matches) === 2) {
        // Seems to be a header, pass it on if it's one of the allowed keys, or the 'HTTP/1.1 xyz' code

        // Suppress notice for referencing [1] when explode() on string without ':'
        @list($key, $value) = explode(':', $matches[1], 2);

        if ($key && $value) {
            if (array_key_exists(strtolower($key), $proxyHeaders)) {
                header($matches[1]);
            }
        } else {
            header($matches[1]);
        }
    }

    return strlen($headerLine);
}

function bodyResponseHeaderProxy($curl, $headerLine) {
    preg_match('/([^\r]+)/i', $headerLine, $matches);

    $proxyHeaders = array(
        'last-modified' => true,
        'date' => true,
        'location' => true,
        'x-one-version' => true
    );

    // Gets all headers, also HTTP/1.1 statusCode statusMessage
    if (count($matches) === 2) {
        // Seems to be a header, pass it on if it's one of the allowed keys, or the 'HTTP/1.1 xyz' code

        // Suppress notice for referencing [1] when explode() on string without ':'
        @list($key, $value) = explode(':', $matches[1], 2);

        if ($key && $value) {
            if (array_key_exists(strtolower($key), $proxyHeaders)) {
                header($matches[1]);
            }
        } else {
            header($matches[1]);
        }
    }

    return strlen($headerLine);
}

function proxyIfApiCall() {
    $host = getHost();

    if (isset($_SERVER['PATH_INFO'])) {
        $pathInfo = $_SERVER['PATH_INFO'];
    } else {
        $pathInfo = '/';
    }

    if (strpos($pathInfo, '/shop/') !== 0) {
        // Only proxy paths that start with /shop/ directly.
        return;
    }

    $handle = curl_init();

    // Request header handling. Just pass on ALL headers, but add X-Forwarded-For
    curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']);

    $requestHeadersArray = getallheaders();
    $requestHeadersArray = array_change_key_case($requestHeadersArray, CASE_LOWER);

    $requestHeadersArray['x-proxied-by'] = 'webshop-php-proxy';

    if (isset($_SERVER['HTTP_X_ONECOM_FORWARDED_IP']) && isset($_SERVER['HTTP_X_ONECOM_FORWARDED_PROTO'])) {
        $requestHeadersArray['x-forwarded-for'] = $_SERVER['HTTP_X_ONECOM_FORWARDED_IP'];
        $requestHeadersArray['x-forwarded-proto'] = $_SERVER['HTTP_X_ONECOM_FORWARDED_PROTO'];
    } else {
        unset($requestHeadersArray['x-forwarded-for']);
        unset($requestHeadersArray['x-forwarded-proto']);
    }

    $curlRequestHeaders = [];
    foreach($requestHeadersArray as $key => $val) {
        $curlRequestHeaders[] = "{$key}: {$val}";
    }
    curl_setopt($handle, CURLOPT_HTTPHEADER, $curlRequestHeaders);

    // Response header handling. Passes on ALL headers too
    curl_setopt($handle, CURLOPT_HEADERFUNCTION, 'apiResponseHeaderProxy');

    // Request body
    $data = file_get_contents('php://input');

    if (!empty($data)) {
        curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
    }

    // URL, just pass on pathInfo like nothing happened. Backend's responsibility to deny wrong requests
    $url = $host . $pathInfo . '?base=' . rawurlencode($_SERVER['SCRIPT_NAME']);
    if (count($_GET)) {
        $url .= '&' . http_build_query($_GET);
    }

    curl_setopt($handle, CURLOPT_URL, $url);

    // Response body
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($handle);

    echo $response;
    ob_end_flush();
    die;
}

proxyIfApiCall();