Skip to content

fix: 브라우저 확장 문서 URL 해석 및 응답 검증#437

Closed
postmelee wants to merge 8 commits into
edwardkim:develfrom
postmelee:contrib/fix-document-url-resolver
Closed

fix: 브라우저 확장 문서 URL 해석 및 응답 검증#437
postmelee wants to merge 8 commits into
edwardkim:develfrom
postmelee:contrib/fix-document-url-resolver

Conversation

@postmelee

@postmelee postmelee commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

개요

Refs #432

브라우저 확장에서 .hwp/.hwpx처럼 보이는 링크가 실제 문서 바이트가 아닌 HTML 미리보기/오류 페이지를 반환할 때, viewer가 이를 그대로 HWP 파서에 넘겨 CFB 오류로 표시하던 문제를 해결합니다.

이번 PR은 특정 GitHub wiki 링크만 rule-based로 처리하지 않고, 다음 두 계층으로 일반화했습니다.

  • 문서 URL 해석 계층: provider별 파일 상세/미리보기 URL을 실제 파일 바이트 URL로 변환
  • 원격 응답 검증 계층: WASM 파서 호출 전 실제 HWP/HWPX 바이트인지 확인

원인

GitHub wiki의 saved/pr360-edward.hwp 링크는 URL pathname만 보면 HWP 파일처럼 보이지만, 실제 링크 대상은 GitHub blob HTML 페이지입니다.

기존 viewer는 원격 응답의 content-type이나 파일 시그니처를 확인하지 않고 곧바로 wasm.loadDocument()에 넘겼기 때문에 HTML의 첫 바이트가 CFB 파서 오류로 노출되었습니다.

변경 사항

  • rhwp-shared/sw/document-url-resolver.js 추가
    • https://github.com/{owner}/{repo}/blob/{ref}/{path}.hwp[x]raw.githubusercontent.com URL로 변환
    • query 문자열에만 .hwp가 있는 위장 URL은 변환하지 않음
    • provider adapter 구조로 GitHub 외 서비스 확장 여지 확보
  • Chrome/Firefox 확장 viewer launcher에 resolver 적용
    • viewer url 파라미터가 실제 fetch 가능한 문서 URL을 받도록 변경
  • Chrome/Firefox thumbnail extractor에 resolver 적용
    • cache key는 원본 URL로 유지하고 fetch 대상만 resolved URL로 변경
  • rhwp-studio/src/main.tsloadFromUrlParam()에 원격 응답 바이트 검증 추가
    • HWP: CFB 시그니처 확인
    • HWPX: ZIP 시그니처 확인
    • HTML/오류 페이지는 파서 호출 전에 차단
  • HTML/미리보기 응답에는 기존 CFB 오류 대신 원인 중심 메시지를 표시

후속 확장 가능성

이번 PR의 핵심은 GitHub wiki 링크 하나를 예외 처리하는 것이 아니라, “링크 URL”과 “실제 파일 바이트 URL”이 다른 서비스를 provider adapter로 흡수할 수 있는 구조를 만든 것입니다.

따라서 이후 공공기관/교육청/지자체/전자문서 게시판처럼 HWP 링크가 다음 형태로 제공되는 사이트도 같은 계층에서 점진적으로 대응할 수 있습니다.

  • .hwp 링크가 실제로는 미리보기 HTML 페이지를 반환하는 경우
  • 다운로드 URL이 별도 download, file, attach, view endpoint 뒤에 숨어 있는 경우
  • redirect 후에야 실제 파일 URL이 결정되는 경우
  • 파일명은 HWP/HWPX이지만 오류/권한/안내 페이지가 200 OK로 반환되는 경우

새 사이트 대응 시에는 viewer나 thumbnail 호출부를 다시 분기하지 않고, document-url-resolver.js에 provider adapter와 테스트 케이스를 추가하는 방식으로 확장할 수 있습니다. 또한 resolver가 아직 모르는 사이트라도 응답 바이트 검증 계층이 HTML/오류 페이지를 파서에 넘기지 않으므로, 내부 CFB 오류 대신 원인 중심 오류를 표시할 수 있습니다.

사용자 영향

  • GitHub wiki/문서 페이지의 HWP 링크 카드에서 썸네일과 viewer 열기가 정상 동작합니다.
  • 실제 문서가 아닌 HTML 응답을 열 때 내부 파서 오류 대신 다음 메시지가 표시됩니다.
파일 로드 실패: 실제 HWP/HWPX 파일이 아닙니다. 파일 미리보기/오류 페이지가 반환되었습니다.

