1- // 다운로드 가로채기
1+ // 다운로드 가로채기 (Chrome)
22// - .hwp/.hwpx 다운로드 감지 → 뷰어로 열기
33// - 사용자 설정(autoOpen)에 따라 동작
44//
55// #198 (chrome-fd-001): HWP 가 아닌 일반 파일 다운로드에는 suggest() 를 호출하지 않아
66// Chrome 의 마지막 저장 위치 기억 동작을 보존한다.
7+ // #207: 판정 로직은 rhwp-shared/sw/download-interceptor-common.js 와 공유.
78
89import { openViewer } from './viewer-launcher.js' ;
9-
10- /** filename 또는 URL 에서 .hwp/.hwpx 확장자를 감지 (쿼리 문자열 허용). */
11- const HWP_EXTENSION_RE = / \. ( h w p | h w p x ) ( \? | $ ) / i;
12-
13- /** 한컴 HWP/HWPX MIME 타입 힌트 (소문자 비교). */
14- const HWP_MIME_HINTS = [ 'haansoft' , 'x-hwp' , 'hwp+zip' ] ;
15-
16- /**
17- * 재요청 불가 다운로드 패턴 (#198).
18- *
19- * Chrome `chrome.downloads.DownloadItem` 에는 HTTP method 필드가 없어 POST 직접 감지 불가.
20- * 대신 url / referrer 의 알려진 핸들러 패턴으로 추정한다.
21- *
22- * 이런 다운로드는:
23- * - rhwp 뷰어가 url 을 GET 으로 재요청해도 빈 응답/에러 반환 (POST 전용)
24- * - 토큰/세션 만료 가능
25- * → 인터셉트 포기 (Chrome 기본 다운로드만 진행, 빈 뷰어 탭 안 띄움)
26- *
27- * 블랙리스트 방식으로 운영. 사용자 보고로 새 패턴이 들어오면 본 배열에 추가.
28- */
29- const NON_REFETCHABLE_PATTERNS = [
30- / \/ d e x t 5 h a n d l e r \. [ a - z 0 - 9 ] + / i, // DEXT5 (예: dext5handler.ndo, .jsp, .do)
31- ] ;
32-
33- /**
34- * 다운로드 항목이 HWP/HWPX 인지 판별 (#198).
35- *
36- * filename / url / finalUrl / mime 어느 하나라도 매치되면 true.
37- * Chrome API 와 무관한 순수 함수 — 단위 테스트 가능.
38- *
39- * @param {{filename?: string, url?: string, finalUrl?: string, mime?: string} } item
40- * @returns {boolean }
41- */
42- export function shouldInterceptDownload ( item ) {
43- if ( ! item ) return false ;
44-
45- // 재요청 불가 패턴 (POST / 세션 의존 핸들러) — 뷰어가 GET 으로 다시 받지 못함
46- // → 인터셉트 포기 (Chrome 기본 다운로드만 진행, 빈 뷰어 탭 안 띄움)
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- }
10+ import { shouldInterceptDownload } from './download-interceptor-common.js' ;
6611
6712/**
6813 * 다운로드 인터셉터를 설정한다.
6914 *
70- * #198 변경:
7115 * - HWP/HWPX 다운로드: handleHwpDownload + suggest 호출 (자체 뷰어 트리거)
72- * - 일반 파일: suggest 호출 안 함 → Chrome 의 마지막 저장 위치 기억 동작 유지
16+ * - 일반 파일: suggest 호출 안 함 → Chrome 의 마지막 저장 위치 기억 동작 유지 (#198)
7317 */
7418export function setupDownloadInterceptor ( ) {
7519 chrome . downloads . onDeterminingFilename . addListener ( ( item , suggest ) => {
@@ -84,18 +28,17 @@ export function setupDownloadInterceptor() {
8428async function handleHwpDownload ( item ) {
8529 try {
8630 const settings = await chrome . storage . sync . get ( { autoOpen : true } ) ;
31+ if ( ! settings . autoOpen ) return ;
8732
88- if ( settings . autoOpen ) {
89- // 대용량 파일 경고 (50MB 초과)
90- if ( item . fileSize > 50 * 1024 * 1024 ) {
91- console . warn ( `[rhwp] 대용량 파일: ${ item . filename } (${ ( item . fileSize / 1024 / 1024 ) . toFixed ( 1 ) } MB)` ) ;
92- }
93-
94- openViewer ( {
95- url : item . url ,
96- filename : item . filename
97- } ) ;
33+ // 대용량 파일 경고 (50MB 초과)
34+ if ( item . fileSize > 50 * 1024 * 1024 ) {
35+ console . warn ( `[rhwp] 대용량 파일: ${ item . filename } (${ ( item . fileSize / 1024 / 1024 ) . toFixed ( 1 ) } MB)` ) ;
9836 }
37+
38+ openViewer ( {
39+ url : item . url ,
40+ filename : item . filename ,
41+ } ) ;
9942 } catch ( err ) {
10043 console . error ( '[rhwp] 다운로드 인터셉터 오류:' , err ) ;
10144 }
0 commit comments