브라우저가 조용히 놓아버린 파일
관리하는 자산 브라우저 앱에는 이미지 카드를 브라우저 밖 데스크톱으로 그대로 끌어다 놓는 기능이 있었다. 어느 시점부터 그게 안 됐다. “예전엔 됐는데”는 버그 리포트로서는 가장 쓸모없는 축에 든다 — 증상과 확신은 담고 있지만 원인에 대해서는 아무것도 말해주지 않는다.
부러진 순간을 찾다
저장소 이력을 훑으니 정확한 커밋이 나왔다. 며칠 전 어떤 변경이 이미지 엘리먼트의 기본 드래그 동작을 꺼두면서, 컨테이너 쪽에서 그 역할을 대신 맡을 것이라는 주석을 남겼다. 그런데 그 컨테이너 구현은 실제로 작성된 적이 없었다. 사용자의 “예전엔 됐다”는 기억은 정확했다 — 기본 <img> 드래그로 잘 되고 있던 것을, 그 한 줄이 조용히 꺼버리고 아무것도 대신 채우지 않았다.
다시 만들었는데도 계속 막혔다
컨테이너 수준에서 드래그를 다시 구현했다 — 드래그가 시작될 때 데스크톱으로 내보내기용 다운로드 참조, 웹 간 드롭을 위한 실제 파일 객체, 그리고 텍스트 폴백까지 데이터 전송 객체에 채워 넣는 방식이다. 드래그 시작 이벤트는 동기적으로 일어나고 이미지 데이터는 서버에 있으므로, 사용자가 카드를 집기 전에 파일을 미리 받아둬야 했다 — 카드에 마우스를 올리거나 누르는 순간 미리 가져오기 시작하는 방식으로 처리했다.
그런데도 웹페이지에서 웹페이지로의 드래그는 여전히 실패했다. 이걸 확인하려고 진단 페이지를 따로 만들었다 — 한쪽엔 앱 본체, 다른 쪽엔 드롭존과 복사 확인용 대조군 타일을 나란히 놓았다. 앱과 무관한 대조군 타일까지 똑같이 실패하는 걸 보고서야 이게 앱의 버그가 아니라 브라우저 자체의 한계라는 게 드러났다. 드래그가 시작되는 시점에는 파일이 1개 있다고 보고되는데, 도착 시점에는 텍스트와 내부 드래그 ID만 남아 있었다 — 크롬이 blob 기반으로 합성한 파일을 옮기는 도중에 버리고 있었다.
다른 경로에서 열린 문
같은 조사 과정에서 클립보드 복사 경로 하나가 열렸다. http://mpro:포트처럼 IP나 호스트명으로 접속하면 보안 컨텍스트가 아니라서 클립보드 API 자체가 존재하지 않았다. 반면 http://localhost:포트는 크롬이 신뢰할 수 있는 출처로 취급해 API가 열렸다. 이미 서버 설정에 localhost 접속 경로가 포함돼 있어서, 인증서나 설정을 바꾸지 않고도 이 경로로 이미지 복사 기능을 붙일 수 있었다. 구식 복사 방식(execCommand)도 시도해봤지만 http 환경에서는 성공을 반환해도 실제로는 이미지가 아니라 링크 텍스트만 클립보드에 실렸다 — 웹페이지 간 드래그는 막혀 있어도, 파인더로 직접 끌어다 놓는 경로와 클립보드 복사 경로는 살아 있었다.