스크린샷

1. HTML/preview 응답 차단

CFB 파서 오류 대신 원인 중심 오류 메시지를 표시합니다.

test5

2. GitHub blob 페이지 hover 카드 썸네일

GitHub blob 페이지에서 pr360-edward.hwp hover 카드 썸네일이 정상 표시됩니다.

test3

3. wiki 카드에서 viewer 열기

wiki hover 카드의 rhwp로 열기 클릭 후 viewer에서 35페이지 문서가 정상 로드됩니다.

test4

4. 기존 raw/blob viewer 흐름 유지

기존 blob/raw 흐름에서도 pr360-edward.hwp 35페이지 로드가 유지됩니다.

test4

5. GitHub wiki hover 카드 썸네일

원래 실패하던 wiki 링크 카드에서도 썸네일이 정상 표시됩니다.

변경 전 변경 후
test test1

검증

  • node --test rhwp-shared/sw/document-url-resolver.test.js 통과 (12 tests)
  • node --test rhwp-shared/sw/download-interceptor-common.test.js 통과 (26 tests)
  • cd rhwp-firefox && npm run build 통과
  • cd rhwp-chrome && npm run build 통과
  • Firefox 확장 수동 검증 통과
    • GitHub wiki saved/pr360-edward.hwp hover 카드에서 문서 썸네일 표시
    • wiki hover 카드의 rhwp로 열기 클릭 시 viewer에서 pr360-edward.hwp 35페이지 로드
    • GitHub blob 원본 페이지 hover 카드에서도 썸네일 표시 유지
    • 기존 blob/raw viewer 흐름에서도 pr360-edward.hwp 35페이지 로드 유지
    • HTML/preview-page 응답은 기존 CFB 파서 오류 대신 원인 중심 오류 메시지 표시

메모

@edwardkim

Copy link
Copy Markdown
Owner

@postmelee 님 PR 감사드립니다. 코드 본질은 정상이고 메인테이너 dry-run 검증 게이트 모두 통과했습니다. 머지 전 한 가지 작은 보강 부탁드립니다.

