<?php
/**
 * 图片代理脚本 - 带流量限制、白名单校验、简易缓存
 * 兼容 PHP 7.0+
 * 使用方法：proxy.php?url=http://img.zuanke8.cn/forum/xxx.jpg
 */

// ==================== 配置区域 ====================

$maxMonthlyTraffic = 500 * 1024 * 1024 * 1024; // 500GB
$trafficFile = __DIR__ . '/proxy_traffic.log';
$cacheDir = __DIR__ . '/proxy_cache';
$cacheExpire = 7 * 24 * 60 * 60; // 7天

$allowedDomains = [
    'img.zuanke8.cn',
    'www.zuanke8.cn',
    'cdn.zuanke8.cn',
    'img2.doubanio.com',
    'img3.doubanio.com',
    'img4.doubanio.com',
    'img1.doubanio.com',
];

// ==================== 辅助函数（兼容 PHP 7.x） ====================

/**
 * 判断字符串结尾（替代 str_ends_with，兼容 PHP 7.x）
 */
function strEndsWith($haystack, $needle) {
    $length = strlen($needle);
    if ($length === 0) return true;
    return substr($haystack, -$length) === $needle;
}

/**
 * 通过扩展名获取 MIME 类型（替代 mime_content_type，无需 fileinfo 扩展）
 */
function getMimeType($filePath) {
    $ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
    $map = [
        'jpg'  => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'png'  => 'image/png',
        'gif'  => 'image/gif',
        'webp' => 'image/webp',
        'bmp'  => 'image/bmp',
        'svg'  => 'image/svg+xml',
        'ico'  => 'image/x-icon',
    ];
    return isset($map[$ext]) ? $map[$ext] : 'image/jpeg';
}

// ==================== 初始化 ====================

if (!is_dir($cacheDir)) {
    mkdir($cacheDir, 0755, true);
}

$currentMonth = date('Y-m');

// ==================== 流量检查 ====================

$usedTraffic = 0;
if (file_exists($trafficFile)) {
    $data = file_get_contents($trafficFile);
    $record = json_decode($data, true);
    if ($record && isset($record['month']) && $record['month'] === $currentMonth) {
        $usedTraffic = $record['traffic'];
    }
}

if ($usedTraffic >= $maxMonthlyTraffic) {
    header('HTTP/1.1 509 Bandwidth Limit Exceeded');
    header('Content-Type: image/jpeg');
    exit('Monthly traffic limit exceeded.');
}

// ==================== URL 校验 ====================

$url = isset($_GET['url']) ? $_GET['url'] : '';
if (!$url) {
    header('HTTP/1.1 400 Bad Request');
    exit('Missing URL parameter.');
}

$urlParts = parse_url($url);
if (!isset($urlParts['host'])) {
    header('HTTP/1.1 400 Bad Request');
    exit('Invalid URL.');
}

$host = $urlParts['host'];

$isAllowed = false;
foreach ($allowedDomains as $allowedDomain) {
    if ($host === $allowedDomain || strEndsWith($host, '.' . $allowedDomain)) {
        $isAllowed = true;
        break;
    }
}

if (!$isAllowed) {
    header('HTTP/1.1 403 Forbidden');
    exit('Domain not in whitelist.');
}

// ==================== 缓存检查 ====================

$cacheKey = md5($url);
$cacheFile = null;

// 查找已存在的缓存文件（可能有不同扩展名）
$extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'ico'];
foreach ($extensions as $ext) {
    $testFile = $cacheDir . '/' . $cacheKey . '.' . $ext;
    if (file_exists($testFile) && (time() - filemtime($testFile)) < $cacheExpire) {
        $cacheFile = $testFile;
        break;
    }
}

if ($cacheFile !== null) {
    $imageData = file_get_contents($cacheFile);
    $imageSize = strlen($imageData);

    $newTraffic = $usedTraffic + $imageSize;
    file_put_contents($trafficFile, json_encode([
        'month'   => $currentMonth,
        'traffic' => $newTraffic,
    ]));

    header('Content-Type: ' . getMimeType($cacheFile));
    header('Content-Length: ' . $imageSize);
    echo $imageData;
    exit;
}

// ==================== 拉取远程图片 ====================

// 根据目标域名动态设置 Referer
$refererMap = [
    'img.zuanke8.cn'     => 'https://www.zuanke8.com/',
    'www.zuanke8.cn'     => 'https://www.zuanke8.com/',
    'cdn.zuanke8.cn'     => 'https://www.zuanke8.com/',
    'img2.doubanio.com'  => 'https://www.douban.com/',
    'img3.doubanio.com'  => 'https://www.douban.com/',
    'img4.doubanio.com'  => 'https://www.douban.com/',
    'img1.doubanio.com'  => 'https://www.douban.com/',
];

// 获取对应的 Referer
$referer = isset($refererMap[$host]) ? $refererMap[$host] : '';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// 设置请求头，Referer 动态赋值
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Referer: ' . $referer,
    'Accept: image/webp,image/apng,image/*,*/*;q=0.8',
    'Accept-Language: zh-CN,zh;q=0.9',
]);

$imageData = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);

if ($httpCode !== 200 || !$imageData) {
    header('HTTP/1.1 404 Not Found');
    exit('Image not found.');
}

// ==================== 写入缓存（带扩展名） ====================

$extMap = [
    'image/jpeg' => 'jpg',
    'image/png'  => 'png',
    'image/gif'  => 'gif',
    'image/webp' => 'webp',
    'image/bmp'  => 'bmp',
    'image/svg+xml' => 'svg',
    'image/x-icon' => 'ico',
];
$ext = isset($extMap[$contentType]) ? $extMap[$contentType] : 'jpg';
$cacheFile = $cacheDir . '/' . $cacheKey . '.' . $ext;
file_put_contents($cacheFile, $imageData);

// ==================== 更新流量 ====================

$imageSize = strlen($imageData);
$newTraffic = $usedTraffic + $imageSize;
file_put_contents($trafficFile, json_encode([
    'month'   => $currentMonth,
    'traffic' => $newTraffic,
]));

// ==================== 输出图片 ====================

header('Content-Type: ' . $contentType);
header('Content-Length: ' . $imageSize);
echo $imageData;
