wpbridge/includes/Performance/ConditionalRequest.php
feibisi 546304fb4a feat: WPBridge v0.2.0 - 完整插件实现
v0.1.0 核心功能:
- 更新源管理 (SourceManager, SourceModel, SourceType)
- 插件/主题更新器 (PluginUpdater, ThemeUpdater)
- 缓存系统 (CacheManager, HealthChecker, FallbackStrategy)
- 安全模块 (Validator, Encryption)
- 管理界面 (AdminPage, templates, CSS, JS)
- 预设源支持 (ArkPress, AspireCloud)

v0.2.0 新增功能:
- 性能优化 (ParallelRequestManager, RequestDeduplicator)
- 条件请求 (ConditionalRequest - ETag/Last-Modified)
- 后台更新 (BackgroundUpdater - WP-Cron)
- Git 平台支持 (GitHub, GitLab, Gitee handlers)
- WP-CLI 命令 (wp bridge source/check/cache/diagnose/config)

安全修复:
- SQL 注入防护 ($wpdb->prepare)
- GET 参数清理 (sanitize_text_field)
- auth_token 加密存储 (AES-256-CBC)
- 缓存键哈希 (md5 + site_url)
- 卸载清理 (uninstall.php)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:52:27 +08:00

160 lines
3.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 条件请求处理器
*
* @package WPBridge
*/
namespace WPBridge\Performance;
use WPBridge\Cache\CacheManager;
use WPBridge\Core\Logger;
// 防止直接访问
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 条件请求处理器类
* 使用 ETag 和 Last-Modified 减少数据传输
*/
class ConditionalRequest {
/**
* 缓存管理器
*
* @var CacheManager
*/
private CacheManager $cache;
/**
* 缓存前缀
*
* @var string
*/
const CACHE_PREFIX = 'conditional_';
/**
* 构造函数
*/
public function __construct() {
$this->cache = new CacheManager();
}
/**
* 构建条件请求头
*
* @param string $source_id 源 ID
* @return array
*/
public function build_headers( string $source_id ): array {
$cached = $this->get_cached_metadata( $source_id );
$headers = [];
if ( ! empty( $cached['etag'] ) ) {
$headers['If-None-Match'] = $cached['etag'];
}
if ( ! empty( $cached['last_modified'] ) ) {
$headers['If-Modified-Since'] = $cached['last_modified'];
}
return $headers;
}
/**
* 处理响应
*
* @param string $source_id 源 ID
* @param array $response 响应数据
* @param array $headers 响应头
* @return array|null 处理后的数据304 时返回缓存数据
*/
public function process_response( string $source_id, ?array $response, array $headers ): ?array {
// 保存元数据
$metadata = [];
if ( ! empty( $headers['etag'] ) ) {
$metadata['etag'] = $headers['etag'];
}
if ( ! empty( $headers['last-modified'] ) ) {
$metadata['last_modified'] = $headers['last-modified'];
}
if ( ! empty( $metadata ) ) {
$this->save_metadata( $source_id, $metadata );
}
// 如果有新数据,缓存并返回
if ( null !== $response ) {
$this->save_cached_data( $source_id, $response );
return $response;
}
// 返回缓存数据
return $this->get_cached_data( $source_id );
}
/**
* 处理 304 响应
*
* @param string $source_id 源 ID
* @return array|null 缓存的数据
*/
public function handle_not_modified( string $source_id ): ?array {
Logger::debug( '304 Not Modified', [ 'source' => $source_id ] );
return $this->get_cached_data( $source_id );
}
/**
* 获取缓存的元数据
*
* @param string $source_id 源 ID
* @return array
*/
private function get_cached_metadata( string $source_id ): array {
$cached = $this->cache->get( self::CACHE_PREFIX . 'meta_' . $source_id );
return is_array( $cached ) ? $cached : [];
}
/**
* 保存元数据
*
* @param string $source_id 源 ID
* @param array $metadata 元数据
*/
private function save_metadata( string $source_id, array $metadata ): void {
$this->cache->set(
self::CACHE_PREFIX . 'meta_' . $source_id,
$metadata,
WEEK_IN_SECONDS
);
}
/**
* 获取缓存的数据
*
* @param string $source_id 源 ID
* @return array|null
*/
private function get_cached_data( string $source_id ): ?array {
$cached = $this->cache->get( self::CACHE_PREFIX . 'data_' . $source_id );
return is_array( $cached ) ? $cached : null;
}
/**
* 保存缓存数据
*
* @param string $source_id 源 ID
* @param array $data 数据
*/
private function save_cached_data( string $source_id, array $data ): void {
$this->cache->set(
self::CACHE_PREFIX . 'data_' . $source_id,
$data,
DAY_IN_SECONDS
);
}
}