검증 결과 (메인테이너 dry-run cherry-pick 후)

  • cargo test --lib: 1066 passed (회귀 0)
  • cargo test --test svg_snapshot: 6/6
  • cargo test --test issue_418: 1/1 (Task samples/hwpspec.hwp 20 페이지 이미지 이중 출력 (PR 처리 후 회귀) #418 보존)
  • cargo clippy --lib -D warnings: 0건
  • TypeScript 검증 (tsc --noEmit): 통과
  • Rust core 영향 0: devel baseline 과 SVG byte 단위 동일 (4,103,796 bytes) — 라이브러리 본체 변경 없는 정상 정황
  • document-url-resolver 단위 테스트 12건 모두 통과 (.mjs 로 실행 시)

보강 요청 — 자동 테스트 실행 가능 상태 정비

PR 본문에 "실행: node --test rhwp-shared/sw/document-url-resolver.test.js" 라고 명시해 주셨는데, 실제로 그 명령으로 실행하면 다음 에러가 발생합니다:

(node:XXXX) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
SyntaxError: Cannot use import statement outside a module

원인: rhwp-shared/package.json 이 없고, .test.js 확장자라서 Node 가 CommonJS 로 해석합니다. 코드는 ESM (import 사용) 인데 환경이 CJS 로 해석하니 충돌.

확장 (Chrome / Firefox SW) 런타임에서는 ESM 정상 동작이라 사용자 영향은 없습니다. 그러나 자동 테스트가 명령 한 번으로 실행되지 않으면 후속 컨트리뷰터가 회귀 검증을 누락할 위험 이 있습니다.

두 가지 선택지

선택지 1: rhwp-shared/package.json 신규 추가 (권장)

{
  "name": "rhwp-shared",
  "private": true,
  "type": "module"
}

장점: 향후 rhwp-shared/ 에 다른 ESM 모듈/테스트가 추가되어도 일괄 적용. PR 본문 명시한 실행 명령이 그대로 동작.

선택지 2: 테스트 파일을 .test.mjs 로 rename + import 경로도 .mjs 로 변경

mv rhwp-shared/sw/document-url-resolver.test.js rhwp-shared/sw/document-url-resolver.test.mjs
mv rhwp-shared/sw/document-url-resolver.js rhwp-shared/sw/document-url-resolver.mjs
# + 모든 import 경로 .mjs 로 갱신 (chrome/firefox sw/, viewer-launcher, thumbnail-extractor)

장점: package.json 추가 없이 가능. 단점: import 경로 갱신 범위가 크고 (5+ 파일) 확장 빌드 영향 가능성 점검 필요.

선택지 1 권장 — 변경 범위 최소 + 명확.

추가 검증

선택 후 다음 명령으로 통과 확인 부탁드립니다:

node --test rhwp-shared/sw/document-url-resolver.test.js
# 기대: 12 tests passed (제가 .mjs 확장자로 직접 실행 시 12개 모두 통과 확인했습니다)

본 PR 의 좋은 점 (참고)

  • 이슈 브라우저 확장: 실제 HWP/HWPX 응답 검증 및 파일 URL 해석 계층 도입 #432 의 본질 정확 식별 — "특정 GitHub wiki 링크 rule-based" 가 아닌 provider adapter 구조 로 일반화한 점이 좋습니다. 향후 공공기관/교육청 게시판 등 확장 가능
  • 두 계층 분리 (URL 해석 + 응답 검증) 가 깔끔합니다 — resolver 가 모르는 사이트도 응답 검증 계층이 HTML/오류 페이지 차단
  • 하이퍼-워터폴 절차 정확 준수 (계획서 + 4 stage + 보고서)
  • Rust core 영향 0 — 영향 범위 한정 명확

후속 정정 commit 추가하시면 즉시 머지 진행하겠습니다. 감사합니다.

edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_437_review.md (브라우저 확장 URL 해석/검증, dry-run cherry-pick + 검증 게이트 통과 + ESM 정황 발견)
- mydocs/orders/20260429.md (PR #437 작성자 보강 대기 + v0.7.8 릴리즈 + Discussion #438 행 추가)

핵심: 코드 본질 정상 + 12 단위 테스트 통과 (.mjs 실행 시) + Rust core 영향 0
정황: PR 본문 명시 자동 테스트 명령이 rhwp-shared/package.json 부재로 실행 불가
요청: rhwp-shared/package.json 추가 ("type": "module") 권장 (선택지 1)
PR #437 OPEN 유지, 작성자 재제출 대기
@postmelee

Copy link
Copy Markdown
Collaborator Author

@edwardkim 검토와 dry-run 확인 감사합니다.

요청 주신 권장안대로 rhwp-shared/package.json을 추가해 rhwp-shared를 ESM package로 명시했습니다.

추가 커밋:

  • 2b06a41 fix: declare rhwp-shared as ESM package

재검증 결과:

node --test rhwp-shared/sw/document-url-resolver.test.js
  • 12 tests passed
  • 기존 ESM 재해석 warning 없이 실행 확인
node --test rhwp-shared/sw/download-interceptor-common.test.js
  • 26 tests passed
cd rhwp-firefox && npm run build
cd rhwp-chrome && npm run build
  • 둘 다 통과했습니다.

edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_437_report.md (작성자 후속 정정 commit 1건 추가 흡수, 자동 테스트 38건 통과)
- mydocs/orders/20260429.md (PR #437 완료 행으로 갱신)

작성자 신속 응답:
- 1차 검토 후 17분 만에 권장안 정확 채택 (rhwp-shared/package.json 신규)
- 보너스 효과: ESM 선언으로 download-interceptor-common.test.js (26 tests) 도 정상화

검증: 1066 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0
+ document-url-resolver 12 + download-interceptor-common 26 + Rust core byte 동일
@edwardkim

Copy link
Copy Markdown
Owner

@postmelee 님 빠른 정정 감사합니다. 메인테이너가 cherry-pick 으로 devel 에 적용 완료했습니다.

처리

작성자 attribution 보존 6 commits cherry-pick (5 본질 + 1 후속 정정):

devel 머지 commit: 30351cd

재검증 (메인테이너)

보너스 효과

ESM 패키지 선언으로 download-interceptor-common.test.js (26 tests) 도 자동 실행 가능 상태가 되었습니다 — 본 정정의 범위가 후속 컨트리뷰터의 자동 회귀 검증 환경 전반을 정비한 효과입니다.

본 PR 의 좋은 점

  • 이슈 본질 정확 식별 — provider adapter 구조 일반화 (특정 wiki rule-based 회피)
  • 두 계층 분리 — URL 해석 + 응답 검증 (resolver 가 모르는 사이트도 검증 계층이 차단)
  • 하이퍼-워터폴 절차 정확 준수 (계획서 + 4 stage + 보고서)
  • 신속한 정정 응답 — 1차 검토 후 17분 만에 권장안 정확 채택 + 자체 재검증 보고

이슈 #432 도 함께 close 됩니다. 감사합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants