import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import '../../../core/network/network_client.dart'; import '../../../core/network/network_config.dart'; import '../../../core/errors/network_exceptions.dart'; /// 네이버 프록시 클라이언트 /// /// 웹 환경에서 CORS 문제를 해결하기 위한 프록시 클라이언트입니다. class NaverProxyClient { final NetworkClient _networkClient; NaverProxyClient({NetworkClient? networkClient}) : _networkClient = networkClient ?? NetworkClient(); /// 웹 환경에서 프록시를 통해 HTML 가져오기 Future fetchViaProxy(String url) async { if (!kIsWeb) { throw UnsupportedError('프록시는 웹 환경에서만 사용 가능합니다'); } try { final proxyUrl = NetworkConfig.getCorsProxyUrl(url); debugPrint('Using proxy URL: $proxyUrl'); final response = await _networkClient.get( proxyUrl, options: Options( responseType: ResponseType.plain, headers: { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'ko-KR,ko;q=0.9,en;q=0.8', }, ), ); if (response.data == null || response.data!.isEmpty) { throw ParseException(message: '프록시 응답이 비어있습니다'); } return response.data!; } on DioException catch (e) { debugPrint('Proxy fetch error: ${e.message}'); debugPrint('Status code: ${e.response?.statusCode}'); debugPrint('Response: ${e.response?.data}'); if (e.response?.statusCode == 403) { throw ServerException( message: 'CORS 프록시 접근이 거부되었습니다. 잠시 후 다시 시도해주세요.', statusCode: 403, originalError: e, ); } throw ServerException( message: '프록시를 통한 페이지 로드에 실패했습니다', statusCode: e.response?.statusCode ?? 500, originalError: e, ); } } /// 프록시 상태 확인 Future checkProxyStatus() async { if (!kIsWeb) { return true; // 웹이 아니면 프록시 불필요 } try { final testUrl = 'https://map.naver.com'; final proxyUrl = NetworkConfig.getCorsProxyUrl(testUrl); final response = await _networkClient.head( proxyUrl, options: Options(validateStatus: (status) => status! < 500), ); return response.statusCode == 200; } catch (e) { debugPrint('Proxy status check failed: $e'); return false; } } /// 프록시 URL 생성 String getProxyUrl(String originalUrl) { if (!kIsWeb) { return originalUrl; } return NetworkConfig.getCorsProxyUrl(originalUrl); } void dispose() { // 필요시 리소스 정리 } }