Summary#
ililtoon source adapter는 단순히 episode HTML에서 <img> URL을 긁어 저장하는 구조로 두면 쉽게 깨진다. 이미지 URL이 단기 토큰, 세션 쿠키, Referer/Origin 검사, CDN query parameter, lazy-load 속성, redirect, 또는 재발급 흐름에 묶여 있을 수 있기 때문이다. 따라서 adapter의 핵심은 “이미지 URL 문자열”을 영구 식별자로 취급하지 않고, episode manifest, request contract, resolution trace, recollection policy를 분리하는 것이다.
권장 초안 구조는 다음과 같다.
series_manifest
└─ episode_manifest
├─ episode_identity
├─ page_slots[]
│ ├─ page_index
│ ├─ observed_image_ref
│ ├─ resolved_image_url
│ ├─ request_contract_id
│ ├─ content_fingerprint
│ └─ collection_status
├─ session_contract
├─ referer_contract
├─ token_resolution_trace
└─ recollection_policy
이 구조는 tokenized image URL이 만료되거나 CDN path가 바뀌어도, episode/page 단위 manifest를 기준으로 부분 재수집과 검증을 수행할 수 있게 한다. 다만 공개 웹 실측 없이 특정 ililtoon의 실제 URL 규칙, 토큰 생성 방식, 쿠키 요구사항, hotlink 보호 동작을 단정하면 안 된다.
Key Points#
- 이미지 URL은 영구 자산 ID가 아니라 관측값이다.
- CDN 이미지 URL에 query token, signed URL, expiring parameter, cache-busting parameter가 포함될 수 있다.
- 따라서
resolved_image_url은 manifest에 저장하되 canonical page identity로 쓰지 않는다. - 안정적인 page key는 다음처럼 별도 구성한다.
page_key = site_scope
+ series_key
+ episode_key
+ page_index
+ optional_content_fingerprint
- tokenized image URL resolution은 별도 단계로 분리한다.
- episode HTML 또는 viewer JSON에서 발견한 값은
observed_image_ref로 저장한다. - 실제 다운로드 가능한 URL은 adapter의 resolver가 만든
resolved_image_url로 저장한다. - resolver는 URL 생성/redirect/final URL/HTTP status/content-type/content-length를 trace로 남긴다.
resolution_trace:
observed_ref: "..."
resolution_method: "html_attr | lazy_attr | inline_json | api_payload | redirect"
resolved_url: "..."
final_url: "..."
status: 200
content_type: "image/webp | image/jpeg | image/png"
resolved_at: "timestamp"
expires_hint: "unknown | short_lived | session_bound"
- Referer/session hotlink contract는 adapter 설정으로 명시한다.
- 이미지 요청이 episode page의
Referer를 요구할 수 있으므로, 헤더를 우발적으로 전역 적용하지 말고 source별 contract로 표현한다. - 쿠키가 필요한 경우도 “브라우저 세션에서 관측된 합법적 요청을 재현하는 범위”로 제한해야 한다.
- token이나 세션 검사를 우회·무력화하는 방식은 adapter 설계 범위에 넣지 않는다.
request_contract:
id: "ililtoon-image-v1"
scope: "episode_image"
required_headers:
referer: "episode_effective_url"
user_agent: "collector_browser_profile"
credentials:
mode: "same-origin/session-observed"
cookie_policy: "do-not-log-secret-values"
retry_policy:
on_403: "refresh_episode_page_then_resolve_again"
on_404: "mark_stale_url"
on_429: "backoff"
- manifest-driven recollection이 필요하다.
- 수집 중 일부 이미지만 실패하거나, URL token이 만료되거나, viewer script가 바뀌면 전체 series를 다시 긁는 대신 manifest를 기준으로 누락분만 재수집한다.
- 각 page slot에 상태를 둔다.
collection_status:
state: "pending | resolved | fetched | verified | stale | failed"
attempts: 2
last_error: "403_hotlink_or_expired_token"
next_action: "refresh_manifest_and_resolve"
- 부분 재수집 정책은 URL이 아니라 slot 기준으로 동작해야 한다.
page_index=12가 실패했으면 이전에 저장된 URL을 다시 요청하는 것이 아니라, episode page/viewer manifest를 다시 읽고 12번 slot을 재해석한다.-
이렇게 해야 signed URL rotation, CDN host migration, 이미지 포맷 변경에 대응할 수 있다.
-
content fingerprint는 보조 검증 신호로만 사용한다.
- 이미지 bytes hash, perceptual hash, width/height, content-length, MIME type을 저장하면 drift 감지에 도움이 된다.
-
하지만 재압축, webp 변환, watermark 변경, crop 변경으로 hash가 달라질 수 있으므로 단독 identity로 쓰면 위험하다.
-
adapter boundary를 분리한다.
IliltoonSourceAdapter
discover_series()
list_episodes(series)
load_episode_manifest(episode)
resolve_page_images(manifest, session_contract)
fetch_page_image(page_slot, request_contract)
verify_page_image(page_slot, bytes)
plan_recollection(manifest, failures)
- 실패 모드는 명시적으로 분류한다.
failure_modes:
- expired_token
- missing_referer
- missing_session_cookie
- viewer_schema_changed
- lazy_load_not_triggered
- cdn_redirect_changed
- partial_episode_update
- duplicate_page_slot
- page_count_mismatch
- rate_limited
- 보안/프라이버시 로그 정책이 필요하다.
- signed URL, cookie, auth-like token, session identifier는 원문 로그에 남기지 않는다.
- manifest에는 token 값 전체 대신 redacted URL 또는 hash를 저장한다.
redaction:
query_params:
- token
- expires
- signature
- key
cookies: "never_persist_raw"
Cautions#
- 이 실행 환경에는 사용자가 지정한
WebSearch/WebFetch도구가 제공되지 않았다. 따라서 이 초안은 실시간 공개 웹 검색으로ililtoon의 현재 HTML, CDN, cookie, referer 동작을 검증한 결과가 아니다. - 특정
ililtoonURL 패턴, token parameter 이름, 실제 CDN host, session cookie 이름, viewer API endpoint는 확인하지 않았다. 모두 후속 공개 웹 검증 전까지 미확정으로 취급해야 한다. - hotlink protection, signed URL, 세션 검사는 콘텐츠 제공자가 접근 범위를 통제하기 위한 장치일 수 있다. 이 capsule은 우회 방법이 아니라, 합법적·허가된 수집기에서 관측된 요청 계약을 명시적으로 모델링하는 architecture 초안으로 제한한다.
Referer헤더나 cookie를 재현하는 설계는 사이트 약관, 저작권, robots 정책, 접근 권한, 지역 법규와 충돌할 수 있다. 실제 구현 전 법적·윤리적 검토가 필요하다.- 이미지 URL token이 만료되는지, session-bound인지, 단순 cache-busting인지 공개 검증 없이 단정하면 안 된다.
- manifest-driven recollection은 안정성을 높이지만, 대상 사이트가 빈번히 구조를 바꾸거나 anti-automation 정책을 두는 경우 실패할 수 있다.
- content fingerprint는 drift 탐지에 유용하지만, 재압축·포맷 변환·워터마크 변경으로 false positive/false negative가 생길 수 있다.
- private capsule로 저장할 때도 cookie, token, signed URL 원문을 포함하지 않는 redaction 정책이 필요하다.
Sources#
- https://www.rfc-editor.org/rfc/rfc9110
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429
- https://www.rfc-editor.org/rfc/rfc3986
Related#
Sagwan Revalidation 2026-07-19T04:43:20Z#
- verdict:
ok - note: 특정 실측 단정 없이 URL 토큰·세션 분리 원칙은 여전히 유효함
Sagwan Revalidation 2026-07-21T05:55:42Z#
- verdict:
ok - note: 특정 수치보다 일반 설계 원칙이라 현재 practice와 충돌 없음