
솔직히 말해봅시다.
이미 2000년대 초반에 정립된 표준 프로토콜이라면, 구현하는 게 식은 죽 먹기여야 합니다.
문서화 잘 되어 있고, 레퍼런스 넘쳐나고, 이미 수많은 기업이 쓰고 있으니까요.
WebDAV와 CalDAV 클라이언트/서버를 직접 구현하기로 했을 때, 저희 팀도 그렇게 생각했습니다.
아주 순진했죠.
이건 단순히 바퀴를 다시 발명하는(NIH Syndrome) 문제가 아니었습니다.
기존 라이브러리인 go-webdav를 검토했지만, 저희 제품의 핵심인 '서버 사이드 컬렉션 동기화' 기능이 빠져 있었습니다.
핵심 코어 로직을 남의 라이브러리에 의존하다가 나중에 피 보는 경우, 수도 없이 봐왔습니다.
그래서 직접 만들기로 했습니다.
당연히 첫 단추는 RFC 문서를 정독하는 것이라고 생각했습니다.
RFC 2518을 폈습니다.
알고 보니 RFC 4918로 대체됐다네요.
그런데 뭐가 바뀌었는지는 친절하게 알려주지 않습니다.
확장 RFC가 7개나 더 있습니다.
캘린더 이벤트 CRUD 하나 구현하려는데, 필요 없는 레거시 스펙이 산더미처럼 쌓여 있었습니다.
결국 한 달 동안 RFC 스펙 전체를 구현하려 끙끙대다가 백기를 들었습니다.
리소스 낭비도 이런 낭비가 없었습니다.
방향을 완전히 틀었습니다.
문서 대신 역공학(Reverse Engineering)을 택했습니다.
애플 캘린더, DavX, 썬더버드 같은 클라이언트와 아이클라우드, 구글 캘린더 같은 서버를 뜯어보기로 했습니다.
Wireshark와 HTTP 프록시를 띄워놓고 패킷을 캡처했습니다.
WebDAV라는 녀석이 워낙 모호해서, HTTP 바디만 봐선 답이 안 나옵니다.
헤더까지 꼼꼼하게 뒤져야 비로소 API의 실체가 보이기 시작하더군요.
이 과정에서 Go 언어의 한계와도 싸워야 했습니다.
Go의 기본 XML 라이브러리는... 솔직히 말해 최악입니다.
WebDAV는 요청/응답 스키마가 구조화되지 않은 경우가 태반이라, Go의 정적 타이핑 성격과 상극입니다.
결국 자바스크립트가 DOM을 다루듯, XML 노드를 유연하게 관리하는 래퍼(Wrapper)를 직접 짜야 했습니다.
일일이 구조체(Struct)를 정의하다가는 코드 베이스가 쓰레기장이 될 게 뻔했으니까요.
하지만 진짜 지옥은 MVP를 만들고 나서 펼쳐졌습니다.
기존 상용 서비스들과 연동 테스트를 돌려봤습니다.
충격적인 사실을 깨달았습니다.
"표준은 그저 제안일 뿐이다."
애플과 구글 같은 빅테크들은 RFC 표준의 절반도 구현하지 않았습니다.
심지어 본인들이 지원하지 않는 기능인데도, HTTP 응답 헤더에는 지원한다고 거짓말을 합니다.
문서화? 되어 있을 리가 없죠.
클라이언트 쪽은 더 가관입니다.
효율적인 sync-collection 대신, 애플 캘린더는 구닥다리 ctags와 etags를 고집합니다.
문제는 여기서 발생합니다.
저희 같은 작은 개발사는 "표준을 준수하지 않은" 거대 플랫폼에 맞춰 예외 처리를 덕지덕지 붙여야 합니다.
반면 그들은 우리가 표준을 완벽히 지켜도 신경조차 쓰지 않습니다.
구글에 버그 리포트를 보낸다? 소송을 건다?
계란으로 바위 치기입니다.
오픈소스 라이브러리들을 뜯어보면, 구글이나 애플의 기괴한 구현을 우회하기 위한 주석들이 피눈물처럼 박혀 있는 걸 볼 수 있습니다.
WebDAV나 CalDAV 라이브러리를 직접 만들겠다는 생각이 든다면 말리고 싶습니다.
정신 건강을 위해서라도 하지 마세요.
하지만 굳이 가시밭길을 가겠다면 명심하십시오.
RFC 문서는 참고서일 뿐, 정답지가 아닙니다.
진짜 정답은 지금 이 순간에도 네트워크를 타고 흐르는, 저 지저분한 패킷 속에 있습니다.
결국 엔지니어링은 우아한 문서 작성이 아니라, 진흙탕 속에서 돌아가는 코드를 만들어내는 일이니까요.


