|
| 1 | +// 다운로드 인터셉터 공통 판정 로직 (Chrome / Firefox 공용) |
| 2 | +// |
| 3 | +// Chrome(onDeterminingFilename)·Firefox(onCreated/onChanged) 모두 동일한 |
| 4 | +// 판정 기준을 사용하도록 추출한 순수 함수. 브라우저 API에 의존하지 않아 |
| 5 | +// 단위 테스트 가능. |
| 6 | +// |
| 7 | +// 원본: rhwp-shared/sw/download-interceptor-common.js |
| 8 | +// 참조: rhwp-chrome/sw/download-interceptor-common.js (symlink) |
| 9 | +// rhwp-firefox/sw/download-interceptor-common.js (symlink) |
| 10 | +// |
| 11 | +// 관련 이슈: |
| 12 | +// - #198: Chrome 마지막 저장 위치 보존 + DEXT5 블랙리스트 + MIME 힌트 |
| 13 | +// - #207: 동일 판정 로직을 Firefox 측에도 적용 |
| 14 | + |
| 15 | +/** filename 또는 URL 에서 .hwp/.hwpx 확장자를 감지 (쿼리 문자열 허용). */ |
| 16 | +export const HWP_EXTENSION_RE = /\.(hwp|hwpx)(\?|$)/i; |
| 17 | + |
| 18 | +/** 한컴 HWP/HWPX MIME 타입 힌트 (소문자 비교). */ |
| 19 | +export const HWP_MIME_HINTS = ['haansoft', 'x-hwp', 'hwp+zip']; |
| 20 | + |
| 21 | +/** |
| 22 | + * 재요청 불가 다운로드 패턴 (#198). |
| 23 | + * |
| 24 | + * POST 요청 / 세션 토큰 의존 핸들러는 rhwp 뷰어가 url 을 GET 으로 다시 받지 못해 |
| 25 | + * 빈 응답/에러 발생 → 인터셉트 포기 (브라우저 기본 다운로드만 진행). |
| 26 | + * |
| 27 | + * 블랙리스트 방식. 사용자 보고로 새 패턴이 들어오면 본 배열에 추가. |
| 28 | + */ |
| 29 | +export const NON_REFETCHABLE_PATTERNS = [ |
| 30 | + /\/dext5handler\.[a-z0-9]+/i, // DEXT5 (예: dext5handler.ndo, .jsp, .do) |
| 31 | +]; |
| 32 | + |
| 33 | +/** |
| 34 | + * 다운로드 항목이 HWP/HWPX 인지 판별 (#198 / #207). |
| 35 | + * |
| 36 | + * filename / url / finalUrl / mime / referrer 어느 조합이든 수용. |
| 37 | + * Chrome `chrome.downloads.DownloadItem` 과 Firefox `browser.downloads.DownloadItem` |
| 38 | + * 모두 대응 (필드 부재 시 안전하게 false 반환). |
| 39 | + * |
| 40 | + * @param {{filename?: string, url?: string, finalUrl?: string, mime?: string, referrer?: string}} item |
| 41 | + * @returns {boolean} |
| 42 | + */ |
| 43 | +export function shouldInterceptDownload(item) { |
| 44 | + if (!item) return false; |
| 45 | + |
| 46 | + // 재요청 불가 패턴 (POST / 세션 의존 핸들러) |
| 47 | + const url = item.url || ''; |
| 48 | + const referrer = item.referrer || ''; |
| 49 | + if (NON_REFETCHABLE_PATTERNS.some(re => re.test(url) || re.test(referrer))) { |
| 50 | + return false; |
| 51 | + } |
| 52 | + |
| 53 | + const filename = item.filename || ''; |
| 54 | + if (HWP_EXTENSION_RE.test(filename)) return true; |
| 55 | + |
| 56 | + if (HWP_EXTENSION_RE.test(url)) return true; |
| 57 | + |
| 58 | + const finalUrl = item.finalUrl || ''; |
| 59 | + if (finalUrl !== url && HWP_EXTENSION_RE.test(finalUrl)) return true; |
| 60 | + |
| 61 | + const mime = (item.mime || '').toLowerCase(); |
| 62 | + if (HWP_MIME_HINTS.some(hint => mime.includes(hint))) return true; |
| 63 | + |
| 64 | + return false; |
| 65 | +} |
0 commit comments